i386: Rewrite pushfl<mode>2 and popfl<mode>1 as unspecs
[official-gcc.git] / gcc / config / i386 / i386.md
blob29289f48e9c058596961215460abee5df29e1471
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2023 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
5 ;;
6 ;; This file is part of GCC.
7 ;;
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.  */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
33 ;;      otherwise nothing
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
42 ;;      delimiter.
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;;      %b0 would print %al if operands[0] is reg 0.
45 ;; w --  likewise, print the HImode name of the register.
46 ;; k --  likewise, print the SImode name of the register.
47 ;; q --  likewise, print the DImode name of the register.
48 ;; x --  likewise, print the V4SFmode name of the register.
49 ;; t --  likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
65 ;; ! -- print NOTRACK prefix for jxx/call/ret instructions if required.
67 (define_c_enum "unspec" [
68   ;; Relocation specifiers
69   UNSPEC_GOT
70   UNSPEC_GOTOFF
71   UNSPEC_GOTPCREL
72   UNSPEC_GOTTPOFF
73   UNSPEC_TPOFF
74   UNSPEC_NTPOFF
75   UNSPEC_DTPOFF
76   UNSPEC_GOTNTPOFF
77   UNSPEC_INDNTPOFF
78   UNSPEC_PLTOFF
79   UNSPEC_MACHOPIC_OFFSET
80   UNSPEC_PCREL
81   UNSPEC_SIZEOF
83   ;; Prologue support
84   UNSPEC_STACK_ALLOC
85   UNSPEC_SET_GOT
86   UNSPEC_SET_RIP
87   UNSPEC_SET_GOT_OFFSET
88   UNSPEC_MEMORY_BLOCKAGE
89   UNSPEC_PROBE_STACK
91   ;; TLS support
92   UNSPEC_TP
93   UNSPEC_TLS_GD
94   UNSPEC_TLS_LD_BASE
95   UNSPEC_TLSDESC
96   UNSPEC_TLS_IE_SUN
98   ;; Other random patterns
99   UNSPEC_SCAS
100   UNSPEC_FNSTSW
101   UNSPEC_SAHF
102   UNSPEC_NOTRAP
103   UNSPEC_PARITY
104   UNSPEC_FSTCW
105   UNSPEC_REP
106   UNSPEC_LD_MPIC        ; load_macho_picbase
107   UNSPEC_TRUNC_NOOP
108   UNSPEC_DIV_ALREADY_SPLIT
109   UNSPEC_PAUSE
110   UNSPEC_LEA_ADDR
111   UNSPEC_XBEGIN_ABORT
112   UNSPEC_STOS
113   UNSPEC_PEEPSIB
114   UNSPEC_INSN_FALSE_DEP
115   UNSPEC_SBB
116   UNSPEC_CC_NE
117   UNSPEC_STC
118   UNSPEC_PUSHFL
119   UNSPEC_POPFL
121   ;; For SSE/MMX support:
122   UNSPEC_FIX_NOTRUNC
123   UNSPEC_MASKMOV
124   UNSPEC_MOVCC_MASK
125   UNSPEC_MOVMSK
126   UNSPEC_INSERTPS
127   UNSPEC_BLENDV
128   UNSPEC_PSHUFB
129   UNSPEC_XOP_PERMUTE
130   UNSPEC_RCP
131   UNSPEC_RSQRT
132   UNSPEC_PSADBW
134   ;; Different from generic us_truncate RTX
135   ;; as it does unsigned saturation of signed source.
136   UNSPEC_US_TRUNCATE
138   ;; For AVX/AVX512F support
139   UNSPEC_SCALEF
140   UNSPEC_PCMP
141   UNSPEC_CVTBFSF
143   ;; Generic math support
144   UNSPEC_IEEE_MIN       ; not commutative
145   UNSPEC_IEEE_MAX       ; not commutative
147   ;; x87 Floating point
148   UNSPEC_SIN
149   UNSPEC_COS
150   UNSPEC_FPATAN
151   UNSPEC_FYL2X
152   UNSPEC_FYL2XP1
153   UNSPEC_FRNDINT
154   UNSPEC_FIST
155   UNSPEC_F2XM1
156   UNSPEC_TAN
157   UNSPEC_FXAM
159   ;; x87 Rounding
160   UNSPEC_FRNDINT_ROUNDEVEN
161   UNSPEC_FRNDINT_FLOOR
162   UNSPEC_FRNDINT_CEIL
163   UNSPEC_FRNDINT_TRUNC
164   UNSPEC_FIST_FLOOR
165   UNSPEC_FIST_CEIL
167   ;; x87 Double output FP
168   UNSPEC_SINCOS_COS
169   UNSPEC_SINCOS_SIN
170   UNSPEC_XTRACT_FRACT
171   UNSPEC_XTRACT_EXP
172   UNSPEC_FSCALE_FRACT
173   UNSPEC_FSCALE_EXP
174   UNSPEC_FPREM_F
175   UNSPEC_FPREM_U
176   UNSPEC_FPREM1_F
177   UNSPEC_FPREM1_U
179   UNSPEC_C2_FLAG
180   UNSPEC_FXAM_MEM
182   ;; SSP patterns
183   UNSPEC_SP_SET
184   UNSPEC_SP_TEST
186   ;; For ROUND support
187   UNSPEC_ROUND
189   ;; For CRC32 support
190   UNSPEC_CRC32
192   ;; For LZCNT suppoprt
193   UNSPEC_LZCNT
195   ;; For BMI support
196   UNSPEC_TZCNT
197   UNSPEC_BEXTR
199   ;; For BMI2 support
200   UNSPEC_PDEP
201   UNSPEC_PEXT
203   ;; IRET support
204   UNSPEC_INTERRUPT_RETURN
206   ;; For MOVDIRI and MOVDIR64B support
207   UNSPEC_MOVDIRI
208   UNSPEC_MOVDIR64B
210   ;; For insn_callee_abi:
211   UNSPEC_CALLEE_ABI
213   ;; For PUSH2/POP2 support
214   UNSPEC_APXPUSH2
215   UNSPEC_APXPOP2_LOW
216   UNSPEC_APXPOP2_HIGH
219 (define_c_enum "unspecv" [
220   UNSPECV_UD2
221   UNSPECV_BLOCKAGE
222   UNSPECV_STACK_PROBE
223   UNSPECV_PROBE_STACK_RANGE
224   UNSPECV_ALIGN
225   UNSPECV_PROLOGUE_USE
226   UNSPECV_SPLIT_STACK_RETURN
227   UNSPECV_CLD
228   UNSPECV_NOPS
229   UNSPECV_RDTSC
230   UNSPECV_RDTSCP
231   UNSPECV_RDPMC
232   UNSPECV_LLWP_INTRINSIC
233   UNSPECV_SLWP_INTRINSIC
234   UNSPECV_LWPVAL_INTRINSIC
235   UNSPECV_LWPINS_INTRINSIC
236   UNSPECV_RDFSBASE
237   UNSPECV_RDGSBASE
238   UNSPECV_WRFSBASE
239   UNSPECV_WRGSBASE
240   UNSPECV_FXSAVE
241   UNSPECV_FXRSTOR
242   UNSPECV_FXSAVE64
243   UNSPECV_FXRSTOR64
244   UNSPECV_XSAVE
245   UNSPECV_XRSTOR
246   UNSPECV_XSAVE64
247   UNSPECV_XRSTOR64
248   UNSPECV_XSAVEOPT
249   UNSPECV_XSAVEOPT64
250   UNSPECV_XSAVES
251   UNSPECV_XRSTORS
252   UNSPECV_XSAVES64
253   UNSPECV_XRSTORS64
254   UNSPECV_XSAVEC
255   UNSPECV_XSAVEC64
256   UNSPECV_XGETBV
257   UNSPECV_XSETBV
258   UNSPECV_WBINVD
259   UNSPECV_WBNOINVD
261   ;; For atomic compound assignments.
262   UNSPECV_FNSTENV
263   UNSPECV_FLDENV
264   UNSPECV_FNSTSW
265   UNSPECV_FNCLEX
267   ;; For RDRAND support
268   UNSPECV_RDRAND
270   ;; For RDSEED support
271   UNSPECV_RDSEED
273   ;; For RTM support
274   UNSPECV_XBEGIN
275   UNSPECV_XEND
276   UNSPECV_XABORT
277   UNSPECV_XTEST
279   UNSPECV_NLGR
281   ;; For CLWB support
282   UNSPECV_CLWB
284   ;; For CLFLUSHOPT support
285   UNSPECV_CLFLUSHOPT
287   ;; For MONITORX and MWAITX support 
288   UNSPECV_MONITORX
289   UNSPECV_MWAITX
291   ;; For CLZERO support
292   UNSPECV_CLZERO
294   ;; For RDPKRU and WRPKRU support
295   UNSPECV_PKU
297   ;; For RDPID support
298   UNSPECV_RDPID
300   ;; For CET support
301   UNSPECV_NOP_ENDBR
302   UNSPECV_NOP_RDSSP
303   UNSPECV_INCSSP
304   UNSPECV_SAVEPREVSSP
305   UNSPECV_RSTORSSP
306   UNSPECV_WRSS
307   UNSPECV_WRUSS
308   UNSPECV_SETSSBSY
309   UNSPECV_CLRSSBSY
311   ;; For TSXLDTRK support
312   UNSPECV_XSUSLDTRK
313   UNSPECV_XRESLDTRK
315   ;; For WAITPKG support
316   UNSPECV_UMWAIT
317   UNSPECV_UMONITOR
318   UNSPECV_TPAUSE
320   ;; For UINTR support
321   UNSPECV_CLUI
322   UNSPECV_STUI
323   UNSPECV_TESTUI
324   UNSPECV_SENDUIPI
326   ;; For CLDEMOTE support
327   UNSPECV_CLDEMOTE
329   ;; For Speculation Barrier support
330   UNSPECV_SPECULATION_BARRIER
332   UNSPECV_PTWRITE
334   ;; For ENQCMD and ENQCMDS support
335   UNSPECV_ENQCMD
336   UNSPECV_ENQCMDS
338   ;; For SERIALIZE support
339   UNSPECV_SERIALIZE
341   ;; For patchable area support
342   UNSPECV_PATCHABLE_AREA
344   ;; For HRESET support
345   UNSPECV_HRESET
347   ;; For PREFETCHI support
348   UNSPECV_PREFETCHI
350   ;; For USER_MSR support
351   UNSPECV_URDMSR
352   UNSPECV_UWRMSR
355 ;; Constants to represent rounding modes in the ROUND instruction
356 (define_constants
357   [(ROUND_ROUNDEVEN             0x0)
358    (ROUND_FLOOR                 0x1)
359    (ROUND_CEIL                  0x2)
360    (ROUND_TRUNC                 0x3)
361    (ROUND_MXCSR                 0x4)
362    (ROUND_NO_EXC                0x8)
363   ])
365 ;; Constants to represent AVX512F embeded rounding
366 (define_constants
367   [(ROUND_NEAREST_INT                   0)
368    (ROUND_NEG_INF                       1)
369    (ROUND_POS_INF                       2)
370    (ROUND_ZERO                          3)
371    (NO_ROUND                            4)
372    (ROUND_SAE                           8)
373   ])
375 ;; Constants to represent pcomtrue/pcomfalse variants
376 (define_constants
377   [(PCOM_FALSE                  0)
378    (PCOM_TRUE                   1)
379    (COM_FALSE_S                 2)
380    (COM_FALSE_P                 3)
381    (COM_TRUE_S                  4)
382    (COM_TRUE_P                  5)
383   ])
385 ;; Constants used in the XOP pperm instruction
386 (define_constants
387   [(PPERM_SRC                   0x00)   /* copy source */
388    (PPERM_INVERT                0x20)   /* invert source */
389    (PPERM_REVERSE               0x40)   /* bit reverse source */
390    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
391    (PPERM_ZERO                  0x80)   /* all 0's */
392    (PPERM_ONES                  0xa0)   /* all 1's */
393    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
394    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
395    (PPERM_SRC1                  0x00)   /* use first source byte */
396    (PPERM_SRC2                  0x10)   /* use second source byte */
397    ])
399 ;; Registers by name.
400 (define_constants
401   [(AX_REG                       0)
402    (DX_REG                       1)
403    (CX_REG                       2)
404    (BX_REG                       3)
405    (SI_REG                       4)
406    (DI_REG                       5)
407    (BP_REG                       6)
408    (SP_REG                       7)
409    (ST0_REG                      8)
410    (ST1_REG                      9)
411    (ST2_REG                     10)
412    (ST3_REG                     11)
413    (ST4_REG                     12)
414    (ST5_REG                     13)
415    (ST6_REG                     14)
416    (ST7_REG                     15)
417    (ARGP_REG                    16)
418    (FLAGS_REG                   17)
419    (FPSR_REG                    18)
420    (FRAME_REG                   19)
421    (XMM0_REG                    20)
422    (XMM1_REG                    21)
423    (XMM2_REG                    22)
424    (XMM3_REG                    23)
425    (XMM4_REG                    24)
426    (XMM5_REG                    25)
427    (XMM6_REG                    26)
428    (XMM7_REG                    27)
429    (MM0_REG                     28)
430    (MM1_REG                     29)
431    (MM2_REG                     30)
432    (MM3_REG                     31)
433    (MM4_REG                     32)
434    (MM5_REG                     33)
435    (MM6_REG                     34)
436    (MM7_REG                     35)
437    (R8_REG                      36)
438    (R9_REG                      37)
439    (R10_REG                     38)
440    (R11_REG                     39)
441    (R12_REG                     40)
442    (R13_REG                     41)
443    (R14_REG                     42)
444    (R15_REG                     43)
445    (XMM8_REG                    44)
446    (XMM9_REG                    45)
447    (XMM10_REG                   46)
448    (XMM11_REG                   47)
449    (XMM12_REG                   48)
450    (XMM13_REG                   49)
451    (XMM14_REG                   50)
452    (XMM15_REG                   51)
453    (XMM16_REG                   52)
454    (XMM17_REG                   53)
455    (XMM18_REG                   54)
456    (XMM19_REG                   55)
457    (XMM20_REG                   56)
458    (XMM21_REG                   57)
459    (XMM22_REG                   58)
460    (XMM23_REG                   59)
461    (XMM24_REG                   60)
462    (XMM25_REG                   61)
463    (XMM26_REG                   62)
464    (XMM27_REG                   63)
465    (XMM28_REG                   64)
466    (XMM29_REG                   65)
467    (XMM30_REG                   66)
468    (XMM31_REG                   67)
469    (MASK0_REG                   68)
470    (MASK1_REG                   69)
471    (MASK2_REG                   70)
472    (MASK3_REG                   71)
473    (MASK4_REG                   72)
474    (MASK5_REG                   73)
475    (MASK6_REG                   74)
476    (MASK7_REG                   75)
477    (R16_REG                     76)
478    (R17_REG                     77)
479    (R18_REG                     78)
480    (R19_REG                     79)
481    (R20_REG                     80)
482    (R21_REG                     81)
483    (R22_REG                     82)
484    (R23_REG                     83)
485    (R24_REG                     84)
486    (R25_REG                     85)
487    (R26_REG                     86)
488    (R27_REG                     87)
489    (R28_REG                     88)
490    (R29_REG                     89)
491    (R30_REG                     90)
492    (R31_REG                     91)
493    (FIRST_PSEUDO_REG            92)
494   ])
496 ;; Insn callee abi index.
497 (define_constants
498   [(ABI_DEFAULT         0)
499    (ABI_VZEROUPPER      1)
500    (ABI_UNKNOWN         2)])
502 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
503 ;; from i386.cc.
505 ;; In C guard expressions, put expressions which may be compile-time
506 ;; constants first.  This allows for better optimization.  For
507 ;; example, write "TARGET_64BIT && reload_completed", not
508 ;; "reload_completed && TARGET_64BIT".
511 ;; Processor type.
512 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
513                     atom,slm,glm,haswell,generic,lujiazui,yongfeng,amdfam10,bdver1,
514                     bdver2,bdver3,bdver4,btver2,znver1,znver2,znver3,znver4"
515   (const (symbol_ref "ix86_schedule")))
517 ;; A basic instruction type.  Refinements due to arguments to be
518 ;; provided in other attributes.
519 (define_attr "type"
520   "other,multi,
521    alu,alu1,negnot,imov,imovx,lea,
522    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
523    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
524    push,pop,call,callv,leave,
525    str,bitmanip,
526    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
527    fxch,fistp,fisttp,frndint,
528    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
529    ssemul,sseimul,ssediv,sselog,sselog1,
530    sseishft,sseishft1,ssecmp,ssecomi,
531    ssecvt,ssecvt1,sseicvt,sseins,
532    sseshuf,sseshuf1,ssemuladd,sse4arg,
533    lwp,mskmov,msklog,
534    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
535   (const_string "other"))
537 ;; Main data type used by the insn
538 (define_attr "mode"
539   "unknown,none,QI,HI,SI,DI,TI,OI,XI,HF,BF,SF,DF,XF,TF,V32HF,V16HF,V8HF,
540    V16SF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,V8DF,V4HF,V4BF,V2HF,V2BF"
541   (const_string "unknown"))
543 ;; The CPU unit operations uses.
544 (define_attr "unit" "integer,i387,sse,mmx,unknown"
545   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
546                           fxch,fistp,fisttp,frndint")
547            (const_string "i387")
548          (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
549                           ssemul,sseimul,ssediv,sselog,sselog1,
550                           sseishft,sseishft1,ssecmp,ssecomi,
551                           ssecvt,ssecvt1,sseicvt,sseins,
552                           sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
553            (const_string "sse")
554          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
555            (const_string "mmx")
556          (eq_attr "type" "other")
557            (const_string "unknown")]
558          (const_string "integer")))
560 ;; Used to control the "enabled" attribute on a per-instruction basis.
561 (define_attr "isa" "base,x64,nox64,x64_sse2,x64_sse4,x64_sse4_noavx,
562                     x64_avx,x64_avx512bw,x64_avx512dq,aes,
563                     sse_noavx,sse2,sse2_noavx,sse3,sse3_noavx,sse4,sse4_noavx,
564                     avx,noavx,avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,avx512f_512,
565                     noavx512f,avx512bw,avx512bw_512,noavx512bw,avx512dq,
566                     noavx512dq,fma_or_avx512vl,avx512vl,noavx512vl,avxvnni,
567                     avx512vnnivl,avx512fp16,avxifma,avx512ifmavl,avxneconvert,
568                     avx512bf16vl,vpclmulqdqvl,avx_noavx512f,avx_noavx512vl"
569   (const_string "base"))
571 ;; The (bounding maximum) length of an instruction immediate.
572 (define_attr "length_immediate" ""
573   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
574                           bitmanip,imulx,msklog,mskmov")
575            (const_int 0)
576          (ior (eq_attr "type" "sse4arg")
577               (eq_attr "isa" "fma4"))
578            (const_int 1)
579          (eq_attr "unit" "i387,sse,mmx")
580            (const_int 0)
581          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
582                           rotate,rotatex,rotate1,imul,icmp,push,pop")
583            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
584          (eq_attr "type" "imov,test")
585            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
586          (eq_attr "type" "call")
587            (if_then_else (match_operand 0 "constant_call_address_operand")
588              (const_int 4)
589              (const_int 0))
590          (eq_attr "type" "callv")
591            (if_then_else (match_operand 1 "constant_call_address_operand")
592              (const_int 4)
593              (const_int 0))
594          ;; We don't know the size before shorten_branches.  Expect
595          ;; the instruction to fit for better scheduling.
596          (eq_attr "type" "ibr")
597            (const_int 1)
598          ]
599          (symbol_ref "/* Update immediate_length and other attributes! */
600                       gcc_unreachable (),1")))
602 ;; The (bounding maximum) length of an instruction address.
603 (define_attr "length_address" ""
604   (cond [(eq_attr "type" "str,other,multi,fxch")
605            (const_int 0)
606          (and (eq_attr "type" "call")
607               (match_operand 0 "constant_call_address_operand"))
608              (const_int 0)
609          (and (eq_attr "type" "callv")
610               (match_operand 1 "constant_call_address_operand"))
611              (const_int 0)
612          ]
613          (symbol_ref "ix86_attr_length_address_default (insn)")))
615 ;; Set when length prefix is used.
616 (define_attr "prefix_data16" ""
617   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
618            (const_int 0)
619          (eq_attr "mode" "HI")
620            (const_int 1)
621          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
622            (const_int 1)
623         ]
624         (const_int 0)))
626 ;; Set when string REP prefix is used.
627 (define_attr "prefix_rep" ""
628   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
629            (const_int 0)
630          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
631            (const_int 1)
632         ]
633         (const_int 0)))
635 ;; Set when 0f opcode prefix is used.
636 (define_attr "prefix_0f" ""
637   (if_then_else
638     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
639          (eq_attr "unit" "sse,mmx"))
640     (const_int 1)
641     (const_int 0)))
643 ;; Set when REX opcode prefix is used.
644 (define_attr "prefix_rex" ""
645   (cond [(not (match_test "TARGET_64BIT"))
646            (const_int 0)
647          (and (eq_attr "mode" "DI")
648               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
649                    (eq_attr "unit" "!mmx")))
650            (const_int 1)
651          (and (eq_attr "mode" "QI")
652               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
653            (const_int 1)
654          (match_test "x86_extended_reg_mentioned_p (insn)")
655            (const_int 1)
656          (and (eq_attr "type" "imovx")
657               (match_operand:QI 1 "ext_QIreg_operand"))
658            (const_int 1)
659         ]
660         (const_int 0)))
662 ;; There are also additional prefixes in 3DNOW, SSSE3.
663 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
664 ;; While generally inapplicable to VEX/XOP/EVEX encodings, "length_vex" uses
665 ;; the attribute evaluating to zero to know that VEX2 encoding may be usable.
666 (define_attr "prefix_extra" ""
667   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
668            (const_int 1)
669         ]
670         (const_int 0)))
672 ;; Prefix used: original, VEX or maybe VEX.
673 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
674   (cond [(eq_attr "mode" "OI,V8SF,V4DF")
675            (const_string "vex")
676          (eq_attr "mode" "XI,V16SF,V8DF")
677            (const_string "evex")
678          (eq_attr "type" "ssemuladd")
679            (if_then_else (eq_attr "isa" "fma4")
680              (const_string "vex")
681              (const_string "maybe_evex"))
682          (eq_attr "type" "sse4arg")
683            (const_string "vex")
684         ]
685         (const_string "orig")))
687 ;; VEX W bit is used.
688 (define_attr "prefix_vex_w" "" (const_int 0))
690 ;; The length of VEX prefix
691 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
692 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
693 ;; still prefix_0f 1, with prefix_extra 1.
694 (define_attr "length_vex" ""
695   (if_then_else (and (eq_attr "prefix_0f" "1")
696                      (eq_attr "prefix_extra" "0"))
697     (if_then_else (eq_attr "prefix_vex_w" "1")
698       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
699       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
700     (if_then_else (eq_attr "prefix_vex_w" "1")
701       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
702       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
704 ;; 4-bytes evex prefix and 1 byte opcode.
705 (define_attr "length_evex" "" (const_int 5))
707 ;; Set when modrm byte is used.
708 (define_attr "modrm" ""
709   (cond [(eq_attr "type" "str,leave")
710            (const_int 0)
711          (eq_attr "unit" "i387")
712            (const_int 0)
713          (and (eq_attr "type" "incdec")
714               (and (not (match_test "TARGET_64BIT"))
715                    (ior (match_operand:SI 1 "register_operand")
716                         (match_operand:HI 1 "register_operand"))))
717            (const_int 0)
718          (and (eq_attr "type" "push")
719               (not (match_operand 1 "memory_operand")))
720            (const_int 0)
721          (and (eq_attr "type" "pop")
722               (not (match_operand 0 "memory_operand")))
723            (const_int 0)
724          (and (eq_attr "type" "imov")
725               (and (not (eq_attr "mode" "DI"))
726                    (ior (and (match_operand 0 "register_operand")
727                              (match_operand 1 "immediate_operand"))
728                         (ior (and (match_operand 0 "ax_reg_operand")
729                                   (match_operand 1 "memory_displacement_only_operand"))
730                              (and (match_operand 0 "memory_displacement_only_operand")
731                                   (match_operand 1 "ax_reg_operand"))))))
732            (const_int 0)
733          (and (eq_attr "type" "call")
734               (match_operand 0 "constant_call_address_operand"))
735              (const_int 0)
736          (and (eq_attr "type" "callv")
737               (match_operand 1 "constant_call_address_operand"))
738              (const_int 0)
739          (and (eq_attr "type" "alu,alu1,icmp,test")
740               (match_operand 0 "ax_reg_operand"))
741              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
742          ]
743          (const_int 1)))
745 ;; The (bounding maximum) length of an instruction in bytes.
746 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
747 ;; Later we may want to split them and compute proper length as for
748 ;; other insns.
749 (define_attr "length" ""
750   (cond [(eq_attr "type" "other,multi,fistp,frndint")
751            (const_int 16)
752          (eq_attr "type" "fcmp")
753            (const_int 4)
754          (eq_attr "unit" "i387")
755            (plus (const_int 2)
756                  (plus (attr "prefix_data16")
757                        (attr "length_address")))
758          (ior (eq_attr "prefix" "evex")
759               (and (ior (eq_attr "prefix" "maybe_evex")
760                         (eq_attr "prefix" "maybe_vex"))
761                    (match_test "TARGET_AVX512F")))
762            (plus (attr "length_evex")
763                  (plus (attr "length_immediate")
764                        (plus (attr "modrm")
765                              (attr "length_address"))))
766          (ior (eq_attr "prefix" "vex")
767               (and (ior (eq_attr "prefix" "maybe_vex")
768                         (eq_attr "prefix" "maybe_evex"))
769                    (match_test "TARGET_AVX")))
770            (plus (attr "length_vex")
771                  (plus (attr "length_immediate")
772                        (plus (attr "modrm")
773                              (attr "length_address"))))]
774          (plus (plus (attr "modrm")
775                      (plus (attr "prefix_0f")
776                            (plus (attr "prefix_rex")
777                                  (plus (attr "prefix_extra")
778                                        (const_int 1)))))
779                (plus (attr "prefix_rep")
780                      (plus (attr "prefix_data16")
781                            (plus (attr "length_immediate")
782                                  (attr "length_address")))))))
784 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
785 ;; `store' if there is a simple memory reference therein, or `unknown'
786 ;; if the instruction is complex.
788 (define_attr "memory" "none,load,store,both,unknown"
789   (cond [(eq_attr "type" "other,multi,str,lwp")
790            (const_string "unknown")
791          (eq_attr "type" "lea,fcmov,fpspc")
792            (const_string "none")
793          (eq_attr "type" "fistp,leave")
794            (const_string "both")
795          (eq_attr "type" "frndint")
796            (const_string "load")
797          (eq_attr "type" "push")
798            (if_then_else (match_operand 1 "memory_operand")
799              (const_string "both")
800              (const_string "store"))
801          (eq_attr "type" "pop")
802            (if_then_else (match_operand 0 "memory_operand")
803              (const_string "both")
804              (const_string "load"))
805          (eq_attr "type" "setcc")
806            (if_then_else (match_operand 0 "memory_operand")
807              (const_string "store")
808              (const_string "none"))
809          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
810            (if_then_else (ior (match_operand 0 "memory_operand")
811                               (match_operand 1 "memory_operand"))
812              (const_string "load")
813              (const_string "none"))
814          (eq_attr "type" "ibr")
815            (if_then_else (match_operand 0 "memory_operand")
816              (const_string "load")
817              (const_string "none"))
818          (eq_attr "type" "call")
819            (if_then_else (match_operand 0 "constant_call_address_operand")
820              (const_string "none")
821              (const_string "load"))
822          (eq_attr "type" "callv")
823            (if_then_else (match_operand 1 "constant_call_address_operand")
824              (const_string "none")
825              (const_string "load"))
826          (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
827               (match_operand 1 "memory_operand"))
828            (const_string "both")
829          (and (match_operand 0 "memory_operand")
830               (match_operand 1 "memory_operand"))
831            (const_string "both")
832          (match_operand 0 "memory_operand")
833            (const_string "store")
834          (match_operand 1 "memory_operand")
835            (const_string "load")
836          (and (eq_attr "type"
837                  "!alu1,negnot,ishift1,rotate1,
838                    imov,imovx,icmp,test,bitmanip,
839                    fmov,fcmp,fsgn,
840                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
841                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
842                    mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
843               (match_operand 2 "memory_operand"))
844            (const_string "load")
845          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
846               (match_operand 3 "memory_operand"))
847            (const_string "load")
848         ]
849         (const_string "none")))
851 ;; Indicates if an instruction has both an immediate and a displacement.
853 (define_attr "imm_disp" "false,true,unknown"
854   (cond [(eq_attr "type" "other,multi")
855            (const_string "unknown")
856          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
857               (and (match_operand 0 "memory_displacement_operand")
858                    (match_operand 1 "immediate_operand")))
859            (const_string "true")
860          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
861               (and (match_operand 0 "memory_displacement_operand")
862                    (match_operand 2 "immediate_operand")))
863            (const_string "true")
864         ]
865         (const_string "false")))
867 ;; Indicates if an FP operation has an integer source.
869 (define_attr "fp_int_src" "false,true"
870   (const_string "false"))
872 ;; Defines rounding mode of an FP operation.
874 (define_attr "i387_cw" "roundeven,floor,ceil,trunc,uninitialized,any"
875   (const_string "any"))
877 ;; Define attribute to indicate AVX insns with partial XMM register update.
878 (define_attr "avx_partial_xmm_update" "false,true"
879   (const_string "false"))
881 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
882 (define_attr "use_carry" "0,1" (const_string "0"))
884 ;; Define attribute to indicate unaligned ssemov insns
885 (define_attr "movu" "0,1" (const_string "0"))
887 ;; Define attribute to limit memory address register set.
888 (define_attr "addr" "gpr8,gpr16,gpr32" (const_string "gpr32"))
890 ;; Define instruction set of MMX instructions
891 (define_attr "mmx_isa" "base,native,sse,sse_noavx,avx"
892   (const_string "base"))
894 (define_attr "enabled" ""
895   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
896          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
897          (eq_attr "isa" "x64_sse2")
898            (symbol_ref "TARGET_64BIT && TARGET_SSE2")
899          (eq_attr "isa" "x64_sse4")
900            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
901          (eq_attr "isa" "x64_sse4_noavx")
902            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
903          (eq_attr "isa" "x64_avx")
904            (symbol_ref "TARGET_64BIT && TARGET_AVX")
905          (eq_attr "isa" "x64_avx512bw")
906            (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
907          (eq_attr "isa" "x64_avx512dq")
908            (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
909          (eq_attr "isa" "aes") (symbol_ref "TARGET_AES")
910          (eq_attr "isa" "sse_noavx")
911            (symbol_ref "TARGET_SSE && !TARGET_AVX")
912          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
913          (eq_attr "isa" "sse2_noavx")
914            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
915          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
916          (eq_attr "isa" "sse3_noavx")
917            (symbol_ref "TARGET_SSE3 && !TARGET_AVX")
918          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
919          (eq_attr "isa" "sse4_noavx")
920            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
921          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
922          (eq_attr "isa" "avx_noavx512f")
923            (symbol_ref "TARGET_AVX && !TARGET_AVX512F")
924          (eq_attr "isa" "avx_noavx512vl")
925            (symbol_ref "TARGET_AVX && !TARGET_AVX512VL")
926          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
927          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
928          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
929          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
930          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
931          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
932          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
933          (eq_attr "isa" "fma_or_avx512vl")
934            (symbol_ref "TARGET_FMA || TARGET_AVX512VL")
935          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
936          (eq_attr "isa" "avx512f_512")
937            (symbol_ref "TARGET_AVX512F && TARGET_EVEX512")
938          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
939          (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
940          (eq_attr "isa" "avx512bw_512")
941            (symbol_ref "TARGET_AVX512BW && TARGET_EVEX512")
942          (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
943          (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
944          (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
945          (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
946          (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
947          (eq_attr "isa" "avxvnni") (symbol_ref "TARGET_AVXVNNI")
948          (eq_attr "isa" "avx512vnnivl")
949            (symbol_ref "TARGET_AVX512VNNI && TARGET_AVX512VL")
950          (eq_attr "isa" "avx512fp16")
951            (symbol_ref "TARGET_AVX512FP16")
952          (eq_attr "isa" "avxifma") (symbol_ref "TARGET_AVXIFMA")
953          (eq_attr "isa" "avx512ifmavl")
954            (symbol_ref "TARGET_AVX512IFMA && TARGET_AVX512VL")
955          (eq_attr "isa" "avxneconvert") (symbol_ref "TARGET_AVXNECONVERT")
956          (eq_attr "isa" "avx512bf16vl")
957            (symbol_ref "TARGET_AVX512BF16 && TARGET_AVX512VL")
958          (eq_attr "isa" "vpclmulqdqvl")
959            (symbol_ref "TARGET_VPCLMULQDQ && TARGET_AVX512VL")
961          (eq_attr "mmx_isa" "native")
962            (symbol_ref "!TARGET_MMX_WITH_SSE")
963          (eq_attr "mmx_isa" "sse")
964            (symbol_ref "TARGET_MMX_WITH_SSE")
965          (eq_attr "mmx_isa" "sse_noavx")
966            (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
967          (eq_attr "mmx_isa" "avx")
968            (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
969         ]
970         (const_int 1)))
972 (define_attr "preferred_for_size" "" (const_int 1))
973 (define_attr "preferred_for_speed" "" (const_int 1))
975 ;; Describe a user's asm statement.
976 (define_asm_attributes
977   [(set_attr "length" "128")
978    (set_attr "type" "multi")])
980 (define_code_iterator plusminus [plus minus])
981 (define_code_iterator plusminusmult [plus minus mult])
982 (define_code_iterator plusminusmultdiv [plus minus mult div])
984 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
986 ;; Base name for insn mnemonic.
987 (define_code_attr plusminus_mnemonic
988   [(plus "add") (ss_plus "adds") (us_plus "addus")
989    (minus "sub") (ss_minus "subs") (us_minus "subus")])
991 (define_code_iterator multdiv [mult div])
993 (define_code_attr multdiv_mnemonic
994   [(mult "mul") (div "div")])
996 ;; Mark commutative operators as such in constraints.
997 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
998                         (minus "") (ss_minus "") (us_minus "")
999                         (mult "%") (div "")])
1001 ;; Mapping of max and min
1002 (define_code_iterator maxmin [smax smin umax umin])
1004 ;; Mapping of signed max and min
1005 (define_code_iterator smaxmin [smax smin])
1007 ;; Mapping of unsigned max and min
1008 (define_code_iterator umaxmin [umax umin])
1010 ;; Base name for integer and FP insn mnemonic
1011 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
1012                               (umax "maxu") (umin "minu")])
1013 (define_code_attr maxmin_float [(smax "max") (smin "min")])
1015 (define_int_iterator IEEE_MAXMIN
1016         [UNSPEC_IEEE_MAX
1017          UNSPEC_IEEE_MIN])
1019 (define_int_attr ieee_maxmin
1020         [(UNSPEC_IEEE_MAX "max")
1021          (UNSPEC_IEEE_MIN "min")])
1023 ;; Mapping of logic operators
1024 (define_code_iterator any_logic [and ior xor])
1025 (define_code_iterator any_or [ior xor])
1026 (define_code_iterator fpint_logic [and xor])
1028 ;; Base name for insn mnemonic.
1029 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
1031 ;; Mapping of logic-shift operators
1032 (define_code_iterator any_lshift [ashift lshiftrt])
1034 ;; Mapping of shift-right operators
1035 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
1037 ;; Mapping of all shift operators
1038 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
1040 ;; Base name for insn mnemonic.
1041 (define_code_attr shift [(ashift "sal") (lshiftrt "shr") (ashiftrt "sar")])
1042 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
1044 ;; Mapping of rotate operators
1045 (define_code_iterator any_rotate [rotate rotatert])
1047 ;; Base name for insn mnemonic.
1048 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
1050 ;; Mapping of abs neg operators
1051 (define_code_iterator absneg [abs neg])
1053 ;; Mapping of abs neg operators to logic operation
1054 (define_code_attr absneg_op [(abs "and") (neg "xor")])
1056 ;; Base name for x87 insn mnemonic.
1057 (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
1059 ;; Mapping of extend operators
1060 (define_code_iterator any_extend [sign_extend zero_extend])
1062 ;; Mapping of highpart multiply operators
1063 (define_code_iterator any_mul_highpart [smul_highpart umul_highpart])
1065 ;; Prefix for insn menmonic.
1066 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
1067                              (smul_highpart "i") (umul_highpart "")
1068                              (div "i") (udiv "")])
1069 ;; Prefix for define_insn
1070 (define_code_attr s [(sign_extend "s") (zero_extend "u")
1071                      (smul_highpart "s") (umul_highpart "u")])
1072 (define_code_attr u [(sign_extend "") (zero_extend "u")
1073                      (div "") (udiv "u")])
1074 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")
1075                           (div "false") (udiv "true")])
1077 ;; Used in signed and unsigned truncations.
1078 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
1079 ;; Instruction suffix for truncations.
1080 (define_code_attr trunsuffix
1081   [(ss_truncate "s") (truncate "") (us_truncate "us")])
1083 ;; Instruction suffix for SSE sign and zero extensions.
1084 (define_code_attr extsuffix [(sign_extend "sx") (zero_extend "zx")])
1086 ;; Used in signed and unsigned fix.
1087 (define_code_iterator any_fix [fix unsigned_fix])
1088 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
1089 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
1090 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
1092 ;; Used in signed and unsigned float.
1093 (define_code_iterator any_float [float unsigned_float])
1094 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
1095 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
1096 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
1098 ;; Base name for expression
1099 (define_code_attr insn
1100   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
1101    (minus "sub") (ss_minus "sssub") (us_minus "ussub")
1102    (sign_extend "extend") (zero_extend "zero_extend")
1103    (ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")
1104    (rotate "rotl") (rotatert "rotr")
1105    (mult "mul") (div "div")])
1107 ;; All integer modes.
1108 (define_mode_iterator SWI1248x [QI HI SI DI])
1110 ;; All integer modes without QImode.
1111 (define_mode_iterator SWI248x [HI SI DI])
1113 ;; All integer modes without QImode and HImode.
1114 (define_mode_iterator SWI48x [SI DI])
1116 ;; All integer modes without SImode and DImode.
1117 (define_mode_iterator SWI12 [QI HI])
1119 ;; All integer modes without DImode.
1120 (define_mode_iterator SWI124 [QI HI SI])
1122 ;; All integer modes without QImode and DImode.
1123 (define_mode_iterator SWI24 [HI SI])
1125 ;; Single word integer modes.
1126 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1128 ;; Single word integer modes without QImode.
1129 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1131 ;; Single word integer modes without QImode and HImode.
1132 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1134 ;; All math-dependant single and double word integer modes.
1135 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1136                              (HI "TARGET_HIMODE_MATH")
1137                              SI DI (TI "TARGET_64BIT")])
1139 ;; Math-dependant single word integer modes.
1140 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1141                             (HI "TARGET_HIMODE_MATH")
1142                             SI (DI "TARGET_64BIT")])
1144 ;; Math-dependant integer modes without DImode.
1145 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1146                                (HI "TARGET_HIMODE_MATH")
1147                                SI])
1149 ;; Math-dependant integer modes with DImode.
1150 (define_mode_iterator SWIM1248x
1151         [(QI "TARGET_QIMODE_MATH")
1152          (HI "TARGET_HIMODE_MATH")
1153          SI DI])
1155 ;; Math-dependant single word integer modes without QImode.
1156 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1157                                SI (DI "TARGET_64BIT")])
1159 ;; Double word integer modes.
1160 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1161                            (TI "TARGET_64BIT")])
1163 ;; SWI and DWI together.
1164 (define_mode_iterator SWIDWI [QI HI SI DI (TI "TARGET_64BIT")])
1166 ;; SWI48 and DWI together.
1167 (define_mode_iterator SWI48DWI [SI DI (TI "TARGET_64BIT")])
1169 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
1170 ;; compile time constant, it is faster to use <MODE_SIZE> than
1171 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
1172 ;; command line options just use GET_MODE_SIZE macro.
1173 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8")
1174                              (TI "16") (HF "2") (BF "2") (SF "4") (DF "8")
1175                              (XF "GET_MODE_SIZE (XFmode)")
1176                              (V16QI "16") (V32QI "32") (V64QI "64")
1177                              (V8HI "16") (V16HI "32") (V32HI "64")
1178                              (V4SI "16") (V8SI "32") (V16SI "64")
1179                              (V2DI "16") (V4DI "32") (V8DI "64")
1180                              (V1TI "16") (V2TI "32") (V4TI "64")
1181                              (V2DF "16") (V4DF "32") (V8DF "64")
1182                              (V4SF "16") (V8SF "32") (V16SF "64")
1183                              (V8HF "16") (V16HF "32") (V32HF "64")
1184                              (V4HF "8") (V2HF "4")
1185                              (V8BF "16") (V16BF "32") (V32BF "64")
1186                              (V4BF "8") (V2BF "4")])
1188 ;; Double word integer modes as mode attribute.
1189 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "OI")])
1190 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti") (TI "oi")])
1192 ;; Half sized integer modes.
1193 (define_mode_attr HALF [(TI "DI") (DI "SI")])
1194 (define_mode_attr half [(TI "di") (DI "si")])
1196 ;; LEA mode corresponding to an integer mode
1197 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1199 ;; Half mode for double word integer modes.
1200 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1201                             (DI "TARGET_64BIT")])
1203 ;; Instruction suffix for integer modes.
1204 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1206 ;; Instruction suffix for masks.
1207 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1209 ;; Pointer size prefix for integer modes (Intel asm dialect)
1210 (define_mode_attr iptrsize [(QI "BYTE")
1211                             (HI "WORD")
1212                             (SI "DWORD")
1213                             (DI "QWORD")])
1215 ;; Register class for integer modes.
1216 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1218 ;; Immediate operand constraint for integer modes.
1219 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1221 ;; General operand constraint for word modes.
1222 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1224 ;; Memory operand constraint for word modes.
1225 (define_mode_attr m [(QI "m") (HI "m") (SI "BM") (DI "BM")])
1227 ;; Immediate operand constraint for double integer modes.
1228 (define_mode_attr di [(SI "nF") (DI "Wd")])
1230 ;; Immediate operand constraint for shifts.
1231 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1232 (define_mode_attr KS [(QI "Wb") (HI "Ww") (SI "I") (DI "J")])
1234 ;; Print register name in the specified mode.
1235 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1237 ;; General operand predicate for integer modes.
1238 (define_mode_attr general_operand
1239         [(QI "general_operand")
1240          (HI "general_operand")
1241          (SI "x86_64_general_operand")
1242          (DI "x86_64_general_operand")
1243          (TI "x86_64_general_operand")])
1245 ;; General operand predicate for integer modes, where for TImode
1246 ;; we need both words of the operand to be general operands.
1247 (define_mode_attr general_hilo_operand
1248         [(QI "general_operand")
1249          (HI "general_operand")
1250          (SI "x86_64_general_operand")
1251          (DI "x86_64_general_operand")
1252          (TI "x86_64_hilo_general_operand")])
1254 ;; General sign extend operand predicate for integer modes,
1255 ;; which disallows VOIDmode operands and thus it is suitable
1256 ;; for use inside sign_extend.
1257 (define_mode_attr general_sext_operand
1258         [(QI "sext_operand")
1259          (HI "sext_operand")
1260          (SI "x86_64_sext_operand")
1261          (DI "x86_64_sext_operand")])
1263 ;; General sign/zero extend operand predicate for integer modes.
1264 (define_mode_attr general_szext_operand
1265         [(QI "general_operand")
1266          (HI "general_operand")
1267          (SI "x86_64_szext_general_operand")
1268          (DI "x86_64_szext_general_operand")
1269          (TI "x86_64_hilo_general_operand")])
1271 (define_mode_attr nonmemory_szext_operand
1272         [(QI "nonmemory_operand")
1273          (HI "nonmemory_operand")
1274          (SI "x86_64_szext_nonmemory_operand")
1275          (DI "x86_64_szext_nonmemory_operand")])
1277 ;; Immediate operand predicate for integer modes.
1278 (define_mode_attr immediate_operand
1279         [(QI "immediate_operand")
1280          (HI "immediate_operand")
1281          (SI "x86_64_immediate_operand")
1282          (DI "x86_64_immediate_operand")])
1284 ;; Nonmemory operand predicate for integer modes.
1285 (define_mode_attr nonmemory_operand
1286         [(QI "nonmemory_operand")
1287          (HI "nonmemory_operand")
1288          (SI "x86_64_nonmemory_operand")
1289          (DI "x86_64_nonmemory_operand")])
1291 ;; Operand predicate for shifts.
1292 (define_mode_attr shift_operand
1293         [(QI "nonimmediate_operand")
1294          (HI "nonimmediate_operand")
1295          (SI "nonimmediate_operand")
1296          (DI "shiftdi_operand")
1297          (TI "register_operand")])
1299 ;; Operand predicate for shift argument.
1300 (define_mode_attr shift_immediate_operand
1301         [(QI "const_1_to_31_operand")
1302          (HI "const_1_to_31_operand")
1303          (SI "const_1_to_31_operand")
1304          (DI "const_1_to_63_operand")])
1306 ;; Input operand predicate for arithmetic left shifts.
1307 (define_mode_attr ashl_input_operand
1308         [(QI "nonimmediate_operand")
1309          (HI "nonimmediate_operand")
1310          (SI "nonimmediate_operand")
1311          (DI "ashldi_input_operand")
1312          (TI "reg_or_pm1_operand")])
1314 ;; SSE and x87 SFmode and DFmode floating point modes
1315 (define_mode_iterator MODEF [SF DF])
1317 ;; SSE floating point modes
1318 (define_mode_iterator MODEFH [(HF "TARGET_AVX512FP16") SF DF])
1320 ;; All x87 floating point modes
1321 (define_mode_iterator X87MODEF [SF DF XF])
1323 ;; All x87 floating point modes plus HFmode
1324 (define_mode_iterator X87MODEFH [HF SF DF XF BF])
1326 ;; All SSE floating point modes
1327 (define_mode_iterator SSEMODEF [HF SF DF TF])
1328 (define_mode_attr ssevecmodef [(HF "V8HF") (SF "V4SF") (DF "V2DF") (TF "TF")])
1330 ;; SSE instruction suffix for various modes
1331 (define_mode_attr ssemodesuffix
1332   [(HF "sh") (SF "ss") (DF "sd")
1333    (V32HF "ph") (V16SF "ps") (V8DF "pd")
1334    (V16HF "ph") (V16BF "bf") (V8SF "ps") (V4DF "pd")
1335    (V8HF "ph")  (V8BF "bf") (V4SF "ps") (V2DF "pd")
1336    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1337    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1338    (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1340 ;; SSE vector suffix for floating point modes
1341 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1343 ;; SSE vector mode corresponding to a scalar mode
1344 (define_mode_attr ssevecmode
1345   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (HF "V8HF") (BF "V8BF") (SF "V4SF") (DF "V2DF")])
1346 (define_mode_attr ssevecmodelower
1347   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1349 ;; AVX512F vector mode corresponding to a scalar mode
1350 (define_mode_attr avx512fvecmode
1351   [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1353 ;; Instruction suffix for REX 64bit operators.
1354 (define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")])
1355 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1357 ;; This mode iterator allows :P to be used for patterns that operate on
1358 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1359 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1361 ;; This mode iterator allows :W to be used for patterns that operate on
1362 ;; word_mode sized quantities.
1363 (define_mode_iterator W
1364   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1366 ;; This mode iterator allows :PTR to be used for patterns that operate on
1367 ;; ptr_mode sized quantities.
1368 (define_mode_iterator PTR
1369   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1371 ;; Scheduling descriptions
1373 (include "pentium.md")
1374 (include "ppro.md")
1375 (include "k6.md")
1376 (include "athlon.md")
1377 (include "bdver1.md")
1378 (include "bdver3.md")
1379 (include "btver2.md")
1380 (include "znver.md")
1381 (include "znver4.md")
1382 (include "geode.md")
1383 (include "atom.md")
1384 (include "slm.md")
1385 (include "glm.md")
1386 (include "core2.md")
1387 (include "haswell.md")
1388 (include "lujiazui.md")
1389 (include "yongfeng.md")
1392 ;; Operand and operator predicates and constraints
1394 (include "predicates.md")
1395 (include "constraints.md")
1398 ;; Compare and branch/compare and store instructions.
1400 (define_expand "cbranch<mode>4"
1401   [(set (reg:CC FLAGS_REG)
1402         (compare:CC (match_operand:SWIM1248x 1 "nonimmediate_operand")
1403                     (match_operand:SWIM1248x 2 "<general_operand>")))
1404    (set (pc) (if_then_else
1405                (match_operator 0 "ordered_comparison_operator"
1406                 [(reg:CC FLAGS_REG) (const_int 0)])
1407                (label_ref (match_operand 3))
1408                (pc)))]
1409   ""
1411   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1412     operands[1] = force_reg (<MODE>mode, operands[1]);
1413   ix86_expand_branch (GET_CODE (operands[0]),
1414                       operands[1], operands[2], operands[3]);
1415   DONE;
1418 (define_expand "cbranchti4"
1419   [(set (reg:CC FLAGS_REG)
1420         (compare:CC (match_operand:TI 1 "nonimmediate_operand")
1421                     (match_operand:TI 2 "ix86_timode_comparison_operand")))
1422    (set (pc) (if_then_else
1423                (match_operator 0 "ix86_timode_comparison_operator"
1424                 [(reg:CC FLAGS_REG) (const_int 0)])
1425                (label_ref (match_operand 3))
1426                (pc)))]
1427   "TARGET_64BIT || TARGET_SSE4_1"
1429   ix86_expand_branch (GET_CODE (operands[0]),
1430                       operands[1], operands[2], operands[3]);
1431   DONE;
1434 (define_expand "cbranchoi4"
1435   [(set (reg:CC FLAGS_REG)
1436         (compare:CC (match_operand:OI 1 "nonimmediate_operand")
1437                     (match_operand:OI 2 "nonimmediate_operand")))
1438    (set (pc) (if_then_else
1439                (match_operator 0 "bt_comparison_operator"
1440                 [(reg:CC FLAGS_REG) (const_int 0)])
1441                (label_ref (match_operand 3))
1442                (pc)))]
1443   "TARGET_AVX"
1445   ix86_expand_branch (GET_CODE (operands[0]),
1446                       operands[1], operands[2], operands[3]);
1447   DONE;
1450 (define_expand "cbranchxi4"
1451   [(set (reg:CC FLAGS_REG)
1452         (compare:CC (match_operand:XI 1 "nonimmediate_operand")
1453                     (match_operand:XI 2 "nonimmediate_operand")))
1454    (set (pc) (if_then_else
1455                (match_operator 0 "bt_comparison_operator"
1456                 [(reg:CC FLAGS_REG) (const_int 0)])
1457                (label_ref (match_operand 3))
1458                (pc)))]
1459   "TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256"
1461   ix86_expand_branch (GET_CODE (operands[0]),
1462                       operands[1], operands[2], operands[3]);
1463   DONE;
1466 (define_expand "cstore<mode>4"
1467   [(set (reg:CC FLAGS_REG)
1468         (compare:CC (match_operand:SDWIM 2 "nonimmediate_operand")
1469                     (match_operand:SDWIM 3 "<general_operand>")))
1470    (set (match_operand:QI 0 "register_operand")
1471         (match_operator 1 "ordered_comparison_operator"
1472           [(reg:CC FLAGS_REG) (const_int 0)]))]
1473   ""
1475   if (<MODE>mode == (TARGET_64BIT ? TImode : DImode))
1476     {
1477       if (GET_CODE (operands[1]) != EQ
1478           && GET_CODE (operands[1]) != NE)
1479         FAIL;
1480     }
1481   else if (MEM_P (operands[2]) && MEM_P (operands[3]))
1482     operands[2] = force_reg (<MODE>mode, operands[2]);
1483   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1484                      operands[2], operands[3]);
1485   DONE;
1488 (define_expand "@cmp<mode>_1"
1489   [(set (reg:CC FLAGS_REG)
1490         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1491                     (match_operand:SWI48 1 "<general_operand>")))])
1493 (define_mode_iterator SWI1248_AVX512BWDQ_64
1494   [(QI "TARGET_AVX512DQ") HI
1495    (SI "TARGET_AVX512BW")
1496    (DI "TARGET_AVX512BW && TARGET_EVEX512 && TARGET_64BIT")])
1498 (define_insn "*cmp<mode>_ccz_1"
1499   [(set (reg FLAGS_REG)
1500         (compare (match_operand:SWI1248_AVX512BWDQ_64 0
1501                         "nonimmediate_operand" "<r>,?m<r>,$k")
1502                  (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))]
1503   "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
1504   "@
1505    test{<imodesuffix>}\t%0, %0
1506    cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1507    kortest<mskmodesuffix>\t%0, %0"
1508   [(set_attr "type" "test,icmp,msklog")
1509    (set_attr "length_immediate" "0,1,*")
1510    (set_attr "prefix" "*,*,vex")
1511    (set_attr "mode" "<MODE>")])
1513 (define_insn "*cmp<mode>_ccno_1"
1514   [(set (reg FLAGS_REG)
1515         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1516                  (match_operand:SWI 1 "const0_operand")))]
1517   "ix86_match_ccmode (insn, CCNOmode)"
1518   "@
1519    test{<imodesuffix>}\t%0, %0
1520    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1521   [(set_attr "type" "test,icmp")
1522    (set_attr "length_immediate" "0,1")
1523    (set_attr "mode" "<MODE>")])
1525 (define_insn "*cmp<mode>_1"
1526   [(set (reg FLAGS_REG)
1527         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1528                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>")))]
1529   "ix86_match_ccmode (insn, CCmode)"
1530   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1531   [(set_attr "type" "icmp")
1532    (set_attr "mode" "<MODE>")])
1534 (define_insn "*cmp<mode>_minus_1"
1535   [(set (reg FLAGS_REG)
1536         (compare
1537           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1538                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>"))
1539           (const_int 0)))]
1540   "ix86_match_ccmode (insn, CCGOCmode)"
1541   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1542   [(set_attr "type" "icmp")
1543    (set_attr "mode" "<MODE>")])
1545 (define_insn "*cmpqi_ext<mode>_1"
1546   [(set (reg FLAGS_REG)
1547         (compare
1548           (match_operand:QI 0 "nonimmediate_operand" "QBn")
1549           (subreg:QI
1550             (match_operator:SWI248 2 "extract_operator"
1551               [(match_operand 1 "int248_register_operand" "Q")
1552                (const_int 8)
1553                (const_int 8)]) 0)))]
1554   "ix86_match_ccmode (insn, CCmode)"
1555   "cmp{b}\t{%h1, %0|%0, %h1}"
1556   [(set_attr "addr" "gpr8")
1557    (set_attr "type" "icmp")
1558    (set_attr "mode" "QI")])
1560 (define_insn "*cmpqi_ext<mode>_2"
1561   [(set (reg FLAGS_REG)
1562         (compare
1563           (subreg:QI
1564             (match_operator:SWI248 2 "extract_operator"
1565               [(match_operand 0 "int248_register_operand" "Q")
1566                (const_int 8)
1567                (const_int 8)]) 0)
1568           (match_operand:QI 1 "const0_operand")))]
1569   "ix86_match_ccmode (insn, CCNOmode)"
1570   "test{b}\t%h0, %h0"
1571   [(set_attr "type" "test")
1572    (set_attr "length_immediate" "0")
1573    (set_attr "mode" "QI")])
1575 (define_expand "cmpqi_ext_3"
1576   [(set (reg:CC FLAGS_REG)
1577         (compare:CC
1578           (subreg:QI
1579             (zero_extract:HI
1580               (match_operand:HI 0 "register_operand")
1581               (const_int 8)
1582               (const_int 8)) 0)
1583           (match_operand:QI 1 "const_int_operand")))])
1585 (define_insn "*cmpqi_ext<mode>_3"
1586   [(set (reg FLAGS_REG)
1587         (compare
1588           (subreg:QI
1589             (match_operator:SWI248 2 "extract_operator"
1590               [(match_operand 0 "int248_register_operand" "Q")
1591                (const_int 8)
1592                (const_int 8)]) 0)
1593           (match_operand:QI 1 "general_operand" "QnBn")))]
1594   "ix86_match_ccmode (insn, CCmode)"
1595   "cmp{b}\t{%1, %h0|%h0, %1}"
1596   [(set_attr "addr" "gpr8")
1597    (set_attr "type" "icmp")
1598    (set_attr "mode" "QI")])
1600 (define_insn "*cmpqi_ext<mode>_4"
1601   [(set (reg FLAGS_REG)
1602         (compare
1603           (subreg:QI
1604             (match_operator:SWI248 2 "extract_operator"
1605               [(match_operand 0 "int248_register_operand" "Q")
1606                (const_int 8)
1607                (const_int 8)]) 0)
1608           (subreg:QI
1609             (match_operator:SWI248 3 "extract_operator"
1610               [(match_operand 1 "int248_register_operand" "Q")
1611                (const_int 8)
1612                (const_int 8)]) 0)))]
1613   "ix86_match_ccmode (insn, CCmode)"
1614   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1615   [(set_attr "type" "icmp")
1616    (set_attr "mode" "QI")])
1618 (define_insn_and_split "*cmp<dwi>_doubleword"
1619   [(set (reg:CCZ FLAGS_REG)
1620         (compare:CCZ (match_operand:<DWI> 0 "nonimmediate_operand")
1621                      (match_operand:<DWI> 1 "general_operand")))]
1622   "ix86_pre_reload_split ()"
1623   "#"
1624   "&& 1"
1625   [(parallel [(set (reg:CCZ FLAGS_REG)
1626                    (compare:CCZ (ior:DWIH (match_dup 4) (match_dup 5))
1627                                 (const_int 0)))
1628               (set (match_dup 4) (ior:DWIH (match_dup 4) (match_dup 5)))])]
1630   split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);
1631   /* Placing the SUBREG pieces in pseudos helps reload.  */
1632   for (int i = 0; i < 4; i++)
1633     if (SUBREG_P (operands[i]))
1634       operands[i] = force_reg (<MODE>mode, operands[i]);
1636   operands[4] = gen_reg_rtx (<MODE>mode);
1638   /* Special case comparisons against -1.  */
1639   if (operands[1] == constm1_rtx && operands[3] == constm1_rtx)
1640     {
1641       emit_insn (gen_and<mode>3 (operands[4], operands[0], operands[2]));
1642       emit_insn (gen_cmp_1 (<MODE>mode, operands[4], constm1_rtx));
1643       DONE;
1644     }
1646   if (operands[1] == const0_rtx)
1647     emit_move_insn (operands[4], operands[0]);
1648   else if (operands[0] == const0_rtx)
1649     emit_move_insn (operands[4], operands[1]);
1650   else if (operands[1] == constm1_rtx)
1651     emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[0]));
1652   else if (operands[0] == constm1_rtx)
1653     emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[1]));
1654   else
1655     {
1656       if (CONST_SCALAR_INT_P (operands[1])
1657           && !x86_64_immediate_operand (operands[1], <MODE>mode))
1658         operands[1] = force_reg (<MODE>mode, operands[1]);
1659       emit_insn (gen_xor<mode>3 (operands[4], operands[0], operands[1]));
1660     }
1662   if (operands[3] == const0_rtx)
1663     operands[5] = operands[2];
1664   else if (operands[2] == const0_rtx)
1665     operands[5] = operands[3];
1666   else
1667     {
1668       operands[5] = gen_reg_rtx (<MODE>mode);
1669       if (operands[3] == constm1_rtx)
1670         emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[2]));
1671       else if (operands[2] == constm1_rtx)
1672         emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[3]));
1673       else
1674         {
1675           if (CONST_SCALAR_INT_P (operands[3])
1676               && !x86_64_immediate_operand (operands[3], <MODE>mode))
1677             operands[3] = force_reg (<MODE>mode, operands[3]);
1678           emit_insn (gen_xor<mode>3 (operands[5], operands[2], operands[3]));
1679         }
1680     }
1683 ;; These implement float point compares.
1684 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1685 ;; which would allow mix and match FP modes on the compares.  Which is what
1686 ;; the old patterns did, but with many more of them.
1688 (define_expand "cbranchxf4"
1689   [(set (reg:CC FLAGS_REG)
1690         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1691                     (match_operand:XF 2 "nonmemory_operand")))
1692    (set (pc) (if_then_else
1693               (match_operator 0 "ix86_fp_comparison_operator"
1694                [(reg:CC FLAGS_REG)
1695                 (const_int 0)])
1696               (label_ref (match_operand 3))
1697               (pc)))]
1698   "TARGET_80387"
1700   ix86_expand_branch (GET_CODE (operands[0]),
1701                       operands[1], operands[2], operands[3]);
1702   DONE;
1705 (define_expand "cstorexf4"
1706   [(set (reg:CC FLAGS_REG)
1707         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1708                     (match_operand:XF 3 "nonmemory_operand")))
1709    (set (match_operand:QI 0 "register_operand")
1710               (match_operator 1 "ix86_fp_comparison_operator"
1711                [(reg:CC FLAGS_REG)
1712                 (const_int 0)]))]
1713   "TARGET_80387"
1715   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1716                      operands[2], operands[3]);
1717   DONE;
1720 (define_expand "cbranchhf4"
1721   [(set (reg:CC FLAGS_REG)
1722         (compare:CC (match_operand:HF 1 "cmp_fp_expander_operand")
1723                     (match_operand:HF 2 "cmp_fp_expander_operand")))
1724    (set (pc) (if_then_else
1725               (match_operator 0 "ix86_fp_comparison_operator"
1726                [(reg:CC FLAGS_REG)
1727                 (const_int 0)])
1728               (label_ref (match_operand 3))
1729               (pc)))]
1730   "TARGET_AVX512FP16"
1732   ix86_expand_branch (GET_CODE (operands[0]),
1733                       operands[1], operands[2], operands[3]);
1734   DONE;
1737 (define_expand "cbranch<mode>4"
1738   [(set (reg:CC FLAGS_REG)
1739         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1740                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1741    (set (pc) (if_then_else
1742               (match_operator 0 "ix86_fp_comparison_operator"
1743                [(reg:CC FLAGS_REG)
1744                 (const_int 0)])
1745               (label_ref (match_operand 3))
1746               (pc)))]
1747   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1749   ix86_expand_branch (GET_CODE (operands[0]),
1750                       operands[1], operands[2], operands[3]);
1751   DONE;
1754 (define_expand "cbranchbf4"
1755   [(set (reg:CC FLAGS_REG)
1756         (compare:CC (match_operand:BF 1 "cmp_fp_expander_operand")
1757                     (match_operand:BF 2 "cmp_fp_expander_operand")))
1758    (set (pc) (if_then_else
1759               (match_operator 0 "comparison_operator"
1760                [(reg:CC FLAGS_REG)
1761                 (const_int 0)])
1762               (label_ref (match_operand 3))
1763               (pc)))]
1764   "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1766   rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[1]);
1767   rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1768   do_compare_rtx_and_jump (op1, op2, GET_CODE (operands[0]), 0,
1769                            SFmode, NULL_RTX, NULL,
1770                            as_a <rtx_code_label *> (operands[3]),
1771                            /* Unfortunately this isn't propagated.  */
1772                            profile_probability::even ());
1773   DONE;
1776 (define_expand "cstorehf4"
1777   [(set (reg:CC FLAGS_REG)
1778         (compare:CC (match_operand:HF 2 "cmp_fp_expander_operand")
1779                     (match_operand:HF 3 "cmp_fp_expander_operand")))
1780    (set (match_operand:QI 0 "register_operand")
1781         (match_operator 1 "ix86_fp_comparison_operator"
1782           [(reg:CC FLAGS_REG)
1783            (const_int 0)]))]
1784   "TARGET_AVX512FP16"
1786   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1787                      operands[2], operands[3]);
1788   DONE;
1791 (define_expand "cstorebf4"
1792   [(set (reg:CC FLAGS_REG)
1793         (compare:CC (match_operand:BF 2 "cmp_fp_expander_operand")
1794                     (match_operand:BF 3 "cmp_fp_expander_operand")))
1795    (set (match_operand:QI 0 "register_operand")
1796         (match_operator 1 "comparison_operator"
1797           [(reg:CC FLAGS_REG)
1798            (const_int 0)]))]
1799   "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1801   rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1802   rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[3]);
1803   rtx res = emit_store_flag_force (operands[0], GET_CODE (operands[1]),
1804                                    op1, op2, SFmode, 0, 1);
1805   if (!rtx_equal_p (res, operands[0]))
1806     emit_move_insn (operands[0], res);
1807   DONE;
1810 (define_expand "cstore<mode>4"
1811   [(set (reg:CC FLAGS_REG)
1812         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1813                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1814    (set (match_operand:QI 0 "register_operand")
1815               (match_operator 1 "ix86_fp_comparison_operator"
1816                [(reg:CC FLAGS_REG)
1817                 (const_int 0)]))]
1818   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1820   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1821                      operands[2], operands[3]);
1822   DONE;
1825 (define_expand "cbranchcc4"
1826   [(set (pc) (if_then_else
1827               (match_operator 0 "comparison_operator"
1828                [(match_operand 1 "flags_reg_operand")
1829                 (match_operand 2 "const0_operand")])
1830               (label_ref (match_operand 3))
1831               (pc)))]
1832   ""
1834   ix86_expand_branch (GET_CODE (operands[0]),
1835                       operands[1], operands[2], operands[3]);
1836   DONE;
1839 (define_expand "cstorecc4"
1840   [(set (match_operand:QI 0 "register_operand")
1841               (match_operator 1 "comparison_operator"
1842                [(match_operand 2 "flags_reg_operand")
1843                 (match_operand 3 "const0_operand")]))]
1844   ""
1846   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1847                      operands[2], operands[3]);
1848   DONE;
1851 ;; FP compares, step 1:
1852 ;; Set the FP condition codes and move fpsr to ax.
1854 ;; We may not use "#" to split and emit these
1855 ;; due to reg-stack pops killing fpsr.
1857 (define_insn "*cmpxf_i387"
1858   [(set (match_operand:HI 0 "register_operand" "=a")
1859         (unspec:HI
1860           [(compare:CCFP
1861              (match_operand:XF 1 "register_operand" "f")
1862              (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1863           UNSPEC_FNSTSW))]
1864   "TARGET_80387"
1865   "* return output_fp_compare (insn, operands, false, false);"
1866   [(set_attr "type" "multi")
1867    (set_attr "unit" "i387")
1868    (set_attr "mode" "XF")])
1870 (define_insn "*cmp<mode>_i387"
1871   [(set (match_operand:HI 0 "register_operand" "=a")
1872         (unspec:HI
1873           [(compare:CCFP
1874              (match_operand:MODEF 1 "register_operand" "f")
1875              (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1876           UNSPEC_FNSTSW))]
1877   "TARGET_80387"
1878   "* return output_fp_compare (insn, operands, false, false);"
1879   [(set_attr "type" "multi")
1880    (set_attr "unit" "i387")
1881    (set_attr "mode" "<MODE>")])
1883 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1884   [(set (match_operand:HI 0 "register_operand" "=a")
1885         (unspec:HI
1886           [(compare:CCFP
1887              (match_operand:X87MODEF 1 "register_operand" "f")
1888              (float:X87MODEF
1889                (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1890           UNSPEC_FNSTSW))]
1891   "TARGET_80387
1892    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1893        || optimize_function_for_size_p (cfun))"
1894   "* return output_fp_compare (insn, operands, false, false);"
1895   [(set_attr "type" "multi")
1896    (set_attr "unit" "i387")
1897    (set_attr "fp_int_src" "true")
1898    (set_attr "mode" "<SWI24:MODE>")])
1900 (define_insn "*cmpu<mode>_i387"
1901   [(set (match_operand:HI 0 "register_operand" "=a")
1902         (unspec:HI
1903           [(unspec:CCFP
1904              [(compare:CCFP
1905                 (match_operand:X87MODEF 1 "register_operand" "f")
1906                 (match_operand:X87MODEF 2 "register_operand" "f"))]
1907              UNSPEC_NOTRAP)]
1908           UNSPEC_FNSTSW))]
1909   "TARGET_80387"
1910   "* return output_fp_compare (insn, operands, false, true);"
1911   [(set_attr "type" "multi")
1912    (set_attr "unit" "i387")
1913    (set_attr "mode" "<MODE>")])
1915 ;; FP compares, step 2:
1916 ;; Get ax into flags, general case.
1918 (define_insn "x86_sahf_1"
1919   [(set (reg:CC FLAGS_REG)
1920         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1921                    UNSPEC_SAHF))]
1922   "TARGET_SAHF"
1924 #ifndef HAVE_AS_IX86_SAHF
1925   if (TARGET_64BIT)
1926     return ASM_BYTE "0x9e";
1927   else
1928 #endif
1929   return "sahf";
1931   [(set_attr "length" "1")
1932    (set_attr "athlon_decode" "vector")
1933    (set_attr "amdfam10_decode" "direct")
1934    (set_attr "bdver1_decode" "direct")
1935    (set_attr "mode" "SI")])
1937 ;; Pentium Pro can do both steps in one go.
1938 ;; (these instructions set flags directly)
1940 (define_subst_attr "unord" "unord_subst" "" "u")
1941 (define_subst_attr "unordered" "unord_subst" "false" "true")
1943 (define_subst "unord_subst"
1944   [(set (match_operand:CCFP 0)
1945         (match_operand:CCFP 1))]
1946   ""
1947   [(set (match_dup 0)
1948         (unspec:CCFP
1949           [(match_dup 1)]
1950           UNSPEC_NOTRAP))])
1952 (define_insn "*cmpi<unord>xf_i387"
1953   [(set (reg:CCFP FLAGS_REG)
1954         (compare:CCFP
1955           (match_operand:XF 0 "register_operand" "f")
1956           (match_operand:XF 1 "register_operand" "f")))]
1957   "TARGET_80387 && TARGET_CMOVE"
1958   "* return output_fp_compare (insn, operands, true, <unordered>);"
1959   [(set_attr "type" "fcmp")
1960    (set_attr "mode" "XF")
1961    (set_attr "athlon_decode" "vector")
1962    (set_attr "amdfam10_decode" "direct")
1963    (set_attr "bdver1_decode" "double")
1964    (set_attr "znver1_decode" "double")])
1966 (define_insn "*cmpi<unord><MODEF:mode>"
1967   [(set (reg:CCFP FLAGS_REG)
1968         (compare:CCFP
1969           (match_operand:MODEF 0 "register_operand" "f,v")
1970           (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1971   "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1972    || (TARGET_80387 && TARGET_CMOVE)"
1973   "@
1974    * return output_fp_compare (insn, operands, true, <unordered>);
1975    %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1976   [(set_attr "type" "fcmp,ssecomi")
1977    (set_attr "prefix" "orig,maybe_vex")
1978    (set_attr "mode" "<MODEF:MODE>")
1979    (set_attr "prefix_rep" "*,0")
1980    (set (attr "prefix_data16")
1981         (cond [(eq_attr "alternative" "0")
1982                  (const_string "*")
1983                (eq_attr "mode" "DF")
1984                  (const_string "1")
1985               ]
1986               (const_string "0")))
1987    (set_attr "athlon_decode" "vector")
1988    (set_attr "amdfam10_decode" "direct")
1989    (set_attr "bdver1_decode" "double")
1990    (set_attr "znver1_decode" "double")
1991    (set (attr "enabled")
1992      (if_then_else
1993        (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1994        (if_then_else
1995          (eq_attr "alternative" "0")
1996          (symbol_ref "TARGET_MIX_SSE_I387")
1997          (symbol_ref "true"))
1998        (if_then_else
1999          (eq_attr "alternative" "0")
2000          (symbol_ref "true")
2001          (symbol_ref "false"))))])
2003 (define_insn "*cmpi<unord>hf"
2004   [(set (reg:CCFP FLAGS_REG)
2005         (compare:CCFP
2006           (match_operand:HF 0 "register_operand" "v")
2007           (match_operand:HF 1 "nonimmediate_operand" "vm")))]
2008   "TARGET_AVX512FP16"
2009   "v<unord>comish\t{%1, %0|%0, %1}"
2010   [(set_attr "type" "ssecomi")
2011    (set_attr "prefix" "evex")
2012    (set_attr "mode" "HF")])
2014 ;; Set carry flag.
2015 (define_insn "x86_stc"
2016   [(set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2017   ""
2018   "stc"
2019   [(set_attr "length" "1")
2020    (set_attr "length_immediate" "0")
2021    (set_attr "modrm" "0")])
2023 ;; On Pentium 4, set the carry flag using mov $1,%al;addb $-1,%al.
2024 (define_peephole2
2025   [(match_scratch:QI 0 "r")
2026    (set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2027   "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2028   [(set (match_dup 0) (const_int 1))
2029    (parallel
2030      [(set (reg:CCC FLAGS_REG)
2031            (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2032                         (match_dup 0)))
2033       (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2035 ;; Complement carry flag.
2036 (define_insn "*x86_cmc"
2037   [(set (reg:CCC FLAGS_REG)
2038         (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2039                      (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2040   ""
2041   "cmc"
2042   [(set_attr "length" "1")
2043    (set_attr "length_immediate" "0")
2044    (set_attr "use_carry" "1")
2045    (set_attr "modrm" "0")])
2047 ;; On Pentium 4, cmc is replaced with setnc %al;addb $-1,%al.
2048 (define_peephole2
2049   [(match_scratch:QI 0 "r")
2050    (set (reg:CCC FLAGS_REG)
2051         (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2052                      (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2053   "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2054   [(set (match_dup 0) (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
2055    (parallel
2056      [(set (reg:CCC FLAGS_REG)
2057            (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2058                         (match_dup 0)))
2059       (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2061 ;; Push/pop instructions.
2063 (define_insn_and_split "*pushv1ti2"
2064   [(set (match_operand:V1TI 0 "push_operand" "=<")
2065         (match_operand:V1TI 1 "register_operand" "v"))]
2066   "TARGET_64BIT && TARGET_STV"
2067   "#"
2068   "&& reload_completed"
2069   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2070    (set (match_dup 0) (match_dup 1))]
2072   operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (V1TImode)));
2073   /* Preserve memory attributes. */
2074   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2076   [(set_attr "type" "multi")
2077    (set_attr "mode" "TI")])
2079 (define_insn "*push<mode>2"
2080   [(set (match_operand:DWI 0 "push_operand" "=<,<")
2081         (match_operand:DWI 1 "general_no_elim_operand" "riF*o,*v"))]
2082   ""
2083   "#"
2084   [(set_attr "type" "multi")
2085    (set_attr "mode" "<MODE>")])
2087 (define_split
2088   [(set (match_operand:DWI 0 "push_operand")
2089         (match_operand:DWI 1 "general_gr_operand"))]
2090   "reload_completed"
2091   [(const_int 0)]
2092   "ix86_split_long_move (operands); DONE;")
2094 (define_insn "*pushdi2_rex64"
2095   [(set (match_operand:DI 0 "push_operand" "=<,<,!<")
2096         (match_operand:DI 1 "general_no_elim_operand" "re*m,*v,n"))]
2097   "TARGET_64BIT"
2098   "@
2099    push{q}\t%1
2100    #
2101    #"
2102   [(set_attr "type" "push,multi,multi")
2103    (set_attr "mode" "DI")])
2105 ;; Convert impossible pushes of immediate to existing instructions.
2106 ;; First try to get scratch register and go through it.  In case this
2107 ;; fails, push sign extended lower part first and then overwrite
2108 ;; upper part by 32bit move.
2110 (define_peephole2
2111   [(match_scratch:DI 2 "r")
2112    (set (match_operand:DI 0 "push_operand")
2113         (match_operand:DI 1 "immediate_operand"))]
2114   "TARGET_64BIT
2115    && !symbolic_operand (operands[1], DImode)
2116    && !x86_64_immediate_operand (operands[1], DImode)"
2117   [(set (match_dup 2) (match_dup 1))
2118    (set (match_dup 0) (match_dup 2))])
2120 (define_split
2121   [(set (match_operand:DI 0 "push_operand")
2122         (match_operand:DI 1 "immediate_operand"))]
2123   "TARGET_64BIT && epilogue_completed
2124    && !symbolic_operand (operands[1], DImode)
2125    && !x86_64_immediate_operand (operands[1], DImode)"
2126   [(set (match_dup 0) (match_dup 1))
2127    (set (match_dup 2) (match_dup 3))]
2129   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
2131   operands[1] = gen_lowpart (DImode, operands[2]);
2132   operands[2] = gen_rtx_MEM (SImode,
2133                              plus_constant (Pmode, stack_pointer_rtx, 4));
2136 ;; For TARGET_64BIT we always round up to 8 bytes.
2137 (define_insn "*pushsi2_rex64"
2138   [(set (match_operand:SI 0 "push_operand" "=X,X")
2139         (match_operand:SI 1 "nonmemory_no_elim_operand" "re,*v"))]
2140   "TARGET_64BIT"
2141   "@
2142    push{q}\t%q1
2143    #"
2144   [(set_attr "type" "push,multi")
2145    (set_attr "mode" "DI")])
2147 (define_insn "*pushsi2"
2148   [(set (match_operand:SI 0 "push_operand" "=<,<")
2149         (match_operand:SI 1 "general_no_elim_operand" "ri*m,*v"))]
2150   "!TARGET_64BIT"
2151   "@
2152    push{l}\t%1
2153    #"
2154   [(set_attr "type" "push,multi")
2155    (set_attr "mode" "SI")])
2157 (define_split
2158   [(set (match_operand:SWI48DWI 0 "push_operand")
2159         (match_operand:SWI48DWI 1 "sse_reg_operand"))]
2160   "TARGET_SSE && reload_completed"
2161   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2162     (set (match_dup 0) (match_dup 1))]
2164   operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (<SWI48DWI:MODE>mode)));
2165   /* Preserve memory attributes. */
2166   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2169 ;; emit_push_insn when it calls move_by_pieces requires an insn to
2170 ;; "push a byte/word".  But actually we use push{l,q}, which has
2171 ;; the effect of rounding the amount pushed up to a word.
2173 (define_insn "*push<mode>2"
2174   [(set (match_operand:SWI12 0 "push_operand" "=X")
2175         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
2176   ""
2177   "* return TARGET_64BIT ? \"push{q}\t%q1\" : \"push{l}\t%k1\";"
2178   [(set_attr "type" "push")
2179    (set (attr "mode")
2180         (if_then_else (match_test "TARGET_64BIT")
2181           (const_string "DI")
2182           (const_string "SI")))])
2184 (define_insn "*push<mode>2_prologue"
2185   [(set (match_operand:W 0 "push_operand" "=<")
2186         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
2187    (clobber (mem:BLK (scratch)))]
2188   ""
2189   "push{<imodesuffix>}\t%1"
2190   [(set_attr "type" "push")
2191    (set_attr "mode" "<MODE>")])
2193 (define_insn "*pop<mode>1"
2194   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2195         (match_operand:W 1 "pop_operand" ">"))]
2196   ""
2197   "pop{<imodesuffix>}\t%0"
2198   [(set_attr "type" "pop")
2199    (set_attr "mode" "<MODE>")])
2201 (define_insn "*pop<mode>1_epilogue"
2202   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2203         (match_operand:W 1 "pop_operand" ">"))
2204    (clobber (mem:BLK (scratch)))]
2205   ""
2206   "pop{<imodesuffix>}\t%0"
2207   [(set_attr "type" "pop")
2208    (set_attr "mode" "<MODE>")])
2210 (define_insn "@pushfl<mode>2"
2211   [(set (match_operand:W 0 "push_operand" "=<")
2212         (unspec:W [(match_operand:CC 1 "flags_reg_operand")]
2213                   UNSPEC_PUSHFL))]
2214   ""
2215   "pushf{<imodesuffix>}"
2216   [(set_attr "type" "push")
2217    (set_attr "mode" "<MODE>")])
2219 (define_insn "@popfl<mode>1"
2220   [(set (match_operand:CC 0 "flags_reg_operand")
2221         (unspec:CC [(match_operand:W 1 "pop_operand" ">")]
2222                    UNSPEC_POPFL))]
2223   ""
2224   "popf{<imodesuffix>}"
2225   [(set_attr "type" "pop")
2226    (set_attr "mode" "<MODE>")])
2229 ;; Reload patterns to support multi-word load/store
2230 ;; with non-offsetable address.
2231 (define_expand "reload_noff_store"
2232   [(parallel [(match_operand 0 "memory_operand" "=m")
2233               (match_operand 1 "register_operand" "r")
2234               (match_operand:DI 2 "register_operand" "=&r")])]
2235   "TARGET_64BIT"
2237   rtx mem = operands[0];
2238   rtx addr = XEXP (mem, 0);
2240   emit_move_insn (operands[2], addr);
2241   mem = replace_equiv_address_nv (mem, operands[2]);
2243   emit_insn (gen_rtx_SET (mem, operands[1]));
2244   DONE;
2247 (define_expand "reload_noff_load"
2248   [(parallel [(match_operand 0 "register_operand" "=r")
2249               (match_operand 1 "memory_operand" "m")
2250               (match_operand:DI 2 "register_operand" "=r")])]
2251   "TARGET_64BIT"
2253   rtx mem = operands[1];
2254   rtx addr = XEXP (mem, 0);
2256   emit_move_insn (operands[2], addr);
2257   mem = replace_equiv_address_nv (mem, operands[2]);
2259   emit_insn (gen_rtx_SET (operands[0], mem));
2260   DONE;
2263 ;; Move instructions.
2265 (define_expand "movxi"
2266   [(set (match_operand:XI 0 "nonimmediate_operand")
2267         (match_operand:XI 1 "general_operand"))]
2268   "TARGET_AVX512F && TARGET_EVEX512"
2269   "ix86_expand_vector_move (XImode, operands); DONE;")
2271 (define_expand "movoi"
2272   [(set (match_operand:OI 0 "nonimmediate_operand")
2273         (match_operand:OI 1 "general_operand"))]
2274   "TARGET_AVX"
2275   "ix86_expand_vector_move (OImode, operands); DONE;")
2277 (define_expand "movti"
2278   [(set (match_operand:TI 0 "nonimmediate_operand")
2279         (match_operand:TI 1 "general_operand"))]
2280   "TARGET_64BIT || TARGET_SSE"
2282   if (TARGET_64BIT)
2283     ix86_expand_move (TImode, operands);
2284   else
2285     ix86_expand_vector_move (TImode, operands);
2286   DONE;
2289 ;; This expands to what emit_move_complex would generate if we didn't
2290 ;; have a movti pattern.  Having this avoids problems with reload on
2291 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2292 ;; to have around all the time.
2293 (define_expand "movcdi"
2294   [(set (match_operand:CDI 0 "nonimmediate_operand")
2295         (match_operand:CDI 1 "general_operand"))]
2296   ""
2298   if (push_operand (operands[0], CDImode))
2299     emit_move_complex_push (CDImode, operands[0], operands[1]);
2300   else
2301     emit_move_complex_parts (operands[0], operands[1]);
2302   DONE;
2305 (define_expand "mov<mode>"
2306   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2307         (match_operand:SWI1248x 1 "general_operand"))]
2308   ""
2309   "ix86_expand_move (<MODE>mode, operands); DONE;")
2311 (define_insn "*mov<mode>_xor"
2312   [(set (match_operand:SWI48 0 "register_operand" "=r")
2313         (match_operand:SWI48 1 "const0_operand"))
2314    (clobber (reg:CC FLAGS_REG))]
2315   "reload_completed"
2316   "xor{l}\t%k0, %k0"
2317   [(set_attr "type" "alu1")
2318    (set_attr "mode" "SI")
2319    (set_attr "length_immediate" "0")])
2321 (define_insn "*mov<mode>_and"
2322   [(set (match_operand:SWI248 0 "memory_operand" "=m")
2323         (match_operand:SWI248 1 "const0_operand"))
2324    (clobber (reg:CC FLAGS_REG))]
2325   "reload_completed"
2326   "and{<imodesuffix>}\t{%1, %0|%0, %1}"
2327   [(set_attr "type" "alu1")
2328    (set_attr "mode" "<MODE>")
2329    (set_attr "length_immediate" "1")])
2331 (define_insn "*mov<mode>_or"
2332   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
2333         (match_operand:SWI248 1 "constm1_operand"))
2334    (clobber (reg:CC FLAGS_REG))]
2335   "reload_completed"
2336   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2337   [(set_attr "type" "alu1")
2338    (set_attr "mode" "<MODE>")
2339    (set_attr "length_immediate" "1")])
2341 (define_insn "*movxi_internal_avx512f"
2342   [(set (match_operand:XI 0 "nonimmediate_operand"              "=v,v ,v ,m")
2343         (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2344   "TARGET_AVX512F && TARGET_EVEX512
2345    && (register_operand (operands[0], XImode)
2346        || register_operand (operands[1], XImode))"
2348   switch (get_attr_type (insn))
2349     {
2350     case TYPE_SSELOG1:
2351       return standard_sse_constant_opcode (insn, operands);
2353     case TYPE_SSEMOV:
2354       return ix86_output_ssemov (insn, operands);
2356     default:
2357       gcc_unreachable ();
2358     }
2360   [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2361    (set_attr "prefix" "evex")
2362    (set_attr "mode" "XI")])
2364 (define_insn "*movoi_internal_avx"
2365   [(set (match_operand:OI 0 "nonimmediate_operand"              "=v,v ,v ,m")
2366         (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2367   "TARGET_AVX
2368    && (register_operand (operands[0], OImode)
2369        || register_operand (operands[1], OImode))"
2371   switch (get_attr_type (insn))
2372     {
2373     case TYPE_SSELOG1:
2374       return standard_sse_constant_opcode (insn, operands);
2376     case TYPE_SSEMOV:
2377       return ix86_output_ssemov (insn, operands);
2379     default:
2380       gcc_unreachable ();
2381     }
2383   [(set_attr "isa" "*,avx2,*,*")
2384    (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2385    (set_attr "prefix" "vex")
2386    (set_attr "mode" "OI")])
2388 (define_insn "*movti_internal"
2389   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?jc,?Yd")
2390         (match_operand:TI 1 "general_operand"      "riFo,re,C,BC,vm,v,Yd,jc"))]
2391   "(TARGET_64BIT
2392     && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2393    || (TARGET_SSE
2394        && nonimmediate_or_sse_const_operand (operands[1], TImode)
2395        && (register_operand (operands[0], TImode)
2396            || register_operand (operands[1], TImode)))"
2398   switch (get_attr_type (insn))
2399     {
2400     case TYPE_MULTI:
2401       return "#";
2403     case TYPE_SSELOG1:
2404       return standard_sse_constant_opcode (insn, operands);
2406     case TYPE_SSEMOV:
2407       return ix86_output_ssemov (insn, operands);
2409     default:
2410       gcc_unreachable ();
2411     }
2413   [(set (attr "isa")
2414      (cond [(eq_attr "alternative" "0,1,6,7")
2415               (const_string "x64")
2416             (eq_attr "alternative" "3")
2417               (const_string "sse2")
2418            ]
2419            (const_string "*")))
2420    (set (attr "type")
2421      (cond [(eq_attr "alternative" "0,1,6,7")
2422               (const_string "multi")
2423             (eq_attr "alternative" "2,3")
2424               (const_string "sselog1")
2425            ]
2426            (const_string "ssemov")))
2427    (set (attr "prefix")
2428      (if_then_else (eq_attr "type" "sselog1,ssemov")
2429        (const_string "maybe_vex")
2430        (const_string "orig")))
2431    (set (attr "mode")
2432         (cond [(eq_attr "alternative" "0,1")
2433                  (const_string "DI")
2434                (match_test "TARGET_AVX")
2435                  (const_string "TI")
2436                (ior (not (match_test "TARGET_SSE2"))
2437                     (match_test "optimize_function_for_size_p (cfun)"))
2438                  (const_string "V4SF")
2439                (and (eq_attr "alternative" "5")
2440                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2441                  (const_string "V4SF")
2442                ]
2443                (const_string "TI")))
2444    (set (attr "preferred_for_speed")
2445      (cond [(eq_attr "alternative" "6")
2446               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2447             (eq_attr "alternative" "7")
2448               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2449            ]
2450            (symbol_ref "true")))])
2452 (define_split
2453   [(set (match_operand:TI 0 "sse_reg_operand")
2454         (match_operand:TI 1 "general_reg_operand"))]
2455   "TARGET_64BIT && TARGET_SSE4_1
2456    && reload_completed"
2457   [(set (match_dup 2)
2458         (vec_merge:V2DI
2459           (vec_duplicate:V2DI (match_dup 3))
2460           (match_dup 2)
2461           (const_int 2)))]
2463   operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2464   operands[3] = gen_highpart (DImode, operands[1]);
2466   emit_move_insn (gen_lowpart (DImode, operands[0]),
2467                   gen_lowpart (DImode, operands[1]));
2470 (define_insn "*movdi_internal"
2471   [(set (match_operand:DI 0 "nonimmediate_operand"
2472     "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r,?*y,?Yv,?v,?v,m ,m,?jc,?*Yd,?r,?v,?*y,?*x,*k,*k  ,*r,*m,*k")
2473         (match_operand:DI 1 "general_operand"
2474     "riFo,riF,Z,rem,i,re,C ,*y,Bk ,*y,*y,r  ,C  ,?v,Bk,?v,v,*Yd,jc  ,?v,r  ,*x ,*y ,*r,*kBk,*k,*k,CBC"))]
2475   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2476    && ix86_hardreg_mov_ok (operands[0], operands[1])"
2478   switch (get_attr_type (insn))
2479     {
2480     case TYPE_MSKMOV:
2481       return "kmovq\t{%1, %0|%0, %1}";
2483     case TYPE_MSKLOG:
2484       if (operands[1] == const0_rtx)
2485         return "kxorq\t%0, %0, %0";
2486       else if (operands[1] == constm1_rtx)
2487         return "kxnorq\t%0, %0, %0";
2488       gcc_unreachable ();
2490     case TYPE_MULTI:
2491       return "#";
2493     case TYPE_MMX:
2494       return "pxor\t%0, %0";
2496     case TYPE_MMXMOV:
2497       /* Handle broken assemblers that require movd instead of movq.  */
2498       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2499           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2500         return "movd\t{%1, %0|%0, %1}";
2501       return "movq\t{%1, %0|%0, %1}";
2503     case TYPE_SSELOG1:
2504       return standard_sse_constant_opcode (insn, operands);
2506     case TYPE_SSEMOV:
2507       return ix86_output_ssemov (insn, operands);
2509     case TYPE_SSECVT:
2510       if (SSE_REG_P (operands[0]))
2511         return "movq2dq\t{%1, %0|%0, %1}";
2512       else
2513         return "movdq2q\t{%1, %0|%0, %1}";
2515     case TYPE_LEA:
2516       return "lea{q}\t{%E1, %0|%0, %E1}";
2518     case TYPE_IMOV:
2519       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2520       if (get_attr_mode (insn) == MODE_SI)
2521         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2522       else if (which_alternative == 4)
2523         return "movabs{q}\t{%1, %0|%0, %1}";
2524       else if (ix86_use_lea_for_mov (insn, operands))
2525         return "lea{q}\t{%E1, %0|%0, %E1}";
2526       else
2527         return "mov{q}\t{%1, %0|%0, %1}";
2529     default:
2530       gcc_unreachable ();
2531     }
2533   [(set (attr "isa")
2534      (cond [(eq_attr "alternative" "0,1,17,18")
2535               (const_string "nox64")
2536             (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2537               (const_string "x64")
2538             (eq_attr "alternative" "19,20")
2539               (const_string "x64_sse2")
2540             (eq_attr "alternative" "21,22")
2541               (const_string "sse2")
2542            ]
2543            (const_string "*")))
2544    (set (attr "type")
2545      (cond [(eq_attr "alternative" "0,1,17,18")
2546               (const_string "multi")
2547             (eq_attr "alternative" "6")
2548               (const_string "mmx")
2549             (eq_attr "alternative" "7,8,9,10,11")
2550               (const_string "mmxmov")
2551             (eq_attr "alternative" "12")
2552               (const_string "sselog1")
2553             (eq_attr "alternative" "13,14,15,16,19,20")
2554               (const_string "ssemov")
2555             (eq_attr "alternative" "21,22")
2556               (const_string "ssecvt")
2557             (eq_attr "alternative" "23,24,25,26")
2558               (const_string "mskmov")
2559             (eq_attr "alternative" "27")
2560               (const_string "msklog")
2561             (and (match_operand 0 "register_operand")
2562                  (match_operand 1 "pic_32bit_operand"))
2563               (const_string "lea")
2564            ]
2565            (const_string "imov")))
2566    (set (attr "modrm")
2567      (if_then_else
2568        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2569        (const_string "0")
2570        (const_string "*")))
2571    (set (attr "length_immediate")
2572      (if_then_else
2573        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2574        (const_string "8")
2575        (const_string "*")))
2576    (set (attr "prefix_rex")
2577      (if_then_else
2578        (eq_attr "alternative" "10,11,19,20")
2579        (const_string "1")
2580        (const_string "*")))
2581    (set (attr "prefix")
2582      (if_then_else (eq_attr "type" "sselog1,ssemov")
2583        (const_string "maybe_vex")
2584        (const_string "orig")))
2585    (set (attr "prefix_data16")
2586      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2587        (const_string "1")
2588        (const_string "*")))
2589    (set (attr "mode")
2590      (cond [(eq_attr "alternative" "2")
2591               (const_string "SI")
2592             (eq_attr "alternative" "12")
2593               (cond [(match_test "TARGET_AVX")
2594                        (const_string "TI")
2595                      (ior (not (match_test "TARGET_SSE2"))
2596                           (match_test "optimize_function_for_size_p (cfun)"))
2597                        (const_string "V4SF")
2598                     ]
2599                     (const_string "TI"))
2600             (eq_attr "alternative" "13")
2601               (cond [(match_test "TARGET_AVX512VL")
2602                        (const_string "TI")
2603                      (match_test "TARGET_AVX512F")
2604                        (const_string "DF")
2605                      (match_test "TARGET_AVX")
2606                        (const_string "TI")
2607                      (ior (not (match_test "TARGET_SSE2"))
2608                           (match_test "optimize_function_for_size_p (cfun)"))
2609                        (const_string "V4SF")
2610                     ]
2611                     (const_string "TI"))
2613             (and (eq_attr "alternative" "14,15,16")
2614                  (not (match_test "TARGET_SSE2")))
2615               (const_string "V2SF")
2616            ]
2617            (const_string "DI")))
2618    (set (attr "preferred_for_speed")
2619      (cond [(eq_attr "alternative" "10,17,19")
2620               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2621             (eq_attr "alternative" "11,18,20")
2622               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2623            ]
2624            (symbol_ref "true")))
2625    (set (attr "enabled")
2626      (cond [(eq_attr "alternative" "15")
2627               (if_then_else
2628                 (match_test "TARGET_STV && TARGET_SSE2")
2629                 (symbol_ref "false")
2630                 (const_string "*"))
2631             (eq_attr "alternative" "16")
2632               (if_then_else
2633                 (match_test "TARGET_STV && TARGET_SSE2")
2634                 (symbol_ref "true")
2635                 (symbol_ref "false"))
2636            ]
2637            (const_string "*")))])
2639 (define_split
2640   [(set (match_operand:<DWI> 0 "general_reg_operand")
2641         (match_operand:<DWI> 1 "sse_reg_operand"))]
2642   "TARGET_SSE4_1
2643    && reload_completed"
2644   [(set (match_dup 2)
2645         (vec_select:DWIH
2646           (match_dup 3)
2647           (parallel [(const_int 1)])))]
2649   operands[2] = gen_highpart (<MODE>mode, operands[0]);
2650   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2652   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2653                   gen_lowpart (<MODE>mode, operands[1]));
2656 (define_split
2657   [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2658         (match_operand:DWI 1 "general_gr_operand"))]
2659   "reload_completed"
2660   [(const_int 0)]
2661   "ix86_split_long_move (operands); DONE;")
2663 (define_split
2664   [(set (match_operand:DI 0 "sse_reg_operand")
2665         (match_operand:DI 1 "general_reg_operand"))]
2666   "!TARGET_64BIT && TARGET_SSE4_1
2667    && reload_completed"
2668   [(set (match_dup 2)
2669         (vec_merge:V4SI
2670           (vec_duplicate:V4SI (match_dup 3))
2671           (match_dup 2)
2672           (const_int 2)))]
2674   operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2675   operands[3] = gen_highpart (SImode, operands[1]);
2677   emit_move_insn (gen_lowpart (SImode, operands[0]),
2678                   gen_lowpart (SImode, operands[1]));
2681 ;; movabsq $0x0012345678000000, %rax is longer
2682 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2683 (define_peephole2
2684   [(set (match_operand:DI 0 "register_operand")
2685         (match_operand:DI 1 "const_int_operand"))]
2686   "TARGET_64BIT
2687    && optimize_insn_for_size_p ()
2688    && LEGACY_INT_REG_P (operands[0])
2689    && !x86_64_immediate_operand (operands[1], DImode)
2690    && !x86_64_zext_immediate_operand (operands[1], DImode)
2691    && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2692         & ~(HOST_WIDE_INT) 0xffffffff)
2693    && peep2_regno_dead_p (0, FLAGS_REG)"
2694   [(set (match_dup 0) (match_dup 1))
2695    (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2696               (clobber (reg:CC FLAGS_REG))])]
2698   int shift = ctz_hwi (UINTVAL (operands[1]));
2699   operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2700   operands[2] = gen_int_mode (shift, QImode);
2703 (define_insn "*movsi_internal"
2704   [(set (match_operand:SI 0 "nonimmediate_operand"
2705     "=r,m ,*y,*y,?*y,?m,?r,?*y,?Yv,?v,?v,m ,?r,?v,*k,*k  ,*rm,*k")
2706         (match_operand:SI 1 "general_operand"
2707     "g ,re,C ,*y,Bk ,*y,*y,r  ,C  ,?v,Bk,?v,?v,r  ,*r,*kBk,*k ,CBC"))]
2708   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2709    && ix86_hardreg_mov_ok (operands[0], operands[1])"
2711   switch (get_attr_type (insn))
2712     {
2713     case TYPE_SSELOG1:
2714       return standard_sse_constant_opcode (insn, operands);
2716     case TYPE_MSKMOV:
2717       return "kmovd\t{%1, %0|%0, %1}";
2719     case TYPE_MSKLOG:
2720       if (operands[1] == const0_rtx)
2721         return "kxord\t%0, %0, %0";
2722       else if (operands[1] == constm1_rtx)
2723         return "kxnord\t%0, %0, %0";
2724       gcc_unreachable ();
2726     case TYPE_SSEMOV:
2727       return ix86_output_ssemov (insn, operands);
2729     case TYPE_MMX:
2730       return "pxor\t%0, %0";
2732     case TYPE_MMXMOV:
2733       switch (get_attr_mode (insn))
2734         {
2735         case MODE_DI:
2736           return "movq\t{%1, %0|%0, %1}";
2737         case MODE_SI:
2738           return "movd\t{%1, %0|%0, %1}";
2740         default:
2741           gcc_unreachable ();
2742         }
2744     case TYPE_LEA:
2745       return "lea{l}\t{%E1, %0|%0, %E1}";
2747     case TYPE_IMOV:
2748       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2749       if (ix86_use_lea_for_mov (insn, operands))
2750         return "lea{l}\t{%E1, %0|%0, %E1}";
2751       else
2752         return "mov{l}\t{%1, %0|%0, %1}";
2754     default:
2755       gcc_unreachable ();
2756     }
2758   [(set (attr "isa")
2759      (cond [(eq_attr "alternative" "12,13")
2760               (const_string "sse2")
2761            ]
2762            (const_string "*")))
2763    (set (attr "type")
2764      (cond [(eq_attr "alternative" "2")
2765               (const_string "mmx")
2766             (eq_attr "alternative" "3,4,5,6,7")
2767               (const_string "mmxmov")
2768             (eq_attr "alternative" "8")
2769               (const_string "sselog1")
2770             (eq_attr "alternative" "9,10,11,12,13")
2771               (const_string "ssemov")
2772             (eq_attr "alternative" "14,15,16")
2773               (const_string "mskmov")
2774             (eq_attr "alternative" "17")
2775               (const_string "msklog")
2776             (and (match_operand 0 "register_operand")
2777                  (match_operand 1 "pic_32bit_operand"))
2778               (const_string "lea")
2779            ]
2780            (const_string "imov")))
2781    (set (attr "prefix")
2782      (if_then_else (eq_attr "type" "sselog1,ssemov")
2783        (const_string "maybe_vex")
2784        (const_string "orig")))
2785    (set (attr "prefix_data16")
2786      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2787        (const_string "1")
2788        (const_string "*")))
2789    (set (attr "mode")
2790      (cond [(eq_attr "alternative" "2,3")
2791               (const_string "DI")
2792             (eq_attr "alternative" "8")
2793               (cond [(match_test "TARGET_AVX")
2794                        (const_string "TI")
2795                      (ior (not (match_test "TARGET_SSE2"))
2796                           (match_test "optimize_function_for_size_p (cfun)"))
2797                        (const_string "V4SF")
2798                     ]
2799                     (const_string "TI"))
2800             (eq_attr "alternative" "9")
2801               (cond [(match_test "TARGET_AVX512VL")
2802                        (const_string "TI")
2803                      (match_test "TARGET_AVX512F")
2804                        (const_string "SF")
2805                      (match_test "TARGET_AVX")
2806                        (const_string "TI")
2807                      (ior (not (match_test "TARGET_SSE2"))
2808                           (match_test "optimize_function_for_size_p (cfun)"))
2809                        (const_string "V4SF")
2810                     ]
2811                     (const_string "TI"))
2813             (and (eq_attr "alternative" "10,11")
2814                  (not (match_test "TARGET_SSE2")))
2815               (const_string "SF")
2816            ]
2817            (const_string "SI")))
2818    (set (attr "preferred_for_speed")
2819      (cond [(eq_attr "alternative" "6,12")
2820               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2821             (eq_attr "alternative" "7,13")
2822               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2823            ]
2824            (symbol_ref "true")))])
2826 ;; With -Oz, transform mov $imm,reg to the shorter push $imm; pop reg.
2827 (define_peephole2
2828   [(set (match_operand:SWI248 0 "general_reg_operand")
2829         (match_operand:SWI248 1 "const_int_operand"))]
2830   "optimize_insn_for_size_p () && optimize_size > 1
2831    && operands[1] != const0_rtx
2832    && IN_RANGE (INTVAL (operands[1]), -128, 127)
2833    && !ix86_red_zone_used
2834    && REGNO (operands[0]) != SP_REG"
2835   [(set (match_dup 2) (match_dup 1))
2836    (set (match_dup 0) (match_dup 3))]
2838   if (GET_MODE (operands[0]) != word_mode)
2839     operands[0] = gen_rtx_REG (word_mode, REGNO (operands[0]));
2841   operands[2] = gen_rtx_MEM (word_mode,
2842                              gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
2843   operands[3] = gen_rtx_MEM (word_mode,
2844                              gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2847 ;; With -Oz, transform mov $0,mem to the shorter and $0,mem.
2848 ;; Likewise, transform mov $-1,mem to the shorter or $-1,mem.
2849 (define_peephole2
2850   [(set (match_operand:SWI248 0 "memory_operand")
2851         (match_operand:SWI248 1 "const_int_operand"))]
2852   "(operands[1] == const0_rtx || operands[1] == constm1_rtx)
2853    && optimize_insn_for_size_p () && optimize_size > 1
2854    && peep2_regno_dead_p (0, FLAGS_REG)"
2855   [(parallel [(set (match_dup 0) (match_dup 1))
2856               (clobber (reg:CC FLAGS_REG))])])
2858 (define_insn "*movhi_internal"
2859   [(set (match_operand:HI 0 "nonimmediate_operand"
2860     "=r,r,r,m ,*k,*k ,r ,m ,*k ,?r,?*v,*Yv,*v,*v,jm,m")
2861         (match_operand:HI 1 "general_operand"
2862     "r ,n,m,rn,r ,*km,*k,*k,CBC,*v,r  ,C  ,*v,m ,*x,*v"))]
2863   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2864    && ix86_hardreg_mov_ok (operands[0], operands[1])"
2866   switch (get_attr_type (insn))
2867     {
2868     case TYPE_IMOVX:
2869       /* movzwl is faster than movw on p2 due to partial word stalls,
2870          though not as fast as an aligned movl.  */
2871       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2873     case TYPE_MSKMOV:
2874       switch (which_alternative)
2875         {
2876         case 4:
2877           return "kmovw\t{%k1, %0|%0, %k1}";
2878         case 6:
2879           return "kmovw\t{%1, %k0|%k0, %1}";
2880         case 5:
2881         case 7:
2882           return "kmovw\t{%1, %0|%0, %1}";
2883         default:
2884           gcc_unreachable ();
2885         }
2887     case TYPE_SSEMOV:
2888       return ix86_output_ssemov (insn, operands);
2890     case TYPE_SSELOG1:
2891       if (satisfies_constraint_C (operands[1]))
2892         return standard_sse_constant_opcode (insn, operands);
2894       if (SSE_REG_P (operands[0]))
2895         return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
2896       else
2897         return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
2899     case TYPE_MSKLOG:
2900       if (operands[1] == const0_rtx)
2901         return "kxorw\t%0, %0, %0";
2902       else if (operands[1] == constm1_rtx)
2903         return "kxnorw\t%0, %0, %0";
2904       gcc_unreachable ();
2906     default:
2907       if (get_attr_mode (insn) == MODE_SI)
2908         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2909       else
2910         return "mov{w}\t{%1, %0|%0, %1}";
2911     }
2913   [(set (attr "isa")
2914         (cond [(eq_attr "alternative" "9,10,11,12,13")
2915                   (const_string "sse2")
2916                (eq_attr "alternative" "14")
2917                   (const_string "sse4_noavx")
2918                (eq_attr "alternative" "15")
2919                   (const_string "avx")
2920                ]
2921                (const_string "*")))
2922    (set (attr "addr")
2923         (if_then_else (eq_attr "alternative" "14")
2924                       (const_string "gpr16")
2925                       (const_string "*")))
2926    (set (attr "type")
2927      (cond [(eq_attr "alternative" "4,5,6,7")
2928               (const_string "mskmov")
2929             (eq_attr "alternative" "8")
2930               (const_string "msklog")
2931             (eq_attr "alternative" "13,14,15")
2932               (if_then_else (match_test "TARGET_AVX512FP16")
2933                 (const_string "ssemov")
2934                 (const_string "sselog1"))
2935             (eq_attr "alternative" "11")
2936               (const_string "sselog1")
2937             (eq_attr "alternative" "9,10,12")
2938               (const_string "ssemov")
2939             (match_test "optimize_function_for_size_p (cfun)")
2940               (const_string "imov")
2941             (and (eq_attr "alternative" "0")
2942                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2943                       (not (match_test "TARGET_HIMODE_MATH"))))
2944               (const_string "imov")
2945             (and (eq_attr "alternative" "1,2")
2946                  (match_operand:HI 1 "aligned_operand"))
2947               (const_string "imov")
2948             (and (match_test "TARGET_MOVX")
2949                  (eq_attr "alternative" "0,2"))
2950               (const_string "imovx")
2951            ]
2952            (const_string "imov")))
2953    (set (attr "prefix")
2954         (cond [(eq_attr "alternative" "4,5,6,7,8")
2955                  (const_string "vex")
2956                (eq_attr "alternative" "9,10,11,12,13,14,15")
2957                  (const_string "maybe_evex")
2958               ]
2959               (const_string "orig")))
2960    (set (attr "mode")
2961      (cond [(eq_attr "alternative" "9,10")
2962               (if_then_else (match_test "TARGET_AVX512FP16")
2963                 (const_string "HI")
2964                 (const_string "SI"))
2965             (eq_attr "alternative" "13,14,15")
2966               (if_then_else (match_test "TARGET_AVX512FP16")
2967                 (const_string "HI")
2968                 (const_string "TI"))
2969             (eq_attr "alternative" "11")
2970               (cond [(match_test "TARGET_AVX")
2971                        (const_string "TI")
2972                      (ior (not (match_test "TARGET_SSE2"))
2973                           (match_test "optimize_function_for_size_p (cfun)"))
2974                        (const_string "V4SF")
2975                     ]
2976                     (const_string "TI"))
2977             (eq_attr "alternative" "12")
2978               (cond [(match_test "TARGET_AVX512VL")
2979                        (const_string "TI")
2980                      (match_test "TARGET_AVX512FP16")
2981                        (const_string "HF")
2982                      (match_test "TARGET_AVX512F")
2983                        (const_string "SF")
2984                      (match_test "TARGET_AVX")
2985                        (const_string "TI")
2986                      (ior (not (match_test "TARGET_SSE2"))
2987                           (match_test "optimize_function_for_size_p (cfun)"))
2988                        (const_string "V4SF")
2989                     ]
2990                     (const_string "TI"))
2991             (eq_attr "type" "imovx")
2992               (const_string "SI")
2993             (and (eq_attr "alternative" "1,2")
2994                  (match_operand:HI 1 "aligned_operand"))
2995               (const_string "SI")
2996             (and (eq_attr "alternative" "0")
2997                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2998                       (not (match_test "TARGET_HIMODE_MATH"))))
2999               (const_string "SI")
3000             ]
3001             (const_string "HI")))
3002    (set (attr "preferred_for_speed")
3003      (cond [(eq_attr "alternative" "9")
3004               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3005             (eq_attr "alternative" "10")
3006               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3007            ]
3008            (symbol_ref "true")))])
3010 ;; Situation is quite tricky about when to choose full sized (SImode) move
3011 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
3012 ;; partial register dependency machines (such as AMD Athlon), where QImode
3013 ;; moves issue extra dependency and for partial register stalls machines
3014 ;; that don't use QImode patterns (and QImode move cause stall on the next
3015 ;; instruction).
3017 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
3018 ;; register stall machines with, where we use QImode instructions, since
3019 ;; partial register stall can be caused there.  Then we use movzx.
3021 (define_insn "*movqi_internal"
3022   [(set (match_operand:QI 0 "nonimmediate_operand"
3023                         "=Q,R,r,q,q,r,r ,?r,m ,*k,*k,*r,*m,*k,*k,*k")
3024         (match_operand:QI 1 "general_operand"
3025                         "Q ,R,r,n,m,q,rn, m,qn,*r,*k,*k,*k,*m,C,BC"))]
3026   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3027    && ix86_hardreg_mov_ok (operands[0], operands[1])"
3030   char buf[128];
3031   const char *ops;
3032   const char *suffix;
3034   switch (get_attr_type (insn))
3035     {
3036     case TYPE_IMOVX:
3037       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
3038       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
3040     case TYPE_MSKMOV:
3041       switch (which_alternative)
3042         {
3043         case 9:
3044           ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
3045           break;
3046         case 11:
3047           ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
3048           break;
3049         case 12:
3050         case 13:
3051           gcc_assert (TARGET_AVX512DQ);
3052           /* FALLTHRU */
3053         case 10:
3054           ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
3055           break;
3056         default:
3057           gcc_unreachable ();
3058         }
3060       suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
3062       snprintf (buf, sizeof (buf), ops, suffix);
3063       output_asm_insn (buf, operands);
3064       return "";
3066     case TYPE_MSKLOG:
3067       if (operands[1] == const0_rtx)
3068         {
3069           if (get_attr_mode (insn) == MODE_HI)
3070             return "kxorw\t%0, %0, %0";
3071           else
3072             return "kxorb\t%0, %0, %0";
3073         }
3074       else if (operands[1] == constm1_rtx)
3075         {
3076           gcc_assert (TARGET_AVX512DQ);
3077           return "kxnorb\t%0, %0, %0";
3078         }
3079       gcc_unreachable ();
3081     default:
3082       if (get_attr_mode (insn) == MODE_SI)
3083         return "mov{l}\t{%k1, %k0|%k0, %k1}";
3084       else
3085         return "mov{b}\t{%1, %0|%0, %1}";
3086     }
3088   [(set (attr "isa")
3089      (cond [(eq_attr "alternative" "1,2")
3090               (const_string "x64")
3091             (eq_attr "alternative" "12,13,15")
3092               (const_string "avx512dq")
3093            ]
3094            (const_string "*")))
3095    (set (attr "type")
3096      (cond [(eq_attr "alternative" "9,10,11,12,13")
3097               (const_string "mskmov")
3098             (eq_attr "alternative" "14,15")
3099               (const_string "msklog")
3100             (and (eq_attr "alternative" "7")
3101                  (not (match_operand:QI 1 "aligned_operand")))
3102               (const_string "imovx")
3103             (match_test "optimize_function_for_size_p (cfun)")
3104               (const_string "imov")
3105             (and (eq_attr "alternative" "5")
3106                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
3107                       (not (match_test "TARGET_QIMODE_MATH"))))
3108               (const_string "imov")
3109             (eq_attr "alternative" "5,7")
3110               (const_string "imovx")
3111             (and (match_test "TARGET_MOVX")
3112                  (eq_attr "alternative" "4"))
3113               (const_string "imovx")
3114            ]
3115            (const_string "imov")))
3116    (set (attr "prefix")
3117      (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15")
3118        (const_string "vex")
3119        (const_string "orig")))
3120    (set (attr "mode")
3121       (cond [(eq_attr "alternative" "5,6,7")
3122                (const_string "SI")
3123              (eq_attr "alternative" "8")
3124                (const_string "QI")
3125              (and (eq_attr "alternative" "9,10,11,14")
3126                   (not (match_test "TARGET_AVX512DQ")))
3127                (const_string "HI")
3128              (eq_attr "type" "imovx")
3129                (const_string "SI")
3130              ;; For -Os, 8-bit immediates are always shorter than 32-bit
3131              ;; ones.
3132              (and (eq_attr "type" "imov")
3133                   (and (eq_attr "alternative" "3")
3134                        (match_test "optimize_function_for_size_p (cfun)")))
3135                (const_string "QI")
3136              ;; For -Os, movl where one or both operands are NON_Q_REGS
3137              ;; and both are LEGACY_REGS is shorter than movb.
3138              ;; Otherwise movb and movl sizes are the same, so decide purely
3139              ;; based on speed factors.
3140              (and (eq_attr "type" "imov")
3141                   (and (eq_attr "alternative" "1")
3142                        (match_test "optimize_function_for_size_p (cfun)")))
3143                (const_string "SI")
3144              (and (eq_attr "type" "imov")
3145                   (and (eq_attr "alternative" "0,1,2,3")
3146                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
3147                             (not (match_test "TARGET_PARTIAL_REG_STALL")))))
3148                (const_string "SI")
3149              ;; Avoid partial register stalls when not using QImode arithmetic
3150              (and (eq_attr "type" "imov")
3151                   (and (eq_attr "alternative" "0,1,2,3")
3152                        (and (match_test "TARGET_PARTIAL_REG_STALL")
3153                             (not (match_test "TARGET_QIMODE_MATH")))))
3154                (const_string "SI")
3155            ]
3156            (const_string "QI")))])
3158 /* Reload dislikes loading 0/-1 directly into mask registers.
3159    Try to tidy things up here.  */
3160 (define_peephole2
3161   [(set (match_operand:SWI 0 "general_reg_operand")
3162         (match_operand:SWI 1 "immediate_operand"))
3163    (set (match_operand:SWI 2 "mask_reg_operand")
3164         (match_dup 0))]
3165   "peep2_reg_dead_p (2, operands[0])
3166    && (const0_operand (operands[1], <MODE>mode)
3167        || (constm1_operand (operands[1], <MODE>mode)
3168            && (<MODE_SIZE> > 1 || TARGET_AVX512DQ)))"
3169   [(set (match_dup 2) (match_dup 1))])
3171 ;; Stores and loads of ax to arbitrary constant address.
3172 ;; We fake an second form of instruction to force reload to load address
3173 ;; into register when rax is not available
3174 (define_insn "*movabs<mode>_1"
3175   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
3176         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
3177   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
3179   /* Recover the full memory rtx.  */
3180   operands[0] = SET_DEST (PATTERN (insn));
3181   switch (which_alternative)
3182     {
3183     case 0:
3184       return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
3185     case 1:
3186       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3187     default:
3188       gcc_unreachable ();
3189     }
3191   [(set_attr "type" "imov")
3192    (set_attr "modrm" "0,*")
3193    (set_attr "length_address" "8,0")
3194    (set_attr "length_immediate" "0,*")
3195    (set_attr "memory" "store")
3196    (set_attr "mode" "<MODE>")])
3198 (define_insn "*movabs<mode>_2"
3199   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
3200         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
3201   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
3203   /* Recover the full memory rtx.  */
3204   operands[1] = SET_SRC (PATTERN (insn));
3205   switch (which_alternative)
3206     {
3207     case 0:
3208       return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
3209     case 1:
3210       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3211     default:
3212       gcc_unreachable ();
3213     }
3215   [(set_attr "type" "imov")
3216    (set_attr "modrm" "0,*")
3217    (set_attr "length_address" "8,0")
3218    (set_attr "length_immediate" "0")
3219    (set_attr "memory" "load")
3220    (set_attr "mode" "<MODE>")])
3222 (define_insn "swap<mode>"
3223   [(set (match_operand:SWI48 0 "register_operand" "+r")
3224         (match_operand:SWI48 1 "register_operand" "+r"))
3225    (set (match_dup 1)
3226         (match_dup 0))]
3227   ""
3228   "xchg{<imodesuffix>}\t%1, %0"
3229   [(set_attr "type" "imov")
3230    (set_attr "mode" "<MODE>")
3231    (set_attr "pent_pair" "np")
3232    (set_attr "athlon_decode" "vector")
3233    (set_attr "amdfam10_decode" "double")
3234    (set_attr "bdver1_decode" "double")])
3236 (define_insn "*swap<mode>"
3237   [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
3238         (match_operand:SWI12 1 "register_operand" "+<r>,r"))
3239    (set (match_dup 1)
3240         (match_dup 0))]
3241   ""
3242   "@
3243    xchg{<imodesuffix>}\t%1, %0
3244    xchg{l}\t%k1, %k0"
3245   [(set_attr "type" "imov")
3246    (set_attr "mode" "<MODE>,SI")
3247    (set (attr "preferred_for_size")
3248      (cond [(eq_attr "alternative" "0")
3249               (symbol_ref "false")]
3250            (symbol_ref "true")))
3251    ;; Potential partial reg stall on alternative 1.
3252    (set (attr "preferred_for_speed")
3253      (cond [(eq_attr "alternative" "1")
3254               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
3255            (symbol_ref "true")))
3256    (set_attr "pent_pair" "np")
3257    (set_attr "athlon_decode" "vector")
3258    (set_attr "amdfam10_decode" "double")
3259    (set_attr "bdver1_decode" "double")])
3261 (define_peephole2
3262   [(set (match_operand:SWI 0 "general_reg_operand")
3263         (match_operand:SWI 1 "general_reg_operand"))
3264    (set (match_dup 1)
3265         (match_operand:SWI 2 "general_reg_operand"))
3266    (set (match_dup 2) (match_dup 0))]
3267   "peep2_reg_dead_p (3, operands[0])
3268    && optimize_insn_for_size_p ()"
3269   [(parallel [(set (match_dup 1) (match_dup 2))
3270               (set (match_dup 2) (match_dup 1))])])
3272 ;; Convert xchg with a REG_UNUSED note to a mov (variant #1).
3273 (define_peephole2
3274   [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3275                    (match_operand:SWI 1 "general_reg_operand"))
3276               (set (match_dup 1) (match_dup 0))])]
3277   "((REGNO (operands[0]) != AX_REG
3278      && REGNO (operands[1]) != AX_REG)
3279     || optimize_size < 2
3280     || !optimize_insn_for_size_p ())
3281    && peep2_reg_dead_p (1, operands[0])"
3282   [(set (match_dup 1) (match_dup 0))])
3284 ;; Convert xchg with a REG_UNUSED note to a mov (variant #2).
3285 (define_peephole2
3286   [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3287                    (match_operand:SWI 1 "general_reg_operand"))
3288               (set (match_dup 1) (match_dup 0))])]
3289   "((REGNO (operands[0]) != AX_REG
3290      && REGNO (operands[1]) != AX_REG)
3291     || optimize_size < 2
3292     || !optimize_insn_for_size_p ())
3293    && peep2_reg_dead_p (1, operands[1])"
3294   [(set (match_dup 0) (match_dup 1))])
3296 ;; Convert moves to/from AX_REG into xchg with -Oz.
3297 (define_peephole2
3298   [(set (match_operand:SWI48 0 "general_reg_operand")
3299         (match_operand:SWI48 1 "general_reg_operand"))]
3300  "optimize_size > 1
3301   && ((REGNO (operands[0]) == AX_REG)
3302       != (REGNO (operands[1]) == AX_REG))
3303   && optimize_insn_for_size_p ()
3304   && peep2_reg_dead_p (1, operands[1])"
3305   [(parallel [(set (match_dup 0) (match_dup 1))
3306               (set (match_dup 1) (match_dup 0))])])
3308 (define_expand "movstrict<mode>"
3309   [(set (strict_low_part (match_operand:SWI12 0 "register_operand"))
3310         (match_operand:SWI12 1 "general_operand"))]
3311   ""
3313   gcc_assert (SUBREG_P (operands[0]));
3314   if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
3315       || !VALID_INT_MODE_P (GET_MODE (SUBREG_REG (operands[0]))))
3316     FAIL;
3319 (define_insn "*movstrict<mode>_1"
3320   [(set (strict_low_part
3321           (match_operand:SWI12 0 "register_operand" "+<r>"))
3322         (match_operand:SWI12 1 "general_operand" "<r>mn"))]
3323   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
3324   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
3325   [(set_attr "type" "imov")
3326    (set_attr "mode" "<MODE>")])
3328 (define_insn "*movstrict<mode>_xor"
3329   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
3330         (match_operand:SWI12 1 "const0_operand"))
3331    (clobber (reg:CC FLAGS_REG))]
3332   "reload_completed"
3333   "xor{<imodesuffix>}\t%0, %0"
3334   [(set_attr "type" "alu1")
3335    (set_attr "mode" "<MODE>")
3336    (set_attr "length_immediate" "0")])
3338 (define_expand "extv<mode>"
3339   [(set (match_operand:SWI24 0 "register_operand")
3340         (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
3341                             (match_operand:QI 2 "const_int_operand")
3342                             (match_operand:QI 3 "const_int_operand")))]
3343   ""
3345   /* Handle extractions from %ah et al.  */
3346   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3347     FAIL;
3349   unsigned int regno = reg_or_subregno (operands[1]);
3351   /* Be careful to expand only with registers having upper parts.  */
3352   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3353     operands[1] = copy_to_reg (operands[1]);
3356 (define_insn "*extv<mode>"
3357   [(set (match_operand:SWI24 0 "register_operand" "=R")
3358         (sign_extract:SWI24 (match_operand 1 "int248_register_operand" "Q")
3359                             (const_int 8)
3360                             (const_int 8)))]
3361   ""
3362   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
3363   [(set_attr "type" "imovx")
3364    (set_attr "mode" "SI")])
3366 ;; Split sign-extension of single least significant bit as and x,$1;neg x
3367 (define_insn_and_split "*extv<mode>_1_0"
3368   [(set (match_operand:SWI48 0 "register_operand" "=r")
3369         (sign_extract:SWI48 (match_operand:SWI48 1 "register_operand" "0")
3370                             (const_int 1)
3371                             (const_int 0)))
3372    (clobber (reg:CC FLAGS_REG))]
3373   ""
3374   "#"
3375   ""
3376   [(parallel [(set (match_dup 0) (and:SWI48 (match_dup 1) (const_int 1)))
3377               (clobber (reg:CC FLAGS_REG))])
3378    (parallel [(set (match_dup 0) (neg:SWI48 (match_dup 0)))
3379               (clobber (reg:CC FLAGS_REG))])])
3381 (define_expand "extzv<mode>"
3382   [(set (match_operand:SWI248 0 "register_operand")
3383         (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
3384                              (match_operand:QI 2 "const_int_operand")
3385                              (match_operand:QI 3 "const_int_operand")))]
3386   ""
3388   if (ix86_expand_pextr (operands))
3389     DONE;
3391   /* Handle extractions from %ah et al.  */
3392   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3393     FAIL;
3395   unsigned int regno = reg_or_subregno (operands[1]);
3397   /* Be careful to expand only with registers having upper parts.  */
3398   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3399     operands[1] = copy_to_reg (operands[1]);
3402 (define_insn "*extzv<mode>"
3403   [(set (match_operand:SWI248 0 "register_operand" "=R")
3404         (zero_extract:SWI248 (match_operand 1 "int248_register_operand" "Q")
3405                              (const_int 8)
3406                              (const_int 8)))]
3407   ""
3408   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
3409   [(set_attr "type" "imovx")
3410    (set_attr "mode" "SI")])
3412 (define_insn "*extzvqi"
3413   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn,?R")
3414         (subreg:QI
3415           (match_operator:SWI248 2 "extract_operator"
3416             [(match_operand 1 "int248_register_operand" "Q,Q")
3417              (const_int 8)
3418              (const_int 8)]) 0))]
3419   ""
3421   switch (get_attr_type (insn))
3422     {
3423     case TYPE_IMOVX:
3424       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
3425     default:
3426       return "mov{b}\t{%h1, %0|%0, %h1}";
3427     }
3429   [(set_attr "addr" "gpr8,*")
3430    (set (attr "type")
3431      (if_then_else (and (match_operand:QI 0 "register_operand")
3432                         (ior (not (match_operand:QI 0 "QIreg_operand"))
3433                              (match_test "TARGET_MOVX")))
3434         (const_string "imovx")
3435         (const_string "imov")))
3436    (set (attr "mode")
3437      (if_then_else (eq_attr "type" "imovx")
3438         (const_string "SI")
3439         (const_string "QI")))])
3441 (define_expand "insv<mode>"
3442   [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3443                              (match_operand:QI 1 "const_int_operand")
3444                              (match_operand:QI 2 "const_int_operand"))
3445         (match_operand:SWI248 3 "register_operand"))]
3446   ""
3448   rtx dst;
3450   if (ix86_expand_pinsr (operands))
3451     DONE;
3453   /* Handle insertions to %ah et al.  */
3454   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3455     FAIL;
3457   unsigned int regno = reg_or_subregno (operands[0]);
3459   /* Be careful to expand only with registers having upper parts.  */
3460   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3461     dst = copy_to_reg (operands[0]);
3462   else
3463     dst = operands[0];
3465   emit_insn (gen_insv_1 (<MODE>mode, dst, operands[3]));
3467   /* Fix up the destination if needed.  */
3468   if (dst != operands[0])
3469     emit_move_insn (operands[0], dst);
3471   DONE;
3474 (define_insn "@insv<mode>_1"
3475   [(set (zero_extract:SWI248
3476           (match_operand 0 "int248_register_operand" "+Q")
3477           (const_int 8)
3478           (const_int 8))
3479         (match_operand:SWI248 1 "general_operand" "QnBn"))]
3480   ""
3482   if (CONST_INT_P (operands[1]))
3483     operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3484   return "mov{b}\t{%b1, %h0|%h0, %b1}";
3486   [(set_attr "addr" "gpr8")
3487    (set_attr "type" "imov")
3488    (set_attr "mode" "QI")])
3490 (define_insn "*insvqi_1"
3491   [(set (zero_extract:SWI248
3492           (match_operand 0 "int248_register_operand" "+Q")
3493           (const_int 8)
3494           (const_int 8))
3495         (subreg:SWI248
3496           (match_operand:QI 1 "general_operand" "QnBn") 0))]
3497   ""
3498   "mov{b}\t{%1, %h0|%h0, %1}"
3499   [(set_attr "addr" "gpr8")
3500    (set_attr "type" "imov")
3501    (set_attr "mode" "QI")])
3503 ;; Eliminate redundant insv, e.g. xorl %eax,%eax; movb $0, %ah
3504 (define_peephole2
3505   [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3506                    (const_int 0))
3507               (clobber (reg:CC FLAGS_REG))])
3508    (set (zero_extract:SWI248 (match_operand 1 "int248_register_operand")
3509                              (const_int 8)
3510                              (const_int 8))
3511         (const_int 0))]
3512   "REGNO (operands[0]) == REGNO (operands[1])"
3513   [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3514                    (const_int 0))
3515               (clobber (reg:CC FLAGS_REG))])])
3517 ;; Combine movl followed by movb.
3518 (define_peephole2
3519   [(set (match_operand:SWI48 0 "general_reg_operand")
3520         (match_operand:SWI48 1 "const_int_operand"))
3521    (set (zero_extract:SWI248 (match_operand 2 "int248_register_operand")
3522                              (const_int 8)
3523                              (const_int 8))
3524         (match_operand:SWI248 3 "const_int_operand"))]
3525   "REGNO (operands[0]) == REGNO (operands[2])"
3526   [(set (match_operand:SWI48 0 "general_reg_operand")
3527         (match_dup 4))]
3529   HOST_WIDE_INT tmp = INTVAL (operands[1]) & ~(HOST_WIDE_INT)0xff00;
3530   tmp |= (INTVAL (operands[3]) & 0xff) << 8;
3531   operands[4] = gen_int_mode (tmp, <SWI48:MODE>mode);
3534 (define_insn "*insvqi_2"
3535   [(set (zero_extract:SWI248
3536           (match_operand 0 "int248_register_operand" "+Q")
3537           (const_int 8)
3538           (const_int 8))
3539         (match_operator:SWI248 2 "extract_operator"
3540           [(match_operand 1 "int248_register_operand" "Q")
3541            (const_int 8)
3542            (const_int 8)]))]
3543   ""
3544   "mov{b}\t{%h1, %h0|%h0, %h1}"
3545   [(set_attr "type" "imov")
3546    (set_attr "mode" "QI")])
3548 (define_insn "*insvqi_3"
3549   [(set (zero_extract:SWI248
3550           (match_operand 0 "int248_register_operand" "+Q")
3551           (const_int 8)
3552           (const_int 8))
3553         (any_shiftrt:SWI248
3554           (match_operand:SWI248 1 "register_operand" "Q")
3555           (const_int 8)))]
3556   ""
3557   "mov{b}\t{%h1, %h0|%h0, %h1}"
3558   [(set_attr "type" "imov")
3559    (set_attr "mode" "QI")])
3561 (define_code_iterator any_or_plus [plus ior xor])
3563 (define_insn_and_split "*insvti_highpart_1"
3564   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3565         (any_or_plus:TI
3566           (and:TI
3567             (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3568             (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3569           (ashift:TI
3570             (zero_extend:TI
3571               (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))
3572             (const_int 64))))]
3573   "TARGET_64BIT
3574    && CONST_WIDE_INT_P (operands[3])
3575    && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3576    && CONST_WIDE_INT_ELT (operands[3], 0) == -1
3577    && CONST_WIDE_INT_ELT (operands[3], 1) == 0"
3578   "#"
3579   "&& reload_completed"
3580   [(const_int 0)]
3582   operands[4] = gen_lowpart (DImode, operands[1]);
3583   split_double_concat (TImode, operands[0], operands[4], operands[2]);
3584   DONE;
3587 (define_insn_and_split "*insvti_lowpart_1"
3588   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3589         (any_or_plus:TI
3590           (and:TI
3591             (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3592             (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3593           (zero_extend:TI
3594             (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))))]
3595   "TARGET_64BIT
3596    && CONST_WIDE_INT_P (operands[3])
3597    && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3598    && CONST_WIDE_INT_ELT (operands[3], 0) == 0
3599    && CONST_WIDE_INT_ELT (operands[3], 1) == -1"
3600   "#"
3601   "&& reload_completed"
3602   [(const_int 0)]
3604   operands[4] = gen_highpart (DImode, operands[1]);
3605   split_double_concat (TImode, operands[0], operands[2], operands[4]);
3606   DONE;
3609 (define_insn_and_split "*insvdi_lowpart_1"
3610   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,r,r,&r")
3611         (any_or_plus:DI
3612           (and:DI
3613             (match_operand:DI 1 "nonimmediate_operand" "r,m,r,m")
3614             (match_operand:DI 3 "const_int_operand" "n,n,n,n"))
3615           (zero_extend:DI
3616             (match_operand:SI 2 "nonimmediate_operand" "r,r,m,m"))))]
3617   "!TARGET_64BIT
3618    && CONST_INT_P (operands[3])
3619    && UINTVAL (operands[3]) == 0xffffffff00000000ll"
3620   "#"
3621   "&& reload_completed"
3622   [(const_int 0)]
3624   operands[4] = gen_highpart (SImode, operands[1]);
3625   split_double_concat (DImode, operands[0], operands[2], operands[4]);
3626   DONE;
3629 ;; Floating point push instructions.
3631 (define_insn "*pushtf"
3632   [(set (match_operand:TF 0 "push_operand" "=<,<")
3633         (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3634   "TARGET_64BIT || TARGET_SSE"
3636   /* This insn should be already split before reg-stack.  */
3637   return "#";
3639   [(set_attr "isa" "*,x64")
3640    (set_attr "type" "multi")
3641    (set_attr "unit" "sse,*")
3642    (set_attr "mode" "TF,DI")])
3644 ;; %%% Kill this when call knows how to work this out.
3645 (define_split
3646   [(set (match_operand:TF 0 "push_operand")
3647         (match_operand:TF 1 "sse_reg_operand"))]
3648   "TARGET_SSE && reload_completed"
3649   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3650    (set (match_dup 0) (match_dup 1))]
3652   /* Preserve memory attributes. */
3653   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3656 (define_insn "*pushxf"
3657   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3658         (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3659   ""
3661   /* This insn should be already split before reg-stack.  */
3662   return "#";
3664   [(set_attr "isa" "*,*,*,nox64,x64")
3665    (set_attr "type" "multi")
3666    (set_attr "unit" "i387,*,*,*,*")
3667    (set (attr "mode")
3668         (cond [(eq_attr "alternative" "1,2,3,4")
3669                  (if_then_else (match_test "TARGET_64BIT")
3670                    (const_string "DI")
3671                    (const_string "SI"))
3672               ]
3673               (const_string "XF")))
3674    (set (attr "preferred_for_size")
3675      (cond [(eq_attr "alternative" "1")
3676               (symbol_ref "false")]
3677            (symbol_ref "true")))])
3679 ;; %%% Kill this when call knows how to work this out.
3680 (define_split
3681   [(set (match_operand:XF 0 "push_operand")
3682         (match_operand:XF 1 "fp_register_operand"))]
3683   "reload_completed"
3684   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3685    (set (match_dup 0) (match_dup 1))]
3687   operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3688   /* Preserve memory attributes. */
3689   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3692 (define_insn "*pushdf"
3693   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3694         (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,v"))]
3695   ""
3697   /* This insn should be already split before reg-stack.  */
3698   return "#";
3700   [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3701    (set_attr "type" "multi")
3702    (set_attr "unit" "i387,*,*,*,*,sse")
3703    (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3704    (set (attr "preferred_for_size")
3705      (cond [(eq_attr "alternative" "1")
3706               (symbol_ref "false")]
3707            (symbol_ref "true")))
3708    (set (attr "preferred_for_speed")
3709      (cond [(eq_attr "alternative" "1")
3710               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3711            (symbol_ref "true")))])
3712    
3713 ;; %%% Kill this when call knows how to work this out.
3714 (define_split
3715   [(set (match_operand:DF 0 "push_operand")
3716         (match_operand:DF 1 "any_fp_register_operand"))]
3717   "reload_completed"
3718   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3719    (set (match_dup 0) (match_dup 1))]
3721   /* Preserve memory attributes. */
3722   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3725 (define_mode_iterator HFBF [HF BF])
3727 (define_insn "*push<mode>_rex64"
3728   [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3729         (match_operand:HFBF 1 "nonmemory_no_elim_operand" "r,x"))]
3730   "TARGET_64BIT"
3732   /* Anything else should be already split before reg-stack.  */
3733   gcc_assert (which_alternative == 0);
3734   return "push{q}\t%q1";
3736   [(set_attr "isa"  "*,sse4")
3737    (set_attr "type" "push,multi")
3738    (set_attr "mode" "DI,TI")])
3740 (define_insn "*push<mode>"
3741   [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3742         (match_operand:HFBF 1 "general_no_elim_operand" "rmF,x"))]
3743   "!TARGET_64BIT"
3745   /* Anything else should be already split before reg-stack.  */
3746   gcc_assert (which_alternative == 0);
3747   return "push{l}\t%k1";
3749   [(set_attr "isa"  "*,sse4")
3750    (set_attr "type" "push,multi")
3751    (set_attr "mode" "SI,TI")])
3753 (define_insn "push2_di"
3754   [(set (match_operand:TI 0 "push_operand" "=<")
3755         (unspec:TI [(match_operand:DI 1 "register_operand" "r")
3756                     (match_operand:DI 2 "register_operand" "r")]
3757                     UNSPEC_APXPUSH2))]
3758   "TARGET_APX_PUSH2POP2"
3759   "push2\t%1, %2"
3760   [(set_attr "mode" "TI")
3761    (set_attr "type" "multi")
3762    (set_attr "prefix" "evex")])
3764 (define_insn "pop2_di"
3765   [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3766                    (unspec:DI [(match_operand:TI 1 "pop_operand" ">")]
3767                               UNSPEC_APXPOP2_LOW))
3768               (set (match_operand:DI 2 "register_operand" "=r")
3769                    (unspec:DI [(const_int 0)] UNSPEC_APXPOP2_HIGH))])]
3770   "TARGET_APX_PUSH2POP2"
3771   "pop2\t%0, %2"
3772   [(set_attr "mode" "TI")
3773    (set_attr "prefix" "evex")])
3775 (define_insn "*pushsf_rex64"
3776   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3777         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,v"))]
3778   "TARGET_64BIT"
3780   /* Anything else should be already split before reg-stack.  */
3781   if (which_alternative != 1)
3782     return "#";
3783   return "push{q}\t%q1";
3785   [(set_attr "type" "multi,push,multi")
3786    (set_attr "unit" "i387,*,*")
3787    (set_attr "mode" "SF,DI,SF")])
3789 (define_insn "*pushsf"
3790   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3791         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,v"))]
3792   "!TARGET_64BIT"
3794   /* Anything else should be already split before reg-stack.  */
3795   if (which_alternative != 1)
3796     return "#";
3797   return "push{l}\t%1";
3799   [(set_attr "type" "multi,push,multi")
3800    (set_attr "unit" "i387,*,*")
3801    (set_attr "mode" "SF,SI,SF")])
3803 (define_mode_iterator MODESH [SF HF BF])
3804 ;; %%% Kill this when call knows how to work this out.
3805 (define_split
3806   [(set (match_operand:MODESH 0 "push_operand")
3807         (match_operand:MODESH 1 "any_fp_register_operand"))]
3808   "reload_completed"
3809   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3810    (set (match_dup 0) (match_dup 1))]
3812   rtx op = XEXP (operands[0], 0);
3813   if (GET_CODE (op) == PRE_DEC)
3814     {
3815       gcc_assert (!TARGET_64BIT);
3816       op = GEN_INT (-4);
3817     }
3818   else
3819     {
3820       op = XEXP (XEXP (op, 1), 1);
3821       gcc_assert (CONST_INT_P (op));
3822     }
3823   operands[2] = op;
3824   /* Preserve memory attributes. */
3825   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3828 (define_split
3829   [(set (match_operand:SF 0 "push_operand")
3830         (match_operand:SF 1 "memory_operand"))]
3831   "reload_completed
3832    && find_constant_src (insn)"
3833   [(set (match_dup 0) (match_dup 2))]
3834   "operands[2] = find_constant_src (curr_insn);")
3836 (define_split
3837   [(set (match_operand 0 "push_operand")
3838         (match_operand 1 "general_gr_operand"))]
3839   "reload_completed
3840    && (GET_MODE (operands[0]) == TFmode
3841        || GET_MODE (operands[0]) == XFmode
3842        || GET_MODE (operands[0]) == DFmode)"
3843   [(const_int 0)]
3844   "ix86_split_long_move (operands); DONE;")
3846 ;; Floating point move instructions.
3848 (define_expand "movtf"
3849   [(set (match_operand:TF 0 "nonimmediate_operand")
3850         (match_operand:TF 1 "nonimmediate_operand"))]
3851   "TARGET_64BIT || TARGET_SSE"
3852   "ix86_expand_move (TFmode, operands); DONE;")
3854 (define_expand "mov<mode>"
3855   [(set (match_operand:X87MODEFH 0 "nonimmediate_operand")
3856         (match_operand:X87MODEFH 1 "general_operand"))]
3857   ""
3858   "ix86_expand_move (<MODE>mode, operands); DONE;")
3860 (define_insn "*movtf_internal"
3861   [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3862         (match_operand:TF 1 "general_operand"      "C ,vm,v,*roF,*rC"))]
3863   "(TARGET_64BIT || TARGET_SSE)
3864    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3865    && (lra_in_progress || reload_completed
3866        || !CONST_DOUBLE_P (operands[1])
3867        || (standard_sse_constant_p (operands[1], TFmode) == 1
3868            && !memory_operand (operands[0], TFmode))
3869        || (!TARGET_MEMORY_MISMATCH_STALL
3870            && memory_operand (operands[0], TFmode)))"
3872   switch (get_attr_type (insn))
3873     {
3874     case TYPE_SSELOG1:
3875       return standard_sse_constant_opcode (insn, operands);
3877     case TYPE_SSEMOV:
3878       return ix86_output_ssemov (insn, operands);
3880     case TYPE_MULTI:
3881         return "#";
3883     default:
3884       gcc_unreachable ();
3885     }
3887   [(set_attr "isa" "*,*,*,x64,x64")
3888    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3889    (set (attr "prefix")
3890      (if_then_else (eq_attr "type" "sselog1,ssemov")
3891        (const_string "maybe_vex")
3892        (const_string "orig")))
3893    (set (attr "mode")
3894         (cond [(eq_attr "alternative" "3,4")
3895                  (const_string "DI")
3896                (match_test "TARGET_AVX")
3897                  (const_string "TI")
3898                (ior (not (match_test "TARGET_SSE2"))
3899                     (match_test "optimize_function_for_size_p (cfun)"))
3900                  (const_string "V4SF")
3901                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3902                  (const_string "V4SF")
3903                (and (eq_attr "alternative" "2")
3904                     (match_test "TARGET_SSE_TYPELESS_STORES"))
3905                  (const_string "V4SF")
3906                ]
3907                (const_string "TI")))])
3909 (define_split
3910   [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3911         (match_operand:TF 1 "general_gr_operand"))]
3912   "reload_completed"
3913   [(const_int 0)]
3914   "ix86_split_long_move (operands); DONE;")
3916 ;; Possible store forwarding (partial memory) stall
3917 ;; in alternatives 4, 6, 7 and 8.
3918 (define_insn "*movxf_internal"
3919   [(set (match_operand:XF 0 "nonimmediate_operand"
3920          "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r  ,o ,o")
3921         (match_operand:XF 1 "general_operand"
3922          "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3923   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3924    && (lra_in_progress || reload_completed
3925        || !CONST_DOUBLE_P (operands[1])
3926        || ((optimize_function_for_size_p (cfun)
3927             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3928            && standard_80387_constant_p (operands[1]) > 0
3929            && !memory_operand (operands[0], XFmode))
3930        || (!TARGET_MEMORY_MISMATCH_STALL
3931            && memory_operand (operands[0], XFmode))
3932        || !TARGET_HARD_XF_REGS)"
3934   switch (get_attr_type (insn))
3935     {
3936     case TYPE_FMOV:
3937       if (which_alternative == 2)
3938         return standard_80387_constant_opcode (operands[1]);
3939       return output_387_reg_move (insn, operands);
3941     case TYPE_MULTI:
3942       return "#";
3944     default:
3945       gcc_unreachable ();
3946     }
3948   [(set (attr "isa")
3949         (cond [(eq_attr "alternative" "7,10")
3950                  (const_string "nox64")
3951                (eq_attr "alternative" "8,11")
3952                  (const_string "x64")
3953               ]
3954               (const_string "*")))
3955    (set (attr "type")
3956         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3957                  (const_string "multi")
3958               ]
3959               (const_string "fmov")))
3960    (set (attr "mode")
3961         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3962                  (if_then_else (match_test "TARGET_64BIT")
3963                    (const_string "DI")
3964                    (const_string "SI"))
3965               ]
3966               (const_string "XF")))
3967    (set (attr "preferred_for_size")
3968      (cond [(eq_attr "alternative" "3,4")
3969               (symbol_ref "false")]
3970            (symbol_ref "true")))
3971    (set (attr "enabled")
3972      (cond [(eq_attr "alternative" "9,10,11")
3973               (if_then_else
3974                 (match_test "TARGET_HARD_XF_REGS")
3975                 (symbol_ref "false")
3976                 (const_string "*"))
3977             (not (match_test "TARGET_HARD_XF_REGS"))
3978               (symbol_ref "false")
3979            ]
3980            (const_string "*")))])
3981    
3982 (define_split
3983   [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3984         (match_operand:XF 1 "general_gr_operand"))]
3985   "reload_completed"
3986   [(const_int 0)]
3987   "ix86_split_long_move (operands); DONE;")
3989 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3990 (define_insn "*movdf_internal"
3991   [(set (match_operand:DF 0 "nonimmediate_operand"
3992     "=Yf*f,m   ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,Yv,v,v,m,*x,*x,*x,m ,?r,?v,r  ,o ,r  ,m")
3993         (match_operand:DF 1 "general_operand"
3994     "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"))]
3995   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3996    && (lra_in_progress || reload_completed
3997        || !CONST_DOUBLE_P (operands[1])
3998        || ((optimize_function_for_size_p (cfun)
3999             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4000            && IS_STACK_MODE (DFmode)
4001            && standard_80387_constant_p (operands[1]) > 0
4002            && !memory_operand (operands[0], DFmode))
4003        || (TARGET_SSE2 && TARGET_SSE_MATH
4004            && standard_sse_constant_p (operands[1], DFmode) == 1
4005            && !memory_operand (operands[0], DFmode))
4006        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
4007            && memory_operand (operands[0], DFmode))
4008        || !TARGET_HARD_DF_REGS)"
4010   switch (get_attr_type (insn))
4011     {
4012     case TYPE_FMOV:
4013       if (which_alternative == 2)
4014         return standard_80387_constant_opcode (operands[1]);
4015       return output_387_reg_move (insn, operands);
4017     case TYPE_MULTI:
4018       return "#";
4020     case TYPE_IMOV:
4021       if (get_attr_mode (insn) == MODE_SI)
4022         return "mov{l}\t{%1, %k0|%k0, %1}";
4023       else if (which_alternative == 11)
4024         return "movabs{q}\t{%1, %0|%0, %1}";
4025       else
4026         return "mov{q}\t{%1, %0|%0, %1}";
4028     case TYPE_SSELOG1:
4029       return standard_sse_constant_opcode (insn, operands);
4031     case TYPE_SSEMOV:
4032       return ix86_output_ssemov (insn, operands);
4034     default:
4035       gcc_unreachable ();
4036     }
4038   [(set (attr "isa")
4039         (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
4040                  (const_string "nox64")
4041                (eq_attr "alternative" "8,9,10,11,24,25")
4042                  (const_string "x64")
4043                (eq_attr "alternative" "12,13,14,15")
4044                  (const_string "sse2")
4045                (eq_attr "alternative" "20,21")
4046                  (const_string "x64_sse2")
4047               ]
4048               (const_string "*")))
4049    (set (attr "type")
4050         (cond [(eq_attr "alternative" "0,1,2")
4051                  (const_string "fmov")
4052                (eq_attr "alternative" "3,4,5,6,7,22,23")
4053                  (const_string "multi")
4054                (eq_attr "alternative" "8,9,10,11,24,25")
4055                  (const_string "imov")
4056                (eq_attr "alternative" "12,16")
4057                  (const_string "sselog1")
4058               ]
4059               (const_string "ssemov")))
4060    (set (attr "modrm")
4061      (if_then_else (eq_attr "alternative" "11")
4062        (const_string "0")
4063        (const_string "*")))
4064    (set (attr "length_immediate")
4065      (if_then_else (eq_attr "alternative" "11")
4066        (const_string "8")
4067        (const_string "*")))
4068    (set (attr "prefix")
4069      (if_then_else (eq_attr "type" "sselog1,ssemov")
4070        (const_string "maybe_vex")
4071        (const_string "orig")))
4072    (set (attr "prefix_data16")
4073      (if_then_else
4074        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
4075             (eq_attr "mode" "V1DF"))
4076        (const_string "1")
4077        (const_string "*")))
4078    (set (attr "mode")
4079         (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
4080                  (const_string "SI")
4081                (eq_attr "alternative" "8,9,11,20,21,24,25")
4082                  (const_string "DI")
4084                /* xorps is one byte shorter for non-AVX targets.  */
4085                (eq_attr "alternative" "12,16")
4086                  (cond [(match_test "TARGET_AVX")
4087                           (const_string "V2DF")
4088                         (ior (not (match_test "TARGET_SSE2"))
4089                              (match_test "optimize_function_for_size_p (cfun)"))
4090                           (const_string "V4SF")
4091                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4092                           (const_string "TI")
4093                        ]
4094                        (const_string "V2DF"))
4096                /* For architectures resolving dependencies on
4097                   whole SSE registers use movapd to break dependency
4098                   chains, otherwise use short move to avoid extra work.  */
4100                /* movaps is one byte shorter for non-AVX targets.  */
4101                (eq_attr "alternative" "13,17")
4102                  (cond [(match_test "TARGET_AVX512VL")
4103                           (const_string "V2DF")
4104                         (match_test "TARGET_AVX512F")
4105                           (const_string "DF")
4106                         (match_test "TARGET_AVX")
4107                           (const_string "V2DF")
4108                         (ior (not (match_test "TARGET_SSE2"))
4109                              (match_test "optimize_function_for_size_p (cfun)"))
4110                           (const_string "V4SF")
4111                         (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
4112                           (const_string "V4SF")
4113                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4114                           (const_string "V2DF")
4115                        ]
4116                        (const_string "DF"))
4118                /* For architectures resolving dependencies on register
4119                   parts we may avoid extra work to zero out upper part
4120                   of register.  */
4121                (eq_attr "alternative" "14,18")
4122                  (cond [(not (match_test "TARGET_SSE2"))
4123                           (const_string "V2SF")
4124                         (match_test "TARGET_AVX")
4125                           (const_string "DF")
4126                         (match_test "TARGET_SSE_SPLIT_REGS")
4127                           (const_string "V1DF")
4128                        ]
4129                        (const_string "DF"))
4131                (and (eq_attr "alternative" "15,19")
4132                     (not (match_test "TARGET_SSE2")))
4133                  (const_string "V2SF")
4134               ]
4135               (const_string "DF")))
4136    (set (attr "preferred_for_size")
4137      (cond [(eq_attr "alternative" "3,4")
4138               (symbol_ref "false")]
4139            (symbol_ref "true")))
4140    (set (attr "preferred_for_speed")
4141      (cond [(eq_attr "alternative" "3,4")
4142               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
4143             (eq_attr "alternative" "20")
4144               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4145             (eq_attr "alternative" "21")
4146               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4147            ]
4148            (symbol_ref "true")))
4149    (set (attr "enabled")
4150      (cond [(eq_attr "alternative" "22,23,24,25")
4151               (if_then_else
4152                 (match_test "TARGET_HARD_DF_REGS")
4153                 (symbol_ref "false")
4154                 (const_string "*"))
4155             (not (match_test "TARGET_HARD_DF_REGS"))
4156               (symbol_ref "false")
4157            ]
4158            (const_string "*")))])
4160 (define_split
4161   [(set (match_operand:DF 0 "nonimmediate_gr_operand")
4162         (match_operand:DF 1 "general_gr_operand"))]
4163   "!TARGET_64BIT && reload_completed"
4164   [(const_int 0)]
4165   "ix86_split_long_move (operands); DONE;")
4167 (define_insn "*movsf_internal"
4168   [(set (match_operand:SF 0 "nonimmediate_operand"
4169           "=Yf*f,m   ,Yf*f,?r ,?m,Yv,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r  ,m")
4170         (match_operand:SF 1 "general_operand"
4171           "Yf*fm,Yf*f,G   ,rmF,rF,C ,v,m,v,v ,r ,*y ,m  ,*y,*y,r  ,rmF,rF"))]
4172   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4173    && (lra_in_progress || reload_completed
4174        || !CONST_DOUBLE_P (operands[1])
4175        || ((optimize_function_for_size_p (cfun)
4176             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4177            && IS_STACK_MODE (SFmode)
4178            && standard_80387_constant_p (operands[1]) > 0)
4179        || (TARGET_SSE && TARGET_SSE_MATH
4180            && standard_sse_constant_p (operands[1], SFmode) == 1)
4181        || memory_operand (operands[0], SFmode)
4182        || !TARGET_HARD_SF_REGS)"
4184   switch (get_attr_type (insn))
4185     {
4186     case TYPE_FMOV:
4187       if (which_alternative == 2)
4188         return standard_80387_constant_opcode (operands[1]);
4189       return output_387_reg_move (insn, operands);
4191     case TYPE_IMOV:
4192       return "mov{l}\t{%1, %0|%0, %1}";
4194     case TYPE_SSELOG1:
4195       return standard_sse_constant_opcode (insn, operands);
4197     case TYPE_SSEMOV:
4198       return ix86_output_ssemov (insn, operands);
4200     case TYPE_MMXMOV:
4201       switch (get_attr_mode (insn))
4202         {
4203         case MODE_DI:
4204           return "movq\t{%1, %0|%0, %1}";
4205         case MODE_SI:
4206           return "movd\t{%1, %0|%0, %1}";
4208         default:
4209           gcc_unreachable ();
4210         }
4212     default:
4213       gcc_unreachable ();
4214     }
4216   [(set (attr "isa")
4217      (cond [(eq_attr "alternative" "9,10")
4218               (const_string "sse2")
4219            ]
4220            (const_string "*")))
4221    (set (attr "type")
4222         (cond [(eq_attr "alternative" "0,1,2")
4223                  (const_string "fmov")
4224                (eq_attr "alternative" "3,4,16,17")
4225                  (const_string "imov")
4226                (eq_attr "alternative" "5")
4227                  (const_string "sselog1")
4228                (eq_attr "alternative" "11,12,13,14,15")
4229                  (const_string "mmxmov")
4230               ]
4231               (const_string "ssemov")))
4232    (set (attr "prefix")
4233      (if_then_else (eq_attr "type" "sselog1,ssemov")
4234        (const_string "maybe_vex")
4235        (const_string "orig")))
4236    (set (attr "prefix_data16")
4237      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
4238        (const_string "1")
4239        (const_string "*")))
4240    (set (attr "mode")
4241         (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
4242                  (const_string "SI")
4243                (eq_attr "alternative" "11")
4244                  (const_string "DI")
4245                (eq_attr "alternative" "5")
4246                  (cond [(and (match_test "TARGET_AVX512F && TARGET_EVEX512")
4247                              (not (match_test "TARGET_PREFER_AVX256")))
4248                           (const_string "V16SF")
4249                         (match_test "TARGET_AVX")
4250                           (const_string "V4SF")
4251                         (ior (not (match_test "TARGET_SSE2"))
4252                              (match_test "optimize_function_for_size_p (cfun)"))
4253                           (const_string "V4SF")
4254                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4255                           (const_string "TI")
4256                        ]
4257                        (const_string "V4SF"))
4259                /* For architectures resolving dependencies on
4260                   whole SSE registers use APS move to break dependency
4261                   chains, otherwise use short move to avoid extra work.
4263                   Do the same for architectures resolving dependencies on
4264                   the parts.  While in DF mode it is better to always handle
4265                   just register parts, the SF mode is different due to lack
4266                   of instructions to load just part of the register.  It is
4267                   better to maintain the whole registers in single format
4268                   to avoid problems on using packed logical operations.  */
4269                (eq_attr "alternative" "6")
4270                  (cond [(match_test "TARGET_AVX512VL")
4271                           (const_string "V4SF")
4272                         (match_test "TARGET_AVX512F")
4273                           (const_string "SF")
4274                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4275                              (match_test "TARGET_SSE_SPLIT_REGS"))
4276                           (const_string "V4SF")
4277                        ]
4278                        (const_string "SF"))
4279               ]
4280               (const_string "SF")))
4281    (set (attr "preferred_for_speed")
4282      (cond [(eq_attr "alternative" "9,14")
4283               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4284             (eq_attr "alternative" "10,15")
4285               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4286            ]
4287            (symbol_ref "true")))
4288    (set (attr "enabled")
4289      (cond [(eq_attr "alternative" "16,17")
4290               (if_then_else
4291                 (match_test "TARGET_HARD_SF_REGS")
4292                 (symbol_ref "false")
4293                 (const_string "*"))
4294             (not (match_test "TARGET_HARD_SF_REGS"))
4295               (symbol_ref "false")
4296            ]
4297            (const_string "*")))])
4299 (define_mode_attr hfbfconstf
4300  [(HF "F") (BF "")])
4302 (define_insn "*mov<mode>_internal"
4303  [(set (match_operand:HFBF 0 "nonimmediate_operand"
4304          "=?r,?r,?r,?m           ,Yv,v,?r,jm,m,?v,v")
4305        (match_operand:HFBF 1 "general_operand"
4306          "r  ,F ,m ,r<hfbfconstf>,C ,v, v,v ,v,r ,m"))]
4307  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4308   && (lra_in_progress
4309       || reload_completed
4310       || !CONST_DOUBLE_P (operands[1])
4311       || (TARGET_SSE2
4312           && standard_sse_constant_p (operands[1], <MODE>mode) == 1)
4313       || memory_operand (operands[0], <MODE>mode))"
4315   switch (get_attr_type (insn))
4316     {
4317     case TYPE_IMOVX:
4318       /* movzwl is faster than movw on p2 due to partial word stalls,
4319          though not as fast as an aligned movl.  */
4320       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
4322     case TYPE_SSEMOV:
4323       return ix86_output_ssemov (insn, operands);
4325     case TYPE_SSELOG1:
4326       if (satisfies_constraint_C (operands[1]))
4327         return standard_sse_constant_opcode (insn, operands);
4329       if (SSE_REG_P (operands[0]))
4330         return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
4331       else
4332         return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
4334     default:
4335       if (get_attr_mode (insn) == MODE_SI)
4336         return "mov{l}\t{%k1, %k0|%k0, %k1}";
4337       else
4338         return "mov{w}\t{%1, %0|%0, %1}";
4339     }
4341   [(set (attr "isa")
4342         (cond [(eq_attr "alternative" "4,5,6,9,10")
4343                  (const_string "sse2")
4344                (eq_attr "alternative" "7")
4345                  (const_string "sse4_noavx")
4346                (eq_attr "alternative" "8")
4347                  (const_string "avx")
4348               ]
4349               (const_string "*")))
4350    (set (attr "addr")
4351         (if_then_else (eq_attr "alternative" "7")
4352                       (const_string "gpr16")
4353                       (const_string "*")))
4354    (set (attr "type")
4355         (cond [(eq_attr "alternative" "4")
4356                  (const_string "sselog1")
4357                (eq_attr "alternative" "5,6,9")
4358                  (const_string "ssemov")
4359                (eq_attr "alternative" "7,8,10")
4360                  (if_then_else
4361                    (match_test ("TARGET_AVX512FP16"))
4362                    (const_string "ssemov")
4363                    (const_string "sselog1"))
4364                (match_test "optimize_function_for_size_p (cfun)")
4365                  (const_string "imov")
4366                (and (eq_attr "alternative" "0")
4367                     (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4368                          (not (match_test "TARGET_HIMODE_MATH"))))
4369                  (const_string "imov")
4370                (and (eq_attr "alternative" "1,2")
4371                     (match_operand:HI 1 "aligned_operand"))
4372                  (const_string "imov")
4373                (and (match_test "TARGET_MOVX")
4374                     (eq_attr "alternative" "0,2"))
4375                  (const_string "imovx")
4376                  ]
4377               (const_string "imov")))
4378    (set (attr "prefix")
4379         (cond [(eq_attr "alternative" "4,5,6,7,8,9,10")
4380                  (const_string "maybe_vex")
4381               ]
4382               (const_string "orig")))
4383    (set (attr "mode")
4384         (cond [(eq_attr "alternative" "4")
4385                  (const_string "V4SF")
4386                (eq_attr "alternative" "6,9")
4387                  (if_then_else
4388                    (match_test "TARGET_AVX512FP16")
4389                    (const_string "HI")
4390                    (const_string "SI"))
4391                (eq_attr "alternative" "7,8,10")
4392                  (if_then_else
4393                    (match_test "TARGET_AVX512FP16")
4394                    (const_string "HI")
4395                    (const_string "TI"))
4396                (eq_attr "alternative" "5")
4397                  (cond [(match_test "TARGET_AVX512VL")
4398                         (const_string "V4SF")
4399                         (match_test "TARGET_AVX512FP16")
4400                           (const_string "HF")
4401                         (match_test "TARGET_AVX512F")
4402                           (const_string "SF")
4403                         (match_test "TARGET_AVX")
4404                           (const_string "V4SF")
4405                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4406                              (match_test "TARGET_SSE_SPLIT_REGS"))
4407                           (const_string "V4SF")
4408                        ]
4409                        (const_string "SF"))
4410                (eq_attr "type" "imovx")
4411                  (const_string "SI")
4412                (and (eq_attr "alternative" "1,2")
4413                     (match_operand:HI 1 "aligned_operand"))
4414                  (const_string "SI")
4415                (and (eq_attr "alternative" "0")
4416                     (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4417                          (not (match_test "TARGET_HIMODE_MATH"))))
4418                  (const_string "SI")
4419               ]
4420               (const_string "HI")))
4421    (set (attr "enabled")
4422         (cond [(and (match_test "<MODE>mode == BFmode")
4423                     (eq_attr "alternative" "1"))
4424                 (symbol_ref "false")
4425               ]
4426               (const_string "*")))])
4428 (define_split
4429   [(set (match_operand 0 "any_fp_register_operand")
4430         (match_operand 1 "memory_operand"))]
4431   "reload_completed
4432    && (GET_MODE (operands[0]) == TFmode
4433        || GET_MODE (operands[0]) == XFmode
4434        || GET_MODE (operands[0]) == DFmode
4435        || GET_MODE (operands[0]) == SFmode)
4436    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4437   [(set (match_dup 0) (match_dup 2))]
4438   "operands[2] = find_constant_src (curr_insn);")
4440 (define_split
4441   [(set (match_operand 0 "any_fp_register_operand")
4442         (float_extend (match_operand 1 "memory_operand")))]
4443   "reload_completed
4444    && (GET_MODE (operands[0]) == TFmode
4445        || GET_MODE (operands[0]) == XFmode
4446        || GET_MODE (operands[0]) == DFmode)
4447    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4448   [(set (match_dup 0) (match_dup 2))]
4449   "operands[2] = find_constant_src (curr_insn);")
4451 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
4452 (define_split
4453   [(set (match_operand:X87MODEF 0 "fp_register_operand")
4454         (match_operand:X87MODEF 1 "immediate_operand"))]
4455   "reload_completed
4456    && (standard_80387_constant_p (operands[1]) == 8
4457        || standard_80387_constant_p (operands[1]) == 9)"
4458   [(set (match_dup 0)(match_dup 1))
4459    (set (match_dup 0)
4460         (neg:X87MODEF (match_dup 0)))]
4462   if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
4463     operands[1] = CONST0_RTX (<MODE>mode);
4464   else
4465     operands[1] = CONST1_RTX (<MODE>mode);
4468 (define_insn "*swapxf"
4469   [(set (match_operand:XF 0 "register_operand" "+f")
4470         (match_operand:XF 1 "register_operand" "+f"))
4471    (set (match_dup 1)
4472         (match_dup 0))]
4473   "TARGET_80387"
4475   if (STACK_TOP_P (operands[0]))
4476     return "fxch\t%1";
4477   else
4478     return "fxch\t%0";
4480   [(set_attr "type" "fxch")
4481    (set_attr "mode" "XF")])
4484 ;; Zero extension instructions
4486 (define_insn_and_split "zero_extendditi2"
4487   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4488         (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "rm,r")))]
4489   "TARGET_64BIT"
4490   "#"
4491   "&& reload_completed"
4492   [(set (match_dup 3) (match_dup 1))
4493    (set (match_dup 4) (const_int 0))]
4494   "split_double_mode (TImode, &operands[0], 1, &operands[3], &operands[4]);")
4496 (define_expand "zero_extendsidi2"
4497   [(set (match_operand:DI 0 "nonimmediate_operand")
4498         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
4500 (define_insn "*zero_extendsidi2"
4501   [(set (match_operand:DI 0 "nonimmediate_operand"
4502                 "=r,?r,?o,r   ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r,*k")
4503         (zero_extend:DI
4504          (match_operand:SI 1 "x86_64_zext_operand"
4505                 "0 ,rm,r ,rmWz,0,r  ,m   ,v ,r ,m ,*x,*v,*k,*km")))]
4506   ""
4508   switch (get_attr_type (insn))
4509     {
4510     case TYPE_IMOVX:
4511       if (ix86_use_lea_for_mov (insn, operands))
4512         return "lea{l}\t{%E1, %k0|%k0, %E1}";
4513       else
4514         return "mov{l}\t{%1, %k0|%k0, %1}";
4516     case TYPE_MULTI:
4517       return "#";
4519     case TYPE_MMXMOV:
4520       return "movd\t{%1, %0|%0, %1}";
4522     case TYPE_SSEMOV:
4523       if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
4524         {
4525           if (EXT_REX_SSE_REG_P (operands[0])
4526               || EXT_REX_SSE_REG_P (operands[1]))
4527             return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
4528           else
4529             return "%vpmovzxdq\t{%1, %0|%0, %1}";
4530         }
4532       if (GENERAL_REG_P (operands[0]))
4533         return "%vmovd\t{%1, %k0|%k0, %1}";
4535       return "%vmovd\t{%1, %0|%0, %1}";
4537     case TYPE_MSKMOV:
4538       return "kmovd\t{%1, %k0|%k0, %1}";
4540     default:
4541       gcc_unreachable ();
4542     }
4544   [(set (attr "isa")
4545      (cond [(eq_attr "alternative" "0,1,2")
4546               (const_string "nox64")
4547             (eq_attr "alternative" "3")
4548               (const_string "x64")
4549             (eq_attr "alternative" "7,8,9")
4550               (const_string "sse2")
4551             (eq_attr "alternative" "10")
4552               (const_string "sse4")
4553             (eq_attr "alternative" "11")
4554               (const_string "avx512f")
4555             (eq_attr "alternative" "12")
4556               (const_string "x64_avx512bw")
4557             (eq_attr "alternative" "13")
4558               (const_string "avx512bw_512")
4559            ]
4560            (const_string "*")))
4561    (set (attr "mmx_isa")
4562      (if_then_else (eq_attr "alternative" "5,6")
4563                    (const_string "native")
4564                    (const_string "*")))
4565    (set (attr "type")
4566      (cond [(eq_attr "alternative" "0,1,2,4")
4567               (const_string "multi")
4568             (eq_attr "alternative" "5,6")
4569               (const_string "mmxmov")
4570             (eq_attr "alternative" "7")
4571               (if_then_else (match_test "TARGET_64BIT")
4572                 (const_string "ssemov")
4573                 (const_string "multi"))
4574             (eq_attr "alternative" "8,9,10,11")
4575               (const_string "ssemov")
4576             (eq_attr "alternative" "12,13")
4577               (const_string "mskmov")
4578            ]
4579            (const_string "imovx")))
4580    (set (attr "prefix_extra")
4581      (if_then_else (eq_attr "alternative" "10,11")
4582        (const_string "1")
4583        (const_string "*")))
4584    (set (attr "prefix")
4585      (if_then_else (eq_attr "type" "ssemov")
4586        (const_string "maybe_vex")
4587        (const_string "orig")))
4588    (set (attr "prefix_0f")
4589      (if_then_else (eq_attr "type" "imovx")
4590        (const_string "0")
4591        (const_string "*")))
4592    (set (attr "mode")
4593      (cond [(eq_attr "alternative" "5,6")
4594               (const_string "DI")
4595             (and (eq_attr "alternative" "7")
4596                  (match_test "TARGET_64BIT"))
4597               (const_string "TI")
4598             (eq_attr "alternative" "8,10,11")
4599               (const_string "TI")
4600            ]
4601            (const_string "SI")))
4602    (set (attr "preferred_for_speed")
4603      (cond [(eq_attr "alternative" "7")
4604               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4605             (eq_attr "alternative" "5,8")
4606               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4607            ]
4608            (symbol_ref "true")))])
4610 (define_split
4611   [(set (match_operand:DI 0 "memory_operand")
4612         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
4613   "reload_completed"
4614   [(set (match_dup 4) (const_int 0))]
4615   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4617 (define_split
4618   [(set (match_operand:DI 0 "general_reg_operand")
4619         (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
4620   "!TARGET_64BIT && reload_completed
4621    && REGNO (operands[0]) == REGNO (operands[1])"
4622   [(set (match_dup 4) (const_int 0))]
4623   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4625 (define_split
4626   [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4627         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4628   "!TARGET_64BIT && reload_completed
4629    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4630   [(set (match_dup 3) (match_dup 1))
4631    (set (match_dup 4) (const_int 0))]
4632   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4634 (define_mode_attr kmov_isa
4635   [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw_512")])
4637 (define_insn "zero_extend<mode>di2"
4638   [(set (match_operand:DI 0 "register_operand" "=r,*r,*k")
4639         (zero_extend:DI
4640          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4641   "TARGET_64BIT"
4642   "@
4643    movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4644    kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
4645    kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4646   [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4647    (set_attr "type" "imovx,mskmov,mskmov")
4648    (set_attr "mode" "SI,<MODE>,<MODE>")])
4650 (define_expand "zero_extend<mode>si2"
4651   [(set (match_operand:SI 0 "register_operand")
4652         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4653   ""
4655   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4656     {
4657       operands[1] = force_reg (<MODE>mode, operands[1]);
4658       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4659       DONE;
4660     }
4663 (define_insn_and_split "zero_extend<mode>si2_and"
4664   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4665         (zero_extend:SI
4666           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4667    (clobber (reg:CC FLAGS_REG))]
4668   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4669   "#"
4670   "&& reload_completed"
4671   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4672               (clobber (reg:CC FLAGS_REG))])]
4674   if (!REG_P (operands[1])
4675       || REGNO (operands[0]) != REGNO (operands[1]))
4676     {
4677       ix86_expand_clear (operands[0]);
4679       gcc_assert (!TARGET_PARTIAL_REG_STALL);
4680       emit_insn (gen_rtx_SET
4681                  (gen_rtx_STRICT_LOW_PART
4682                   (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
4683                   operands[1]));
4684       DONE;
4685     }
4687   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4689   [(set_attr "type" "alu1")
4690    (set_attr "mode" "SI")])
4692 (define_insn "*zero_extend<mode>si2"
4693   [(set (match_operand:SI 0 "register_operand" "=r,*r,*k")
4694         (zero_extend:SI
4695           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4696   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4697   "@
4698    movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4699    kmov<mskmodesuffix>\t{%1, %0|%0, %1}
4700    kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4701   [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4702    (set_attr "type" "imovx,mskmov,mskmov")
4703    (set_attr "mode" "SI,<MODE>,<MODE>")])
4705 (define_expand "zero_extendqihi2"
4706   [(set (match_operand:HI 0 "register_operand")
4707         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4708   ""
4710   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4711     {
4712       operands[1] = force_reg (QImode, operands[1]);
4713       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4714       DONE;
4715     }
4718 (define_insn_and_split "zero_extendqihi2_and"
4719   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4720         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4721    (clobber (reg:CC FLAGS_REG))]
4722   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4723   "#"
4724   "&& reload_completed"
4725   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4726               (clobber (reg:CC FLAGS_REG))])]
4728   if (!REG_P (operands[1])
4729       || REGNO (operands[0]) != REGNO (operands[1]))
4730     {
4731       ix86_expand_clear (operands[0]);
4733       gcc_assert (!TARGET_PARTIAL_REG_STALL);
4734       emit_insn (gen_rtx_SET
4735                  (gen_rtx_STRICT_LOW_PART
4736                   (VOIDmode, gen_lowpart (QImode, operands[0])),
4737                   operands[1]));
4738       DONE;
4739     }
4741   operands[0] = gen_lowpart (SImode, operands[0]);
4743   [(set_attr "type" "alu1")
4744    (set_attr "mode" "SI")])
4746 ; zero extend to SImode to avoid partial register stalls
4747 (define_insn "*zero_extendqihi2"
4748   [(set (match_operand:HI 0 "register_operand" "=r,*r,*k")
4749         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k,*km")))]
4750   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4751   "@
4752    movz{bl|x}\t{%1, %k0|%k0, %1}
4753    kmovb\t{%1, %k0|%k0, %1}
4754    kmovb\t{%1, %0|%0, %1}"
4755   [(set_attr "isa" "*,avx512dq,avx512dq")
4756    (set_attr "type" "imovx,mskmov,mskmov")
4757    (set_attr "mode" "SI,QI,QI")])
4759 ;; Transform xorl; mov[bw] (set strict_low_part) into movz[bw]l.
4760 (define_peephole2
4761   [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
4762                    (const_int 0))
4763               (clobber (reg:CC FLAGS_REG))])
4764    (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4765         (match_operand:SWI12 2 "nonimmediate_operand"))]
4766   "REGNO (operands[0]) == REGNO (operands[1])
4767    && (<SWI48:MODE>mode != SImode
4768        || !TARGET_ZERO_EXTEND_WITH_AND
4769        || !optimize_function_for_speed_p (cfun))"
4770   [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4772 ;; Likewise, but preserving FLAGS_REG.
4773 (define_peephole2
4774   [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
4775    (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4776         (match_operand:SWI12 2 "nonimmediate_operand"))]
4777   "REGNO (operands[0]) == REGNO (operands[1])
4778    && (<SWI48:MODE>mode != SImode
4779        || !TARGET_ZERO_EXTEND_WITH_AND
4780        || !optimize_function_for_speed_p (cfun))"
4781   [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4783 ;; Sign extension instructions
4785 (define_expand "extendsidi2"
4786   [(set (match_operand:DI 0 "register_operand")
4787         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4788   ""
4790   if (!TARGET_64BIT)
4791     {
4792       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4793       DONE;
4794     }
4797 (define_insn "*extendsidi2_rex64"
4798   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4799         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4800   "TARGET_64BIT"
4801   "@
4802    {cltq|cdqe}
4803    movs{lq|x}\t{%1, %0|%0, %1}"
4804   [(set_attr "type" "imovx")
4805    (set_attr "mode" "DI")
4806    (set_attr "prefix_0f" "0")
4807    (set_attr "modrm" "0,1")])
4809 (define_insn "extendsidi2_1"
4810   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4811         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4812    (clobber (reg:CC FLAGS_REG))
4813    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4814   "!TARGET_64BIT"
4815   "#")
4817 (define_insn "extendditi2"
4818   [(set (match_operand:TI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4819         (sign_extend:TI (match_operand:DI 1 "register_operand" "0,0,r,r")))
4820    (clobber (reg:CC FLAGS_REG))
4821    (clobber (match_scratch:DI 2 "=X,X,X,&r"))]
4822   "TARGET_64BIT"
4823   "#")
4825 ;; Split the memory case.  If the source register doesn't die, it will stay
4826 ;; this way, if it does die, following peephole2s take care of it.
4827 (define_split
4828   [(set (match_operand:<DWI> 0 "memory_operand")
4829         (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4830    (clobber (reg:CC FLAGS_REG))
4831    (clobber (match_operand:DWIH 2 "register_operand"))]
4832   "reload_completed"
4833   [(const_int 0)]
4835   rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4837   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4839   emit_move_insn (operands[3], operands[1]);
4841   /* Generate a cltd if possible and doing so it profitable.  */
4842   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4843       && REGNO (operands[1]) == AX_REG
4844       && REGNO (operands[2]) == DX_REG)
4845     {
4846       emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[1], bits));
4847     }
4848   else
4849     {
4850       emit_move_insn (operands[2], operands[1]);
4851       emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[2], bits));
4852     }
4853   emit_move_insn (operands[4], operands[2]);
4854   DONE;
4857 ;; Peepholes for the case where the source register does die, after
4858 ;; being split with the above splitter.
4859 (define_peephole2
4860   [(set (match_operand:DWIH 0 "memory_operand")
4861         (match_operand:DWIH 1 "general_reg_operand"))
4862    (set (match_operand:DWIH 2 "general_reg_operand") (match_dup 1))
4863    (parallel [(set (match_dup 2)
4864                    (ashiftrt:DWIH (match_dup 2)
4865                                   (match_operand 4 "const_int_operand")))
4866                (clobber (reg:CC FLAGS_REG))])
4867    (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4868   "REGNO (operands[1]) != REGNO (operands[2])
4869    && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4870    && peep2_reg_dead_p (2, operands[1])
4871    && peep2_reg_dead_p (4, operands[2])
4872    && !reg_mentioned_p (operands[2], operands[3])"
4873   [(set (match_dup 0) (match_dup 1))
4874    (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4875               (clobber (reg:CC FLAGS_REG))])
4876    (set (match_dup 3) (match_dup 1))])
4878 (define_peephole2
4879   [(set (match_operand:DWIH 0 "memory_operand")
4880         (match_operand:DWIH 1 "general_reg_operand"))
4881    (parallel [(set (match_operand:DWIH 2 "general_reg_operand")
4882                    (ashiftrt:DWIH (match_dup 1)
4883                                   (match_operand 4 "const_int_operand")))
4884                (clobber (reg:CC FLAGS_REG))])
4885    (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4886   "/* cltd is shorter than sarl $31, %eax */
4887    !optimize_function_for_size_p (cfun)
4888    && REGNO (operands[1]) == AX_REG
4889    && REGNO (operands[2]) == DX_REG
4890    && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4891    && peep2_reg_dead_p (2, operands[1])
4892    && peep2_reg_dead_p (3, operands[2])
4893    && !reg_mentioned_p (operands[2], operands[3])"
4894   [(set (match_dup 0) (match_dup 1))
4895    (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4896               (clobber (reg:CC FLAGS_REG))])
4897    (set (match_dup 3) (match_dup 1))])
4899 ;; Extend to register case.  Optimize case where source and destination
4900 ;; registers match and cases where we can use cltd.
4901 (define_split
4902   [(set (match_operand:<DWI> 0 "register_operand")
4903         (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4904    (clobber (reg:CC FLAGS_REG))
4905    (clobber (match_scratch:DWIH 2))]
4906   "reload_completed"
4907   [(const_int 0)]
4909   rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4911   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4913   if (REGNO (operands[3]) != REGNO (operands[1]))
4914     emit_move_insn (operands[3], operands[1]);
4916   rtx src = operands[1];
4917   if (REGNO (operands[3]) == AX_REG)
4918     src = operands[3];
4920   /* Generate a cltd if possible and doing so it profitable.  */
4921   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4922       && REGNO (src) == AX_REG
4923       && REGNO (operands[4]) == DX_REG)
4924     {
4925       emit_insn (gen_ashr<mode>3_cvt (operands[4], src, bits));
4926       DONE;
4927     }
4929   if (REGNO (operands[4]) != REGNO (operands[1]))
4930     emit_move_insn (operands[4], operands[1]);
4932   emit_insn (gen_ashr<mode>3_cvt (operands[4], operands[4], bits));
4933   DONE;
4936 (define_insn "extend<mode>di2"
4937   [(set (match_operand:DI 0 "register_operand" "=r")
4938         (sign_extend:DI
4939          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4940   "TARGET_64BIT"
4941   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4942   [(set_attr "type" "imovx")
4943    (set_attr "mode" "DI")])
4945 (define_insn "extendhisi2"
4946   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4947         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4948   ""
4950   switch (get_attr_prefix_0f (insn))
4951     {
4952     case 0:
4953       return "{cwtl|cwde}";
4954     default:
4955       return "movs{wl|x}\t{%1, %0|%0, %1}";
4956     }
4958   [(set_attr "type" "imovx")
4959    (set_attr "mode" "SI")
4960    (set (attr "prefix_0f")
4961      ;; movsx is short decodable while cwtl is vector decoded.
4962      (if_then_else (and (eq_attr "cpu" "!k6")
4963                         (eq_attr "alternative" "0"))
4964         (const_string "0")
4965         (const_string "1")))
4966    (set (attr "znver1_decode")
4967      (if_then_else (eq_attr "prefix_0f" "0")
4968         (const_string "double")
4969         (const_string "direct")))
4970    (set (attr "modrm")
4971      (if_then_else (eq_attr "prefix_0f" "0")
4972         (const_string "0")
4973         (const_string "1")))])
4975 (define_insn "*extendhisi2_zext"
4976   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4977         (zero_extend:DI
4978          (sign_extend:SI
4979           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4980   "TARGET_64BIT"
4982   switch (get_attr_prefix_0f (insn))
4983     {
4984     case 0:
4985       return "{cwtl|cwde}";
4986     default:
4987       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4988     }
4990   [(set_attr "type" "imovx")
4991    (set_attr "mode" "SI")
4992    (set (attr "prefix_0f")
4993      ;; movsx is short decodable while cwtl is vector decoded.
4994      (if_then_else (and (eq_attr "cpu" "!k6")
4995                         (eq_attr "alternative" "0"))
4996         (const_string "0")
4997         (const_string "1")))
4998    (set (attr "modrm")
4999      (if_then_else (eq_attr "prefix_0f" "0")
5000         (const_string "0")
5001         (const_string "1")))])
5003 (define_insn "extendqisi2"
5004   [(set (match_operand:SI 0 "register_operand" "=r")
5005         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
5006   ""
5007   "movs{bl|x}\t{%1, %0|%0, %1}"
5008    [(set_attr "type" "imovx")
5009     (set_attr "mode" "SI")])
5011 (define_insn "*extendqisi2_zext"
5012   [(set (match_operand:DI 0 "register_operand" "=r")
5013         (zero_extend:DI
5014           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
5015   "TARGET_64BIT"
5016   "movs{bl|x}\t{%1, %k0|%k0, %1}"
5017    [(set_attr "type" "imovx")
5018     (set_attr "mode" "SI")])
5020 (define_insn "extendqihi2"
5021   [(set (match_operand:HI 0 "register_operand" "=*a,r")
5022         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
5023   ""
5025   switch (get_attr_prefix_0f (insn))
5026     {
5027     case 0:
5028       return "{cbtw|cbw}";
5029     default:
5030       return "movs{bw|x}\t{%1, %0|%0, %1}";
5031     }
5033   [(set_attr "type" "imovx")
5034    (set_attr "mode" "HI")
5035    (set (attr "prefix_0f")
5036      ;; movsx is short decodable while cwtl is vector decoded.
5037      (if_then_else (and (eq_attr "cpu" "!k6")
5038                         (eq_attr "alternative" "0"))
5039         (const_string "0")
5040         (const_string "1")))
5041    (set (attr "modrm")
5042      (if_then_else (eq_attr "prefix_0f" "0")
5043         (const_string "0")
5044         (const_string "1")))])
5046 (define_insn "*extendqi<SWI24:mode>_ext_1"
5047   [(set (match_operand:SWI24 0 "register_operand" "=R")
5048         (sign_extend:SWI24
5049           (subreg:QI
5050             (match_operator:SWI248 2 "extract_operator"
5051               [(match_operand 1 "int248_register_operand" "Q")
5052                (const_int 8)
5053                (const_int 8)]) 0)))]
5054   ""
5055   "movs{b<SWI24:imodesuffix>|x}\t{%h1, %0|%0, %h1}"
5056    [(set_attr "type" "imovx")
5057     (set_attr "mode" "<SWI24:MODE>")])
5059 ;; Conversions between float and double.
5061 ;; These are all no-ops in the model used for the 80387.
5062 ;; So just emit moves.
5064 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
5065 (define_split
5066   [(set (match_operand:DF 0 "push_operand")
5067         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
5068   "reload_completed"
5069   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
5070    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
5072 (define_split
5073   [(set (match_operand:XF 0 "push_operand")
5074         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
5075   "reload_completed"
5076   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
5077    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
5078   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
5080 (define_expand "extendsfdf2"
5081   [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
5082         (float_extend:DF (match_operand:SF 1 "general_operand")))]
5083   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5085   /* ??? Needed for compress_float_constant since all fp constants
5086      are TARGET_LEGITIMATE_CONSTANT_P.  */
5087   if (CONST_DOUBLE_P (operands[1]))
5088     {
5089       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
5090           && standard_80387_constant_p (operands[1]) > 0)
5091         {
5092           operands[1] = simplify_const_unary_operation
5093             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
5094           emit_move_insn_1 (operands[0], operands[1]);
5095           DONE;
5096         }
5097       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
5098     }
5101 (define_insn "*extendsfdf2"
5102   [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
5103         (float_extend:DF
5104           (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
5105   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5107   switch (which_alternative)
5108     {
5109     case 0:
5110     case 1:
5111       return output_387_reg_move (insn, operands);
5113     case 2:
5114       return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
5115     case 3:
5116       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
5118     default:
5119       gcc_unreachable ();
5120     }
5122   [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5123    (set_attr "avx_partial_xmm_update" "false,false,false,true")
5124    (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
5125    (set_attr "mode" "SF,XF,DF,DF")
5126    (set (attr "enabled")
5127      (if_then_else
5128        (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5129        (if_then_else
5130          (eq_attr "alternative" "0,1")
5131          (symbol_ref "TARGET_MIX_SSE_I387")
5132          (symbol_ref "true"))
5133        (if_then_else
5134          (eq_attr "alternative" "0,1")
5135          (symbol_ref "true")
5136          (symbol_ref "false"))))])
5138 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
5139    cvtss2sd:
5140       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
5141       cvtps2pd xmm2,xmm1
5142    We do the conversion post reload to avoid producing of 128bit spills
5143    that might lead to ICE on 32bit target.  The sequence unlikely combine
5144    anyway.  */
5145 (define_split
5146   [(set (match_operand:DF 0 "sse_reg_operand")
5147         (float_extend:DF
5148           (match_operand:SF 1 "nonimmediate_operand")))]
5149   "TARGET_USE_VECTOR_FP_CONVERTS
5150    && optimize_insn_for_speed_p ()
5151    && reload_completed
5152    && (!EXT_REX_SSE_REG_P (operands[0])
5153        || TARGET_AVX512VL || TARGET_EVEX512)"
5154    [(set (match_dup 2)
5155          (float_extend:V2DF
5156            (vec_select:V2SF
5157              (match_dup 3)
5158              (parallel [(const_int 0) (const_int 1)]))))]
5160   operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5161   operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
5162   /* Use movss for loading from memory, unpcklps reg, reg for registers.
5163      Try to avoid move when unpacking can be done in source.  */
5164   if (REG_P (operands[1]))
5165     {
5166       /* If it is unsafe to overwrite upper half of source, we need
5167          to move to destination and unpack there.  */
5168       if (REGNO (operands[0]) != REGNO (operands[1])
5169           || (EXT_REX_SSE_REG_P (operands[1])
5170               && !TARGET_AVX512VL))
5171         {
5172           rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
5173           emit_move_insn (tmp, operands[1]);
5174         }
5175       else
5176         operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
5177       /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
5178          =v, v, then vbroadcastss will be only needed for AVX512F without
5179          AVX512VL.  */
5180       if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
5181         emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
5182                                                operands[3]));
5183       else
5184         {
5185           rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
5186           emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
5187         }
5188     }
5189   else
5190     emit_insn (gen_vec_setv4sf_0 (operands[3],
5191                                   CONST0_RTX (V4SFmode), operands[1]));
5194 ;; It's more profitable to split and then extend in the same register.
5195 (define_peephole2
5196   [(set (match_operand:DF 0 "sse_reg_operand")
5197         (float_extend:DF
5198           (match_operand:SF 1 "memory_operand")))]
5199   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5200    && optimize_insn_for_speed_p ()"
5201   [(set (match_dup 2) (match_dup 1))
5202    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
5203   "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
5205 ;; Break partial SSE register dependency stall.  This splitter should split
5206 ;; late in the pass sequence (after register rename pass), so allocated
5207 ;; registers won't change anymore
5209 (define_split
5210   [(set (match_operand:DF 0 "sse_reg_operand")
5211         (float_extend:DF
5212           (match_operand:SF 1 "nonimmediate_operand")))]
5213   "!TARGET_AVX
5214    && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5215    && epilogue_completed
5216    && optimize_function_for_speed_p (cfun)
5217    && (!REG_P (operands[1])
5218        || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5219    && (!EXT_REX_SSE_REG_P (operands[0])
5220        || TARGET_AVX512VL)"
5221   [(set (match_dup 0)
5222         (vec_merge:V2DF
5223           (vec_duplicate:V2DF
5224             (float_extend:DF
5225               (match_dup 1)))
5226           (match_dup 0)
5227           (const_int 1)))]
5229   operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5230   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5233 (define_expand "extendhfsf2"
5234   [(set (match_operand:SF 0 "register_operand")
5235         (float_extend:SF
5236           (match_operand:HF 1 "nonimmediate_operand")))]
5237   "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5239   if (!TARGET_AVX512FP16)
5240     {
5241       rtx res = gen_reg_rtx (V4SFmode);
5242       rtx tmp = gen_reg_rtx (V8HFmode);
5243       rtx zero = force_reg (V8HFmode, CONST0_RTX (V8HFmode));
5245       emit_insn (gen_vec_setv8hf_0 (tmp, zero, operands[1]));
5246       emit_insn (gen_vcvtph2ps (res, gen_lowpart (V8HImode, tmp)));
5247       emit_move_insn (operands[0], gen_lowpart (SFmode, res));
5248       DONE;
5249     }
5252 (define_expand "extendhfdf2"
5253   [(set (match_operand:DF 0 "register_operand")
5254         (float_extend:DF
5255           (match_operand:HF 1 "nonimmediate_operand")))]
5256   "TARGET_AVX512FP16")
5258 (define_insn "*extendhf<mode>2"
5259   [(set (match_operand:MODEF 0 "register_operand" "=v")
5260         (float_extend:MODEF
5261           (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5262   "TARGET_AVX512FP16"
5263   "vcvtsh2<ssemodesuffix>\t{%1, %0, %0|%0, %0, %1}"
5264   [(set_attr "type" "ssecvt")
5265    (set_attr "prefix" "evex")
5266    (set_attr "mode" "<MODE>")])
5268 (define_expand "extendbfsf2"
5269   [(set (match_operand:SF 0 "register_operand")
5270         (unspec:SF
5271           [(match_operand:BF 1 "register_operand")]
5272          UNSPEC_CVTBFSF))]
5273  "TARGET_SSE2 && !HONOR_NANS (BFmode)")
5275 ;; Don't use float_extend since psrlld doesn't raise
5276 ;; exceptions and turn a sNaN into a qNaN.
5277 (define_insn "extendbfsf2_1"
5278   [(set (match_operand:SF 0 "register_operand"   "=x,Yv,v")
5279         (unspec:SF
5280           [(match_operand:BF 1 "register_operand" " 0,Yv,v")]
5281           UNSPEC_CVTBFSF))]
5282  "TARGET_SSE2"
5283  "@
5284   pslld\t{$16, %0|%0, 16}
5285   vpslld\t{$16, %1, %0|%0, %1, 16}
5286   vpslld\t{$16, %g1, %g0|%g0, %g1, 16}"
5287   [(set_attr "isa" "noavx,avx,*")
5288    (set_attr "type" "sseishft1")
5289    (set_attr "length_immediate" "1")
5290    (set_attr "prefix_data16" "1,*,*")
5291    (set_attr "prefix" "orig,maybe_evex,evex")
5292    (set_attr "mode" "TI,TI,XI")
5293    (set_attr "memory" "none")
5294    (set (attr "enabled")
5295      (if_then_else (eq_attr "alternative" "2")
5296        (symbol_ref "TARGET_AVX512F && TARGET_EVEX512
5297                     && !TARGET_AVX512VL && !TARGET_PREFER_AVX256")
5298        (const_string "*")))])
5300 (define_expand "extend<mode>xf2"
5301   [(set (match_operand:XF 0 "nonimmediate_operand")
5302         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
5303   "TARGET_80387"
5305   /* ??? Needed for compress_float_constant since all fp constants
5306      are TARGET_LEGITIMATE_CONSTANT_P.  */
5307   if (CONST_DOUBLE_P (operands[1]))
5308     {
5309       if (standard_80387_constant_p (operands[1]) > 0)
5310         {
5311           operands[1] = simplify_const_unary_operation
5312             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
5313           emit_move_insn_1 (operands[0], operands[1]);
5314           DONE;
5315         }
5316       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
5317     }
5320 (define_insn "*extend<mode>xf2_i387"
5321   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
5322         (float_extend:XF
5323           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
5324   "TARGET_80387"
5325   "* return output_387_reg_move (insn, operands);"
5326   [(set_attr "type" "fmov")
5327    (set_attr "mode" "<MODE>,XF")])
5329 ;; %%% This seems like bad news.
5330 ;; This cannot output into an f-reg because there is no way to be sure
5331 ;; of truncating in that case.  Otherwise this is just like a simple move
5332 ;; insn.  So we pretend we can output to a reg in order to get better
5333 ;; register preferencing, but we really use a stack slot.
5335 ;; Conversion from DFmode to SFmode.
5337 (define_insn "truncdfsf2"
5338   [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
5339         (float_truncate:SF
5340           (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
5341   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5343   switch (which_alternative)
5344     {
5345     case 0:
5346     case 1:
5347       return output_387_reg_move (insn, operands);
5349     case 2:
5350       return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
5351     case 3:
5352       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
5354     default:
5355       gcc_unreachable ();
5356     }
5358   [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5359    (set_attr "avx_partial_xmm_update" "false,false,false,true")
5360    (set_attr "mode" "SF")
5361    (set (attr "enabled")
5362      (if_then_else
5363        (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5364        (cond [(eq_attr "alternative" "0")
5365                 (symbol_ref "TARGET_MIX_SSE_I387")
5366               (eq_attr "alternative" "1")
5367                 (symbol_ref "TARGET_MIX_SSE_I387
5368                              && flag_unsafe_math_optimizations")
5369            ]
5370            (symbol_ref "true"))
5371        (cond [(eq_attr "alternative" "0")
5372                 (symbol_ref "true")
5373               (eq_attr "alternative" "1")
5374                 (symbol_ref "flag_unsafe_math_optimizations")
5375            ]
5376            (symbol_ref "false"))))])
5378 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
5379    cvtsd2ss:
5380       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
5381       cvtpd2ps xmm2,xmm1
5382    We do the conversion post reload to avoid producing of 128bit spills
5383    that might lead to ICE on 32bit target.  The sequence unlikely combine
5384    anyway.  */
5385 (define_split
5386   [(set (match_operand:SF 0 "sse_reg_operand")
5387         (float_truncate:SF
5388           (match_operand:DF 1 "nonimmediate_operand")))]
5389   "TARGET_USE_VECTOR_FP_CONVERTS
5390    && optimize_insn_for_speed_p ()
5391    && reload_completed
5392    && (!EXT_REX_SSE_REG_P (operands[0])
5393        || TARGET_AVX512VL)"
5394    [(set (match_dup 2)
5395          (vec_concat:V4SF
5396            (float_truncate:V2SF
5397              (match_dup 4))
5398            (match_dup 3)))]
5400   operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5401   operands[3] = CONST0_RTX (V2SFmode);
5402   operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
5403   /* Use movsd for loading from memory, unpcklpd for registers.
5404      Try to avoid move when unpacking can be done in source, or SSE3
5405      movddup is available.  */
5406   if (REG_P (operands[1]))
5407     {
5408       if ((!TARGET_SSE3 && REGNO (operands[0]) != REGNO (operands[1]))
5409           || (EXT_REX_SSE_REG_P (operands[1]) && !TARGET_AVX512VL))
5410         {
5411           rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
5412           emit_move_insn (tmp, operands[1]);
5413           operands[1] = tmp;
5414         }
5415       else if (!TARGET_SSE3)
5416         operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
5417       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
5418     }
5419   else
5420     emit_insn (gen_vec_concatv2df (operands[4], operands[1],
5421                                    CONST0_RTX (DFmode)));
5424 ;; It's more profitable to split and then truncate in the same register.
5425 (define_peephole2
5426   [(set (match_operand:SF 0 "sse_reg_operand")
5427         (float_truncate:SF
5428           (match_operand:DF 1 "memory_operand")))]
5429   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5430    && optimize_insn_for_speed_p ()"
5431   [(set (match_dup 2) (match_dup 1))
5432    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
5433   "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
5435 ;; Break partial SSE register dependency stall.  This splitter should split
5436 ;; late in the pass sequence (after register rename pass), so allocated
5437 ;; registers won't change anymore
5439 (define_split
5440   [(set (match_operand:SF 0 "sse_reg_operand")
5441         (float_truncate:SF
5442           (match_operand:DF 1 "nonimmediate_operand")))]
5443   "!TARGET_AVX
5444    && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5445    && epilogue_completed
5446    && optimize_function_for_speed_p (cfun)
5447    && (!REG_P (operands[1])
5448        || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5449    && (!EXT_REX_SSE_REG_P (operands[0])
5450        || TARGET_AVX512VL)"
5451   [(set (match_dup 0)
5452         (vec_merge:V4SF
5453           (vec_duplicate:V4SF
5454             (float_truncate:SF
5455               (match_dup 1)))
5456           (match_dup 0)
5457           (const_int 1)))]
5459   operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5460   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5463 ;; Conversion from XFmode to {SF,DF}mode
5465 (define_insn "truncxf<mode>2"
5466   [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
5467         (float_truncate:MODEF
5468           (match_operand:XF 1 "register_operand" "f,f")))]
5469   "TARGET_80387"
5470   "* return output_387_reg_move (insn, operands);"
5471   [(set_attr "type" "fmov")
5472    (set_attr "mode" "<MODE>")
5473    (set (attr "enabled")
5474      (cond [(eq_attr "alternative" "1")
5475               (symbol_ref "flag_unsafe_math_optimizations")
5476            ]
5477            (symbol_ref "true")))])
5479 ;; Conversion from {SF,DF}mode to HFmode.
5481 (define_expand "truncsfhf2"
5482   [(set (match_operand:HF 0 "register_operand")
5483         (float_truncate:HF
5484           (match_operand:SF 1 "nonimmediate_operand")))]
5485   "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5486   {
5487     if (!TARGET_AVX512FP16)
5488     {
5489       rtx res = gen_reg_rtx (V8HFmode);
5490       rtx tmp = gen_reg_rtx (V4SFmode);
5491       rtx zero = force_reg (V4SFmode, CONST0_RTX (V4SFmode));
5493       emit_insn (gen_vec_setv4sf_0 (tmp, zero, operands[1]));
5494       emit_insn (gen_vcvtps2ph (gen_lowpart (V8HImode, res), tmp, GEN_INT (4)));
5495       emit_move_insn (operands[0], gen_lowpart (HFmode, res));
5496       DONE;
5497     }
5498   })
5500 (define_expand "truncdfhf2"
5501   [(set (match_operand:HF 0 "register_operand")
5502         (float_truncate:HF
5503           (match_operand:DF 1 "nonimmediate_operand")))]
5504   "TARGET_AVX512FP16")
5506 (define_insn "*trunc<mode>hf2"
5507   [(set (match_operand:HF 0 "register_operand" "=v")
5508        (float_truncate:HF
5509          (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5510   "TARGET_AVX512FP16"
5511   "vcvt<ssemodesuffix>2sh\t{%1, %d0|%d0, %1}"
5512   [(set_attr "type" "ssecvt")
5513    (set_attr "prefix" "evex")
5514    (set_attr "mode" "HF")])
5516 (define_insn "truncsfbf2"
5517   [(set (match_operand:BF 0 "register_operand" "=x, v")
5518         (float_truncate:BF
5519           (match_operand:SF 1 "register_operand" "x,v")))]
5520   "((TARGET_AVX512BF16 && TARGET_AVX512VL) || TARGET_AVXNECONVERT)
5521    && !HONOR_NANS (BFmode) && flag_unsafe_math_optimizations"
5522   "@
5523   %{vex%} vcvtneps2bf16\t{%1, %0|%0, %1}
5524   vcvtneps2bf16\t{%1, %0|%0, %1}"
5525   [(set_attr "isa" "avxneconvert,avx512bf16vl")
5526    (set_attr "prefix" "vex,evex")])
5528 ;; Signed conversion to DImode.
5530 (define_expand "fix_truncxfdi2"
5531   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5532                    (fix:DI (match_operand:XF 1 "register_operand")))
5533               (clobber (reg:CC FLAGS_REG))])]
5534   "TARGET_80387"
5536   if (TARGET_FISTTP)
5537    {
5538      emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5539      DONE;
5540    }
5543 (define_expand "fix_trunc<mode>di2"
5544   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5545                    (fix:DI (match_operand:MODEF 1 "register_operand")))
5546               (clobber (reg:CC FLAGS_REG))])]
5547   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
5549   if (TARGET_FISTTP
5550       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5551    {
5552      emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5553      DONE;
5554    }
5555   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
5556    {
5557      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
5558      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
5559      if (out != operands[0])
5560         emit_move_insn (operands[0], out);
5561      DONE;
5562    }
5565 (define_insn "fix<fixunssuffix>_trunchf<mode>2"
5566   [(set (match_operand:SWI48 0 "register_operand" "=r")
5567         (any_fix:SWI48
5568           (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5569   "TARGET_AVX512FP16"
5570   "vcvttsh2<fixsuffix>si\t{%1, %0|%0, %1}"
5571   [(set_attr "type" "sseicvt")
5572    (set_attr "prefix" "evex")
5573    (set_attr "mode" "<MODE>")])
5575 ;; Signed conversion to SImode.
5577 (define_expand "fix_truncxfsi2"
5578   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5579                    (fix:SI (match_operand:XF 1 "register_operand")))
5580               (clobber (reg:CC FLAGS_REG))])]
5581   "TARGET_80387"
5583   if (TARGET_FISTTP)
5584    {
5585      emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5586      DONE;
5587    }
5590 (define_expand "fix_trunc<mode>si2"
5591   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5592                    (fix:SI (match_operand:MODEF 1 "register_operand")))
5593               (clobber (reg:CC FLAGS_REG))])]
5594   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
5596   if (TARGET_FISTTP
5597       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5598    {
5599      emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5600      DONE;
5601    }
5602   if (SSE_FLOAT_MODE_P (<MODE>mode))
5603    {
5604      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
5605      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
5606      if (out != operands[0])
5607         emit_move_insn (operands[0], out);
5608      DONE;
5609    }
5612 ;; Signed conversion to HImode.
5614 (define_expand "fix_trunc<mode>hi2"
5615   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
5616                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
5617               (clobber (reg:CC FLAGS_REG))])]
5618   "TARGET_80387
5619    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5621   if (TARGET_FISTTP)
5622    {
5623      emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
5624      DONE;
5625    }
5628 ;; Unsigned conversion to DImode
5630 (define_insn "fixuns_trunc<mode>di2"
5631   [(set (match_operand:DI 0 "register_operand" "=r")
5632         (unsigned_fix:DI
5633           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5634   "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5635   "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5636   [(set_attr "type" "sseicvt")
5637    (set_attr "prefix" "evex")
5638    (set_attr "mode" "DI")])
5640 ;; Unsigned conversion to SImode.
5642 (define_expand "fixuns_trunc<mode>si2"
5643   [(parallel
5644     [(set (match_operand:SI 0 "register_operand")
5645           (unsigned_fix:SI
5646             (match_operand:MODEF 1 "nonimmediate_operand")))
5647      (use (match_dup 2))
5648      (clobber (scratch:<ssevecmode>))
5649      (clobber (scratch:<ssevecmode>))])]
5650   "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
5652   machine_mode mode = <MODE>mode;
5653   machine_mode vecmode = <ssevecmode>mode;
5654   REAL_VALUE_TYPE TWO31r;
5655   rtx two31;
5657   if (TARGET_AVX512F)
5658     {
5659       emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
5660       DONE;
5661     }
5663   if (optimize_insn_for_size_p ())
5664     FAIL;
5666   real_ldexp (&TWO31r, &dconst1, 31);
5667   two31 = const_double_from_real_value (TWO31r, mode);
5668   two31 = ix86_build_const_vector (vecmode, true, two31);
5669   operands[2] = force_reg (vecmode, two31);
5672 (define_insn "fixuns_trunc<mode>si2_avx512f"
5673   [(set (match_operand:SI 0 "register_operand" "=r")
5674         (unsigned_fix:SI
5675           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5676   "TARGET_AVX512F && TARGET_SSE_MATH"
5677   "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5678   [(set_attr "type" "sseicvt")
5679    (set_attr "prefix" "evex")
5680    (set_attr "mode" "SI")])
5682 (define_insn "*fixuns_trunchfsi2zext"
5683   [(set (match_operand:DI 0 "register_operand" "=r")
5684         (zero_extend:DI
5685           (unsigned_fix:SI
5686             (match_operand:HF 1 "nonimmediate_operand" "vm"))))]
5687   "TARGET_64BIT && TARGET_AVX512FP16"
5688   "vcvttsh2usi\t{%1, %k0|%k0, %1}"
5689   [(set_attr "type" "sseicvt")
5690    (set_attr "prefix" "evex")
5691    (set_attr "mode" "SI")])
5693 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
5694   [(set (match_operand:DI 0 "register_operand" "=r")
5695         (zero_extend:DI
5696           (unsigned_fix:SI
5697             (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
5698   "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5699   "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
5700   [(set_attr "type" "sseicvt")
5701    (set_attr "prefix" "evex")
5702    (set_attr "mode" "SI")])
5704 (define_insn_and_split "*fixuns_trunc<mode>_1"
5705   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5706         (unsigned_fix:SI
5707           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5708    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
5709    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5710    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5711   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5712    && optimize_function_for_speed_p (cfun)"
5713   "#"
5714   "&& reload_completed"
5715   [(const_int 0)]
5717   ix86_split_convert_uns_si_sse (operands);
5718   DONE;
5721 ;; Unsigned conversion to HImode.
5722 ;; Without these patterns, we'll try the unsigned SI conversion which
5723 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5725 (define_expand "fixuns_trunchfhi2"
5726   [(set (match_dup 2)
5727         (fix:SI (match_operand:HF 1 "nonimmediate_operand")))
5728    (set (match_operand:HI 0 "nonimmediate_operand")
5729         (subreg:HI (match_dup 2) 0))]
5730   "TARGET_AVX512FP16"
5731   "operands[2] = gen_reg_rtx (SImode);")
5733 (define_expand "fixuns_trunc<mode>hi2"
5734   [(set (match_dup 2)
5735         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5736    (set (match_operand:HI 0 "nonimmediate_operand")
5737         (subreg:HI (match_dup 2) 0))]
5738   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5739   "operands[2] = gen_reg_rtx (SImode);")
5741 ;; When SSE is available, it is always faster to use it!
5742 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5743   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5744         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5745   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5746    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5747   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5748   [(set_attr "type" "sseicvt")
5749    (set_attr "prefix" "maybe_vex")
5750    (set (attr "prefix_rex")
5751         (if_then_else
5752           (match_test "<SWI48:MODE>mode == DImode")
5753           (const_string "1")
5754           (const_string "*")))
5755    (set_attr "mode" "<MODEF:MODE>")
5756    (set_attr "athlon_decode" "double,vector")
5757    (set_attr "amdfam10_decode" "double,double")
5758    (set_attr "bdver1_decode" "double,double")])
5760 ;; Avoid vector decoded forms of the instruction.
5761 (define_peephole2
5762   [(match_scratch:MODEF 2 "x")
5763    (set (match_operand:SWI48 0 "register_operand")
5764         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5765   "TARGET_AVOID_VECTOR_DECODE
5766    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5767    && optimize_insn_for_speed_p ()"
5768   [(set (match_dup 2) (match_dup 1))
5769    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5771 (define_insn "fix_trunc<mode>_i387_fisttp"
5772   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
5773         (fix:SWI248x (match_operand 1 "register_operand" "f")))
5774    (clobber (match_scratch:XF 2 "=&f"))]
5775   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5776    && TARGET_FISTTP
5777    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5778          && (TARGET_64BIT || <MODE>mode != DImode))
5779         && TARGET_SSE_MATH)"
5780   "* return output_fix_trunc (insn, operands, true);"
5781   [(set_attr "type" "fisttp")
5782    (set_attr "mode" "<MODE>")])
5784 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5785 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5786 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5787 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5788 ;; function in i386.cc.
5789 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5790   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5791         (fix:SWI248x (match_operand 1 "register_operand")))
5792    (clobber (reg:CC FLAGS_REG))]
5793   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5794    && !TARGET_FISTTP
5795    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5796          && (TARGET_64BIT || <MODE>mode != DImode))
5797    && ix86_pre_reload_split ()"
5798   "#"
5799   "&& 1"
5800   [(const_int 0)]
5802   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5804   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5805   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5807   emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5808                                        operands[2], operands[3]));
5809   DONE;
5811   [(set_attr "type" "fistp")
5812    (set_attr "i387_cw" "trunc")
5813    (set_attr "mode" "<MODE>")])
5815 (define_insn "fix_truncdi_i387"
5816   [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
5817         (fix:DI (match_operand 1 "register_operand" "f")))
5818    (use (match_operand:HI 2 "memory_operand" "m"))
5819    (use (match_operand:HI 3 "memory_operand" "m"))
5820    (clobber (match_scratch:XF 4 "=&f"))]
5821   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5822    && !TARGET_FISTTP
5823    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5824   "* return output_fix_trunc (insn, operands, false);"
5825   [(set_attr "type" "fistp")
5826    (set_attr "i387_cw" "trunc")
5827    (set_attr "mode" "DI")])
5829 (define_insn "fix_trunc<mode>_i387"
5830   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
5831         (fix:SWI24 (match_operand 1 "register_operand" "f")))
5832    (use (match_operand:HI 2 "memory_operand" "m"))
5833    (use (match_operand:HI 3 "memory_operand" "m"))]
5834   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5835    && !TARGET_FISTTP
5836    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5837   "* return output_fix_trunc (insn, operands, false);"
5838   [(set_attr "type" "fistp")
5839    (set_attr "i387_cw" "trunc")
5840    (set_attr "mode" "<MODE>")])
5842 (define_insn "x86_fnstcw_1"
5843   [(set (match_operand:HI 0 "memory_operand" "=m")
5844         (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
5845   "TARGET_80387"
5846   "fnstcw\t%0"
5847   [(set (attr "length")
5848         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5849    (set_attr "mode" "HI")
5850    (set_attr "unit" "i387")
5851    (set_attr "bdver1_decode" "vector")])
5853 ;; Conversion between fixed point and floating point.
5855 ;; Even though we only accept memory inputs, the backend _really_
5856 ;; wants to be able to do this between registers.  Thankfully, LRA
5857 ;; will fix this up for us during register allocation.
5859 (define_insn "floathi<mode>2"
5860   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5861         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5862   "TARGET_80387
5863    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5864        || TARGET_MIX_SSE_I387)"
5865   "fild%Z1\t%1"
5866   [(set_attr "type" "fmov")
5867    (set_attr "mode" "<MODE>")
5868    (set_attr "znver1_decode" "double")
5869    (set_attr "fp_int_src" "true")])
5871 (define_insn "float<SWI48x:mode>xf2"
5872   [(set (match_operand:XF 0 "register_operand" "=f")
5873         (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5874   "TARGET_80387"
5875   "fild%Z1\t%1"
5876   [(set_attr "type" "fmov")
5877    (set_attr "mode" "XF")
5878    (set_attr "znver1_decode" "double")
5879    (set_attr "fp_int_src" "true")])
5881 (define_expand "float<SWI48x:mode><MODEF:mode>2"
5882   [(set (match_operand:MODEF 0 "register_operand")
5883         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
5884   "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
5885    || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5886        && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
5888 (define_insn "*float<SWI48:mode><MODEF:mode>2"
5889   [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5890         (float:MODEF
5891           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5892   "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5893    || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5894   "@
5895    fild%Z1\t%1
5896    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5897    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5898   [(set_attr "type" "fmov,sseicvt,sseicvt")
5899    (set_attr "avx_partial_xmm_update" "false,true,true")
5900    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5901    (set_attr "mode" "<MODEF:MODE>")
5902    (set (attr "prefix_rex")
5903      (if_then_else
5904        (and (eq_attr "prefix" "maybe_vex")
5905             (match_test "<SWI48:MODE>mode == DImode"))
5906        (const_string "1")
5907        (const_string "*")))
5908    (set_attr "unit" "i387,*,*")
5909    (set_attr "athlon_decode" "*,double,direct")
5910    (set_attr "amdfam10_decode" "*,vector,double")
5911    (set_attr "bdver1_decode" "*,double,direct")
5912    (set_attr "znver1_decode" "double,*,*")
5913    (set_attr "fp_int_src" "true")
5914    (set (attr "enabled")
5915      (if_then_else
5916        (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
5917        (if_then_else
5918          (eq_attr "alternative" "0")
5919          (symbol_ref "TARGET_MIX_SSE_I387
5920                       && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5921                                            <SWI48:MODE>mode)")
5922          (symbol_ref "true"))
5923        (if_then_else
5924          (eq_attr "alternative" "0")
5925          (symbol_ref "true")
5926          (symbol_ref "false"))))
5927    (set (attr "preferred_for_speed")
5928      (cond [(eq_attr "alternative" "1")
5929               (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5930            (symbol_ref "true")))])
5932 (define_insn "float<floatunssuffix><mode>hf2"
5933   [(set (match_operand:HF 0 "register_operand" "=v")
5934         (any_float:HF
5935           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5936   "TARGET_AVX512FP16"
5937   "vcvt<floatsuffix>si2sh<rex64suffix>\t{%1, %d0|%d0, %1}"
5938   [(set_attr "type" "sseicvt")
5939    (set_attr "prefix" "evex")
5940    (set_attr "mode" "HF")])
5942 (define_insn "*floatdi<MODEF:mode>2_i387"
5943   [(set (match_operand:MODEF 0 "register_operand" "=f")
5944         (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
5945   "!TARGET_64BIT
5946    && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
5947   "fild%Z1\t%1"
5948   [(set_attr "type" "fmov")
5949    (set_attr "mode" "<MODEF:MODE>")
5950    (set_attr "znver1_decode" "double")
5951    (set_attr "fp_int_src" "true")])
5953 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5954 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5955 ;; alternative in sse2_loadld.
5956 (define_split
5957   [(set (match_operand:MODEF 0 "sse_reg_operand")
5958         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5959   "TARGET_SSE2
5960    && TARGET_USE_VECTOR_CONVERTS
5961    && optimize_function_for_speed_p (cfun)
5962    && reload_completed
5963    && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5964    && (!EXT_REX_SSE_REG_P (operands[0])
5965        || TARGET_AVX512VL)"
5966   [(const_int 0)]
5968   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5969   operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5971   emit_insn (gen_sse2_loadld (operands[4],
5972                               CONST0_RTX (V4SImode), operands[1]));
5974   if (<ssevecmode>mode == V4SFmode)
5975     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5976   else
5977     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5978   DONE;
5981 ;; Avoid store forwarding (partial memory) stall penalty
5982 ;; by passing DImode value through XMM registers.  */
5984 (define_split
5985   [(set (match_operand:X87MODEF 0 "register_operand")
5986         (float:X87MODEF
5987           (match_operand:DI 1 "register_operand")))]
5988   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5989    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5990    && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
5991    && can_create_pseudo_p ()"
5992   [(const_int 0)]
5994   rtx s = assign_386_stack_local (DImode, SLOT_FLOATxFDI_387);
5995   emit_insn (gen_floatdi<mode>2_i387_with_xmm (operands[0], operands[1], s));
5996   DONE;
5999 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
6000   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
6001         (float:X87MODEF
6002           (match_operand:DI 1 "register_operand" "r,r")))
6003    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
6004    (clobber (match_scratch:V4SI 3 "=x,x"))
6005    (clobber (match_scratch:V4SI 4 "=X,x"))]
6006   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
6007    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6008    && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
6009   "#"
6010   "&& reload_completed"
6011   [(set (match_dup 2) (match_dup 3))
6012    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
6014   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
6015      Assemble the 64-bit DImode value in an xmm register.  */
6016   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
6017                               gen_lowpart (SImode, operands[1])));
6018   if (TARGET_SSE4_1)
6019     emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
6020                                   gen_highpart (SImode, operands[1]),
6021                                   GEN_INT (2)));
6022   else
6023     {
6024       emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
6025                                   gen_highpart (SImode, operands[1])));
6026       emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
6027                                              operands[4]));
6028     }
6029   operands[3] = gen_lowpart (DImode, operands[3]);
6031   [(set_attr "isa" "sse4,*")
6032    (set_attr "type" "multi")
6033    (set_attr "mode" "<X87MODEF:MODE>")
6034    (set_attr "unit" "i387")
6035    (set_attr "fp_int_src" "true")])
6037 ;; Break partial SSE register dependency stall.  This splitter should split
6038 ;; late in the pass sequence (after register rename pass), so allocated
6039 ;; registers won't change anymore
6041 (define_split
6042   [(set (match_operand:MODEF 0 "sse_reg_operand")
6043         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
6044   "!TARGET_AVX
6045    && TARGET_SSE_PARTIAL_REG_CONVERTS_DEPENDENCY
6046    && epilogue_completed
6047    && optimize_function_for_speed_p (cfun)
6048    && (!EXT_REX_SSE_REG_P (operands[0])
6049        || TARGET_AVX512VL)"
6050   [(set (match_dup 0)
6051         (vec_merge:<MODEF:ssevecmode>
6052           (vec_duplicate:<MODEF:ssevecmode>
6053             (float:MODEF
6054               (match_dup 1)))
6055           (match_dup 0)
6056           (const_int 1)))]
6058   const machine_mode vmode = <MODEF:ssevecmode>mode;
6060   operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
6061   emit_move_insn (operands[0], CONST0_RTX (vmode));
6064 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
6065   [(set (match_operand:MODEF 0 "register_operand")
6066         (unsigned_float:MODEF
6067           (match_operand:SWI12 1 "nonimmediate_operand")))]
6068   "!TARGET_64BIT
6069    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
6071   operands[1] = convert_to_mode (SImode, operands[1], 1);
6072   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
6073   DONE;
6076 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
6077   [(set (match_operand:MODEF 0 "register_operand" "=v")
6078         (unsigned_float:MODEF
6079           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
6080   "TARGET_AVX512F && TARGET_SSE_MATH"
6081   "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
6082   [(set_attr "type" "sseicvt")
6083    (set_attr "avx_partial_xmm_update" "true")
6084    (set_attr "prefix" "evex")
6085    (set_attr "mode" "<MODEF:MODE>")])
6087 ;; Avoid store forwarding (partial memory) stall penalty by extending
6088 ;; SImode value to DImode through XMM register instead of pushing two
6089 ;; SImode values to stack. Also note that fild loads from memory only.
6091 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
6092   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
6093         (unsigned_float:X87MODEF
6094           (match_operand:SI 1 "nonimmediate_operand" "rm")))
6095    (clobber (match_operand:DI 2 "memory_operand" "=m"))
6096    (clobber (match_scratch:DI 3 "=x"))]
6097   "!TARGET_64BIT
6098    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6099    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
6100   "#"
6101   "&& reload_completed"
6102   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
6103    (set (match_dup 2) (match_dup 3))
6104    (set (match_dup 0)
6105         (float:X87MODEF (match_dup 2)))]
6106   ""
6107   [(set_attr "type" "multi")
6108    (set_attr "mode" "<MODE>")])
6110 (define_expand "floatunssi<mode>2"
6111   [(set (match_operand:X87MODEF 0 "register_operand")
6112         (unsigned_float:X87MODEF
6113           (match_operand:SI 1 "nonimmediate_operand")))]
6114   "(!TARGET_64BIT
6115     && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6116     && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
6117    || ((!TARGET_64BIT || TARGET_AVX512F)
6118        && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6120   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
6121     {
6122       emit_insn (gen_floatunssi<mode>2_i387_with_xmm
6123                   (operands[0], operands[1],
6124                    assign_386_stack_local (DImode, SLOT_TEMP)));
6125       DONE;
6126     }
6127   if (!TARGET_AVX512F)
6128     {
6129       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6130       DONE;
6131     }
6134 (define_expand "floatunsdisf2"
6135   [(set (match_operand:SF 0 "register_operand")
6136         (unsigned_float:SF
6137           (match_operand:DI 1 "nonimmediate_operand")))]
6138   "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
6140   if (!TARGET_AVX512F)
6141     {
6142       x86_emit_floatuns (operands);
6143       DONE;
6144     }
6147 (define_expand "floatunsdidf2"
6148   [(set (match_operand:DF 0 "register_operand")
6149         (unsigned_float:DF
6150           (match_operand:DI 1 "nonimmediate_operand")))]
6151   "((TARGET_64BIT && TARGET_AVX512F)
6152     || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6153    && TARGET_SSE2 && TARGET_SSE_MATH"
6155   if (!TARGET_64BIT)
6156     {
6157       ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6158       DONE;
6159     }
6160   if (!TARGET_AVX512F)
6161     {
6162       x86_emit_floatuns (operands);
6163       DONE;
6164     }
6167 ;; Load effective address instructions
6169 (define_insn "*lea<mode>"
6170   [(set (match_operand:SWI48 0 "register_operand" "=r")
6171         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
6172   "ix86_hardreg_mov_ok (operands[0], operands[1])"
6174   if (SImode_address_operand (operands[1], VOIDmode))
6175     {
6176       gcc_assert (TARGET_64BIT);
6177       return "lea{l}\t{%E1, %k0|%k0, %E1}";
6178     }
6179   else
6180     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
6182   [(set_attr "type" "lea")
6183    (set (attr "mode")
6184      (if_then_else
6185        (match_operand 1 "SImode_address_operand")
6186        (const_string "SI")
6187        (const_string "<MODE>")))])
6189 (define_peephole2
6190   [(set (match_operand:SWI48 0 "register_operand")
6191         (match_operand:SWI48 1 "address_no_seg_operand"))]
6192   "ix86_hardreg_mov_ok (operands[0], operands[1])
6193    && peep2_regno_dead_p (0, FLAGS_REG)
6194    && ix86_avoid_lea_for_addr (peep2_next_insn (0), operands)"
6195   [(const_int 0)]
6197   machine_mode mode = <MODE>mode;
6199   /* Emit all operations in SImode for zero-extended addresses.  */
6200   if (SImode_address_operand (operands[1], VOIDmode))
6201     mode = SImode;
6203   ix86_split_lea_for_addr (peep2_next_insn (0), operands, mode);
6205   /* Zero-extend return register to DImode for zero-extended addresses.  */
6206   if (mode != <MODE>mode)
6207     emit_insn (gen_zero_extendsidi2 (operands[0],
6208                                      gen_lowpart (mode, operands[0])));
6210   DONE;
6213 ;; ix86_split_lea_for_addr emits the shifts as MULT to avoid it from being
6214 ;; peephole2 optimized back into a lea.  Split that into the shift during
6215 ;; the following split pass.
6216 (define_split
6217   [(set (match_operand:SWI48 0 "general_reg_operand")
6218         (mult:SWI48 (match_dup 0) (match_operand:SWI48 1 "const1248_operand")))
6219    (clobber (reg:CC FLAGS_REG))]
6220   "reload_completed"
6221   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
6222               (clobber (reg:CC FLAGS_REG))])]
6223   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
6225 ;; Add instructions
6227 (define_expand "add<mode>3"
6228   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6229         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6230                     (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6231   ""
6232   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
6234 (define_insn_and_split "*add<dwi>3_doubleword"
6235   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6236         (plus:<DWI>
6237           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
6238           (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
6239    (clobber (reg:CC FLAGS_REG))]
6240   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
6241   "#"
6242   "&& reload_completed"
6243   [(parallel [(set (reg:CCC FLAGS_REG)
6244                    (compare:CCC
6245                      (plus:DWIH (match_dup 1) (match_dup 2))
6246                      (match_dup 1)))
6247               (set (match_dup 0)
6248                    (plus:DWIH (match_dup 1) (match_dup 2)))])
6249    (parallel [(set (match_dup 3)
6250                    (plus:DWIH
6251                      (plus:DWIH
6252                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6253                        (match_dup 4))
6254                      (match_dup 5)))
6255               (clobber (reg:CC FLAGS_REG))])]
6257   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6258   if (operands[2] == const0_rtx)
6259     {
6260       if (operands[5] != const0_rtx)
6261         ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
6262       else if (!rtx_equal_p (operands[3], operands[4]))
6263         emit_move_insn (operands[3], operands[4]);
6264       else
6265         emit_note (NOTE_INSN_DELETED);
6266       DONE;
6267     }
6270 (define_insn_and_split "*add<dwi>3_doubleword_zext"
6271   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6272         (plus:<DWI>
6273           (zero_extend:<DWI>
6274             (match_operand:DWIH 2 "nonimmediate_operand" "rm,r")) 
6275           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")))
6276    (clobber (reg:CC FLAGS_REG))]
6277   "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
6278   "#"
6279   "&& reload_completed"
6280   [(parallel [(set (reg:CCC FLAGS_REG)
6281                    (compare:CCC
6282                      (plus:DWIH (match_dup 1) (match_dup 2))
6283                      (match_dup 1)))
6284               (set (match_dup 0)
6285                    (plus:DWIH (match_dup 1) (match_dup 2)))])
6286    (parallel [(set (match_dup 3)
6287                    (plus:DWIH
6288                      (plus:DWIH
6289                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6290                        (match_dup 4))
6291                      (const_int 0)))
6292               (clobber (reg:CC FLAGS_REG))])]
6293  "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
6295 (define_insn_and_split "*add<dwi>3_doubleword_concat"
6296   [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6297         (plus:<DWI>
6298           (any_or_plus:<DWI>
6299             (ashift:<DWI>
6300               (zero_extend:<DWI>
6301                 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6302               (match_operand:QI 3 "const_int_operand"))
6303             (zero_extend:<DWI>
6304               (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6305           (match_operand:<DWI> 1 "register_operand" "0")))
6306    (clobber (reg:CC FLAGS_REG))]
6307   "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6308   "#"
6309   "&& reload_completed"
6310   [(parallel [(set (reg:CCC FLAGS_REG)
6311                    (compare:CCC
6312                      (plus:DWIH (match_dup 1) (match_dup 4))
6313                      (match_dup 1)))
6314               (set (match_dup 0)
6315                    (plus:DWIH (match_dup 1) (match_dup 4)))])
6316    (parallel [(set (match_dup 5)
6317                    (plus:DWIH
6318                      (plus:DWIH
6319                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6320                        (match_dup 6))
6321                      (match_dup 2)))
6322               (clobber (reg:CC FLAGS_REG))])]
6323  "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[5]);")
6325 (define_insn_and_split "*add<dwi>3_doubleword_concat_zext"
6326   [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6327         (plus:<DWI>
6328           (any_or_plus:<DWI>
6329             (ashift:<DWI>
6330               (zero_extend:<DWI>
6331                 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6332               (match_operand:QI 3 "const_int_operand"))
6333             (zero_extend:<DWI>
6334               (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6335           (zero_extend:<DWI>
6336             (match_operand:DWIH 1 "nonimmediate_operand" "rm"))))
6337    (clobber (reg:CC FLAGS_REG))]
6338   "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6339   "#"
6340   "&& reload_completed"
6341   [(set (match_dup 0) (match_dup 4))
6342    (set (match_dup 5) (match_dup 2))
6343    (parallel [(set (reg:CCC FLAGS_REG)
6344                    (compare:CCC
6345                      (plus:DWIH (match_dup 0) (match_dup 1))
6346                      (match_dup 0)))
6347               (set (match_dup 0)
6348                    (plus:DWIH (match_dup 0) (match_dup 1)))])
6349    (parallel [(set (match_dup 5)
6350                    (plus:DWIH
6351                      (plus:DWIH
6352                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6353                        (match_dup 5))
6354                      (const_int 0)))
6355               (clobber (reg:CC FLAGS_REG))])]
6356  "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[5]);")
6358 (define_insn "*add<mode>_1"
6359   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
6360         (plus:SWI48
6361           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6362           (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le")))
6363    (clobber (reg:CC FLAGS_REG))]
6364   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6366   switch (get_attr_type (insn))
6367     {
6368     case TYPE_LEA:
6369       return "#";
6371     case TYPE_INCDEC:
6372       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6373       if (operands[2] == const1_rtx)
6374         return "inc{<imodesuffix>}\t%0";
6375       else
6376         {
6377           gcc_assert (operands[2] == constm1_rtx);
6378           return "dec{<imodesuffix>}\t%0";
6379         }
6381     default:
6382       /* For most processors, ADD is faster than LEA.  This alternative
6383          was added to use ADD as much as possible.  */
6384       if (which_alternative == 2)
6385         std::swap (operands[1], operands[2]);
6386         
6387       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6388       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6389         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6391       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6392     }
6394   [(set (attr "type")
6395      (cond [(eq_attr "alternative" "3")
6396               (const_string "lea")
6397             (match_operand:SWI48 2 "incdec_operand")
6398               (const_string "incdec")
6399            ]
6400            (const_string "alu")))
6401    (set (attr "length_immediate")
6402       (if_then_else
6403         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6404         (const_string "1")
6405         (const_string "*")))
6406    (set_attr "mode" "<MODE>")])
6408 ;; It may seem that nonimmediate operand is proper one for operand 1.
6409 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6410 ;; we take care in ix86_binary_operator_ok to not allow two memory
6411 ;; operands so proper swapping will be done in reload.  This allow
6412 ;; patterns constructed from addsi_1 to match.
6414 (define_insn "addsi_1_zext"
6415   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6416         (zero_extend:DI
6417           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
6418                    (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le"))))
6419    (clobber (reg:CC FLAGS_REG))]
6420   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6422   switch (get_attr_type (insn))
6423     {
6424     case TYPE_LEA:
6425       return "#";
6427     case TYPE_INCDEC:
6428       if (operands[2] == const1_rtx)
6429         return "inc{l}\t%k0";
6430       else
6431         {
6432           gcc_assert (operands[2] == constm1_rtx);
6433           return "dec{l}\t%k0";
6434         }
6436     default:
6437       /* For most processors, ADD is faster than LEA.  This alternative
6438          was added to use ADD as much as possible.  */
6439       if (which_alternative == 1)
6440         std::swap (operands[1], operands[2]);
6442       if (x86_maybe_negate_const_int (&operands[2], SImode))
6443         return "sub{l}\t{%2, %k0|%k0, %2}";
6445       return "add{l}\t{%2, %k0|%k0, %2}";
6446     }
6448   [(set (attr "type")
6449      (cond [(eq_attr "alternative" "2")
6450               (const_string "lea")
6451             (match_operand:SI 2 "incdec_operand")
6452               (const_string "incdec")
6453            ]
6454            (const_string "alu")))
6455    (set (attr "length_immediate")
6456       (if_then_else
6457         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6458         (const_string "1")
6459         (const_string "*")))
6460    (set_attr "mode" "SI")])
6462 (define_insn "*addhi_1"
6463   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
6464         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
6465                  (match_operand:HI 2 "general_operand" "rn,m,0,ln")))
6466    (clobber (reg:CC FLAGS_REG))]
6467   "ix86_binary_operator_ok (PLUS, HImode, operands)"
6469   switch (get_attr_type (insn))
6470     {
6471     case TYPE_LEA:
6472       return "#";
6474     case TYPE_INCDEC:
6475       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6476       if (operands[2] == const1_rtx)
6477         return "inc{w}\t%0";
6478       else
6479         {
6480           gcc_assert (operands[2] == constm1_rtx);
6481           return "dec{w}\t%0";
6482         }
6484     default:
6485       /* For most processors, ADD is faster than LEA.  This alternative
6486          was added to use ADD as much as possible.  */
6487       if (which_alternative == 2)
6488         std::swap (operands[1], operands[2]);
6490       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6491       if (x86_maybe_negate_const_int (&operands[2], HImode))
6492         return "sub{w}\t{%2, %0|%0, %2}";
6494       return "add{w}\t{%2, %0|%0, %2}";
6495     }
6497   [(set (attr "type")
6498      (cond [(eq_attr "alternative" "3")
6499               (const_string "lea")
6500             (match_operand:HI 2 "incdec_operand")
6501               (const_string "incdec")
6502            ]
6503            (const_string "alu")))
6504    (set (attr "length_immediate")
6505       (if_then_else
6506         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6507         (const_string "1")
6508         (const_string "*")))
6509    (set_attr "mode" "HI,HI,HI,SI")])
6511 (define_insn "*addqi_1"
6512   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
6513         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
6514                  (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln")))
6515    (clobber (reg:CC FLAGS_REG))]
6516   "ix86_binary_operator_ok (PLUS, QImode, operands)"
6518   bool widen = (get_attr_mode (insn) != MODE_QI);
6520   switch (get_attr_type (insn))
6521     {
6522     case TYPE_LEA:
6523       return "#";
6525     case TYPE_INCDEC:
6526       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6527       if (operands[2] == const1_rtx)
6528         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6529       else
6530         {
6531           gcc_assert (operands[2] == constm1_rtx);
6532           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6533         }
6535     default:
6536       /* For most processors, ADD is faster than LEA.  These alternatives
6537          were added to use ADD as much as possible.  */
6538       if (which_alternative == 2 || which_alternative == 4)
6539         std::swap (operands[1], operands[2]);
6541       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6542       if (x86_maybe_negate_const_int (&operands[2], QImode))
6543         {
6544           if (widen)
6545             return "sub{l}\t{%2, %k0|%k0, %2}";
6546           else
6547             return "sub{b}\t{%2, %0|%0, %2}";
6548         }
6549       if (widen)
6550         return "add{l}\t{%k2, %k0|%k0, %k2}";
6551       else
6552         return "add{b}\t{%2, %0|%0, %2}";
6553     }
6555   [(set (attr "type")
6556      (cond [(eq_attr "alternative" "5")
6557               (const_string "lea")
6558             (match_operand:QI 2 "incdec_operand")
6559               (const_string "incdec")
6560            ]
6561            (const_string "alu")))
6562    (set (attr "length_immediate")
6563       (if_then_else
6564         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6565         (const_string "1")
6566         (const_string "*")))
6567    (set_attr "mode" "QI,QI,QI,SI,SI,SI")
6568    ;; Potential partial reg stall on alternatives 3 and 4.
6569    (set (attr "preferred_for_speed")
6570      (cond [(eq_attr "alternative" "3,4")
6571               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
6572            (symbol_ref "true")))])
6574 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6575 (define_insn_and_split "*add<mode>_1_slp"
6576   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
6577         (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
6578                     (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
6579    (clobber (reg:CC FLAGS_REG))]
6580   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6582   if (which_alternative)
6583     return "#";
6585   switch (get_attr_type (insn))
6586     {
6587     case TYPE_INCDEC:
6588       if (operands[2] == const1_rtx)
6589         return "inc{<imodesuffix>}\t%0";
6590       else
6591         {
6592           gcc_assert (operands[2] == constm1_rtx);
6593           return "dec{<imodesuffix>}\t%0";
6594         }
6596     default:
6597       if (x86_maybe_negate_const_int (&operands[2], QImode))
6598         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6600       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6601     }
6603   "&& reload_completed
6604    && !(rtx_equal_p (operands[0], operands[1])
6605         || rtx_equal_p (operands[0], operands[2]))"
6606   [(set (strict_low_part (match_dup 0)) (match_dup 1))
6607    (parallel
6608      [(set (strict_low_part (match_dup 0))
6609            (plus:SWI12 (match_dup 0) (match_dup 2)))
6610       (clobber (reg:CC FLAGS_REG))])]
6611   ""
6612   [(set (attr "type")
6613      (if_then_else (match_operand:QI 2 "incdec_operand")
6614         (const_string "incdec")
6615         (const_string "alu")))
6616    (set_attr "mode" "<MODE>")])
6618 ;; Split non destructive adds if we cannot use lea.
6619 (define_split
6620   [(set (match_operand:SWI48 0 "register_operand")
6621         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
6622                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
6623    (clobber (reg:CC FLAGS_REG))]
6624   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6625   [(set (match_dup 0) (match_dup 1))
6626    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
6627               (clobber (reg:CC FLAGS_REG))])])
6629 ;; Split non destructive adds if we cannot use lea.
6630 (define_split
6631   [(set (match_operand:DI 0 "register_operand")
6632         (zero_extend:DI
6633           (plus:SI (match_operand:SI 1 "register_operand")
6634                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6635    (clobber (reg:CC FLAGS_REG))]
6636   "TARGET_64BIT
6637    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6638   [(set (match_dup 3) (match_dup 1))
6639    (parallel [(set (match_dup 0)
6640                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
6641               (clobber (reg:CC FLAGS_REG))])]
6642   "operands[3] = gen_lowpart (SImode, operands[0]);")
6644 ;; Convert add to the lea pattern to avoid flags dependency.
6645 (define_split
6646   [(set (match_operand:SWI 0 "register_operand")
6647         (plus:SWI (match_operand:SWI 1 "register_operand")
6648                   (match_operand:SWI 2 "<nonmemory_operand>")))
6649    (clobber (reg:CC FLAGS_REG))]
6650   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
6651   [(set (match_dup 0)
6652         (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
6654   if (<MODE>mode != <LEAMODE>mode)
6655     {
6656       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
6657       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
6658       operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
6659     }
6662 ;; Convert add to the lea pattern to avoid flags dependency.
6663 (define_split
6664   [(set (match_operand:DI 0 "register_operand")
6665         (zero_extend:DI
6666           (plus:SI (match_operand:SI 1 "register_operand")
6667                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6668    (clobber (reg:CC FLAGS_REG))]
6669   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6670   [(set (match_dup 0)
6671         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6673 (define_insn "*add<mode>_2"
6674   [(set (reg FLAGS_REG)
6675         (compare
6676           (plus:SWI
6677             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6678             (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,0"))
6679           (const_int 0)))
6680    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>")
6681         (plus:SWI (match_dup 1) (match_dup 2)))]
6682   "ix86_match_ccmode (insn, CCGOCmode)
6683    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6685   switch (get_attr_type (insn))
6686     {
6687     case TYPE_INCDEC:
6688       if (operands[2] == const1_rtx)
6689         return "inc{<imodesuffix>}\t%0";
6690       else
6691         {
6692           gcc_assert (operands[2] == constm1_rtx);
6693           return "dec{<imodesuffix>}\t%0";
6694         }
6696     default:
6697       if (which_alternative == 2)
6698         std::swap (operands[1], operands[2]);
6699         
6700       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6701       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6702         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6704       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6705     }
6707   [(set (attr "type")
6708      (if_then_else (match_operand:SWI 2 "incdec_operand")
6709         (const_string "incdec")
6710         (const_string "alu")))
6711    (set (attr "length_immediate")
6712       (if_then_else
6713         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6714         (const_string "1")
6715         (const_string "*")))
6716    (set_attr "mode" "<MODE>")])
6718 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6719 (define_insn "*addsi_2_zext"
6720   [(set (reg FLAGS_REG)
6721         (compare
6722           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6723                    (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6724           (const_int 0)))
6725    (set (match_operand:DI 0 "register_operand" "=r,r")
6726         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6727   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6728    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6730   switch (get_attr_type (insn))
6731     {
6732     case TYPE_INCDEC:
6733       if (operands[2] == const1_rtx)
6734         return "inc{l}\t%k0";
6735       else
6736         {
6737           gcc_assert (operands[2] == constm1_rtx);
6738           return "dec{l}\t%k0";
6739         }
6741     default:
6742       if (which_alternative == 1)
6743         std::swap (operands[1], operands[2]);
6745       if (x86_maybe_negate_const_int (&operands[2], SImode))
6746         return "sub{l}\t{%2, %k0|%k0, %2}";
6748       return "add{l}\t{%2, %k0|%k0, %2}";
6749     }
6751   [(set (attr "type")
6752      (if_then_else (match_operand:SI 2 "incdec_operand")
6753         (const_string "incdec")
6754         (const_string "alu")))
6755    (set (attr "length_immediate")
6756       (if_then_else
6757         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6758         (const_string "1")
6759         (const_string "*")))
6760    (set_attr "mode" "SI")])
6762 (define_insn "*add<mode>_3"
6763   [(set (reg FLAGS_REG)
6764         (compare
6765           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6766           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6767    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6768   "ix86_match_ccmode (insn, CCZmode)
6769    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6771   switch (get_attr_type (insn))
6772     {
6773     case TYPE_INCDEC:
6774       if (operands[2] == const1_rtx)
6775         return "inc{<imodesuffix>}\t%0";
6776       else
6777         {
6778           gcc_assert (operands[2] == constm1_rtx);
6779           return "dec{<imodesuffix>}\t%0";
6780         }
6782     default:
6783       if (which_alternative == 1)
6784         std::swap (operands[1], operands[2]);
6786       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6787       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6788         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6790       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6791     }
6793   [(set (attr "type")
6794      (if_then_else (match_operand:SWI 2 "incdec_operand")
6795         (const_string "incdec")
6796         (const_string "alu")))
6797    (set (attr "length_immediate")
6798       (if_then_else
6799         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6800         (const_string "1")
6801         (const_string "*")))
6802    (set_attr "mode" "<MODE>")])
6804 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6805 (define_insn "*addsi_3_zext"
6806   [(set (reg FLAGS_REG)
6807         (compare
6808           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6809           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6810    (set (match_operand:DI 0 "register_operand" "=r,r")
6811         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6812   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6813    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6815   switch (get_attr_type (insn))
6816     {
6817     case TYPE_INCDEC:
6818       if (operands[2] == const1_rtx)
6819         return "inc{l}\t%k0";
6820       else
6821         {
6822           gcc_assert (operands[2] == constm1_rtx);
6823           return "dec{l}\t%k0";
6824         }
6826     default:
6827       if (which_alternative == 1)
6828         std::swap (operands[1], operands[2]);
6830       if (x86_maybe_negate_const_int (&operands[2], SImode))
6831         return "sub{l}\t{%2, %k0|%k0, %2}";
6833       return "add{l}\t{%2, %k0|%k0, %2}";
6834     }
6836   [(set (attr "type")
6837      (if_then_else (match_operand:SI 2 "incdec_operand")
6838         (const_string "incdec")
6839         (const_string "alu")))
6840    (set (attr "length_immediate")
6841       (if_then_else
6842         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6843         (const_string "1")
6844         (const_string "*")))
6845    (set_attr "mode" "SI")])
6847 ; For comparisons against 1, -1 and 128, we may generate better code
6848 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6849 ; is matched then.  We can't accept general immediate, because for
6850 ; case of overflows,  the result is messed up.
6851 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6852 ; only for comparisons not depending on it.
6854 (define_insn "*adddi_4"
6855   [(set (reg FLAGS_REG)
6856         (compare
6857           (match_operand:DI 1 "nonimmediate_operand" "0")
6858           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6859    (clobber (match_scratch:DI 0 "=r"))]
6860   "TARGET_64BIT
6861    && ix86_match_ccmode (insn, CCGCmode)"
6863   switch (get_attr_type (insn))
6864     {
6865     case TYPE_INCDEC:
6866       if (operands[2] == constm1_rtx)
6867         return "inc{q}\t%0";
6868       else
6869         {
6870           gcc_assert (operands[2] == const1_rtx);
6871           return "dec{q}\t%0";
6872         }
6874     default:
6875       if (x86_maybe_negate_const_int (&operands[2], DImode))
6876         return "add{q}\t{%2, %0|%0, %2}";
6878       return "sub{q}\t{%2, %0|%0, %2}";
6879     }
6881   [(set (attr "type")
6882      (if_then_else (match_operand:DI 2 "incdec_operand")
6883         (const_string "incdec")
6884         (const_string "alu")))
6885    (set (attr "length_immediate")
6886       (if_then_else
6887         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6888         (const_string "1")
6889         (const_string "*")))
6890    (set_attr "mode" "DI")])
6892 ; For comparisons against 1, -1 and 128, we may generate better code
6893 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6894 ; is matched then.  We can't accept general immediate, because for
6895 ; case of overflows,  the result is messed up.
6896 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6897 ; only for comparisons not depending on it.
6899 (define_insn "*add<mode>_4"
6900   [(set (reg FLAGS_REG)
6901         (compare
6902           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6903           (match_operand:SWI124 2 "const_int_operand")))
6904    (clobber (match_scratch:SWI124 0 "=<r>"))]
6905   "ix86_match_ccmode (insn, CCGCmode)"
6907   switch (get_attr_type (insn))
6908     {
6909     case TYPE_INCDEC:
6910       if (operands[2] == constm1_rtx)
6911         return "inc{<imodesuffix>}\t%0";
6912       else
6913         {
6914           gcc_assert (operands[2] == const1_rtx);
6915           return "dec{<imodesuffix>}\t%0";
6916         }
6918     default:
6919       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6920         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6922       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6923     }
6925   [(set (attr "type")
6926      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6927         (const_string "incdec")
6928         (const_string "alu")))
6929    (set (attr "length_immediate")
6930       (if_then_else
6931         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6932         (const_string "1")
6933         (const_string "*")))
6934    (set_attr "mode" "<MODE>")])
6936 (define_insn "*add<mode>_5"
6937   [(set (reg FLAGS_REG)
6938         (compare
6939           (plus:SWI
6940             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6941             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6942           (const_int 0)))
6943    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6944   "ix86_match_ccmode (insn, CCGOCmode)
6945    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6947   switch (get_attr_type (insn))
6948     {
6949     case TYPE_INCDEC:
6950       if (operands[2] == const1_rtx)
6951         return "inc{<imodesuffix>}\t%0";
6952       else
6953         {
6954           gcc_assert (operands[2] == constm1_rtx);
6955           return "dec{<imodesuffix>}\t%0";
6956         }
6958     default:
6959       if (which_alternative == 1)
6960         std::swap (operands[1], operands[2]);
6962       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6963       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6964         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6966       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6967     }
6969   [(set (attr "type")
6970      (if_then_else (match_operand:SWI 2 "incdec_operand")
6971         (const_string "incdec")
6972         (const_string "alu")))
6973    (set (attr "length_immediate")
6974       (if_then_else
6975         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6976         (const_string "1")
6977         (const_string "*")))
6978    (set_attr "mode" "<MODE>")])
6980 (define_insn "*addqi_ext<mode>_0"
6981   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
6982         (plus:QI
6983           (subreg:QI
6984             (match_operator:SWI248 3 "extract_operator"
6985               [(match_operand 2 "int248_register_operand" "Q")
6986                (const_int 8)
6987                (const_int 8)]) 0)
6988           (match_operand:QI 1 "nonimmediate_operand" "0")))
6989    (clobber (reg:CC FLAGS_REG))]
6990   ""
6991   "add{b}\t{%h2, %0|%0, %h2}"
6992   [(set_attr "addr" "gpr8")
6993    (set_attr "type" "alu")
6994    (set_attr "mode" "QI")])
6996 (define_expand "addqi_ext_1"
6997   [(parallel
6998      [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
6999                             (const_int 8)
7000                             (const_int 8))
7001            (subreg:HI
7002              (plus:QI
7003                (subreg:QI
7004                  (zero_extract:HI (match_operand:HI 1 "register_operand")
7005                                   (const_int 8)
7006                                   (const_int 8)) 0)
7007                (match_operand:QI 2 "const_int_operand")) 0))
7008       (clobber (reg:CC FLAGS_REG))])])
7010 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7011 (define_insn_and_split "*addqi_ext<mode>_1"
7012   [(set (zero_extract:SWI248
7013           (match_operand 0 "int248_register_operand" "+Q,&Q")
7014           (const_int 8)
7015           (const_int 8))
7016         (subreg:SWI248
7017           (plus:QI
7018             (subreg:QI
7019               (match_operator:SWI248 3 "extract_operator"
7020                 [(match_operand 1 "int248_register_operand" "0,!Q")
7021                  (const_int 8)
7022                  (const_int 8)]) 0)
7023             (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
7024    (clobber (reg:CC FLAGS_REG))]
7025   ""
7027   if (which_alternative)
7028     return "#";
7030   switch (get_attr_type (insn))
7031     {
7032     case TYPE_INCDEC:
7033       if (operands[2] == const1_rtx)
7034         return "inc{b}\t%h0";
7035       else
7036         {
7037           gcc_assert (operands[2] == constm1_rtx);
7038           return "dec{b}\t%h0";
7039         }
7041     default:
7042       return "add{b}\t{%2, %h0|%h0, %2}";
7043     }
7045   "reload_completed
7046    && !rtx_equal_p (operands[0], operands[1])"
7047   [(set (zero_extract:SWI248
7048           (match_dup 0) (const_int 8) (const_int 8))
7049         (zero_extract:SWI248
7050           (match_dup 1) (const_int 8) (const_int 8)))
7051    (parallel
7052      [(set (zero_extract:SWI248
7053              (match_dup 0) (const_int 8) (const_int 8))
7054            (subreg:SWI248
7055              (plus:QI
7056                (subreg:QI
7057                  (match_op_dup 3
7058                    [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7059                (match_dup 2)) 0))
7060       (clobber (reg:CC FLAGS_REG))])]
7061   ""
7062   [(set_attr "addr" "gpr8")
7063    (set (attr "type")
7064      (if_then_else (match_operand:QI 2 "incdec_operand")
7065         (const_string "incdec")
7066         (const_string "alu")))
7067    (set_attr "mode" "QI")])
7069 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7070 (define_insn_and_split "*<insn>qi_ext<mode>_2"
7071   [(set (zero_extract:SWI248
7072           (match_operand 0 "int248_register_operand" "+Q,&Q")
7073           (const_int 8)
7074           (const_int 8))
7075         (subreg:SWI248
7076           (plusminus:QI
7077             (subreg:QI
7078               (match_operator:SWI248 3 "extract_operator"
7079                 [(match_operand 1 "int248_register_operand" "<comm>0,!Q")
7080                  (const_int 8)
7081                  (const_int 8)]) 0)
7082             (subreg:QI
7083               (match_operator:SWI248 4 "extract_operator"
7084                 [(match_operand 2 "int248_register_operand" "Q,Q")
7085                  (const_int 8)
7086                  (const_int 8)]) 0)) 0))
7087    (clobber (reg:CC FLAGS_REG))]
7088   ""
7089   "@
7090    <insn>{b}\t{%h2, %h0|%h0, %h2}
7091    #"
7092   "reload_completed
7093    && !(rtx_equal_p (operands[0], operands[1])
7094         || (<CODE> == PLUS && rtx_equal_p (operands[0], operands[2])))"
7095   [(set (zero_extract:SWI248
7096           (match_dup 0) (const_int 8) (const_int 8))
7097         (zero_extract:SWI248
7098           (match_dup 1) (const_int 8) (const_int 8)))
7099    (parallel
7100      [(set (zero_extract:SWI248
7101              (match_dup 0) (const_int 8) (const_int 8))
7102            (subreg:SWI248
7103              (plusminus:QI
7104                (subreg:QI
7105                  (match_op_dup 3
7106                    [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7107                (subreg:QI
7108                  (match_op_dup 4
7109                    [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
7110       (clobber (reg:CC FLAGS_REG))])]
7111   ""
7112   [(set_attr "type" "alu")
7113    (set_attr "mode" "QI")])
7115 ;; Like DWI, but use POImode instead of OImode.
7116 (define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
7118 ;; Add with jump on overflow.
7119 (define_expand "addv<mode>4"
7120   [(parallel [(set (reg:CCO FLAGS_REG)
7121                    (eq:CCO
7122                      (plus:<DPWI>
7123                        (sign_extend:<DPWI>
7124                          (match_operand:SWIDWI 1 "nonimmediate_operand"))
7125                        (match_dup 4))
7126                          (sign_extend:<DPWI>
7127                            (plus:SWIDWI (match_dup 1)
7128                              (match_operand:SWIDWI 2
7129                                "<general_hilo_operand>")))))
7130               (set (match_operand:SWIDWI 0 "register_operand")
7131                    (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7132    (set (pc) (if_then_else
7133                (eq (reg:CCO FLAGS_REG) (const_int 0))
7134                (label_ref (match_operand 3))
7135                (pc)))]
7136   ""
7138   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
7139   if (CONST_SCALAR_INT_P (operands[2]))
7140     operands[4] = operands[2];
7141   else
7142     operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7145 (define_insn "*addv<mode>4"
7146   [(set (reg:CCO FLAGS_REG)
7147         (eq:CCO (plus:<DWI>
7148                    (sign_extend:<DWI>
7149                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7150                    (sign_extend:<DWI>
7151                       (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7152                 (sign_extend:<DWI>
7153                    (plus:SWI (match_dup 1) (match_dup 2)))))
7154    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7155         (plus:SWI (match_dup 1) (match_dup 2)))]
7156   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7157   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7158   [(set_attr "type" "alu")
7159    (set_attr "mode" "<MODE>")])
7161 (define_insn "addv<mode>4_1"
7162   [(set (reg:CCO FLAGS_REG)
7163         (eq:CCO (plus:<DWI>
7164                    (sign_extend:<DWI>
7165                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
7166                    (match_operand:<DWI> 3 "const_int_operand"))
7167                 (sign_extend:<DWI>
7168                    (plus:SWI
7169                      (match_dup 1)
7170                      (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7171    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7172         (plus:SWI (match_dup 1) (match_dup 2)))]
7173   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7174    && CONST_INT_P (operands[2])
7175    && INTVAL (operands[2]) == INTVAL (operands[3])"
7176   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7177   [(set_attr "type" "alu")
7178    (set_attr "mode" "<MODE>")
7179    (set (attr "length_immediate")
7180         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7181                   (const_string "1")
7182                (match_test "<MODE_SIZE> == 8")
7183                   (const_string "4")]
7184               (const_string "<MODE_SIZE>")))])
7186 ;; Quad word integer modes as mode attribute.
7187 (define_mode_attr QPWI [(SI "TI") (DI "POI")])
7189 (define_insn_and_split "*addv<dwi>4_doubleword"
7190   [(set (reg:CCO FLAGS_REG)
7191         (eq:CCO
7192           (plus:<QPWI>
7193             (sign_extend:<QPWI>
7194               (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0"))
7195             (sign_extend:<QPWI>
7196               (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7197           (sign_extend:<QPWI>
7198             (plus:<DWI> (match_dup 1) (match_dup 2)))))
7199    (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7200         (plus:<DWI> (match_dup 1) (match_dup 2)))]
7201   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
7202   "#"
7203   "&& reload_completed"
7204   [(parallel [(set (reg:CCC FLAGS_REG)
7205                    (compare:CCC
7206                      (plus:DWIH (match_dup 1) (match_dup 2))
7207                      (match_dup 1)))
7208               (set (match_dup 0)
7209                    (plus:DWIH (match_dup 1) (match_dup 2)))])
7210    (parallel [(set (reg:CCO FLAGS_REG)
7211                    (eq:CCO
7212                      (plus:<DWI>
7213                        (plus:<DWI>
7214                          (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7215                          (sign_extend:<DWI> (match_dup 4)))
7216                        (sign_extend:<DWI> (match_dup 5)))
7217                      (sign_extend:<DWI>
7218                        (plus:DWIH
7219                          (plus:DWIH
7220                            (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7221                            (match_dup 4))
7222                          (match_dup 5)))))
7223               (set (match_dup 3)
7224                    (plus:DWIH
7225                      (plus:DWIH
7226                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7227                        (match_dup 4))
7228                      (match_dup 5)))])]
7230   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7233 (define_insn_and_split "*addv<dwi>4_doubleword_1"
7234   [(set (reg:CCO FLAGS_REG)
7235         (eq:CCO
7236           (plus:<QPWI>
7237             (sign_extend:<QPWI>
7238               (match_operand:<DWI> 1 "nonimmediate_operand" "%0"))
7239             (match_operand:<QPWI> 3 "const_scalar_int_operand" "n"))
7240           (sign_extend:<QPWI>
7241             (plus:<DWI>
7242               (match_dup 1)
7243               (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7244    (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7245         (plus:<DWI> (match_dup 1) (match_dup 2)))]
7246   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)
7247    && CONST_SCALAR_INT_P (operands[2])
7248    && rtx_equal_p (operands[2], operands[3])"
7249   "#"
7250   "&& reload_completed"
7251   [(parallel [(set (reg:CCC FLAGS_REG)
7252                    (compare:CCC
7253                      (plus:DWIH (match_dup 1) (match_dup 2))
7254                      (match_dup 1)))
7255               (set (match_dup 0)
7256                    (plus:DWIH (match_dup 1) (match_dup 2)))])
7257    (parallel [(set (reg:CCO FLAGS_REG)
7258                    (eq:CCO
7259                      (plus:<DWI>
7260                        (plus:<DWI>
7261                          (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7262                          (sign_extend:<DWI> (match_dup 4)))
7263                        (match_dup 5))
7264                      (sign_extend:<DWI>
7265                        (plus:DWIH
7266                          (plus:DWIH
7267                            (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7268                            (match_dup 4))
7269                          (match_dup 5)))))
7270               (set (match_dup 3)
7271                    (plus:DWIH
7272                      (plus:DWIH
7273                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7274                        (match_dup 4))
7275                      (match_dup 5)))])]
7277   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7278   if (operands[2] == const0_rtx)
7279     {
7280       emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
7281                                     operands[5]));
7282       DONE;
7283     }
7286 (define_insn "*addv<mode>4_overflow_1"
7287   [(set (reg:CCO FLAGS_REG)
7288         (eq:CCO
7289           (plus:<DWI>
7290             (plus:<DWI>
7291               (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7292                 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7293               (sign_extend:<DWI>
7294                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")))
7295             (sign_extend:<DWI>
7296               (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7297           (sign_extend:<DWI>
7298             (plus:SWI
7299               (plus:SWI
7300                 (match_operator:SWI 5 "ix86_carry_flag_operator"
7301                   [(match_dup 3) (const_int 0)])
7302                 (match_dup 1))
7303               (match_dup 2)))))
7304    (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7305         (plus:SWI
7306           (plus:SWI
7307             (match_op_dup 5 [(match_dup 3) (const_int 0)])
7308             (match_dup 1))
7309           (match_dup 2)))]
7310   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7311   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7312   [(set_attr "type" "alu")
7313    (set_attr "mode" "<MODE>")])
7315 (define_insn "*addv<mode>4_overflow_2"
7316   [(set (reg:CCO FLAGS_REG)
7317         (eq:CCO
7318           (plus:<DWI>
7319             (plus:<DWI>
7320               (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7321                 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7322               (sign_extend:<DWI>
7323                 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
7324             (match_operand:<DWI> 6 "const_int_operand" "n"))
7325           (sign_extend:<DWI>
7326             (plus:SWI
7327               (plus:SWI
7328                 (match_operator:SWI 5 "ix86_carry_flag_operator"
7329                   [(match_dup 3) (const_int 0)])
7330                 (match_dup 1))
7331               (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7332    (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7333         (plus:SWI
7334           (plus:SWI
7335             (match_op_dup 5 [(match_dup 3) (const_int 0)])
7336             (match_dup 1))
7337           (match_dup 2)))]
7338   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7339    && CONST_INT_P (operands[2])
7340    && INTVAL (operands[2]) == INTVAL (operands[6])"
7341   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7342   [(set_attr "type" "alu")
7343    (set_attr "mode" "<MODE>")
7344    (set (attr "length_immediate")
7345      (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7346        (const_string "1")
7347        (const_string "4")))])
7349 (define_expand "uaddv<mode>4"
7350   [(parallel [(set (reg:CCC FLAGS_REG)
7351                    (compare:CCC
7352                      (plus:SWIDWI
7353                        (match_operand:SWIDWI 1 "nonimmediate_operand")
7354                        (match_operand:SWIDWI 2 "<general_hilo_operand>"))
7355                      (match_dup 1)))
7356               (set (match_operand:SWIDWI 0 "register_operand")
7357                    (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7358    (set (pc) (if_then_else
7359                (ltu (reg:CCC FLAGS_REG) (const_int 0))
7360                (label_ref (match_operand 3))
7361                (pc)))]
7362   ""
7363   "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
7365 ;; The lea patterns for modes less than 32 bits need to be matched by
7366 ;; several insns converted to real lea by splitters.
7368 (define_insn_and_split "*lea<mode>_general_1"
7369   [(set (match_operand:SWI12 0 "register_operand" "=r")
7370         (plus:SWI12
7371           (plus:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7372                       (match_operand:SWI12 2 "register_operand" "r"))
7373           (match_operand:SWI12 3 "immediate_operand" "i")))]
7374   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7375   "#"
7376   "&& reload_completed"
7377   [(set (match_dup 0)
7378         (plus:SI
7379           (plus:SI (match_dup 1) (match_dup 2))
7380           (match_dup 3)))]
7382   operands[0] = gen_lowpart (SImode, operands[0]);
7383   operands[1] = gen_lowpart (SImode, operands[1]);
7384   operands[2] = gen_lowpart (SImode, operands[2]);
7385   operands[3] = gen_lowpart (SImode, operands[3]);
7387   [(set_attr "type" "lea")
7388    (set_attr "mode" "SI")])
7390 (define_insn_and_split "*lea<mode>_general_2"
7391   [(set (match_operand:SWI12 0 "register_operand" "=r")
7392         (plus:SWI12
7393           (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7394                       (match_operand 2 "const248_operand" "n"))
7395           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7396   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7397   "#"
7398   "&& reload_completed"
7399   [(set (match_dup 0)
7400         (plus:SI
7401           (mult:SI (match_dup 1) (match_dup 2))
7402           (match_dup 3)))]
7404   operands[0] = gen_lowpart (SImode, operands[0]);
7405   operands[1] = gen_lowpart (SImode, operands[1]);
7406   operands[3] = gen_lowpart (SImode, operands[3]);
7408   [(set_attr "type" "lea")
7409    (set_attr "mode" "SI")])
7411 (define_insn_and_split "*lea<mode>_general_2b"
7412   [(set (match_operand:SWI12 0 "register_operand" "=r")
7413         (plus:SWI12
7414           (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7415                         (match_operand 2 "const123_operand" "n"))
7416           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7417   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7418   "#"
7419   "&& reload_completed"
7420   [(set (match_dup 0)
7421         (plus:SI
7422           (ashift:SI (match_dup 1) (match_dup 2))
7423           (match_dup 3)))]
7425   operands[0] = gen_lowpart (SImode, operands[0]);
7426   operands[1] = gen_lowpart (SImode, operands[1]);
7427   operands[3] = gen_lowpart (SImode, operands[3]);
7429   [(set_attr "type" "lea")
7430    (set_attr "mode" "SI")])
7432 (define_insn_and_split "*lea<mode>_general_3"
7433   [(set (match_operand:SWI12 0 "register_operand" "=r")
7434         (plus:SWI12
7435           (plus:SWI12
7436             (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7437                         (match_operand 2 "const248_operand" "n"))
7438             (match_operand:SWI12 3 "register_operand" "r"))
7439           (match_operand:SWI12 4 "immediate_operand" "i")))]
7440   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7441   "#"
7442   "&& reload_completed"
7443   [(set (match_dup 0)
7444         (plus:SI
7445           (plus:SI
7446             (mult:SI (match_dup 1) (match_dup 2))
7447             (match_dup 3))
7448           (match_dup 4)))]
7450   operands[0] = gen_lowpart (SImode, operands[0]);
7451   operands[1] = gen_lowpart (SImode, operands[1]);
7452   operands[3] = gen_lowpart (SImode, operands[3]);
7453   operands[4] = gen_lowpart (SImode, operands[4]);
7455   [(set_attr "type" "lea")
7456    (set_attr "mode" "SI")])
7458 (define_insn_and_split "*lea<mode>_general_3b"
7459   [(set (match_operand:SWI12 0 "register_operand" "=r")
7460         (plus:SWI12
7461           (plus:SWI12
7462             (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7463                           (match_operand 2 "const123_operand" "n"))
7464             (match_operand:SWI12 3 "register_operand" "r"))
7465           (match_operand:SWI12 4 "immediate_operand" "i")))]
7466   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7467   "#"
7468   "&& reload_completed"
7469   [(set (match_dup 0)
7470         (plus:SI
7471           (plus:SI
7472             (ashift:SI (match_dup 1) (match_dup 2))
7473             (match_dup 3))
7474           (match_dup 4)))]
7476   operands[0] = gen_lowpart (SImode, operands[0]);
7477   operands[1] = gen_lowpart (SImode, operands[1]);
7478   operands[3] = gen_lowpart (SImode, operands[3]);
7479   operands[4] = gen_lowpart (SImode, operands[4]);
7481   [(set_attr "type" "lea")
7482    (set_attr "mode" "SI")])
7484 (define_insn_and_split "*lea<mode>_general_4"
7485   [(set (match_operand:SWI12 0 "register_operand" "=r")
7486         (any_or:SWI12
7487           (ashift:SWI12
7488             (match_operand:SWI12 1 "register_no_SP_operand" "l")
7489             (match_operand 2 "const_0_to_3_operand"))
7490           (match_operand 3 "const_int_operand")))]
7491   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7492    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
7493        < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
7494   "#"
7495   "&& reload_completed"
7496   [(set (match_dup 0)
7497         (plus:SI
7498           (mult:SI (match_dup 1) (match_dup 2))
7499           (match_dup 3)))]
7501   operands[0] = gen_lowpart (SImode, operands[0]);
7502   operands[1] = gen_lowpart (SImode, operands[1]);
7503   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
7505   [(set_attr "type" "lea")
7506    (set_attr "mode" "SI")])
7508 (define_insn_and_split "*lea<mode>_general_4"
7509   [(set (match_operand:SWI48 0 "register_operand" "=r")
7510         (any_or:SWI48
7511           (ashift:SWI48
7512             (match_operand:SWI48 1 "register_no_SP_operand" "l")
7513             (match_operand 2 "const_0_to_3_operand"))
7514           (match_operand 3 "const_int_operand")))]
7515   "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
7516    < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
7517   "#"
7518   "&& reload_completed"
7519   [(set (match_dup 0)
7520         (plus:SWI48
7521           (mult:SWI48 (match_dup 1) (match_dup 2))
7522           (match_dup 3)))]
7523   "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
7524   [(set_attr "type" "lea")
7525    (set_attr "mode" "<MODE>")])
7527 ;; Subtract instructions
7529 (define_expand "sub<mode>3"
7530   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
7531         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
7532                      (match_operand:SDWIM 2 "<general_hilo_operand>")))]
7533   ""
7534   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7536 (define_insn_and_split "*sub<dwi>3_doubleword"
7537   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7538         (minus:<DWI>
7539           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7540           (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
7541    (clobber (reg:CC FLAGS_REG))]
7542   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7543   "#"
7544   "&& reload_completed"
7545   [(parallel [(set (reg:CC FLAGS_REG)
7546                    (compare:CC (match_dup 1) (match_dup 2)))
7547               (set (match_dup 0)
7548                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7549    (parallel [(set (match_dup 3)
7550                    (minus:DWIH
7551                      (minus:DWIH
7552                        (match_dup 4)
7553                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7554                      (match_dup 5)))
7555               (clobber (reg:CC FLAGS_REG))])]
7557   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7558   if (operands[2] == const0_rtx)
7559     {
7560       ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
7561       DONE;
7562     }
7565 (define_insn_and_split "*sub<dwi>3_doubleword_zext"
7566   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7567         (minus:<DWI>
7568           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7569           (zero_extend:<DWI>
7570             (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))))
7571    (clobber (reg:CC FLAGS_REG))]
7572   "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
7573   "#"
7574   "&& reload_completed"
7575   [(parallel [(set (reg:CC FLAGS_REG)
7576                    (compare:CC (match_dup 1) (match_dup 2)))
7577               (set (match_dup 0)
7578                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7579    (parallel [(set (match_dup 3)
7580                    (minus:DWIH
7581                      (minus:DWIH
7582                        (match_dup 4)
7583                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7584                      (const_int 0)))
7585               (clobber (reg:CC FLAGS_REG))])]
7586   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
7588 (define_insn "*sub<mode>_1"
7589   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7590         (minus:SWI
7591           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7592           (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7593    (clobber (reg:CC FLAGS_REG))]
7594   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7595   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7596   [(set_attr "type" "alu")
7597    (set_attr "mode" "<MODE>")])
7599 (define_insn "*subsi_1_zext"
7600   [(set (match_operand:DI 0 "register_operand" "=r")
7601         (zero_extend:DI
7602           (minus:SI (match_operand:SI 1 "register_operand" "0")
7603                     (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
7604    (clobber (reg:CC FLAGS_REG))]
7605   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7606   "sub{l}\t{%2, %k0|%k0, %2}"
7607   [(set_attr "type" "alu")
7608    (set_attr "mode" "SI")])
7610 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7611 (define_insn_and_split "*sub<mode>_1_slp"
7612   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
7613         (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
7614                      (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
7615    (clobber (reg:CC FLAGS_REG))]
7616   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7617   "@
7618    sub{<imodesuffix>}\t{%2, %0|%0, %2}
7619    #"
7620   "&& reload_completed
7621    && !(rtx_equal_p (operands[0], operands[1]))"
7622   [(set (strict_low_part (match_dup 0)) (match_dup 1))
7623    (parallel
7624      [(set (strict_low_part (match_dup 0))
7625            (minus:SWI12 (match_dup 0) (match_dup 2)))
7626       (clobber (reg:CC FLAGS_REG))])]
7627   ""
7628   [(set_attr "type" "alu")
7629    (set_attr "mode" "<MODE>")])
7631 (define_insn "*sub<mode>_2"
7632   [(set (reg FLAGS_REG)
7633         (compare
7634           (minus:SWI
7635             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7636             (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
7637           (const_int 0)))
7638    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7639         (minus:SWI (match_dup 1) (match_dup 2)))]
7640   "ix86_match_ccmode (insn, CCGOCmode)
7641    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7642   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7643   [(set_attr "type" "alu")
7644    (set_attr "mode" "<MODE>")])
7646 (define_insn "*subsi_2_zext"
7647   [(set (reg FLAGS_REG)
7648         (compare
7649           (minus:SI (match_operand:SI 1 "register_operand" "0")
7650                     (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
7651           (const_int 0)))
7652    (set (match_operand:DI 0 "register_operand" "=r")
7653         (zero_extend:DI
7654           (minus:SI (match_dup 1)
7655                     (match_dup 2))))]
7656   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7657    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7658   "sub{l}\t{%2, %k0|%k0, %2}"
7659   [(set_attr "type" "alu")
7660    (set_attr "mode" "SI")])
7662 (define_insn "*subqi_ext<mode>_0"
7663   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
7664         (minus:QI
7665           (match_operand:QI 1 "nonimmediate_operand" "0")
7666           (subreg:QI
7667             (match_operator:SWI248 3 "extract_operator"
7668               [(match_operand 2 "int248_register_operand" "Q")
7669                (const_int 8)
7670                (const_int 8)]) 0)))
7671    (clobber (reg:CC FLAGS_REG))]
7672   ""
7673   "sub{b}\t{%h2, %0|%0, %h2}"
7674   [(set_attr "addr" "gpr8")
7675    (set_attr "type" "alu")
7676    (set_attr "mode" "QI")])
7678 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7679 (define_insn_and_split "*subqi_ext<mode>_1"
7680   [(set (zero_extract:SWI248
7681           (match_operand 0 "int248_register_operand" "+Q,&Q")
7682           (const_int 8)
7683           (const_int 8))
7684         (subreg:SWI248
7685           (minus:QI
7686             (subreg:QI
7687               (match_operator:SWI248 3 "extract_operator"
7688                 [(match_operand 1 "int248_register_operand" "0,!Q")
7689                  (const_int 8)
7690                  (const_int 8)]) 0)
7691             (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
7692    (clobber (reg:CC FLAGS_REG))]
7693   ""
7694   "@
7695    sub{b}\t{%2, %h0|%h0, %2}
7696    #"
7697   "reload_completed
7698    && !(rtx_equal_p (operands[0], operands[1]))"
7699   [(set (zero_extract:SWI248
7700           (match_dup 0) (const_int 8) (const_int 8))
7701         (zero_extract:SWI248
7702           (match_dup 1) (const_int 8) (const_int 8)))
7703    (parallel
7704      [(set (zero_extract:SWI248
7705              (match_dup 0) (const_int 8) (const_int 8))
7706            (subreg:SWI248
7707              (minus:QI
7708                (subreg:QI
7709                  (match_op_dup 3
7710                    [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7711                (match_dup 2)) 0))
7712       (clobber (reg:CC FLAGS_REG))])]
7713   ""
7714   [(set_attr "addr" "gpr8")
7715    (set_attr "type" "alu")
7716    (set_attr "mode" "QI")])
7718 ;; Subtract with jump on overflow.
7719 (define_expand "subv<mode>4"
7720   [(parallel [(set (reg:CCO FLAGS_REG)
7721                    (eq:CCO
7722                      (minus:<DPWI>
7723                        (sign_extend:<DPWI>
7724                          (match_operand:SWIDWI 1 "nonimmediate_operand"))
7725                        (match_dup 4))
7726                      (sign_extend:<DPWI>
7727                        (minus:SWIDWI (match_dup 1)
7728                                      (match_operand:SWIDWI 2
7729                                                 "<general_hilo_operand>")))))
7730               (set (match_operand:SWIDWI 0 "register_operand")
7731                    (minus:SWIDWI (match_dup 1) (match_dup 2)))])
7732    (set (pc) (if_then_else
7733                (eq (reg:CCO FLAGS_REG) (const_int 0))
7734                (label_ref (match_operand 3))
7735                (pc)))]
7736   ""
7738   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
7739   if (CONST_SCALAR_INT_P (operands[2]))
7740     operands[4] = operands[2];
7741   else
7742     operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7745 (define_insn "*subv<mode>4"
7746   [(set (reg:CCO FLAGS_REG)
7747         (eq:CCO (minus:<DWI>
7748                    (sign_extend:<DWI>
7749                       (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
7750                    (sign_extend:<DWI>
7751                       (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7752                 (sign_extend:<DWI>
7753                    (minus:SWI (match_dup 1) (match_dup 2)))))
7754    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7755         (minus:SWI (match_dup 1) (match_dup 2)))]
7756   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7757   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7758   [(set_attr "type" "alu")
7759    (set_attr "mode" "<MODE>")])
7761 (define_insn "subv<mode>4_1"
7762   [(set (reg:CCO FLAGS_REG)
7763         (eq:CCO (minus:<DWI>
7764                    (sign_extend:<DWI>
7765                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
7766                    (match_operand:<DWI> 3 "const_int_operand"))
7767                 (sign_extend:<DWI>
7768                    (minus:SWI
7769                      (match_dup 1)
7770                      (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7771    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7772         (minus:SWI (match_dup 1) (match_dup 2)))]
7773   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7774    && CONST_INT_P (operands[2])
7775    && INTVAL (operands[2]) == INTVAL (operands[3])"
7776   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7777   [(set_attr "type" "alu")
7778    (set_attr "mode" "<MODE>")
7779    (set (attr "length_immediate")
7780         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7781                   (const_string "1")
7782                (match_test "<MODE_SIZE> == 8")
7783                   (const_string "4")]
7784               (const_string "<MODE_SIZE>")))])
7786 (define_insn_and_split "*subv<dwi>4_doubleword"
7787   [(set (reg:CCO FLAGS_REG)
7788         (eq:CCO
7789           (minus:<QPWI>
7790             (sign_extend:<QPWI>
7791               (match_operand:<DWI> 1 "nonimmediate_operand" "0,0"))
7792             (sign_extend:<QPWI>
7793               (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7794           (sign_extend:<QPWI>
7795             (minus:<DWI> (match_dup 1) (match_dup 2)))))
7796    (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7797         (minus:<DWI> (match_dup 1) (match_dup 2)))]
7798   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7799   "#"
7800   "&& reload_completed"
7801   [(parallel [(set (reg:CC FLAGS_REG)
7802                    (compare:CC (match_dup 1) (match_dup 2)))
7803               (set (match_dup 0)
7804                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7805    (parallel [(set (reg:CCO FLAGS_REG)
7806                    (eq:CCO
7807                      (minus:<DWI>
7808                        (minus:<DWI>
7809                          (sign_extend:<DWI> (match_dup 4))
7810                          (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7811                        (sign_extend:<DWI> (match_dup 5)))
7812                      (sign_extend:<DWI>
7813                        (minus:DWIH
7814                          (minus:DWIH
7815                            (match_dup 4)
7816                            (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7817                          (match_dup 5)))))
7818               (set (match_dup 3)
7819                    (minus:DWIH
7820                      (minus:DWIH
7821                        (match_dup 4)
7822                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7823                      (match_dup 5)))])]
7825   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7828 (define_insn_and_split "*subv<dwi>4_doubleword_1"
7829   [(set (reg:CCO FLAGS_REG)
7830         (eq:CCO
7831           (minus:<QPWI>
7832             (sign_extend:<QPWI>
7833               (match_operand:<DWI> 1 "nonimmediate_operand" "0"))
7834             (match_operand:<QPWI> 3 "const_scalar_int_operand"))
7835           (sign_extend:<QPWI>
7836             (minus:<DWI>
7837               (match_dup 1)
7838               (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7839    (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7840         (minus:<DWI> (match_dup 1) (match_dup 2)))]
7841   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7842    && CONST_SCALAR_INT_P (operands[2])
7843    && rtx_equal_p (operands[2], operands[3])"
7844   "#"
7845   "&& reload_completed"
7846   [(parallel [(set (reg:CC FLAGS_REG)
7847                    (compare:CC (match_dup 1) (match_dup 2)))
7848               (set (match_dup 0)
7849                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7850    (parallel [(set (reg:CCO FLAGS_REG)
7851                    (eq:CCO
7852                      (minus:<DWI>
7853                        (minus:<DWI>
7854                          (sign_extend:<DWI> (match_dup 4))
7855                          (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7856                        (match_dup 5))
7857                      (sign_extend:<DWI>
7858                        (minus:DWIH
7859                          (minus:DWIH
7860                            (match_dup 4)
7861                            (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7862                          (match_dup 5)))))
7863               (set (match_dup 3)
7864                    (minus:DWIH
7865                      (minus:DWIH
7866                        (match_dup 4)
7867                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7868                      (match_dup 5)))])]
7870   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7871   if (operands[2] == const0_rtx)
7872     {
7873       emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
7874                                     operands[5]));
7875       DONE;
7876     }
7879 (define_insn "*subv<mode>4_overflow_1"
7880   [(set (reg:CCO FLAGS_REG)
7881         (eq:CCO
7882           (minus:<DWI>
7883             (minus:<DWI>
7884               (sign_extend:<DWI>
7885                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7886               (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7887                 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7888             (sign_extend:<DWI>
7889               (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7890           (sign_extend:<DWI>
7891             (minus:SWI
7892               (minus:SWI
7893                 (match_dup 1)
7894                 (match_operator:SWI 5 "ix86_carry_flag_operator"
7895                   [(match_dup 3) (const_int 0)]))
7896               (match_dup 2)))))
7897    (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7898         (minus:SWI
7899           (minus:SWI
7900             (match_dup 1)
7901             (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7902           (match_dup 2)))]
7903   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7904   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7905   [(set_attr "type" "alu")
7906    (set_attr "mode" "<MODE>")])
7908 (define_insn "*subv<mode>4_overflow_2"
7909   [(set (reg:CCO FLAGS_REG)
7910         (eq:CCO
7911           (minus:<DWI>
7912             (minus:<DWI>
7913               (sign_extend:<DWI>
7914                 (match_operand:SWI 1 "nonimmediate_operand" "%0"))
7915               (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7916                 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7917             (match_operand:<DWI> 6 "const_int_operand" "n"))
7918           (sign_extend:<DWI>
7919             (minus:SWI
7920               (minus:SWI
7921                 (match_dup 1)
7922                 (match_operator:SWI 5 "ix86_carry_flag_operator"
7923                   [(match_dup 3) (const_int 0)]))
7924               (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7925    (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7926         (minus:SWI
7927           (minus:SWI
7928             (match_dup 1)
7929             (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7930           (match_dup 2)))]
7931   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7932    && CONST_INT_P (operands[2])
7933    && INTVAL (operands[2]) == INTVAL (operands[6])"
7934   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7935   [(set_attr "type" "alu")
7936    (set_attr "mode" "<MODE>")
7937    (set (attr "length_immediate")
7938      (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7939        (const_string "1")
7940        (const_string "4")))])
7942 (define_expand "usubv<mode>4"
7943   [(parallel [(set (reg:CC FLAGS_REG)
7944                    (compare:CC
7945                      (match_operand:SWI 1 "nonimmediate_operand")
7946                      (match_operand:SWI 2 "<general_operand>")))
7947               (set (match_operand:SWI 0 "register_operand")
7948                    (minus:SWI (match_dup 1) (match_dup 2)))])
7949    (set (pc) (if_then_else
7950                (ltu (reg:CC FLAGS_REG) (const_int 0))
7951                (label_ref (match_operand 3))
7952                (pc)))]
7953   ""
7954   "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
7956 (define_insn "*sub<mode>_3"
7957   [(set (reg FLAGS_REG)
7958         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7959                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7960    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7961         (minus:SWI (match_dup 1) (match_dup 2)))]
7962   "ix86_match_ccmode (insn, CCmode)
7963    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7964   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7965   [(set_attr "type" "alu")
7966    (set_attr "mode" "<MODE>")])
7968 (define_peephole2
7969   [(parallel
7970      [(set (reg:CC FLAGS_REG)
7971            (compare:CC (match_operand:SWI 0 "general_reg_operand")
7972                        (match_operand:SWI 1 "general_gr_operand")))
7973       (set (match_dup 0)
7974            (minus:SWI (match_dup 0) (match_dup 1)))])]
7975   "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
7976   [(set (reg:CC FLAGS_REG)
7977         (compare:CC (match_dup 0) (match_dup 1)))])
7979 (define_peephole2
7980   [(set (match_operand:SWI 0 "general_reg_operand")
7981         (match_operand:SWI 1 "memory_operand"))
7982    (parallel [(set (reg:CC FLAGS_REG)
7983                    (compare:CC (match_dup 0)
7984                                (match_operand:SWI 2 "memory_operand")))
7985               (set (match_dup 0)
7986                    (minus:SWI (match_dup 0) (match_dup 2)))])
7987    (set (match_dup 1) (match_dup 0))]
7988   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
7989    && peep2_reg_dead_p (3, operands[0])
7990    && !reg_overlap_mentioned_p (operands[0], operands[1])
7991    && !reg_overlap_mentioned_p (operands[0], operands[2])"
7992   [(set (match_dup 0) (match_dup 2))
7993    (parallel [(set (reg:CC FLAGS_REG)
7994                    (compare:CC (match_dup 1) (match_dup 0)))
7995               (set (match_dup 1)
7996                    (minus:SWI (match_dup 1) (match_dup 0)))])])
7998 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
7999 ;; subl $1, %eax; jnc .Lxx;
8000 (define_peephole2
8001   [(parallel
8002      [(set (match_operand:SWI 0 "general_reg_operand")
8003            (plus:SWI (match_dup 0) (const_int -1)))
8004       (clobber (reg FLAGS_REG))])
8005    (set (reg:CCZ FLAGS_REG)
8006         (compare:CCZ (match_dup 0) (const_int -1)))
8007    (set (pc)
8008         (if_then_else (match_operator 1 "bt_comparison_operator"
8009                         [(reg:CCZ FLAGS_REG) (const_int 0)])
8010                       (match_operand 2)
8011                       (pc)))]
8012    "peep2_regno_dead_p (3, FLAGS_REG)"
8013    [(parallel
8014       [(set (reg:CC FLAGS_REG)
8015             (compare:CC (match_dup 0) (const_int 1)))
8016        (set (match_dup 0)
8017             (minus:SWI (match_dup 0) (const_int 1)))])
8018     (set (pc)
8019          (if_then_else (match_dup 3)
8020                        (match_dup 2)
8021                        (pc)))]
8023   rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
8024   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
8025                                 ? GEU : LTU, VOIDmode, cc, const0_rtx);
8028 ;; Help combine use borrow flag to test for -1 after dec (add $-1).
8029 (define_insn_and_split "*dec_cmov<mode>"
8030   [(set (match_operand:SWI248 0 "register_operand" "=r")
8031         (if_then_else:SWI248
8032          (match_operator 1 "bt_comparison_operator"
8033           [(match_operand:SWI248 2 "register_operand" "0") (const_int 0)])
8034          (plus:SWI248 (match_dup 2) (const_int -1))
8035          (match_operand:SWI248 3 "nonimmediate_operand" "rm")))
8036    (clobber (reg:CC FLAGS_REG))]
8037   "TARGET_CMOVE"
8038   "#"
8039   "&& reload_completed"
8040   [(parallel [(set (reg:CC FLAGS_REG)
8041                    (compare:CC (match_dup 2) (const_int 1)))
8042               (set (match_dup 0) (minus:SWI248 (match_dup 2) (const_int 1)))])
8043    (set (match_dup 0)
8044         (if_then_else:SWI248 (match_dup 4) (match_dup 0) (match_dup 3)))]
8046   rtx cc = gen_rtx_REG (CCCmode, FLAGS_REG);
8047   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
8048                                 ? GEU : LTU, VOIDmode, cc, const0_rtx);
8051 (define_insn "*subsi_3_zext"
8052   [(set (reg FLAGS_REG)
8053         (compare (match_operand:SI 1 "register_operand" "0")
8054                  (match_operand:SI 2 "x86_64_general_operand" "rBMe")))
8055    (set (match_operand:DI 0 "register_operand" "=r")
8056         (zero_extend:DI
8057           (minus:SI (match_dup 1)
8058                     (match_dup 2))))]
8059   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
8060    && ix86_binary_operator_ok (MINUS, SImode, operands)"
8061   "sub{l}\t{%2, %1|%1, %2}"
8062   [(set_attr "type" "alu")
8063    (set_attr "mode" "SI")])
8065 ;; Add with carry and subtract with borrow
8067 (define_insn "@add<mode>3_carry"
8068   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8069         (plus:SWI
8070           (plus:SWI
8071             (match_operator:SWI 4 "ix86_carry_flag_operator"
8072              [(match_operand 3 "flags_reg_operand") (const_int 0)])
8073             (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
8074           (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8075    (clobber (reg:CC FLAGS_REG))]
8076   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8077   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8078   [(set_attr "type" "alu")
8079    (set_attr "use_carry" "1")
8080    (set_attr "pent_pair" "pu")
8081    (set_attr "mode" "<MODE>")])
8083 (define_peephole2
8084   [(set (match_operand:SWI 0 "general_reg_operand")
8085         (match_operand:SWI 1 "memory_operand"))
8086    (parallel [(set (match_dup 0)
8087                    (plus:SWI
8088                      (plus:SWI
8089                        (match_operator:SWI 4 "ix86_carry_flag_operator"
8090                          [(match_operand 3 "flags_reg_operand")
8091                           (const_int 0)])
8092                        (match_dup 0))
8093                      (match_operand:SWI 2 "memory_operand")))
8094               (clobber (reg:CC FLAGS_REG))])
8095    (set (match_dup 1) (match_dup 0))]
8096   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8097    && peep2_reg_dead_p (3, operands[0])
8098    && !reg_overlap_mentioned_p (operands[0], operands[1])
8099    && !reg_overlap_mentioned_p (operands[0], operands[2])"
8100   [(set (match_dup 0) (match_dup 2))
8101    (parallel [(set (match_dup 1)
8102                    (plus:SWI (plus:SWI (match_op_dup 4
8103                                          [(match_dup 3) (const_int 0)])
8104                                        (match_dup 1))
8105                              (match_dup 0)))
8106               (clobber (reg:CC FLAGS_REG))])])
8108 (define_peephole2
8109   [(set (match_operand:SWI 0 "general_reg_operand")
8110         (match_operand:SWI 1 "memory_operand"))
8111    (parallel [(set (match_dup 0)
8112                    (plus:SWI
8113                      (plus:SWI
8114                        (match_operator:SWI 4 "ix86_carry_flag_operator"
8115                          [(match_operand 3 "flags_reg_operand")
8116                           (const_int 0)])
8117                        (match_dup 0))
8118                      (match_operand:SWI 2 "memory_operand")))
8119               (clobber (reg:CC FLAGS_REG))])
8120    (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8121    (set (match_dup 1) (match_dup 5))]
8122   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8123    && peep2_reg_dead_p (3, operands[0])
8124    && peep2_reg_dead_p (4, operands[5])
8125    && !reg_overlap_mentioned_p (operands[0], operands[1])
8126    && !reg_overlap_mentioned_p (operands[0], operands[2])
8127    && !reg_overlap_mentioned_p (operands[5], operands[1])"
8128   [(set (match_dup 0) (match_dup 2))
8129    (parallel [(set (match_dup 1)
8130                    (plus:SWI (plus:SWI (match_op_dup 4
8131                                          [(match_dup 3) (const_int 0)])
8132                                        (match_dup 1))
8133                              (match_dup 0)))
8134               (clobber (reg:CC FLAGS_REG))])])
8136 (define_insn "*add<mode>3_carry_0"
8137   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8138         (plus:SWI
8139           (match_operator:SWI 2 "ix86_carry_flag_operator"
8140             [(reg FLAGS_REG) (const_int 0)])
8141           (match_operand:SWI 1 "nonimmediate_operand" "0")))
8142    (clobber (reg:CC FLAGS_REG))]
8143   "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8144   "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
8145   [(set_attr "type" "alu")
8146    (set_attr "use_carry" "1")
8147    (set_attr "pent_pair" "pu")
8148    (set_attr "mode" "<MODE>")])
8150 (define_insn "*add<mode>3_carry_0r"
8151   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8152         (plus:SWI
8153           (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8154             [(reg FLAGS_REG) (const_int 0)])
8155           (match_operand:SWI 1 "nonimmediate_operand" "0")))
8156    (clobber (reg:CC FLAGS_REG))]
8157   "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8158   "sbb{<imodesuffix>}\t{$-1, %0|%0, -1}"
8159   [(set_attr "type" "alu")
8160    (set_attr "use_carry" "1")
8161    (set_attr "pent_pair" "pu")
8162    (set_attr "mode" "<MODE>")])
8164 (define_insn "*addsi3_carry_zext"
8165   [(set (match_operand:DI 0 "register_operand" "=r")
8166         (zero_extend:DI
8167           (plus:SI
8168             (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
8169                       [(reg FLAGS_REG) (const_int 0)])
8170                      (match_operand:SI 1 "register_operand" "%0"))
8171             (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8172    (clobber (reg:CC FLAGS_REG))]
8173   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8174   "adc{l}\t{%2, %k0|%k0, %2}"
8175   [(set_attr "type" "alu")
8176    (set_attr "use_carry" "1")
8177    (set_attr "pent_pair" "pu")
8178    (set_attr "mode" "SI")])
8180 (define_insn "*addsi3_carry_zext_0"
8181   [(set (match_operand:DI 0 "register_operand" "=r")
8182         (zero_extend:DI
8183           (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
8184                     [(reg FLAGS_REG) (const_int 0)])
8185                    (match_operand:SI 1 "register_operand" "0"))))
8186    (clobber (reg:CC FLAGS_REG))]
8187   "TARGET_64BIT"
8188   "adc{l}\t{$0, %k0|%k0, 0}"
8189   [(set_attr "type" "alu")
8190    (set_attr "use_carry" "1")
8191    (set_attr "pent_pair" "pu")
8192    (set_attr "mode" "SI")])
8194 (define_insn "*addsi3_carry_zext_0r"
8195   [(set (match_operand:DI 0 "register_operand" "=r")
8196         (zero_extend:DI
8197           (plus:SI (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8198                     [(reg FLAGS_REG) (const_int 0)])
8199                    (match_operand:SI 1 "register_operand" "0"))))
8200    (clobber (reg:CC FLAGS_REG))]
8201   "TARGET_64BIT"
8202   "sbb{l}\t{$-1, %k0|%k0, -1}"
8203   [(set_attr "type" "alu")
8204    (set_attr "use_carry" "1")
8205    (set_attr "pent_pair" "pu")
8206    (set_attr "mode" "SI")])
8208 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
8210 (define_insn "addcarry<mode>"
8211   [(set (reg:CCC FLAGS_REG)
8212         (compare:CCC
8213           (zero_extend:<DWI>
8214             (plus:SWI48
8215               (plus:SWI48
8216                 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8217                   [(match_operand 3 "flags_reg_operand") (const_int 0)])
8218                 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0"))
8219               (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))
8220           (plus:<DWI>
8221             (zero_extend:<DWI> (match_dup 2))
8222             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8223               [(match_dup 3) (const_int 0)]))))
8224    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8225         (plus:SWI48 (plus:SWI48 (match_op_dup 5
8226                                  [(match_dup 3) (const_int 0)])
8227                                 (match_dup 1))
8228                     (match_dup 2)))]
8229   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8230   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8231   [(set_attr "type" "alu")
8232    (set_attr "use_carry" "1")
8233    (set_attr "pent_pair" "pu")
8234    (set_attr "mode" "<MODE>")])
8236 (define_peephole2
8237   [(parallel [(set (reg:CCC FLAGS_REG)
8238                    (compare:CCC
8239                      (zero_extend:<DWI>
8240                        (plus:SWI48
8241                          (plus:SWI48
8242                            (match_operator:SWI48 4 "ix86_carry_flag_operator"
8243                              [(match_operand 2 "flags_reg_operand")
8244                               (const_int 0)])
8245                            (match_operand:SWI48 0 "general_reg_operand"))
8246                          (match_operand:SWI48 1 "memory_operand")))
8247                      (plus:<DWI>
8248                        (zero_extend:<DWI> (match_dup 1))
8249                        (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8250                          [(match_dup 2) (const_int 0)]))))
8251               (set (match_dup 0)
8252                    (plus:SWI48 (plus:SWI48 (match_op_dup 4
8253                                              [(match_dup 2) (const_int 0)])
8254                                            (match_dup 0))
8255                                (match_dup 1)))])
8256    (set (match_dup 1) (match_dup 0))]
8257   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8258    && peep2_reg_dead_p (2, operands[0])
8259    && !reg_overlap_mentioned_p (operands[0], operands[1])"
8260   [(parallel [(set (reg:CCC FLAGS_REG)
8261                    (compare:CCC
8262                      (zero_extend:<DWI>
8263                        (plus:SWI48
8264                          (plus:SWI48
8265                            (match_op_dup 4
8266                              [(match_dup 2) (const_int 0)])
8267                            (match_dup 1))
8268                          (match_dup 0)))
8269                      (plus:<DWI>
8270                        (zero_extend:<DWI> (match_dup 0))
8271                        (match_op_dup 3
8272                          [(match_dup 2) (const_int 0)]))))
8273               (set (match_dup 1)
8274                    (plus:SWI48 (plus:SWI48 (match_op_dup 4
8275                                              [(match_dup 2) (const_int 0)])
8276                                            (match_dup 1))
8277                                (match_dup 0)))])])
8279 (define_peephole2
8280   [(set (match_operand:SWI48 0 "general_reg_operand")
8281         (match_operand:SWI48 1 "memory_operand"))
8282    (parallel [(set (reg:CCC FLAGS_REG)
8283                    (compare:CCC
8284                      (zero_extend:<DWI>
8285                        (plus:SWI48
8286                          (plus:SWI48
8287                            (match_operator:SWI48 5 "ix86_carry_flag_operator"
8288                              [(match_operand 3 "flags_reg_operand")
8289                               (const_int 0)])
8290                            (match_dup 0))
8291                          (match_operand:SWI48 2 "memory_operand")))
8292                      (plus:<DWI>
8293                        (zero_extend:<DWI> (match_dup 2))
8294                        (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8295                          [(match_dup 3) (const_int 0)]))))
8296               (set (match_dup 0)
8297                    (plus:SWI48 (plus:SWI48 (match_op_dup 5
8298                                              [(match_dup 3) (const_int 0)])
8299                                            (match_dup 0))
8300                                (match_dup 2)))])
8301    (set (match_dup 1) (match_dup 0))]
8302   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8303    && peep2_reg_dead_p (3, operands[0])
8304    && !reg_overlap_mentioned_p (operands[0], operands[1])
8305    && !reg_overlap_mentioned_p (operands[0], operands[2])"
8306   [(set (match_dup 0) (match_dup 2))
8307    (parallel [(set (reg:CCC FLAGS_REG)
8308                    (compare:CCC
8309                      (zero_extend:<DWI>
8310                        (plus:SWI48
8311                          (plus:SWI48
8312                            (match_op_dup 5
8313                              [(match_dup 3) (const_int 0)])
8314                            (match_dup 1))
8315                          (match_dup 0)))
8316                      (plus:<DWI>
8317                        (zero_extend:<DWI> (match_dup 0))
8318                        (match_op_dup 4
8319                          [(match_dup 3) (const_int 0)]))))
8320               (set (match_dup 1)
8321                    (plus:SWI48 (plus:SWI48 (match_op_dup 5
8322                                              [(match_dup 3) (const_int 0)])
8323                                            (match_dup 1))
8324                                (match_dup 0)))])])
8326 (define_peephole2
8327   [(parallel [(set (reg:CCC FLAGS_REG)
8328                    (compare:CCC
8329                      (zero_extend:<DWI>
8330                        (plus:SWI48
8331                          (plus:SWI48
8332                            (match_operator:SWI48 4 "ix86_carry_flag_operator"
8333                              [(match_operand 2 "flags_reg_operand")
8334                               (const_int 0)])
8335                            (match_operand:SWI48 0 "general_reg_operand"))
8336                          (match_operand:SWI48 1 "memory_operand")))
8337                      (plus:<DWI>
8338                        (zero_extend:<DWI> (match_dup 1))
8339                        (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8340                          [(match_dup 2) (const_int 0)]))))
8341               (set (match_dup 0)
8342                    (plus:SWI48 (plus:SWI48 (match_op_dup 4
8343                                              [(match_dup 2) (const_int 0)])
8344                                            (match_dup 0))
8345                                (match_dup 1)))])
8346    (set (match_operand:QI 5 "general_reg_operand")
8347         (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8348    (set (match_operand:SWI48 6 "general_reg_operand")
8349         (zero_extend:SWI48 (match_dup 5)))
8350    (set (match_dup 1) (match_dup 0))]
8351   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8352    && peep2_reg_dead_p (4, operands[0])
8353    && !reg_overlap_mentioned_p (operands[0], operands[1])
8354    && !reg_overlap_mentioned_p (operands[0], operands[5])
8355    && !reg_overlap_mentioned_p (operands[5], operands[1])
8356    && !reg_overlap_mentioned_p (operands[0], operands[6])
8357    && !reg_overlap_mentioned_p (operands[6], operands[1])"
8358   [(parallel [(set (reg:CCC FLAGS_REG)
8359                    (compare:CCC
8360                      (zero_extend:<DWI>
8361                        (plus:SWI48
8362                          (plus:SWI48
8363                            (match_op_dup 4
8364                              [(match_dup 2) (const_int 0)])
8365                            (match_dup 1))
8366                          (match_dup 0)))
8367                      (plus:<DWI>
8368                        (zero_extend:<DWI> (match_dup 0))
8369                        (match_op_dup 3
8370                          [(match_dup 2) (const_int 0)]))))
8371               (set (match_dup 1)
8372                    (plus:SWI48 (plus:SWI48 (match_op_dup 4
8373                                              [(match_dup 2) (const_int 0)])
8374                                            (match_dup 1))
8375                                (match_dup 0)))])
8376    (set (match_dup 5) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8377    (set (match_dup 6) (zero_extend:SWI48 (match_dup 5)))])
8379 (define_expand "addcarry<mode>_0"
8380   [(parallel
8381      [(set (reg:CCC FLAGS_REG)
8382            (compare:CCC
8383              (plus:SWI48
8384                (match_operand:SWI48 1 "nonimmediate_operand")
8385                (match_operand:SWI48 2 "x86_64_general_operand"))
8386              (match_dup 1)))
8387       (set (match_operand:SWI48 0 "nonimmediate_operand")
8388            (plus:SWI48 (match_dup 1) (match_dup 2)))])]
8389   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
8391 (define_insn "*addcarry<mode>_1"
8392   [(set (reg:CCC FLAGS_REG)
8393         (compare:CCC
8394           (zero_extend:<DWI>
8395             (plus:SWI48
8396               (plus:SWI48
8397                 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8398                   [(match_operand 3 "flags_reg_operand") (const_int 0)])
8399                 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
8400               (match_operand:SWI48 2 "x86_64_immediate_operand" "e")))
8401           (plus:<DWI>
8402             (match_operand:<DWI> 6 "const_scalar_int_operand")
8403             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8404               [(match_dup 3) (const_int 0)]))))
8405    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8406         (plus:SWI48 (plus:SWI48 (match_op_dup 5
8407                                  [(match_dup 3) (const_int 0)])
8408                                 (match_dup 1))
8409                     (match_dup 2)))]
8410   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
8411    && CONST_INT_P (operands[2])
8412    /* Check that operands[6] is operands[2] zero extended from
8413       <MODE>mode to <DWI>mode.  */
8414    && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0)
8415        ? (CONST_INT_P (operands[6])
8416           && UINTVAL (operands[6]) == (UINTVAL (operands[2])
8417                                        & GET_MODE_MASK (<MODE>mode)))
8418        : (CONST_WIDE_INT_P (operands[6])
8419           && CONST_WIDE_INT_NUNITS (operands[6]) == 2
8420           && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
8421               == UINTVAL (operands[2]))
8422           && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
8423   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8424   [(set_attr "type" "alu")
8425    (set_attr "use_carry" "1")
8426    (set_attr "pent_pair" "pu")
8427    (set_attr "mode" "<MODE>")
8428    (set (attr "length_immediate")
8429      (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8430        (const_string "1")
8431        (const_string "4")))])
8433 (define_insn "@sub<mode>3_carry"
8434   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8435         (minus:SWI
8436           (minus:SWI
8437             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
8438             (match_operator:SWI 4 "ix86_carry_flag_operator"
8439              [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8440           (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8441    (clobber (reg:CC FLAGS_REG))]
8442   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8443   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8444   [(set_attr "type" "alu")
8445    (set_attr "use_carry" "1")
8446    (set_attr "pent_pair" "pu")
8447    (set_attr "mode" "<MODE>")])
8449 (define_peephole2
8450   [(set (match_operand:SWI 0 "general_reg_operand")
8451         (match_operand:SWI 1 "memory_operand"))
8452    (parallel [(set (match_dup 0)
8453                    (minus:SWI
8454                      (minus:SWI
8455                        (match_dup 0)
8456                        (match_operator:SWI 4 "ix86_carry_flag_operator"
8457                          [(match_operand 3 "flags_reg_operand")
8458                           (const_int 0)]))
8459                      (match_operand:SWI 2 "memory_operand")))
8460               (clobber (reg:CC FLAGS_REG))])
8461    (set (match_dup 1) (match_dup 0))]
8462   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8463    && peep2_reg_dead_p (3, operands[0])
8464    && !reg_overlap_mentioned_p (operands[0], operands[1])
8465    && !reg_overlap_mentioned_p (operands[0], operands[2])"
8466   [(set (match_dup 0) (match_dup 2))
8467    (parallel [(set (match_dup 1)
8468                    (minus:SWI (minus:SWI (match_dup 1)
8469                                          (match_op_dup 4
8470                                            [(match_dup 3) (const_int 0)]))
8471                               (match_dup 0)))
8472               (clobber (reg:CC FLAGS_REG))])])
8474 (define_peephole2
8475   [(set (match_operand:SWI 0 "general_reg_operand")
8476         (match_operand:SWI 1 "memory_operand"))
8477    (parallel [(set (match_dup 0)
8478                    (minus:SWI
8479                      (minus:SWI
8480                        (match_dup 0)
8481                        (match_operator:SWI 4 "ix86_carry_flag_operator"
8482                          [(match_operand 3 "flags_reg_operand")
8483                           (const_int 0)]))
8484                      (match_operand:SWI 2 "memory_operand")))
8485               (clobber (reg:CC FLAGS_REG))])
8486    (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8487    (set (match_dup 1) (match_dup 5))]
8488   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8489    && peep2_reg_dead_p (3, operands[0])
8490    && peep2_reg_dead_p (4, operands[5])
8491    && !reg_overlap_mentioned_p (operands[0], operands[1])
8492    && !reg_overlap_mentioned_p (operands[0], operands[2])
8493    && !reg_overlap_mentioned_p (operands[5], operands[1])"
8494   [(set (match_dup 0) (match_dup 2))
8495    (parallel [(set (match_dup 1)
8496                    (minus:SWI (minus:SWI (match_dup 1)
8497                                          (match_op_dup 4
8498                                            [(match_dup 3) (const_int 0)]))
8499                               (match_dup 0)))
8500               (clobber (reg:CC FLAGS_REG))])])
8502 (define_insn "*sub<mode>3_carry_0"
8503   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8504         (minus:SWI
8505           (match_operand:SWI 1 "nonimmediate_operand" "0")
8506           (match_operator:SWI 2 "ix86_carry_flag_operator"
8507             [(reg FLAGS_REG) (const_int 0)])))
8508    (clobber (reg:CC FLAGS_REG))]
8509   "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8510   "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
8511   [(set_attr "type" "alu")
8512    (set_attr "use_carry" "1")
8513    (set_attr "pent_pair" "pu")
8514    (set_attr "mode" "<MODE>")])
8516 (define_insn "*sub<mode>3_carry_0r"
8517   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8518         (minus:SWI
8519           (match_operand:SWI 1 "nonimmediate_operand" "0")
8520           (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8521             [(reg FLAGS_REG) (const_int 0)])))
8522    (clobber (reg:CC FLAGS_REG))]
8523   "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8524   "adc{<imodesuffix>}\t{$-1, %0|%0, -1}"
8525   [(set_attr "type" "alu")
8526    (set_attr "use_carry" "1")
8527    (set_attr "pent_pair" "pu")
8528    (set_attr "mode" "<MODE>")])
8530 (define_insn "*subsi3_carry_zext"
8531   [(set (match_operand:DI 0 "register_operand" "=r")
8532         (zero_extend:DI
8533           (minus:SI
8534             (minus:SI
8535               (match_operand:SI 1 "register_operand" "0")
8536               (match_operator:SI 3 "ix86_carry_flag_operator"
8537                [(reg FLAGS_REG) (const_int 0)]))
8538             (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8539    (clobber (reg:CC FLAGS_REG))]
8540   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8541   "sbb{l}\t{%2, %k0|%k0, %2}"
8542   [(set_attr "type" "alu")
8543    (set_attr "use_carry" "1")
8544    (set_attr "pent_pair" "pu")
8545    (set_attr "mode" "SI")])
8547 (define_insn "*subsi3_carry_zext_0"
8548   [(set (match_operand:DI 0 "register_operand" "=r")
8549         (zero_extend:DI
8550           (minus:SI
8551             (match_operand:SI 1 "register_operand" "0")
8552             (match_operator:SI 2 "ix86_carry_flag_operator"
8553               [(reg FLAGS_REG) (const_int 0)]))))
8554    (clobber (reg:CC FLAGS_REG))]
8555   "TARGET_64BIT"
8556   "sbb{l}\t{$0, %k0|%k0, 0}"
8557   [(set_attr "type" "alu")
8558    (set_attr "use_carry" "1")
8559    (set_attr "pent_pair" "pu")
8560    (set_attr "mode" "SI")])
8562 (define_insn "*subsi3_carry_zext_0r"
8563   [(set (match_operand:DI 0 "register_operand" "=r")
8564         (zero_extend:DI
8565           (minus:SI
8566             (match_operand:SI 1 "register_operand" "0")
8567             (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8568               [(reg FLAGS_REG) (const_int 0)]))))
8569    (clobber (reg:CC FLAGS_REG))]
8570   "TARGET_64BIT"
8571   "adc{l}\t{$-1, %k0|%k0, -1}"
8572   [(set_attr "type" "alu")
8573    (set_attr "use_carry" "1")
8574    (set_attr "pent_pair" "pu")
8575    (set_attr "mode" "SI")])
8577 (define_insn "@sub<mode>3_carry_ccc"
8578   [(set (reg:CCC FLAGS_REG)
8579         (compare:CCC
8580           (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8581           (plus:<DWI>
8582             (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8583             (zero_extend:<DWI>
8584               (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
8585    (clobber (match_scratch:DWIH 0 "=r"))]
8586   ""
8587   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8588   [(set_attr "type" "alu")
8589    (set_attr "mode" "<MODE>")])
8591 (define_insn "*sub<mode>3_carry_ccc_1"
8592   [(set (reg:CCC FLAGS_REG)
8593         (compare:CCC
8594           (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8595           (plus:<DWI>
8596             (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8597             (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
8598    (clobber (match_scratch:DWIH 0 "=r"))]
8599   ""
8601   operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
8602   return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
8604   [(set_attr "type" "alu")
8605    (set_attr "mode" "<MODE>")])
8607 ;; The sign flag is set from the
8608 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
8609 ;; result, the overflow flag likewise, but the overflow flag is also
8610 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
8611 (define_insn "@sub<mode>3_carry_ccgz"
8612   [(set (reg:CCGZ FLAGS_REG)
8613         (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
8614                       (match_operand:DWIH 2 "x86_64_general_operand" "rBMe")
8615                       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
8616                      UNSPEC_SBB))
8617    (clobber (match_scratch:DWIH 0 "=r"))]
8618   ""
8619   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8620   [(set_attr "type" "alu")
8621    (set_attr "mode" "<MODE>")])
8623 (define_insn "subborrow<mode>"
8624   [(set (reg:CCC FLAGS_REG)
8625         (compare:CCC
8626           (zero_extend:<DWI>
8627             (match_operand:SWI48 1 "nonimmediate_operand" "0,0"))
8628           (plus:<DWI>
8629             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8630               [(match_operand 3 "flags_reg_operand") (const_int 0)])
8631             (zero_extend:<DWI>
8632               (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))))
8633    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8634         (minus:SWI48 (minus:SWI48
8635                        (match_dup 1)
8636                        (match_operator:SWI48 5 "ix86_carry_flag_operator"
8637                          [(match_dup 3) (const_int 0)]))
8638                      (match_dup 2)))]
8639   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8640   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8641   [(set_attr "type" "alu")
8642    (set_attr "use_carry" "1")
8643    (set_attr "pent_pair" "pu")
8644    (set_attr "mode" "<MODE>")])
8646 (define_peephole2
8647   [(set (match_operand:SWI48 0 "general_reg_operand")
8648         (match_operand:SWI48 1 "memory_operand"))
8649    (parallel [(set (reg:CCC FLAGS_REG)
8650                    (compare:CCC
8651                      (zero_extend:<DWI> (match_dup 0))
8652                      (plus:<DWI>
8653                        (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8654                          [(match_operand 3 "flags_reg_operand") (const_int 0)])
8655                        (zero_extend:<DWI>
8656                          (match_operand:SWI48 2 "memory_operand")))))
8657               (set (match_dup 0)
8658                    (minus:SWI48
8659                      (minus:SWI48
8660                        (match_dup 0)
8661                        (match_operator:SWI48 5 "ix86_carry_flag_operator"
8662                          [(match_dup 3) (const_int 0)]))
8663                      (match_dup 2)))])
8664    (set (match_dup 1) (match_dup 0))]
8665   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8666    && peep2_reg_dead_p (3, operands[0])
8667    && !reg_overlap_mentioned_p (operands[0], operands[1])
8668    && !reg_overlap_mentioned_p (operands[0], operands[2])"
8669   [(set (match_dup 0) (match_dup 2))
8670    (parallel [(set (reg:CCC FLAGS_REG)
8671                    (compare:CCC
8672                      (zero_extend:<DWI> (match_dup 1))
8673                      (plus:<DWI> (match_op_dup 4
8674                                    [(match_dup 3) (const_int 0)])
8675                                  (zero_extend:<DWI> (match_dup 0)))))
8676               (set (match_dup 1)
8677                    (minus:SWI48 (minus:SWI48 (match_dup 1)
8678                                              (match_op_dup 5
8679                                                [(match_dup 3) (const_int 0)]))
8680                                 (match_dup 0)))])])
8682 (define_peephole2
8683   [(set (match_operand:SWI48 6 "general_reg_operand")
8684         (match_operand:SWI48 7 "memory_operand"))
8685    (set (match_operand:SWI48 8 "general_reg_operand")
8686         (match_operand:SWI48 9 "memory_operand"))
8687    (parallel [(set (reg:CCC FLAGS_REG)
8688                    (compare:CCC
8689                      (zero_extend:<DWI>
8690                        (match_operand:SWI48 0 "general_reg_operand"))
8691                      (plus:<DWI>
8692                        (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8693                          [(match_operand 3 "flags_reg_operand") (const_int 0)])
8694                        (zero_extend:<DWI>
8695                          (match_operand:SWI48 2 "general_reg_operand")))))
8696               (set (match_dup 0)
8697                    (minus:SWI48
8698                      (minus:SWI48
8699                        (match_dup 0)
8700                        (match_operator:SWI48 5 "ix86_carry_flag_operator"
8701                          [(match_dup 3) (const_int 0)]))
8702                      (match_dup 2)))])
8703    (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8704   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8705    && peep2_reg_dead_p (4, operands[0])
8706    && peep2_reg_dead_p (3, operands[2])
8707    && !reg_overlap_mentioned_p (operands[0], operands[1])
8708    && !reg_overlap_mentioned_p (operands[2], operands[1])
8709    && !reg_overlap_mentioned_p (operands[6], operands[9])
8710    && (rtx_equal_p (operands[6], operands[0])
8711        ? (rtx_equal_p (operands[7], operands[1])
8712           && rtx_equal_p (operands[8], operands[2]))
8713        : (rtx_equal_p (operands[8], operands[0])
8714           && rtx_equal_p (operands[9], operands[1])
8715           && rtx_equal_p (operands[6], operands[2])))"
8716   [(set (match_dup 0) (match_dup 9))
8717    (parallel [(set (reg:CCC FLAGS_REG)
8718                    (compare:CCC
8719                      (zero_extend:<DWI> (match_dup 1))
8720                      (plus:<DWI> (match_op_dup 4
8721                                    [(match_dup 3) (const_int 0)])
8722                                  (zero_extend:<DWI> (match_dup 0)))))
8723               (set (match_dup 1)
8724                    (minus:SWI48 (minus:SWI48 (match_dup 1)
8725                                              (match_op_dup 5
8726                                                [(match_dup 3) (const_int 0)]))
8727                                 (match_dup 0)))])]
8729   if (!rtx_equal_p (operands[6], operands[0]))
8730     operands[9] = operands[7];
8733 (define_peephole2
8734   [(set (match_operand:SWI48 6 "general_reg_operand")
8735         (match_operand:SWI48 7 "memory_operand"))
8736    (set (match_operand:SWI48 8 "general_reg_operand")
8737         (match_operand:SWI48 9 "memory_operand"))
8738    (parallel [(set (reg:CCC FLAGS_REG)
8739                    (compare:CCC
8740                      (zero_extend:<DWI>
8741                        (match_operand:SWI48 0 "general_reg_operand"))
8742                      (plus:<DWI>
8743                        (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8744                          [(match_operand 3 "flags_reg_operand") (const_int 0)])
8745                        (zero_extend:<DWI>
8746                          (match_operand:SWI48 2 "general_reg_operand")))))
8747               (set (match_dup 0)
8748                    (minus:SWI48
8749                      (minus:SWI48
8750                        (match_dup 0)
8751                        (match_operator:SWI48 5 "ix86_carry_flag_operator"
8752                          [(match_dup 3) (const_int 0)]))
8753                      (match_dup 2)))])
8754    (set (match_operand:QI 10 "general_reg_operand")
8755         (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8756    (set (match_operand:SWI48 11 "general_reg_operand")
8757         (zero_extend:SWI48 (match_dup 10)))
8758    (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8759   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8760    && peep2_reg_dead_p (6, operands[0])
8761    && peep2_reg_dead_p (3, operands[2])
8762    && !reg_overlap_mentioned_p (operands[0], operands[1])
8763    && !reg_overlap_mentioned_p (operands[2], operands[1])
8764    && !reg_overlap_mentioned_p (operands[6], operands[9])
8765    && !reg_overlap_mentioned_p (operands[0], operands[10])
8766    && !reg_overlap_mentioned_p (operands[10], operands[1])
8767    && !reg_overlap_mentioned_p (operands[0], operands[11])
8768    && !reg_overlap_mentioned_p (operands[11], operands[1])
8769    && (rtx_equal_p (operands[6], operands[0])
8770        ? (rtx_equal_p (operands[7], operands[1])
8771           && rtx_equal_p (operands[8], operands[2]))
8772        : (rtx_equal_p (operands[8], operands[0])
8773           && rtx_equal_p (operands[9], operands[1])
8774           && rtx_equal_p (operands[6], operands[2])))"
8775   [(set (match_dup 0) (match_dup 9))
8776    (parallel [(set (reg:CCC FLAGS_REG)
8777                    (compare:CCC
8778                      (zero_extend:<DWI> (match_dup 1))
8779                      (plus:<DWI> (match_op_dup 4
8780                                    [(match_dup 3) (const_int 0)])
8781                                  (zero_extend:<DWI> (match_dup 0)))))
8782               (set (match_dup 1)
8783                    (minus:SWI48 (minus:SWI48 (match_dup 1)
8784                                              (match_op_dup 5
8785                                                [(match_dup 3) (const_int 0)]))
8786                                 (match_dup 0)))])
8787    (set (match_dup 10) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8788    (set (match_dup 11) (zero_extend:SWI48 (match_dup 10)))]
8790   if (!rtx_equal_p (operands[6], operands[0]))
8791     operands[9] = operands[7];
8794 (define_expand "subborrow<mode>_0"
8795   [(parallel
8796      [(set (reg:CC FLAGS_REG)
8797            (compare:CC
8798              (match_operand:SWI48 1 "nonimmediate_operand")
8799              (match_operand:SWI48 2 "<general_operand>")))
8800       (set (match_operand:SWI48 0 "register_operand")
8801            (minus:SWI48 (match_dup 1) (match_dup 2)))])]
8802   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
8804 (define_expand "uaddc<mode>5"
8805   [(match_operand:SWI48 0 "register_operand")
8806    (match_operand:SWI48 1 "register_operand")
8807    (match_operand:SWI48 2 "register_operand")
8808    (match_operand:SWI48 3 "register_operand")
8809    (match_operand:SWI48 4 "nonmemory_operand")]
8810   ""
8812   rtx cf = gen_rtx_REG (CCCmode, FLAGS_REG), pat, pat2;
8813   if (operands[4] == const0_rtx)
8814     emit_insn (gen_addcarry<mode>_0 (operands[0], operands[2], operands[3]));
8815   else
8816     {
8817       ix86_expand_carry (operands[4]);
8818       pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8819       pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8820       emit_insn (gen_addcarry<mode> (operands[0], operands[2], operands[3],
8821                                      cf, pat, pat2));
8822     }
8823   rtx cc = gen_reg_rtx (QImode);
8824   pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8825   emit_insn (gen_rtx_SET (cc, pat));
8826   emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8827   DONE;
8830 (define_expand "usubc<mode>5"
8831   [(match_operand:SWI48 0 "register_operand")
8832    (match_operand:SWI48 1 "register_operand")
8833    (match_operand:SWI48 2 "register_operand")
8834    (match_operand:SWI48 3 "register_operand")
8835    (match_operand:SWI48 4 "nonmemory_operand")]
8836   ""
8838   rtx cf, pat, pat2;
8839   if (operands[4] == const0_rtx)
8840     {
8841       cf = gen_rtx_REG (CCmode, FLAGS_REG);
8842       emit_insn (gen_subborrow<mode>_0 (operands[0], operands[2],
8843                                         operands[3]));
8844     }
8845   else
8846     {
8847       cf = gen_rtx_REG (CCCmode, FLAGS_REG);
8848       ix86_expand_carry (operands[4]);
8849       pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8850       pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8851       emit_insn (gen_subborrow<mode> (operands[0], operands[2], operands[3],
8852                                       cf, pat, pat2));
8853     }
8854   rtx cc = gen_reg_rtx (QImode);
8855   pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8856   emit_insn (gen_rtx_SET (cc, pat));
8857   emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8858   DONE;
8861 (define_mode_iterator CC_CCC [CC CCC])
8863 ;; Pre-reload splitter to optimize
8864 ;; *setcc_qi followed by *addqi3_cconly_overflow_1 with the same QI
8865 ;; operand and no intervening flags modifications into nothing.
8866 (define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1_<mode>"
8867   [(set (reg:CCC FLAGS_REG)
8868         (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
8869                      (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))))]
8870   "ix86_pre_reload_split ()"
8871   "#"
8872   "&& 1"
8873   [(const_int 0)]
8874   "emit_note (NOTE_INSN_DELETED); DONE;")
8876 ;; Set the carry flag from the carry flag.
8877 (define_insn_and_split "*setccc"
8878   [(set (reg:CCC FLAGS_REG)
8879         (reg:CCC FLAGS_REG))]
8880   "ix86_pre_reload_split ()"
8881   "#"
8882   "&& 1"
8883   [(const_int 0)]
8884   "emit_note (NOTE_INSN_DELETED); DONE;")
8886 ;; Set the carry flag from the carry flag.
8887 (define_insn_and_split "*setcc_qi_negqi_ccc_1_<mode>"
8888   [(set (reg:CCC FLAGS_REG)
8889         (ltu:CCC (reg:CC_CCC FLAGS_REG) (const_int 0)))]
8890   "ix86_pre_reload_split ()"
8891   "#"
8892   "&& 1"
8893   [(const_int 0)]
8894   "emit_note (NOTE_INSN_DELETED); DONE;")
8896 ;; Set the carry flag from the carry flag.
8897 (define_insn_and_split "*setcc_qi_negqi_ccc_2_<mode>"
8898   [(set (reg:CCC FLAGS_REG)
8899         (unspec:CCC [(ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
8900                      (const_int 0)] UNSPEC_CC_NE))]
8901   "ix86_pre_reload_split ()"
8902   "#"
8903   "&& 1"
8904   [(const_int 0)]
8905   "emit_note (NOTE_INSN_DELETED); DONE;")
8907 ;; Overflow setting add instructions
8909 (define_expand "addqi3_cconly_overflow"
8910   [(parallel
8911      [(set (reg:CCC FLAGS_REG)
8912            (compare:CCC
8913              (plus:QI
8914                (match_operand:QI 0 "nonimmediate_operand")
8915                (match_operand:QI 1 "general_operand"))
8916              (match_dup 0)))
8917       (clobber (scratch:QI))])]
8918   "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
8920 (define_insn "*add<mode>3_cconly_overflow_1"
8921   [(set (reg:CCC FLAGS_REG)
8922         (compare:CCC
8923           (plus:SWI
8924             (match_operand:SWI 1 "nonimmediate_operand" "%0")
8925             (match_operand:SWI 2 "<general_operand>" "<g>"))
8926           (match_dup 1)))
8927    (clobber (match_scratch:SWI 0 "=<r>"))]
8928   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8929   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8930   [(set_attr "type" "alu")
8931    (set_attr "mode" "<MODE>")])
8933 (define_insn "@add<mode>3_cc_overflow_1"
8934   [(set (reg:CCC FLAGS_REG)
8935         (compare:CCC
8936             (plus:SWI
8937                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8938                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
8939             (match_dup 1)))
8940    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8941         (plus:SWI (match_dup 1) (match_dup 2)))]
8942   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8943   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8944   [(set_attr "type" "alu")
8945    (set_attr "mode" "<MODE>")])
8947 (define_peephole2
8948   [(parallel [(set (reg:CCC FLAGS_REG)
8949                    (compare:CCC
8950                      (plus:SWI (match_operand:SWI 0 "general_reg_operand")
8951                                (match_operand:SWI 1 "memory_operand"))
8952                      (match_dup 0)))
8953               (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 1)))])
8954    (set (match_dup 1) (match_dup 0))]
8955   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8956    && peep2_reg_dead_p (2, operands[0])
8957    && !reg_overlap_mentioned_p (operands[0], operands[1])"
8958   [(parallel [(set (reg:CCC FLAGS_REG)
8959                    (compare:CCC
8960                      (plus:SWI (match_dup 1) (match_dup 0))
8961                      (match_dup 1)))
8962               (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
8964 (define_peephole2
8965   [(set (match_operand:SWI 0 "general_reg_operand")
8966         (match_operand:SWI 1 "memory_operand"))
8967    (parallel [(set (reg:CCC FLAGS_REG)
8968                    (compare:CCC
8969                      (plus:SWI (match_dup 0)
8970                                (match_operand:SWI 2 "memory_operand"))
8971                      (match_dup 0)))
8972               (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 2)))])
8973    (set (match_dup 1) (match_dup 0))]
8974   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8975    && peep2_reg_dead_p (3, operands[0])
8976    && !reg_overlap_mentioned_p (operands[0], operands[1])
8977    && !reg_overlap_mentioned_p (operands[0], operands[2])"
8978   [(set (match_dup 0) (match_dup 2))
8979    (parallel [(set (reg:CCC FLAGS_REG)
8980                    (compare:CCC
8981                      (plus:SWI (match_dup 1) (match_dup 0))
8982                      (match_dup 1)))
8983               (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
8985 (define_insn "*addsi3_zext_cc_overflow_1"
8986   [(set (reg:CCC FLAGS_REG)
8987         (compare:CCC
8988           (plus:SI
8989             (match_operand:SI 1 "nonimmediate_operand" "%0")
8990             (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
8991           (match_dup 1)))
8992    (set (match_operand:DI 0 "register_operand" "=r")
8993         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8994   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8995   "add{l}\t{%2, %k0|%k0, %2}"
8996   [(set_attr "type" "alu")
8997    (set_attr "mode" "SI")])
8999 (define_insn "*add<mode>3_cconly_overflow_2"
9000   [(set (reg:CCC FLAGS_REG)
9001         (compare:CCC
9002           (plus:SWI
9003             (match_operand:SWI 1 "nonimmediate_operand" "%0")
9004             (match_operand:SWI 2 "<general_operand>" "<g>"))
9005           (match_dup 2)))
9006    (clobber (match_scratch:SWI 0 "=<r>"))]
9007   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9008   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
9009   [(set_attr "type" "alu")
9010    (set_attr "mode" "<MODE>")])
9012 (define_insn "*add<mode>3_cc_overflow_2"
9013   [(set (reg:CCC FLAGS_REG)
9014         (compare:CCC
9015             (plus:SWI
9016                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9017                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
9018             (match_dup 2)))
9019    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
9020         (plus:SWI (match_dup 1) (match_dup 2)))]
9021   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
9022   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
9023   [(set_attr "type" "alu")
9024    (set_attr "mode" "<MODE>")])
9026 (define_insn "*addsi3_zext_cc_overflow_2"
9027   [(set (reg:CCC FLAGS_REG)
9028         (compare:CCC
9029           (plus:SI
9030             (match_operand:SI 1 "nonimmediate_operand" "%0")
9031             (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
9032           (match_dup 2)))
9033    (set (match_operand:DI 0 "register_operand" "=r")
9034         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9035   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
9036   "add{l}\t{%2, %k0|%k0, %2}"
9037   [(set_attr "type" "alu")
9038    (set_attr "mode" "SI")])
9040 (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
9041   [(set (reg:CCC FLAGS_REG)
9042         (compare:CCC
9043           (plus:<DWI>
9044             (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
9045             (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o"))
9046           (match_dup 1)))
9047    (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
9048         (plus:<DWI> (match_dup 1) (match_dup 2)))]
9049   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
9050   "#"
9051   "&& reload_completed"
9052   [(parallel [(set (reg:CCC FLAGS_REG)
9053                    (compare:CCC
9054                      (plus:DWIH (match_dup 1) (match_dup 2))
9055                      (match_dup 1)))
9056               (set (match_dup 0)
9057                    (plus:DWIH (match_dup 1) (match_dup 2)))])
9058    (parallel [(set (reg:CCC FLAGS_REG)
9059                    (compare:CCC
9060                      (zero_extend:<DWI>
9061                        (plus:DWIH
9062                          (plus:DWIH
9063                            (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9064                            (match_dup 4))
9065                          (match_dup 5)))
9066                      (plus:<DWI>
9067                        (match_dup 6)
9068                        (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))))
9069               (set (match_dup 3)
9070                    (plus:DWIH
9071                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9072                                 (match_dup 4))
9073                      (match_dup 5)))])]
9075   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
9076   if (operands[2] == const0_rtx)
9077     {
9078       emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
9079       DONE;
9080     }
9081   if (CONST_INT_P (operands[5]))
9082     operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode,
9083                                             operands[5], <MODE>mode);
9084   else
9085     operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
9088 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
9089 ;; test, where the latter is preferrable if we have some carry consuming
9090 ;; instruction.
9091 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
9092 ;; + (1 - CF).
9093 (define_insn_and_split "*add<mode>3_eq"
9094   [(set (match_operand:SWI 0 "nonimmediate_operand")
9095         (plus:SWI
9096           (plus:SWI
9097             (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9098             (match_operand:SWI 1 "nonimmediate_operand"))
9099           (match_operand:SWI 2 "<general_operand>")))
9100    (clobber (reg:CC FLAGS_REG))]
9101   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9102    && ix86_pre_reload_split ()"
9103   "#"
9104   "&& 1"
9105   [(set (reg:CC FLAGS_REG)
9106         (compare:CC (match_dup 3) (const_int 1)))
9107    (parallel [(set (match_dup 0)
9108                    (plus:SWI
9109                      (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9110                                (match_dup 1))
9111                      (match_dup 2)))
9112               (clobber (reg:CC FLAGS_REG))])])
9114 (define_insn_and_split "*add<mode>3_ne"
9115   [(set (match_operand:SWI 0 "nonimmediate_operand")
9116         (plus:SWI
9117           (plus:SWI
9118             (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9119             (match_operand:SWI 1 "nonimmediate_operand"))
9120           (match_operand:SWI 2 "<immediate_operand>")))
9121    (clobber (reg:CC FLAGS_REG))]
9122   "CONST_INT_P (operands[2])
9123    && (<MODE>mode != DImode
9124        || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9125    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9126    && ix86_pre_reload_split ()"
9127   "#"
9128   "&& 1"
9129   [(set (reg:CC FLAGS_REG)
9130         (compare:CC (match_dup 3) (const_int 1)))
9131    (parallel [(set (match_dup 0)
9132                    (minus:SWI
9133                      (minus:SWI (match_dup 1)
9134                                 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9135                      (match_dup 2)))
9136               (clobber (reg:CC FLAGS_REG))])]
9138   operands[2] = gen_int_mode (~INTVAL (operands[2]),
9139                               <MODE>mode == DImode ? SImode : <MODE>mode);
9142 (define_insn_and_split "*add<mode>3_eq_0"
9143   [(set (match_operand:SWI 0 "nonimmediate_operand")
9144         (plus:SWI
9145           (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9146           (match_operand:SWI 1 "<general_operand>")))
9147    (clobber (reg:CC FLAGS_REG))]
9148   "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9149    && ix86_pre_reload_split ()"
9150   "#"
9151   "&& 1"
9152   [(set (reg:CC FLAGS_REG)
9153         (compare:CC (match_dup 2) (const_int 1)))
9154    (parallel [(set (match_dup 0)
9155                    (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9156                              (match_dup 1)))
9157               (clobber (reg:CC FLAGS_REG))])]
9159   if (!nonimmediate_operand (operands[1], <MODE>mode))
9160     operands[1] = force_reg (<MODE>mode, operands[1]);
9163 (define_insn_and_split "*add<mode>3_ne_0"
9164   [(set (match_operand:SWI 0 "nonimmediate_operand")
9165         (plus:SWI
9166           (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9167           (match_operand:SWI 1 "<general_operand>")))
9168    (clobber (reg:CC FLAGS_REG))]
9169   "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9170    && ix86_pre_reload_split ()"
9171   "#"
9172   "&& 1"
9173   [(set (reg:CC FLAGS_REG)
9174         (compare:CC (match_dup 2) (const_int 1)))
9175    (parallel [(set (match_dup 0)
9176                    (minus:SWI (minus:SWI
9177                                 (match_dup 1)
9178                                 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9179                               (const_int -1)))
9180               (clobber (reg:CC FLAGS_REG))])]
9182   if (!nonimmediate_operand (operands[1], <MODE>mode))
9183     operands[1] = force_reg (<MODE>mode, operands[1]);
9186 (define_insn_and_split "*sub<mode>3_eq"
9187   [(set (match_operand:SWI 0 "nonimmediate_operand")
9188         (minus:SWI
9189           (minus:SWI
9190             (match_operand:SWI 1 "nonimmediate_operand")
9191             (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9192                     (const_int 0)))
9193           (match_operand:SWI 2 "<general_operand>")))
9194    (clobber (reg:CC FLAGS_REG))]
9195   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9196    && ix86_pre_reload_split ()"
9197   "#"
9198   "&& 1"
9199   [(set (reg:CC FLAGS_REG)
9200         (compare:CC (match_dup 3) (const_int 1)))
9201    (parallel [(set (match_dup 0)
9202                    (minus:SWI
9203                      (minus:SWI (match_dup 1)
9204                                 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9205                      (match_dup 2)))
9206               (clobber (reg:CC FLAGS_REG))])])
9208 (define_insn_and_split "*sub<mode>3_ne"
9209   [(set (match_operand:SWI 0 "nonimmediate_operand")
9210         (plus:SWI
9211           (minus:SWI
9212             (match_operand:SWI 1 "nonimmediate_operand")
9213             (ne:SWI (match_operand 3 "int_nonimmediate_operand")
9214                     (const_int 0)))
9215           (match_operand:SWI 2 "<immediate_operand>")))
9216    (clobber (reg:CC FLAGS_REG))]
9217   "CONST_INT_P (operands[2])
9218    && (<MODE>mode != DImode
9219        || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9220    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9221    && ix86_pre_reload_split ()"
9222   "#"
9223   "&& 1"
9224   [(set (reg:CC FLAGS_REG)
9225         (compare:CC (match_dup 3) (const_int 1)))
9226    (parallel [(set (match_dup 0)
9227                    (plus:SWI
9228                      (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9229                                (match_dup 1))
9230                      (match_dup 2)))
9231               (clobber (reg:CC FLAGS_REG))])]
9233   operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
9234                               <MODE>mode == DImode ? SImode : <MODE>mode);
9237 (define_insn_and_split "*sub<mode>3_eq_1"
9238   [(set (match_operand:SWI 0 "nonimmediate_operand")
9239         (plus:SWI
9240           (minus:SWI
9241             (match_operand:SWI 1 "nonimmediate_operand")
9242             (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9243                     (const_int 0)))
9244           (match_operand:SWI 2 "<immediate_operand>")))
9245    (clobber (reg:CC FLAGS_REG))]
9246   "CONST_INT_P (operands[2])
9247    && (<MODE>mode != DImode
9248        || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9249    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9250    && ix86_pre_reload_split ()"
9251   "#"
9252   "&& 1"
9253   [(set (reg:CC FLAGS_REG)
9254         (compare:CC (match_dup 3) (const_int 1)))
9255    (parallel [(set (match_dup 0)
9256                    (minus:SWI
9257                      (minus:SWI (match_dup 1)
9258                                 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9259                      (match_dup 2)))
9260               (clobber (reg:CC FLAGS_REG))])]
9262   operands[2] = gen_int_mode (-INTVAL (operands[2]),
9263                               <MODE>mode == DImode ? SImode : <MODE>mode);
9266 (define_insn_and_split "*sub<mode>3_eq_0"
9267   [(set (match_operand:SWI 0 "nonimmediate_operand")
9268         (minus:SWI
9269           (match_operand:SWI 1 "<general_operand>")
9270           (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9271    (clobber (reg:CC FLAGS_REG))]
9272   "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9273    && ix86_pre_reload_split ()"
9274   "#"
9275   "&& 1"
9276   [(set (reg:CC FLAGS_REG)
9277         (compare:CC (match_dup 2) (const_int 1)))
9278    (parallel [(set (match_dup 0)
9279                    (minus:SWI (match_dup 1)
9280                               (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
9281               (clobber (reg:CC FLAGS_REG))])]
9283   if (!nonimmediate_operand (operands[1], <MODE>mode))
9284     operands[1] = force_reg (<MODE>mode, operands[1]);
9287 (define_insn_and_split "*sub<mode>3_ne_0"
9288   [(set (match_operand:SWI 0 "nonimmediate_operand")
9289         (minus:SWI
9290           (match_operand:SWI 1 "<general_operand>")
9291           (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9292    (clobber (reg:CC FLAGS_REG))]
9293   "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9294    && ix86_pre_reload_split ()"
9295   "#"
9296   "&& 1"
9297   [(set (reg:CC FLAGS_REG)
9298         (compare:CC (match_dup 2) (const_int 1)))
9299    (parallel [(set (match_dup 0)
9300                    (plus:SWI (plus:SWI
9301                                (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9302                                (match_dup 1))
9303                              (const_int -1)))
9304               (clobber (reg:CC FLAGS_REG))])]
9306   if (!nonimmediate_operand (operands[1], <MODE>mode))
9307     operands[1] = force_reg (<MODE>mode, operands[1]);
9310 ;; The patterns that match these are at the end of this file.
9312 (define_expand "<insn>xf3"
9313   [(set (match_operand:XF 0 "register_operand")
9314         (plusminus:XF
9315           (match_operand:XF 1 "register_operand")
9316           (match_operand:XF 2 "register_operand")))]
9317   "TARGET_80387")
9319 (define_expand "<insn>hf3"
9320   [(set (match_operand:HF 0 "register_operand")
9321         (plusminus:HF
9322           (match_operand:HF 1 "register_operand")
9323           (match_operand:HF 2 "nonimmediate_operand")))]
9324   "TARGET_AVX512FP16")
9326 (define_expand "<insn><mode>3"
9327   [(set (match_operand:MODEF 0 "register_operand")
9328         (plusminus:MODEF
9329           (match_operand:MODEF 1 "register_operand")
9330           (match_operand:MODEF 2 "nonimmediate_operand")))]
9331   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9332     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9334 ;; Multiply instructions
9336 (define_expand "mul<mode>3"
9337   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
9338                    (mult:SWIM248
9339                      (match_operand:SWIM248 1 "register_operand")
9340                      (match_operand:SWIM248 2 "<general_operand>")))
9341               (clobber (reg:CC FLAGS_REG))])])
9343 (define_expand "mulqi3"
9344   [(parallel [(set (match_operand:QI 0 "register_operand")
9345                    (mult:QI
9346                      (match_operand:QI 1 "register_operand")
9347                      (match_operand:QI 2 "nonimmediate_operand")))
9348               (clobber (reg:CC FLAGS_REG))])]
9349   "TARGET_QIMODE_MATH")
9351 ;; On AMDFAM10
9352 ;; IMUL reg32/64, reg32/64, imm8        Direct
9353 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
9354 ;; IMUL reg32/64, reg32/64, imm32       Direct
9355 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
9356 ;; IMUL reg32/64, reg32/64              Direct
9357 ;; IMUL reg32/64, mem32/64              Direct
9359 ;; On BDVER1, all above IMULs use DirectPath
9361 ;; On AMDFAM10
9362 ;; IMUL reg16, reg16, imm8      VectorPath
9363 ;; IMUL reg16, mem16, imm8      VectorPath
9364 ;; IMUL reg16, reg16, imm16     VectorPath
9365 ;; IMUL reg16, mem16, imm16     VectorPath
9366 ;; IMUL reg16, reg16            Direct
9367 ;; IMUL reg16, mem16            Direct
9369 ;; On BDVER1, all HI MULs use DoublePath
9371 (define_insn "*mul<mode>3_1"
9372   [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
9373         (mult:SWIM248
9374           (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
9375           (match_operand:SWIM248 2 "<general_operand>" "K,<i>,<m>r")))
9376    (clobber (reg:CC FLAGS_REG))]
9377   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9378   "@
9379    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9380    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9381    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9382   [(set_attr "type" "imul")
9383    (set_attr "prefix_0f" "0,0,1")
9384    (set (attr "athlon_decode")
9385         (cond [(eq_attr "cpu" "athlon")
9386                   (const_string "vector")
9387                (eq_attr "alternative" "1")
9388                   (const_string "vector")
9389                (and (eq_attr "alternative" "2")
9390                     (ior (match_test "<MODE>mode == HImode")
9391                          (match_operand 1 "memory_operand")))
9392                   (const_string "vector")]
9393               (const_string "direct")))
9394    (set (attr "amdfam10_decode")
9395         (cond [(and (eq_attr "alternative" "0,1")
9396                     (ior (match_test "<MODE>mode == HImode")
9397                          (match_operand 1 "memory_operand")))
9398                   (const_string "vector")]
9399               (const_string "direct")))
9400    (set (attr "bdver1_decode")
9401         (if_then_else
9402           (match_test "<MODE>mode == HImode")
9403             (const_string "double")
9404             (const_string "direct")))
9405    (set_attr "mode" "<MODE>")])
9407 (define_insn "*mulsi3_1_zext"
9408   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9409         (zero_extend:DI
9410           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
9411                    (match_operand:SI 2 "x86_64_general_operand" "K,e,BMr"))))
9412    (clobber (reg:CC FLAGS_REG))]
9413   "TARGET_64BIT
9414    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9415   "@
9416    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9417    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9418    imul{l}\t{%2, %k0|%k0, %2}"
9419   [(set_attr "type" "imul")
9420    (set_attr "prefix_0f" "0,0,1")
9421    (set (attr "athlon_decode")
9422         (cond [(eq_attr "cpu" "athlon")
9423                   (const_string "vector")
9424                (eq_attr "alternative" "1")
9425                   (const_string "vector")
9426                (and (eq_attr "alternative" "2")
9427                     (match_operand 1 "memory_operand"))
9428                   (const_string "vector")]
9429               (const_string "direct")))
9430    (set (attr "amdfam10_decode")
9431         (cond [(and (eq_attr "alternative" "0,1")
9432                     (match_operand 1 "memory_operand"))
9433                   (const_string "vector")]
9434               (const_string "direct")))
9435    (set_attr "bdver1_decode" "direct")
9436    (set_attr "mode" "SI")])
9438 ;;On AMDFAM10 and BDVER1
9439 ;; MUL reg8     Direct
9440 ;; MUL mem8     Direct
9442 (define_insn "*mulqi3_1"
9443   [(set (match_operand:QI 0 "register_operand" "=a")
9444         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9445                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
9446    (clobber (reg:CC FLAGS_REG))]
9447   "TARGET_QIMODE_MATH
9448    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9449   "mul{b}\t%2"
9450   [(set_attr "type" "imul")
9451    (set_attr "length_immediate" "0")
9452    (set (attr "athlon_decode")
9453      (if_then_else (eq_attr "cpu" "athlon")
9454         (const_string "vector")
9455         (const_string "direct")))
9456    (set_attr "amdfam10_decode" "direct")
9457    (set_attr "bdver1_decode" "direct")
9458    (set_attr "mode" "QI")])
9460 ;; Multiply with jump on overflow.
9461 (define_expand "mulv<mode>4"
9462   [(parallel [(set (reg:CCO FLAGS_REG)
9463                    (eq:CCO (mult:<DWI>
9464                               (sign_extend:<DWI>
9465                                  (match_operand:SWI248 1 "register_operand"))
9466                               (match_dup 4))
9467                            (sign_extend:<DWI>
9468                               (mult:SWI248 (match_dup 1)
9469                                            (match_operand:SWI248 2
9470                                               "<general_operand>")))))
9471               (set (match_operand:SWI248 0 "register_operand")
9472                    (mult:SWI248 (match_dup 1) (match_dup 2)))])
9473    (set (pc) (if_then_else
9474                (eq (reg:CCO FLAGS_REG) (const_int 0))
9475                (label_ref (match_operand 3))
9476                (pc)))]
9477   ""
9479   if (CONST_INT_P (operands[2]))
9480     operands[4] = operands[2];
9481   else
9482     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
9485 (define_insn "*mulv<mode>4"
9486   [(set (reg:CCO FLAGS_REG)
9487         (eq:CCO (mult:<DWI>
9488                    (sign_extend:<DWI>
9489                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
9490                    (sign_extend:<DWI>
9491                       (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
9492                 (sign_extend:<DWI>
9493                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
9494    (set (match_operand:SWI48 0 "register_operand" "=r,r")
9495         (mult:SWI48 (match_dup 1) (match_dup 2)))]
9496   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9497   "@
9498    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9499    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9500   [(set_attr "type" "imul")
9501    (set_attr "prefix_0f" "0,1")
9502    (set (attr "athlon_decode")
9503         (cond [(eq_attr "cpu" "athlon")
9504                   (const_string "vector")
9505                (eq_attr "alternative" "0")
9506                   (const_string "vector")
9507                (and (eq_attr "alternative" "1")
9508                     (match_operand 1 "memory_operand"))
9509                   (const_string "vector")]
9510               (const_string "direct")))
9511    (set (attr "amdfam10_decode")
9512         (cond [(and (eq_attr "alternative" "1")
9513                     (match_operand 1 "memory_operand"))
9514                   (const_string "vector")]
9515               (const_string "direct")))
9516    (set_attr "bdver1_decode" "direct")
9517    (set_attr "mode" "<MODE>")])
9519 (define_insn "*mulvhi4"
9520   [(set (reg:CCO FLAGS_REG)
9521         (eq:CCO (mult:SI
9522                    (sign_extend:SI
9523                       (match_operand:HI 1 "nonimmediate_operand" "%0"))
9524                    (sign_extend:SI
9525                       (match_operand:HI 2 "nonimmediate_operand" "mr")))
9526                 (sign_extend:SI
9527                    (mult:HI (match_dup 1) (match_dup 2)))))
9528    (set (match_operand:HI 0 "register_operand" "=r")
9529         (mult:HI (match_dup 1) (match_dup 2)))]
9530   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9531   "imul{w}\t{%2, %0|%0, %2}"
9532   [(set_attr "type" "imul")
9533    (set_attr "prefix_0f" "1")
9534    (set_attr "athlon_decode" "vector")
9535    (set_attr "amdfam10_decode" "direct")
9536    (set_attr "bdver1_decode" "double")
9537    (set_attr "mode" "HI")])
9539 (define_insn "*mulv<mode>4_1"
9540   [(set (reg:CCO FLAGS_REG)
9541         (eq:CCO (mult:<DWI>
9542                    (sign_extend:<DWI>
9543                       (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
9544                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
9545                 (sign_extend:<DWI>
9546                    (mult:SWI248 (match_dup 1)
9547                                 (match_operand:SWI248 2
9548                                    "<immediate_operand>" "K,<i>")))))
9549    (set (match_operand:SWI248 0 "register_operand" "=r,r")
9550         (mult:SWI248 (match_dup 1) (match_dup 2)))]
9551   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
9552    && CONST_INT_P (operands[2])
9553    && INTVAL (operands[2]) == INTVAL (operands[3])"
9554   "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9555   [(set_attr "type" "imul")
9556    (set (attr "prefix_0f")
9557         (if_then_else
9558           (match_test "<MODE>mode == HImode")
9559             (const_string "0")
9560             (const_string "*")))
9561    (set (attr "athlon_decode")
9562         (cond [(eq_attr "cpu" "athlon")
9563                   (const_string "vector")
9564                (eq_attr "alternative" "1")
9565                   (const_string "vector")]
9566               (const_string "direct")))
9567    (set (attr "amdfam10_decode")
9568         (cond [(ior (match_test "<MODE>mode == HImode")
9569                     (match_operand 1 "memory_operand"))
9570                   (const_string "vector")]
9571               (const_string "direct")))
9572    (set (attr "bdver1_decode")
9573         (if_then_else
9574           (match_test "<MODE>mode == HImode")
9575             (const_string "double")
9576             (const_string "direct")))
9577    (set_attr "mode" "<MODE>")
9578    (set (attr "length_immediate")
9579         (cond [(eq_attr "alternative" "0")
9580                   (const_string "1")
9581                (match_test "<MODE_SIZE> == 8")
9582                   (const_string "4")]
9583               (const_string "<MODE_SIZE>")))])
9585 (define_expand "umulv<mode>4"
9586   [(parallel [(set (reg:CCO FLAGS_REG)
9587                    (eq:CCO (mult:<DWI>
9588                               (zero_extend:<DWI>
9589                                  (match_operand:SWI248 1
9590                                                       "nonimmediate_operand"))
9591                               (zero_extend:<DWI>
9592                                  (match_operand:SWI248 2
9593                                                       "nonimmediate_operand")))
9594                            (zero_extend:<DWI>
9595                               (mult:SWI248 (match_dup 1) (match_dup 2)))))
9596               (set (match_operand:SWI248 0 "register_operand")
9597                    (mult:SWI248 (match_dup 1) (match_dup 2)))
9598               (clobber (scratch:SWI248))])
9599    (set (pc) (if_then_else
9600                (eq (reg:CCO FLAGS_REG) (const_int 0))
9601                (label_ref (match_operand 3))
9602                (pc)))]
9603   ""
9605   if (MEM_P (operands[1]) && MEM_P (operands[2]))
9606     operands[1] = force_reg (<MODE>mode, operands[1]);
9609 (define_insn "*umulv<mode>4"
9610   [(set (reg:CCO FLAGS_REG)
9611         (eq:CCO (mult:<DWI>
9612                    (zero_extend:<DWI>
9613                       (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
9614                    (zero_extend:<DWI>
9615                       (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
9616                 (zero_extend:<DWI>
9617                    (mult:SWI248 (match_dup 1) (match_dup 2)))))
9618    (set (match_operand:SWI248 0 "register_operand" "=a")
9619         (mult:SWI248 (match_dup 1) (match_dup 2)))
9620    (clobber (match_scratch:SWI248 3 "=d"))]
9621   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9622   "mul{<imodesuffix>}\t%2"
9623   [(set_attr "type" "imul")
9624    (set_attr "length_immediate" "0")
9625    (set (attr "athlon_decode")
9626      (if_then_else (eq_attr "cpu" "athlon")
9627        (const_string "vector")
9628        (const_string "double")))
9629    (set_attr "amdfam10_decode" "double")
9630    (set_attr "bdver1_decode" "direct")
9631    (set_attr "mode" "<MODE>")])
9633 (define_expand "<u>mulvqi4"
9634   [(parallel [(set (reg:CCO FLAGS_REG)
9635                    (eq:CCO (mult:HI
9636                               (any_extend:HI
9637                                  (match_operand:QI 1 "nonimmediate_operand"))
9638                               (any_extend:HI
9639                                  (match_operand:QI 2 "nonimmediate_operand")))
9640                            (any_extend:HI
9641                               (mult:QI (match_dup 1) (match_dup 2)))))
9642               (set (match_operand:QI 0 "register_operand")
9643                    (mult:QI (match_dup 1) (match_dup 2)))])
9644    (set (pc) (if_then_else
9645                (eq (reg:CCO FLAGS_REG) (const_int 0))
9646                (label_ref (match_operand 3))
9647                (pc)))]
9648   "TARGET_QIMODE_MATH"
9650   if (MEM_P (operands[1]) && MEM_P (operands[2]))
9651     operands[1] = force_reg (QImode, operands[1]);
9654 (define_insn "*<u>mulvqi4"
9655   [(set (reg:CCO FLAGS_REG)
9656         (eq:CCO (mult:HI
9657                    (any_extend:HI
9658                       (match_operand:QI 1 "nonimmediate_operand" "%0"))
9659                    (any_extend:HI
9660                       (match_operand:QI 2 "nonimmediate_operand" "qm")))
9661                 (any_extend:HI
9662                    (mult:QI (match_dup 1) (match_dup 2)))))
9663    (set (match_operand:QI 0 "register_operand" "=a")
9664         (mult:QI (match_dup 1) (match_dup 2)))]
9665   "TARGET_QIMODE_MATH
9666    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9667   "<sgnprefix>mul{b}\t%2"
9668   [(set_attr "type" "imul")
9669    (set_attr "length_immediate" "0")
9670    (set (attr "athlon_decode")
9671      (if_then_else (eq_attr "cpu" "athlon")
9672         (const_string "vector")
9673         (const_string "direct")))
9674    (set_attr "amdfam10_decode" "direct")
9675    (set_attr "bdver1_decode" "direct")
9676    (set_attr "mode" "QI")])
9678 (define_expand "<u>mul<mode><dwi>3"
9679   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
9680                    (mult:<DWI>
9681                      (any_extend:<DWI>
9682                        (match_operand:DWIH 1 "register_operand"))
9683                      (any_extend:<DWI>
9684                        (match_operand:DWIH 2 "nonimmediate_operand"))))
9685               (clobber (reg:CC FLAGS_REG))])])
9687 (define_expand "<u>mulqihi3"
9688   [(parallel [(set (match_operand:HI 0 "register_operand")
9689                    (mult:HI
9690                      (any_extend:HI
9691                        (match_operand:QI 1 "register_operand"))
9692                      (any_extend:HI
9693                        (match_operand:QI 2 "nonimmediate_operand"))))
9694               (clobber (reg:CC FLAGS_REG))])]
9695   "TARGET_QIMODE_MATH")
9697 (define_insn "*bmi2_umul<mode><dwi>3_1"
9698   [(set (match_operand:DWIH 0 "register_operand" "=r")
9699         (mult:DWIH
9700           (match_operand:DWIH 2 "register_operand" "%d")
9701           (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
9702    (set (match_operand:DWIH 1 "register_operand" "=r")
9703         (umul_highpart:DWIH (match_dup 2) (match_dup 3)))]
9704   "TARGET_BMI2"
9705   "mulx\t{%3, %0, %1|%1, %0, %3}"
9706   [(set_attr "type" "imulx")
9707    (set_attr "prefix" "vex")
9708    (set_attr "mode" "<MODE>")])
9710 ;; Tweak *bmi2_umul<mode><dwi>3_1 to eliminate following mov.
9711 (define_peephole2
9712   [(parallel [(set (match_operand:DWIH 0 "general_reg_operand")
9713                    (mult:DWIH (match_operand:DWIH 2 "register_operand")
9714                               (match_operand:DWIH 3 "nonimmediate_operand")))
9715               (set (match_operand:DWIH 1 "general_reg_operand")
9716                    (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])
9717    (set (match_operand:DWIH 4 "general_reg_operand")
9718         (match_operand:DWIH 5 "general_reg_operand"))]
9719   "TARGET_BMI2
9720    && ((REGNO (operands[5]) == REGNO (operands[0])
9721         && REGNO (operands[1]) != REGNO (operands[4]))
9722        || (REGNO (operands[5]) == REGNO (operands[1])
9723            && REGNO (operands[0]) != REGNO (operands[4])))
9724    && peep2_reg_dead_p (2, operands[5])"
9725   [(parallel [(set (match_dup 0) (mult:DWIH (match_dup 2) (match_dup 3)))
9726               (set (match_dup 1)
9727                    (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])]
9729   if (REGNO (operands[5]) == REGNO (operands[0]))
9730     operands[0] = operands[4];
9731   else
9732     operands[1] = operands[4];
9735 (define_insn "*umul<mode><dwi>3_1"
9736   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
9737         (mult:<DWI>
9738           (zero_extend:<DWI>
9739             (match_operand:DWIH 1 "register_operand" "%d,a"))
9740           (zero_extend:<DWI>
9741             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
9742    (clobber (reg:CC FLAGS_REG))]
9743   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9744   "@
9745    #
9746    mul{<imodesuffix>}\t%2"
9747   [(set_attr "isa" "bmi2,*")
9748    (set_attr "type" "imulx,imul")
9749    (set_attr "length_immediate" "*,0")
9750    (set (attr "athlon_decode")
9751         (cond [(eq_attr "alternative" "1")
9752                  (if_then_else (eq_attr "cpu" "athlon")
9753                    (const_string "vector")
9754                    (const_string "double"))]
9755               (const_string "*")))
9756    (set_attr "amdfam10_decode" "*,double")
9757    (set_attr "bdver1_decode" "*,direct")
9758    (set_attr "prefix" "vex,orig")
9759    (set_attr "mode" "<MODE>")])
9761 ;; Convert mul to the mulx pattern to avoid flags dependency.
9762 (define_split
9763  [(set (match_operand:<DWI> 0 "register_operand")
9764        (mult:<DWI>
9765          (zero_extend:<DWI>
9766            (match_operand:DWIH 1 "register_operand"))
9767          (zero_extend:<DWI>
9768            (match_operand:DWIH 2 "nonimmediate_operand"))))
9769   (clobber (reg:CC FLAGS_REG))]
9770  "TARGET_BMI2 && reload_completed
9771   && REGNO (operands[1]) == DX_REG"
9772   [(parallel [(set (match_dup 3)
9773                    (mult:DWIH (match_dup 1) (match_dup 2)))
9774               (set (match_dup 4)
9775                    (umul_highpart:DWIH (match_dup 1) (match_dup 2)))])]
9777   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
9779   operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9782 (define_insn "*mul<mode><dwi>3_1"
9783   [(set (match_operand:<DWI> 0 "register_operand" "=A")
9784         (mult:<DWI>
9785           (sign_extend:<DWI>
9786             (match_operand:DWIH 1 "register_operand" "%a"))
9787           (sign_extend:<DWI>
9788             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
9789    (clobber (reg:CC FLAGS_REG))]
9790   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9791   "imul{<imodesuffix>}\t%2"
9792   [(set_attr "type" "imul")
9793    (set_attr "length_immediate" "0")
9794    (set (attr "athlon_decode")
9795      (if_then_else (eq_attr "cpu" "athlon")
9796         (const_string "vector")
9797         (const_string "double")))
9798    (set_attr "amdfam10_decode" "double")
9799    (set_attr "bdver1_decode" "direct")
9800    (set_attr "mode" "<MODE>")])
9802 (define_insn "*<u>mulqihi3_1"
9803   [(set (match_operand:HI 0 "register_operand" "=a")
9804         (mult:HI
9805           (any_extend:HI
9806             (match_operand:QI 1 "register_operand" "%0"))
9807           (any_extend:HI
9808             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
9809    (clobber (reg:CC FLAGS_REG))]
9810   "TARGET_QIMODE_MATH
9811    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9812   "<sgnprefix>mul{b}\t%2"
9813   [(set_attr "type" "imul")
9814    (set_attr "length_immediate" "0")
9815    (set (attr "athlon_decode")
9816      (if_then_else (eq_attr "cpu" "athlon")
9817         (const_string "vector")
9818         (const_string "direct")))
9819    (set_attr "amdfam10_decode" "direct")
9820    (set_attr "bdver1_decode" "direct")
9821    (set_attr "mode" "QI")])
9823 ;; Widening multiplication peephole2s to tweak register allocation.
9824 ;; mov imm,%rdx; mov %rdi,%rax; mulq %rdx  ->  mov imm,%rax; mulq %rdi
9825 (define_peephole2
9826   [(set (match_operand:DWIH 0 "general_reg_operand")
9827         (match_operand:DWIH 1 "immediate_operand"))
9828    (set (match_operand:DWIH 2 "general_reg_operand")
9829         (match_operand:DWIH 3 "general_reg_operand"))
9830    (parallel [(set (match_operand:<DWI> 4 "general_reg_operand")
9831                    (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9832                                (zero_extend:<DWI> (match_dup 0))))
9833               (clobber (reg:CC FLAGS_REG))])]
9834   "REGNO (operands[3]) != AX_REG
9835    && REGNO (operands[0]) != REGNO (operands[2])
9836    && REGNO (operands[0]) != REGNO (operands[3])
9837    && (REGNO (operands[0]) == REGNO (operands[4])
9838        || REGNO (operands[0]) == DX_REG
9839        || peep2_reg_dead_p (3, operands[0]))"
9840   [(set (match_dup 2) (match_dup 1))
9841    (parallel [(set (match_dup 4)
9842                    (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9843                                (zero_extend:<DWI> (match_dup 3))))
9844               (clobber (reg:CC FLAGS_REG))])])
9846 ;; mov imm,%rax; mov %rdi,%rdx; mulx %rax  ->  mov imm,%rdx; mulx %rdi
9847 (define_peephole2
9848   [(set (match_operand:DWIH 0 "general_reg_operand")
9849         (match_operand:DWIH 1 "immediate_operand"))
9850    (set (match_operand:DWIH 2 "general_reg_operand")
9851         (match_operand:DWIH 3 "general_reg_operand"))
9852    (parallel [(set (match_operand:DWIH 4 "general_reg_operand")
9853                    (mult:DWIH (match_dup 2) (match_dup 0)))
9854               (set (match_operand:DWIH 5 "general_reg_operand")
9855                    (umul_highpart:DWIH (match_dup 2) (match_dup 0)))])]
9856   "REGNO (operands[3]) != DX_REG
9857    && REGNO (operands[0]) != REGNO (operands[2])
9858    && REGNO (operands[0]) != REGNO (operands[3])
9859    && (REGNO (operands[0]) == REGNO (operands[4])
9860        || REGNO (operands[0]) == REGNO (operands[5])
9861        || peep2_reg_dead_p (3, operands[0]))"
9862   [(set (match_dup 2) (match_dup 1))
9863    (parallel [(set (match_dup 4)
9864                    (mult:DWIH (match_dup 2) (match_dup 3)))
9865               (set (match_dup 5)
9866                    (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])])
9868 ;; Highpart multiplication patterns
9869 (define_insn "<s>mul<mode>3_highpart"
9870   [(set (match_operand:DWIH 0 "register_operand" "=d")
9871         (any_mul_highpart:DWIH
9872           (match_operand:DWIH 1 "register_operand" "%a")
9873           (match_operand:DWIH 2 "nonimmediate_operand" "rm")))
9874    (clobber (match_scratch:DWIH 3 "=1"))
9875    (clobber (reg:CC FLAGS_REG))]
9876   ""
9877   "<sgnprefix>mul{<imodesuffix>}\t%2"
9878   [(set_attr "type" "imul")
9879    (set_attr "length_immediate" "0")
9880    (set (attr "athlon_decode")
9881      (if_then_else (eq_attr "cpu" "athlon")
9882         (const_string "vector")
9883         (const_string "double")))
9884    (set_attr "amdfam10_decode" "double")
9885    (set_attr "bdver1_decode" "direct")
9886    (set_attr "mode" "<MODE>")])
9888 (define_insn "*<s>mulsi3_highpart_zext"
9889   [(set (match_operand:DI 0 "register_operand" "=d")
9890         (zero_extend:DI 
9891           (any_mul_highpart:SI
9892             (match_operand:SI 1 "register_operand" "%a")
9893             (match_operand:SI 2 "nonimmediate_operand" "rm"))))
9894    (clobber (match_scratch:SI 3 "=1"))
9895    (clobber (reg:CC FLAGS_REG))]
9896   "TARGET_64BIT"
9897   "<sgnprefix>mul{l}\t%2"
9898   [(set_attr "type" "imul")
9899    (set_attr "length_immediate" "0")
9900    (set (attr "athlon_decode")
9901      (if_then_else (eq_attr "cpu" "athlon")
9902         (const_string "vector")
9903         (const_string "double")))
9904    (set_attr "amdfam10_decode" "double")
9905    (set_attr "bdver1_decode" "direct")
9906    (set_attr "mode" "SI")])
9908 (define_insn "*<s>muldi3_highpart_1"
9909   [(set (match_operand:DI 0 "register_operand" "=d")
9910         (truncate:DI
9911           (lshiftrt:TI
9912             (mult:TI
9913               (any_extend:TI
9914                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
9915               (any_extend:TI
9916                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
9917             (const_int 64))))
9918    (clobber (match_scratch:DI 3 "=1"))
9919    (clobber (reg:CC FLAGS_REG))]
9920   "TARGET_64BIT
9921    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9922   "<sgnprefix>mul{q}\t%2"
9923   [(set_attr "type" "imul")
9924    (set_attr "length_immediate" "0")
9925    (set (attr "athlon_decode")
9926      (if_then_else (eq_attr "cpu" "athlon")
9927         (const_string "vector")
9928         (const_string "double")))
9929    (set_attr "amdfam10_decode" "double")
9930    (set_attr "bdver1_decode" "direct")
9931    (set_attr "mode" "DI")])
9933 (define_insn "*<s>mulsi3_highpart_zext"
9934   [(set (match_operand:DI 0 "register_operand" "=d")
9935         (zero_extend:DI (truncate:SI
9936           (lshiftrt:DI
9937             (mult:DI (any_extend:DI
9938                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
9939                      (any_extend:DI
9940                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
9941             (const_int 32)))))
9942    (clobber (match_scratch:SI 3 "=1"))
9943    (clobber (reg:CC FLAGS_REG))]
9944   "TARGET_64BIT
9945    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9946   "<sgnprefix>mul{l}\t%2"
9947   [(set_attr "type" "imul")
9948    (set_attr "length_immediate" "0")
9949    (set (attr "athlon_decode")
9950      (if_then_else (eq_attr "cpu" "athlon")
9951         (const_string "vector")
9952         (const_string "double")))
9953    (set_attr "amdfam10_decode" "double")
9954    (set_attr "bdver1_decode" "direct")
9955    (set_attr "mode" "SI")])
9957 (define_insn "*<s>mulsi3_highpart_1"
9958   [(set (match_operand:SI 0 "register_operand" "=d")
9959         (truncate:SI
9960           (lshiftrt:DI
9961             (mult:DI
9962               (any_extend:DI
9963                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
9964               (any_extend:DI
9965                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9966             (const_int 32))))
9967    (clobber (match_scratch:SI 3 "=1"))
9968    (clobber (reg:CC FLAGS_REG))]
9969   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9970   "<sgnprefix>mul{l}\t%2"
9971   [(set_attr "type" "imul")
9972    (set_attr "length_immediate" "0")
9973    (set (attr "athlon_decode")
9974      (if_then_else (eq_attr "cpu" "athlon")
9975         (const_string "vector")
9976         (const_string "double")))
9977    (set_attr "amdfam10_decode" "double")
9978    (set_attr "bdver1_decode" "direct")
9979    (set_attr "mode" "SI")])
9981 ;; Highpart multiplication peephole2s to tweak register allocation.
9982 ;; mov imm,%rdx; mov %rdi,%rax; imulq %rdx  ->  mov imm,%rax; imulq %rdi
9983 (define_peephole2
9984   [(set (match_operand:SWI48 0 "general_reg_operand")
9985         (match_operand:SWI48 1 "immediate_operand"))
9986    (set (match_operand:SWI48 2 "general_reg_operand")
9987         (match_operand:SWI48 3 "general_reg_operand"))
9988    (parallel [(set (match_operand:SWI48 4 "general_reg_operand")
9989                    (any_mul_highpart:SWI48 (match_dup 2) (match_dup 0)))
9990               (clobber (match_dup 2))
9991               (clobber (reg:CC FLAGS_REG))])]
9992   "REGNO (operands[3]) != AX_REG
9993    && REGNO (operands[0]) != REGNO (operands[2])
9994    && REGNO (operands[0]) != REGNO (operands[3])
9995    && (REGNO (operands[0]) == REGNO (operands[4])
9996        || peep2_reg_dead_p (3, operands[0]))"
9997   [(set (match_dup 2) (match_dup 1))
9998    (parallel [(set (match_dup 4)
9999                    (any_mul_highpart:SWI48 (match_dup 2) (match_dup 3)))
10000               (clobber (match_dup 2))
10001               (clobber (reg:CC FLAGS_REG))])])
10003 (define_peephole2
10004   [(set (match_operand:SI 0 "general_reg_operand")
10005         (match_operand:SI 1 "immediate_operand"))
10006    (set (match_operand:SI 2 "general_reg_operand")
10007         (match_operand:SI 3 "general_reg_operand"))
10008    (parallel [(set (match_operand:DI 4 "general_reg_operand")
10009                    (zero_extend:DI
10010                      (any_mul_highpart:SI (match_dup 2) (match_dup 0))))
10011               (clobber (match_dup 2))
10012               (clobber (reg:CC FLAGS_REG))])]
10013   "TARGET_64BIT
10014    && REGNO (operands[3]) != AX_REG
10015    && REGNO (operands[0]) != REGNO (operands[2])
10016    && REGNO (operands[2]) != REGNO (operands[3])
10017    && REGNO (operands[0]) != REGNO (operands[3])
10018    && (REGNO (operands[0]) == REGNO (operands[4])
10019        || peep2_reg_dead_p (3, operands[0]))"
10020   [(set (match_dup 2) (match_dup 1))
10021    (parallel [(set (match_dup 4)
10022                    (zero_extend:DI
10023                      (any_mul_highpart:SI (match_dup 2) (match_dup 3))))
10024               (clobber (match_dup 2))
10025               (clobber (reg:CC FLAGS_REG))])])
10027 ;; The patterns that match these are at the end of this file.
10029 (define_expand "mulxf3"
10030   [(set (match_operand:XF 0 "register_operand")
10031         (mult:XF (match_operand:XF 1 "register_operand")
10032                  (match_operand:XF 2 "register_operand")))]
10033   "TARGET_80387")
10035 (define_expand "mulhf3"
10036   [(set (match_operand:HF 0 "register_operand")
10037         (mult:HF (match_operand:HF 1 "register_operand")
10038                     (match_operand:HF 2 "nonimmediate_operand")))]
10039   "TARGET_AVX512FP16")
10041 (define_expand "mul<mode>3"
10042   [(set (match_operand:MODEF 0 "register_operand")
10043         (mult:MODEF (match_operand:MODEF 1 "register_operand")
10044                     (match_operand:MODEF 2 "nonimmediate_operand")))]
10045   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
10046     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
10048 ;; Divide instructions
10050 ;; The patterns that match these are at the end of this file.
10052 (define_expand "divxf3"
10053   [(set (match_operand:XF 0 "register_operand")
10054         (div:XF (match_operand:XF 1 "register_operand")
10055                 (match_operand:XF 2 "register_operand")))]
10056   "TARGET_80387")
10058 /* There is no more precision loss than Newton-Rhapson approximation
10059   when using HFmode rcp/rsqrt, so do the transformation directly under
10060   TARGET_RECIP_DIV and fast-math.  */
10061 (define_expand "divhf3"
10062   [(set (match_operand:HF 0 "register_operand")
10063         (div:HF (match_operand:HF 1 "register_operand")
10064                    (match_operand:HF 2 "nonimmediate_operand")))]
10065   "TARGET_AVX512FP16"
10067   if (TARGET_RECIP_DIV
10068       && optimize_insn_for_speed_p ()
10069       && flag_finite_math_only && !flag_trapping_math
10070       && flag_unsafe_math_optimizations)
10071     {
10072       rtx op = gen_reg_rtx (HFmode);
10073       operands[2] = force_reg (HFmode, operands[2]);
10074       emit_insn (gen_rcphf2 (op, operands[2]));
10075       emit_insn (gen_mulhf3 (operands[0], operands[1], op));
10076       DONE;
10077     }
10080 (define_expand "div<mode>3"
10081   [(set (match_operand:MODEF 0 "register_operand")
10082         (div:MODEF (match_operand:MODEF 1 "register_operand")
10083                    (match_operand:MODEF 2 "nonimmediate_operand")))]
10084   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
10085     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10087   if (<MODE>mode == SFmode
10088       && TARGET_SSE && TARGET_SSE_MATH
10089       && TARGET_RECIP_DIV
10090       && optimize_insn_for_speed_p ()
10091       && flag_finite_math_only && !flag_trapping_math
10092       && flag_unsafe_math_optimizations)
10093     {
10094       ix86_emit_swdivsf (operands[0], operands[1],
10095                          operands[2], SFmode);
10096       DONE;
10097     }
10100 ;; Divmod instructions.
10102 (define_code_iterator any_div [div udiv])
10103 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
10105 (define_expand "<u>divmod<mode>4"
10106   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
10107                    (any_div:SWIM248
10108                      (match_operand:SWIM248 1 "register_operand")
10109                      (match_operand:SWIM248 2 "nonimmediate_operand")))
10110               (set (match_operand:SWIM248 3 "register_operand")
10111                    (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
10112               (clobber (reg:CC FLAGS_REG))])])
10114 ;; Split with 8bit unsigned divide:
10115 ;;      if (dividend an divisor are in [0-255])
10116 ;;         use 8bit unsigned integer divide
10117 ;;       else
10118 ;;         use original integer divide
10119 (define_split
10120   [(set (match_operand:SWI48 0 "register_operand")
10121         (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
10122                        (match_operand:SWI48 3 "nonimmediate_operand")))
10123    (set (match_operand:SWI48 1 "register_operand")
10124         (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
10125    (clobber (reg:CC FLAGS_REG))]
10126   "TARGET_USE_8BIT_IDIV
10127    && TARGET_QIMODE_MATH
10128    && can_create_pseudo_p ()
10129    && !optimize_insn_for_size_p ()"
10130   [(const_int 0)]
10131   "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
10133 (define_split
10134   [(set (match_operand:DI 0 "register_operand")
10135         (zero_extend:DI
10136           (any_div:SI (match_operand:SI 2 "register_operand")
10137                       (match_operand:SI 3 "nonimmediate_operand"))))
10138    (set (match_operand:SI 1 "register_operand")
10139         (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10140    (clobber (reg:CC FLAGS_REG))]
10141   "TARGET_64BIT
10142    && TARGET_USE_8BIT_IDIV
10143    && TARGET_QIMODE_MATH
10144    && can_create_pseudo_p ()
10145    && !optimize_insn_for_size_p ()"
10146   [(const_int 0)]
10147   "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10149 (define_split
10150   [(set (match_operand:DI 1 "register_operand")
10151         (zero_extend:DI
10152           (<paired_mod>:SI (match_operand:SI 2 "register_operand")
10153                            (match_operand:SI 3 "nonimmediate_operand"))))
10154    (set (match_operand:SI 0 "register_operand")
10155         (any_div:SI  (match_dup 2) (match_dup 3)))
10156    (clobber (reg:CC FLAGS_REG))]
10157   "TARGET_64BIT
10158    && TARGET_USE_8BIT_IDIV
10159    && TARGET_QIMODE_MATH
10160    && can_create_pseudo_p ()
10161    && !optimize_insn_for_size_p ()"
10162   [(const_int 0)]
10163   "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10165 (define_insn_and_split "divmod<mode>4_1"
10166   [(set (match_operand:SWI48 0 "register_operand" "=a")
10167         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10168                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10169    (set (match_operand:SWI48 1 "register_operand" "=&d")
10170         (mod:SWI48 (match_dup 2) (match_dup 3)))
10171    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10172    (clobber (reg:CC FLAGS_REG))]
10173   ""
10174   "#"
10175   "reload_completed"
10176   [(parallel [(set (match_dup 1)
10177                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
10178               (clobber (reg:CC FLAGS_REG))])
10179    (parallel [(set (match_dup 0)
10180                    (div:SWI48 (match_dup 2) (match_dup 3)))
10181               (set (match_dup 1)
10182                    (mod:SWI48 (match_dup 2) (match_dup 3)))
10183               (use (match_dup 1))
10184               (clobber (reg:CC FLAGS_REG))])]
10186   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10188   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10189     operands[4] = operands[2];
10190   else
10191     {
10192       /* Avoid use of cltd in favor of a mov+shift.  */
10193       emit_move_insn (operands[1], operands[2]);
10194       operands[4] = operands[1];
10195     }
10197   [(set_attr "type" "multi")
10198    (set_attr "mode" "<MODE>")])
10200 (define_insn_and_split "udivmod<mode>4_1"
10201   [(set (match_operand:SWI48 0 "register_operand" "=a")
10202         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10203                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10204    (set (match_operand:SWI48 1 "register_operand" "=&d")
10205         (umod:SWI48 (match_dup 2) (match_dup 3)))
10206    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10207    (clobber (reg:CC FLAGS_REG))]
10208   ""
10209   "#"
10210   "reload_completed"
10211   [(set (match_dup 1) (const_int 0))
10212    (parallel [(set (match_dup 0)
10213                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
10214               (set (match_dup 1)
10215                    (umod:SWI48 (match_dup 2) (match_dup 3)))
10216               (use (match_dup 1))
10217               (clobber (reg:CC FLAGS_REG))])]
10218   ""
10219   [(set_attr "type" "multi")
10220    (set_attr "mode" "<MODE>")])
10222 (define_insn_and_split "divmodsi4_zext_1"
10223   [(set (match_operand:DI 0 "register_operand" "=a")
10224         (zero_extend:DI
10225           (div:SI (match_operand:SI 2 "register_operand" "0")
10226                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10227    (set (match_operand:SI 1 "register_operand" "=&d")
10228         (mod:SI (match_dup 2) (match_dup 3)))
10229    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10230    (clobber (reg:CC FLAGS_REG))]
10231   "TARGET_64BIT"
10232   "#"
10233   "&& reload_completed"
10234   [(parallel [(set (match_dup 1)
10235                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
10236               (clobber (reg:CC FLAGS_REG))])
10237    (parallel [(set (match_dup 0)
10238                    (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10239               (set (match_dup 1)
10240                    (mod:SI (match_dup 2) (match_dup 3)))
10241               (use (match_dup 1))
10242               (clobber (reg:CC FLAGS_REG))])]
10244   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10246   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10247     operands[4] = operands[2];
10248   else
10249     {
10250       /* Avoid use of cltd in favor of a mov+shift.  */
10251       emit_move_insn (operands[1], operands[2]);
10252       operands[4] = operands[1];
10253     }
10255   [(set_attr "type" "multi")
10256    (set_attr "mode" "SI")])
10258 (define_insn_and_split "udivmodsi4_zext_1"
10259   [(set (match_operand:DI 0 "register_operand" "=a")
10260         (zero_extend:DI
10261           (udiv:SI (match_operand:SI 2 "register_operand" "0")
10262                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10263    (set (match_operand:SI 1 "register_operand" "=&d")
10264         (umod:SI (match_dup 2) (match_dup 3)))
10265    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10266    (clobber (reg:CC FLAGS_REG))]
10267   "TARGET_64BIT"
10268   "#"
10269   "&& reload_completed"
10270   [(set (match_dup 1) (const_int 0))
10271    (parallel [(set (match_dup 0)
10272                    (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10273               (set (match_dup 1)
10274                    (umod:SI (match_dup 2) (match_dup 3)))
10275               (use (match_dup 1))
10276               (clobber (reg:CC FLAGS_REG))])]
10277   ""
10278   [(set_attr "type" "multi")
10279    (set_attr "mode" "SI")])
10281 (define_insn_and_split "divmodsi4_zext_2"
10282   [(set (match_operand:DI 1 "register_operand" "=&d")
10283         (zero_extend:DI
10284           (mod:SI (match_operand:SI 2 "register_operand" "0")
10285                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10286    (set (match_operand:SI 0 "register_operand" "=a")
10287         (div:SI (match_dup 2) (match_dup 3)))
10288    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10289    (clobber (reg:CC FLAGS_REG))]
10290   "TARGET_64BIT"
10291   "#"
10292   "&& reload_completed"
10293   [(parallel [(set (match_dup 6)
10294                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
10295               (clobber (reg:CC FLAGS_REG))])
10296    (parallel [(set (match_dup 1)
10297                    (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10298               (set (match_dup 0)
10299                    (div:SI (match_dup 2) (match_dup 3)))
10300               (use (match_dup 6))
10301               (clobber (reg:CC FLAGS_REG))])]
10303   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10304   operands[6] = gen_lowpart (SImode, operands[1]);
10306   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10307     operands[4] = operands[2];
10308   else
10309     {
10310       /* Avoid use of cltd in favor of a mov+shift.  */
10311       emit_move_insn (operands[6], operands[2]);
10312       operands[4] = operands[6];
10313     }
10315   [(set_attr "type" "multi")
10316    (set_attr "mode" "SI")])
10318 (define_insn_and_split "udivmodsi4_zext_2"
10319   [(set (match_operand:DI 1 "register_operand" "=&d")
10320         (zero_extend:DI
10321           (umod:SI (match_operand:SI 2 "register_operand" "0")
10322                  (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10323    (set (match_operand:SI 0 "register_operand" "=a")
10324         (udiv:SI (match_dup 2) (match_dup 3)))
10325    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10326    (clobber (reg:CC FLAGS_REG))]
10327   "TARGET_64BIT"
10328   "#"
10329   "&& reload_completed"
10330   [(set (match_dup 4) (const_int 0))
10331    (parallel [(set (match_dup 1)
10332                    (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10333               (set (match_dup 0)
10334                    (udiv:SI (match_dup 2) (match_dup 3)))
10335               (use (match_dup 4))
10336               (clobber (reg:CC FLAGS_REG))])]
10337   "operands[4] = gen_lowpart (SImode, operands[1]);"
10338   [(set_attr "type" "multi")
10339    (set_attr "mode" "SI")])
10341 (define_insn_and_split "*divmod<mode>4"
10342   [(set (match_operand:SWIM248 0 "register_operand" "=a")
10343         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10344                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10345    (set (match_operand:SWIM248 1 "register_operand" "=&d")
10346         (mod:SWIM248 (match_dup 2) (match_dup 3)))
10347    (clobber (reg:CC FLAGS_REG))]
10348   ""
10349   "#"
10350   "reload_completed"
10351   [(parallel [(set (match_dup 1)
10352                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
10353               (clobber (reg:CC FLAGS_REG))])
10354    (parallel [(set (match_dup 0)
10355                    (div:SWIM248 (match_dup 2) (match_dup 3)))
10356               (set (match_dup 1)
10357                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
10358               (use (match_dup 1))
10359               (clobber (reg:CC FLAGS_REG))])]
10361   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10363   if (<MODE>mode != HImode
10364       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
10365     operands[4] = operands[2];
10366   else
10367     {
10368       /* Avoid use of cltd in favor of a mov+shift.  */
10369       emit_move_insn (operands[1], operands[2]);
10370       operands[4] = operands[1];
10371     }
10373   [(set_attr "type" "multi")
10374    (set_attr "mode" "<MODE>")])
10376 (define_insn_and_split "*udivmod<mode>4"
10377   [(set (match_operand:SWIM248 0 "register_operand" "=a")
10378         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10379                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10380    (set (match_operand:SWIM248 1 "register_operand" "=&d")
10381         (umod:SWIM248 (match_dup 2) (match_dup 3)))
10382    (clobber (reg:CC FLAGS_REG))]
10383   ""
10384   "#"
10385   "reload_completed"
10386   [(set (match_dup 1) (const_int 0))
10387    (parallel [(set (match_dup 0)
10388                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
10389               (set (match_dup 1)
10390                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
10391               (use (match_dup 1))
10392               (clobber (reg:CC FLAGS_REG))])]
10393   ""
10394   [(set_attr "type" "multi")
10395    (set_attr "mode" "<MODE>")])
10397 ;; Optimize division or modulo by constant power of 2, if the constant
10398 ;; materializes only after expansion.
10399 (define_insn_and_split "*udivmod<mode>4_pow2"
10400   [(set (match_operand:SWI48 0 "register_operand" "=r")
10401         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10402                     (match_operand:SWI48 3 "const_int_operand")))
10403    (set (match_operand:SWI48 1 "register_operand" "=r")
10404         (umod:SWI48 (match_dup 2) (match_dup 3)))
10405    (clobber (reg:CC FLAGS_REG))]
10406   "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10407   "#"
10408   "&& reload_completed"
10409   [(set (match_dup 1) (match_dup 2))
10410    (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
10411               (clobber (reg:CC FLAGS_REG))])
10412    (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
10413               (clobber (reg:CC FLAGS_REG))])]
10415   int v = exact_log2 (UINTVAL (operands[3]));
10416   operands[4] = GEN_INT (v);
10417   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10419   [(set_attr "type" "multi")
10420    (set_attr "mode" "<MODE>")])
10422 (define_insn_and_split "*divmodsi4_zext_1"
10423   [(set (match_operand:DI 0 "register_operand" "=a")
10424         (zero_extend:DI
10425           (div:SI (match_operand:SI 2 "register_operand" "0")
10426                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10427    (set (match_operand:SI 1 "register_operand" "=&d")
10428         (mod:SI (match_dup 2) (match_dup 3)))
10429    (clobber (reg:CC FLAGS_REG))]
10430   "TARGET_64BIT"
10431   "#"
10432   "&& reload_completed"
10433   [(parallel [(set (match_dup 1)
10434                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
10435               (clobber (reg:CC FLAGS_REG))])
10436    (parallel [(set (match_dup 0)
10437                    (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10438               (set (match_dup 1)
10439                    (mod:SI (match_dup 2) (match_dup 3)))
10440               (use (match_dup 1))
10441               (clobber (reg:CC FLAGS_REG))])]
10443   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10445   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10446     operands[4] = operands[2];
10447   else
10448     {
10449       /* Avoid use of cltd in favor of a mov+shift.  */
10450       emit_move_insn (operands[1], operands[2]);
10451       operands[4] = operands[1];
10452     }
10454   [(set_attr "type" "multi")
10455    (set_attr "mode" "SI")])
10457 (define_insn_and_split "*udivmodsi4_zext_1"
10458   [(set (match_operand:DI 0 "register_operand" "=a")
10459         (zero_extend:DI
10460           (udiv:SI (match_operand:SI 2 "register_operand" "0")
10461                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10462    (set (match_operand:SI 1 "register_operand" "=&d")
10463         (umod:SI (match_dup 2) (match_dup 3)))
10464    (clobber (reg:CC FLAGS_REG))]
10465   "TARGET_64BIT"
10466   "#"
10467   "&& reload_completed"
10468   [(set (match_dup 1) (const_int 0))
10469    (parallel [(set (match_dup 0)
10470                    (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10471               (set (match_dup 1)
10472                    (umod:SI (match_dup 2) (match_dup 3)))
10473               (use (match_dup 1))
10474               (clobber (reg:CC FLAGS_REG))])]
10475   ""
10476   [(set_attr "type" "multi")
10477    (set_attr "mode" "SI")])
10479 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
10480   [(set (match_operand:DI 0 "register_operand" "=r")
10481         (zero_extend:DI
10482           (udiv:SI (match_operand:SI 2 "register_operand" "0")
10483                    (match_operand:SI 3 "const_int_operand"))))
10484    (set (match_operand:SI 1 "register_operand" "=r")
10485         (umod:SI (match_dup 2) (match_dup 3)))
10486    (clobber (reg:CC FLAGS_REG))]
10487   "TARGET_64BIT
10488    && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10489   "#"
10490   "&& reload_completed"
10491   [(set (match_dup 1) (match_dup 2))
10492    (parallel [(set (match_dup 0)
10493                    (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
10494               (clobber (reg:CC FLAGS_REG))])
10495    (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
10496               (clobber (reg:CC FLAGS_REG))])]
10498   int v = exact_log2 (UINTVAL (operands[3]));
10499   operands[4] = GEN_INT (v);
10500   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10502   [(set_attr "type" "multi")
10503    (set_attr "mode" "SI")])
10505 (define_insn_and_split "*divmodsi4_zext_2"
10506   [(set (match_operand:DI 1 "register_operand" "=&d")
10507         (zero_extend:DI
10508           (mod:SI (match_operand:SI 2 "register_operand" "0")
10509                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10510    (set (match_operand:SI 0 "register_operand" "=a")
10511         (div:SI (match_dup 2) (match_dup 3)))
10512    (clobber (reg:CC FLAGS_REG))]
10513   "TARGET_64BIT"
10514   "#"
10515   "&& reload_completed"
10516   [(parallel [(set (match_dup 6)
10517                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
10518               (clobber (reg:CC FLAGS_REG))])
10519    (parallel [(set (match_dup 1)
10520                    (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10521               (set (match_dup 0)
10522                    (div:SI (match_dup 2) (match_dup 3)))
10523               (use (match_dup 6))
10524               (clobber (reg:CC FLAGS_REG))])]
10526   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10527   operands[6] = gen_lowpart (SImode, operands[1]);
10529   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10530     operands[4] = operands[2];
10531   else
10532     {
10533       /* Avoid use of cltd in favor of a mov+shift.  */
10534       emit_move_insn (operands[6], operands[2]);
10535       operands[4] = operands[6];
10536     }
10538   [(set_attr "type" "multi")
10539    (set_attr "mode" "SI")])
10541 (define_insn_and_split "*udivmodsi4_zext_2"
10542   [(set (match_operand:DI 1 "register_operand" "=&d")
10543         (zero_extend:DI
10544           (umod:SI (match_operand:SI 2 "register_operand" "0")
10545                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10546    (set (match_operand:SI 0 "register_operand" "=a")
10547         (udiv:SI (match_dup 2) (match_dup 3)))
10548    (clobber (reg:CC FLAGS_REG))]
10549   "TARGET_64BIT"
10550   "#"
10551   "&& reload_completed"
10552   [(set (match_dup 4) (const_int 0))
10553    (parallel [(set (match_dup 1)
10554                    (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10555               (set (match_dup 0)
10556                    (udiv:SI (match_dup 2) (match_dup 3)))
10557               (use (match_dup 4))
10558               (clobber (reg:CC FLAGS_REG))])]
10559   "operands[4] = gen_lowpart (SImode, operands[1]);"
10560   [(set_attr "type" "multi")
10561    (set_attr "mode" "SI")])
10563 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
10564   [(set (match_operand:DI 1 "register_operand" "=r")
10565         (zero_extend:DI
10566           (umod:SI (match_operand:SI 2 "register_operand" "0")
10567                    (match_operand:SI 3 "const_int_operand"))))
10568    (set (match_operand:SI 0 "register_operand" "=r")
10569         (udiv:SI (match_dup 2) (match_dup 3)))
10570    (clobber (reg:CC FLAGS_REG))]
10571   "TARGET_64BIT
10572    && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10573   "#"
10574   "&& reload_completed"
10575   [(set (match_dup 1) (match_dup 2))
10576    (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
10577               (clobber (reg:CC FLAGS_REG))])
10578    (parallel [(set (match_dup 1)
10579                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
10580               (clobber (reg:CC FLAGS_REG))])]
10582   int v = exact_log2 (UINTVAL (operands[3]));
10583   operands[4] = GEN_INT (v);
10584   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10586   [(set_attr "type" "multi")
10587    (set_attr "mode" "SI")])
10589 (define_insn "*<u>divmod<mode>4_noext"
10590   [(set (match_operand:SWIM248 0 "register_operand" "=a")
10591         (any_div:SWIM248
10592           (match_operand:SWIM248 2 "register_operand" "0")
10593           (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10594    (set (match_operand:SWIM248 1 "register_operand" "=d")
10595         (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
10596    (use (match_operand:SWIM248 4 "register_operand" "1"))
10597    (clobber (reg:CC FLAGS_REG))]
10598   ""
10599   "<sgnprefix>div{<imodesuffix>}\t%3"
10600   [(set_attr "type" "idiv")
10601    (set_attr "mode" "<MODE>")])
10603 (define_insn "*<u>divmodsi4_noext_zext_1"
10604   [(set (match_operand:DI 0 "register_operand" "=a")
10605         (zero_extend:DI
10606           (any_div:SI (match_operand:SI 2 "register_operand" "0")
10607                       (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10608    (set (match_operand:SI 1 "register_operand" "=d")
10609         (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10610    (use (match_operand:SI 4 "register_operand" "1"))
10611    (clobber (reg:CC FLAGS_REG))]
10612   "TARGET_64BIT"
10613   "<sgnprefix>div{l}\t%3"
10614   [(set_attr "type" "idiv")
10615    (set_attr "mode" "SI")])
10617 (define_insn "*<u>divmodsi4_noext_zext_2"
10618   [(set (match_operand:DI 1 "register_operand" "=d")
10619         (zero_extend:DI
10620           (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
10621                            (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10622    (set (match_operand:SI 0 "register_operand" "=a")
10623         (any_div:SI (match_dup 2) (match_dup 3)))
10624    (use (match_operand:SI 4 "register_operand" "1"))
10625    (clobber (reg:CC FLAGS_REG))]
10626   "TARGET_64BIT"
10627   "<sgnprefix>div{l}\t%3"
10628   [(set_attr "type" "idiv")
10629    (set_attr "mode" "SI")])
10631 ;; Avoid sign-extension (using cdq) for constant numerators.
10632 (define_insn_and_split "*divmodsi4_const"
10633   [(set (match_operand:SI 0 "register_operand" "=&a")
10634         (div:SI (match_operand:SI 2 "const_int_operand")
10635                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
10636    (set (match_operand:SI 1 "register_operand" "=&d")
10637         (mod:SI (match_dup 2) (match_dup 3)))
10638    (clobber (reg:CC FLAGS_REG))]
10639   "!optimize_function_for_size_p (cfun)"
10640   "#"
10641   "&& reload_completed"
10642   [(set (match_dup 0) (match_dup 2))
10643    (set (match_dup 1) (match_dup 4))
10644    (parallel [(set (match_dup 0)
10645                    (div:SI (match_dup 0) (match_dup 3)))
10646               (set (match_dup 1)
10647                    (mod:SI (match_dup 0) (match_dup 3)))
10648               (use (match_dup 1))
10649               (clobber (reg:CC FLAGS_REG))])]
10651   operands[4] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
10653   [(set_attr "type" "multi")
10654    (set_attr "mode" "SI")])
10656 (define_expand "divmodqi4"
10657   [(parallel [(set (match_operand:QI 0 "register_operand")
10658                    (div:QI
10659                      (match_operand:QI 1 "register_operand")
10660                      (match_operand:QI 2 "nonimmediate_operand")))
10661               (set (match_operand:QI 3 "register_operand")
10662                    (mod:QI (match_dup 1) (match_dup 2)))
10663               (clobber (reg:CC FLAGS_REG))])]
10664   "TARGET_QIMODE_MATH"
10666   rtx div, mod;
10667   rtx tmp0, tmp1;
10669   tmp0 = gen_reg_rtx (HImode);
10670   tmp1 = gen_reg_rtx (HImode);
10672   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
10673   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
10674   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
10676   /* Extract remainder from AH.  */
10677   tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10678   tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10679   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10681   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
10682   set_unique_reg_note (insn, REG_EQUAL, mod);
10684   /* Extract quotient from AL.  */
10685   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10687   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
10688   set_unique_reg_note (insn, REG_EQUAL, div);
10690   DONE;
10693 (define_expand "udivmodqi4"
10694   [(parallel [(set (match_operand:QI 0 "register_operand")
10695                    (udiv:QI
10696                      (match_operand:QI 1 "register_operand")
10697                      (match_operand:QI 2 "nonimmediate_operand")))
10698               (set (match_operand:QI 3 "register_operand")
10699                    (umod:QI (match_dup 1) (match_dup 2)))
10700               (clobber (reg:CC FLAGS_REG))])]
10701   "TARGET_QIMODE_MATH"
10703   rtx div, mod;
10704   rtx tmp0, tmp1;
10706   tmp0 = gen_reg_rtx (HImode);
10707   tmp1 = gen_reg_rtx (HImode);
10709   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
10710   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
10711   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
10713   /* Extract remainder from AH.  */
10714   tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10715   tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10716   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10718   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
10719   set_unique_reg_note (insn, REG_EQUAL, mod);
10721   /* Extract quotient from AL.  */
10722   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10724   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
10725   set_unique_reg_note (insn, REG_EQUAL, div);
10727   DONE;
10730 ;; Divide AX by r/m8, with result stored in
10731 ;; AL <- Quotient
10732 ;; AH <- Remainder
10733 ;; Change div/mod to HImode and extend the second argument to HImode
10734 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
10735 ;; combine may fail.
10736 (define_insn "<u>divmodhiqi3"
10737   [(set (match_operand:HI 0 "register_operand" "=a")
10738         (ior:HI
10739           (ashift:HI
10740             (zero_extend:HI
10741               (truncate:QI
10742                 (mod:HI (match_operand:HI 1 "register_operand" "0")
10743                         (any_extend:HI
10744                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
10745             (const_int 8))
10746           (zero_extend:HI
10747             (truncate:QI
10748               (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
10749    (clobber (reg:CC FLAGS_REG))]
10750   "TARGET_QIMODE_MATH"
10751   "<sgnprefix>div{b}\t%2"
10752   [(set_attr "type" "idiv")
10753    (set_attr "mode" "QI")])
10755 ;; We cannot use div/idiv for double division, because it causes
10756 ;; "division by zero" on the overflow and that's not what we expect
10757 ;; from truncate.  Because true (non truncating) double division is
10758 ;; never generated, we can't create this insn anyway.
10760 ;(define_insn ""
10761 ;  [(set (match_operand:SI 0 "register_operand" "=a")
10762 ;       (truncate:SI
10763 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
10764 ;                  (zero_extend:DI
10765 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
10766 ;   (set (match_operand:SI 3 "register_operand" "=d")
10767 ;       (truncate:SI
10768 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
10769 ;   (clobber (reg:CC FLAGS_REG))]
10770 ;  ""
10771 ;  "div{l}\t{%2, %0|%0, %2}"
10772 ;  [(set_attr "type" "idiv")])
10774 ;;- Logical AND instructions
10776 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
10777 ;; Note that this excludes ah.
10779 (define_expand "@test<mode>_ccno_1"
10780   [(set (reg:CCNO FLAGS_REG)
10781         (compare:CCNO
10782           (and:SWI48
10783             (match_operand:SWI48 0 "nonimmediate_operand")
10784             (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
10785           (const_int 0)))])
10787 (define_expand "testqi_ccz_1"
10788   [(set (reg:CCZ FLAGS_REG)
10789         (compare:CCZ
10790           (and:QI
10791             (match_operand:QI 0 "nonimmediate_operand")
10792             (match_operand:QI 1 "nonmemory_operand"))
10793           (const_int 0)))])
10795 (define_insn "*testdi_1"
10796   [(set (reg FLAGS_REG)
10797         (compare
10798           (and:DI
10799             (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
10800             (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
10801          (const_int 0)))]
10802   "TARGET_64BIT
10803    && ix86_match_ccmode
10804         (insn,
10805          /* If we are going to emit testl instead of testq, and the operands[1]
10806             constant might have the SImode sign bit set, make sure the sign
10807             flag isn't tested, because the instruction will set the sign flag
10808             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
10809             conservatively assume it might have bit 31 set.  */
10810          (satisfies_constraint_Z (operands[1])
10811           && (!CONST_INT_P (operands[1])
10812               || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
10813          ? CCZmode : CCNOmode)"
10814   "@
10815    test{l}\t{%k1, %k0|%k0, %k1}
10816    test{q}\t{%1, %0|%0, %1}"
10817   [(set_attr "type" "test")
10818    (set_attr "mode" "SI,DI")])
10820 (define_insn "*testqi_1_maybe_si"
10821   [(set (reg FLAGS_REG)
10822         (compare
10823           (and:QI
10824             (match_operand:QI 0 "nonimmediate_operand" "%qm,qm,r")
10825             (match_operand:QI 1 "nonmemory_operand" "q,n,n"))
10826           (const_int 0)))]
10827   "ix86_match_ccmode (insn,
10828                       CONST_INT_P (operands[1])
10829                       && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
10831   if (get_attr_mode (insn) == MODE_SI)
10832     {
10833       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
10834         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
10835       return "test{l}\t{%1, %k0|%k0, %1}";
10836     }
10837   return "test{b}\t{%1, %0|%0, %1}";
10839   [(set_attr "type" "test")
10840    (set (attr "mode")
10841      (cond [(eq_attr "alternative" "2")
10842               (const_string "SI")
10843             (and (match_test "optimize_insn_for_size_p ()")
10844                  (and (match_operand 0 "ext_QIreg_operand")
10845                       (match_operand 1 "const_0_to_127_operand")))
10846               (const_string "SI")
10847            ]
10848            (const_string "QI")))
10849    (set_attr "pent_pair" "uv,np,np")])
10851 (define_insn "*test<mode>_1"
10852   [(set (reg FLAGS_REG)
10853         (compare
10854           (and:SWI124
10855             (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
10856             (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
10857          (const_int 0)))]
10858   "ix86_match_ccmode (insn, CCNOmode)"
10859   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
10860   [(set_attr "type" "test")
10861    (set_attr "mode" "<MODE>")
10862    (set_attr "pent_pair" "uv,uv,np")])
10864 (define_expand "testqi_ext_1_ccno"
10865   [(set (reg:CCNO FLAGS_REG)
10866         (compare:CCNO
10867           (and:QI
10868             (subreg:QI
10869               (zero_extract:HI
10870                 (match_operand:HI 0 "register_operand")
10871                 (const_int 8)
10872                 (const_int 8)) 0)
10873               (match_operand:QI 1 "const_int_operand"))
10874           (const_int 0)))])
10876 (define_insn "*testqi_ext<mode>_1"
10877   [(set (reg FLAGS_REG)
10878         (compare
10879           (and:QI
10880             (subreg:QI
10881               (match_operator:SWI248 2 "extract_operator"
10882                 [(match_operand 0 "int248_register_operand" "Q")
10883                  (const_int 8)
10884                  (const_int 8)]) 0)
10885             (match_operand:QI 1 "general_operand" "QnBn"))
10886           (const_int 0)))]
10887   "ix86_match_ccmode (insn, CCNOmode)"
10888   "test{b}\t{%1, %h0|%h0, %1}"
10889   [(set_attr "addr" "gpr8")
10890    (set_attr "type" "test")
10891    (set_attr "mode" "QI")])
10893 (define_insn "*testqi_ext<mode>_2"
10894   [(set (reg FLAGS_REG)
10895         (compare
10896           (and:QI
10897             (subreg:QI
10898               (match_operator:SWI248 2 "extract_operator"
10899                 [(match_operand 0 "int248_register_operand" "Q")
10900                  (const_int 8)
10901                  (const_int 8)]) 0)
10902             (subreg:QI
10903               (match_operator:SWI248 3 "extract_operator"
10904                 [(match_operand 1 "int248_register_operand" "Q")
10905                  (const_int 8)
10906                  (const_int 8)]) 0))
10907           (const_int 0)))]
10908   "ix86_match_ccmode (insn, CCNOmode)"
10909   "test{b}\t{%h1, %h0|%h0, %h1}"
10910   [(set_attr "type" "test")
10911    (set_attr "mode" "QI")])
10913 ;; Provide a *testti instruction that STV can implement using ptest.
10914 ;; This pattern splits into *andti3_doubleword and *cmpti_doubleword.
10915 (define_insn_and_split "*testti_doubleword"
10916   [(set (reg:CCZ FLAGS_REG)
10917         (compare:CCZ
10918           (and:TI (match_operand:TI 0 "register_operand")
10919                   (match_operand:TI 1 "general_operand"))
10920           (const_int 0)))]
10921   "TARGET_64BIT
10922    && ix86_pre_reload_split ()"
10923   "#"
10924   "&& 1"
10925   [(parallel [(set (match_dup 2) (and:TI (match_dup 0) (match_dup 1)))
10926               (clobber (reg:CC FLAGS_REG))])
10927    (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
10929   operands[2] = gen_reg_rtx (TImode);
10930   if (!x86_64_hilo_general_operand (operands[1], TImode))
10931     operands[1] = force_reg (TImode, operands[1]);
10934 ;; Combine likes to form bit extractions for some tests.  Humor it.
10935 (define_insn_and_split "*testqi_ext_3"
10936   [(set (match_operand 0 "flags_reg_operand")
10937         (match_operator 1 "compare_operator"
10938           [(zero_extract:SWI248
10939              (match_operand 2 "int_nonimmediate_operand" "rm")
10940              (match_operand:QI 3 "const_int_operand")
10941              (match_operand:QI 4 "const_int_operand"))
10942            (const_int 0)]))]
10943   "/* Ensure that resulting mask is zero or sign extended operand.  */
10944    INTVAL (operands[4]) >= 0
10945    && ((INTVAL (operands[3]) > 0
10946         && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
10947        || (<MODE>mode == DImode
10948            && INTVAL (operands[3]) > 32
10949            && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
10950    && ix86_match_ccmode (insn,
10951                          /* If zero_extract mode precision is the same
10952                             as len, the SF of the zero_extract
10953                             comparison will be the most significant
10954                             extracted bit, but this could be matched
10955                             after splitting only for pos 0 len all bits
10956                             trivial extractions.  Require CCZmode.  */
10957                          (GET_MODE_PRECISION (<MODE>mode)
10958                           == INTVAL (operands[3]))
10959                          /* Otherwise, require CCZmode if we'd use a mask
10960                             with the most significant bit set and can't
10961                             widen it to wider mode.  *testdi_1 also
10962                             requires CCZmode if the mask has bit
10963                             31 set and all bits above it clear.  */
10964                          || (INTVAL (operands[3]) + INTVAL (operands[4])
10965                              >= 32)
10966                          /* We can't widen also if val is not a REG.  */
10967                          || (INTVAL (operands[3]) + INTVAL (operands[4])
10968                              == GET_MODE_PRECISION (GET_MODE (operands[2]))
10969                              && !register_operand (operands[2],
10970                                                    GET_MODE (operands[2])))
10971                          /* And we shouldn't widen if
10972                             TARGET_PARTIAL_REG_STALL.  */
10973                          || (TARGET_PARTIAL_REG_STALL
10974                              && (INTVAL (operands[3]) + INTVAL (operands[4])
10975                                  >= (paradoxical_subreg_p (operands[2])
10976                                      && (GET_MODE_CLASS
10977                                           (GET_MODE (SUBREG_REG (operands[2])))
10978                                          == MODE_INT)
10979                                      ? GET_MODE_PRECISION
10980                                          (GET_MODE (SUBREG_REG (operands[2])))
10981                                      : GET_MODE_PRECISION
10982                                          (GET_MODE (operands[2])))))
10983                          ? CCZmode : CCNOmode)"
10984   "#"
10985   "&& 1"
10986   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
10988   rtx val = operands[2];
10989   HOST_WIDE_INT len = INTVAL (operands[3]);
10990   HOST_WIDE_INT pos = INTVAL (operands[4]);
10991   machine_mode mode = GET_MODE (val);
10993   if (SUBREG_P (val))
10994     {
10995       machine_mode submode = GET_MODE (SUBREG_REG (val));
10997       /* Narrow paradoxical subregs to prevent partial register stalls.  */
10998       if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
10999           && GET_MODE_CLASS (submode) == MODE_INT
11000           && (GET_MODE (operands[0]) == CCZmode
11001               || pos + len < GET_MODE_PRECISION (submode)
11002               || REG_P (SUBREG_REG (val))))
11003         {
11004           val = SUBREG_REG (val);
11005           mode = submode;
11006         }
11007     }
11009   /* Small HImode tests can be converted to QImode.  */
11010   if (pos + len <= 8
11011       && register_operand (val, HImode))
11012     {
11013       rtx nval = gen_lowpart (QImode, val);
11014       if (!MEM_P (nval)
11015           || GET_MODE (operands[0]) == CCZmode
11016           || pos + len < 8)
11017         {
11018           val = nval;
11019           mode = QImode;
11020         }
11021     }
11023   gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
11025   /* If the mask is going to have the sign bit set in the mode
11026      we want to do the comparison in and user isn't interested just
11027      in the zero flag, then we must widen the target mode.  */
11028   if (pos + len == GET_MODE_PRECISION (mode)
11029       && GET_MODE (operands[0]) != CCZmode)
11030     {
11031       gcc_assert (pos + len < 32 && !MEM_P (val));
11032       mode = SImode;
11033       val = gen_lowpart (mode, val);
11034     }
11036   wide_int mask
11037     = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
11039   operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
11042 ;; Split and;cmp (as optimized by combine) into not;test
11043 ;; Except when TARGET_BMI provides andn (*andn_<mode>_ccno).
11044 (define_insn_and_split "*test<mode>_not"
11045   [(set (reg:CCZ FLAGS_REG)
11046         (compare:CCZ
11047           (and:SWI
11048             (not:SWI (match_operand:SWI 0 "register_operand"))
11049             (match_operand:SWI 1 "<nonmemory_szext_operand>"))
11050           (const_int 0)))]
11051   "ix86_pre_reload_split ()
11052    && (!TARGET_BMI || !REG_P (operands[1]))"
11053   "#"
11054   "&& 1"
11055   [(set (match_dup 2) (not:SWI (match_dup 0)))
11056    (set (reg:CCZ FLAGS_REG)
11057         (compare:CCZ (and:SWI (match_dup 2) (match_dup 1))
11058                      (const_int 0)))]
11059   "operands[2] = gen_reg_rtx (<MODE>mode);")
11061 ;; Split and;cmp (as optimized by combine) into andn;cmp $0
11062 (define_insn_and_split "*test<mode>_not_doubleword"
11063   [(set (reg:CCZ FLAGS_REG)
11064         (compare:CCZ
11065           (and:DWI
11066             (not:DWI (match_operand:DWI 0 "nonimmediate_operand"))
11067             (match_operand:DWI 1 "nonimmediate_operand"))
11068           (const_int 0)))]
11069   "ix86_pre_reload_split ()"
11070   "#"
11071   "&& 1"
11072   [(parallel
11073       [(set (match_dup 2) (and:DWI (not:DWI (match_dup 0)) (match_dup 1)))
11074        (clobber (reg:CC FLAGS_REG))])
11075    (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
11077   operands[0] = force_reg (<MODE>mode, operands[0]);
11078   operands[2] = gen_reg_rtx (<MODE>mode);
11081 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
11082 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
11083 ;; this is relatively important trick.
11084 ;; Do the conversion only post-reload to avoid limiting of the register class
11085 ;; to QI regs.
11086 (define_split
11087   [(set (match_operand 0 "flags_reg_operand")
11088         (match_operator 1 "compare_operator"
11089           [(and (match_operand 2 "QIreg_operand")
11090                 (match_operand 3 "const_int_operand"))
11091            (const_int 0)]))]
11092    "reload_completed
11093     && GET_MODE (operands[2]) != QImode
11094     && ((ix86_match_ccmode (insn, CCZmode)
11095          && !(INTVAL (operands[3]) & ~(255 << 8)))
11096         || (ix86_match_ccmode (insn, CCNOmode)
11097             && !(INTVAL (operands[3]) & ~(127 << 8))))"
11098   [(set (match_dup 0)
11099         (match_op_dup 1
11100           [(and:QI
11101              (subreg:QI
11102                (zero_extract:HI (match_dup 2)
11103                                 (const_int 8)
11104                                 (const_int 8)) 0)
11105              (match_dup 3))
11106            (const_int 0)]))]
11108   operands[2] = gen_lowpart (HImode, operands[2]);
11109   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
11112 (define_split
11113   [(set (match_operand 0 "flags_reg_operand")
11114         (match_operator 1 "compare_operator"
11115           [(and (match_operand 2 "nonimmediate_operand")
11116                 (match_operand 3 "const_int_operand"))
11117            (const_int 0)]))]
11118    "reload_completed
11119     && GET_MODE (operands[2]) != QImode
11120     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
11121     && ((ix86_match_ccmode (insn, CCZmode)
11122          && !(INTVAL (operands[3]) & ~255))
11123         || (ix86_match_ccmode (insn, CCNOmode)
11124             && !(INTVAL (operands[3]) & ~127)))"
11125   [(set (match_dup 0)
11126         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
11127                          (const_int 0)]))]
11129   operands[2] = gen_lowpart (QImode, operands[2]);
11130   operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
11133 ;; Narrow test instructions with immediate operands that test
11134 ;; memory locations for zero.  E.g. testl $0x00aa0000, mem can be
11135 ;; converted to testb $0xaa, mem+2.  Reject volatile locations and
11136 ;; targets where reading (possibly unaligned) part of memory
11137 ;; location after a large write to the same address causes
11138 ;; store-to-load forwarding stall.
11139 (define_peephole2
11140   [(set (reg:CCZ FLAGS_REG)
11141         (compare:CCZ
11142           (and:SWI248 (match_operand:SWI248 0 "memory_operand")
11143                       (match_operand 1 "const_int_operand"))
11144           (const_int 0)))]
11145   "!TARGET_PARTIAL_MEMORY_READ_STALL && !MEM_VOLATILE_P (operands[0])"
11146   [(set (reg:CCZ FLAGS_REG)
11147         (compare:CCZ (match_dup 2) (const_int 0)))]
11149   unsigned HOST_WIDE_INT ival = UINTVAL (operands[1]);
11150   int first_nonzero_byte, bitsize;
11151   rtx new_addr, new_const;
11152   machine_mode new_mode;
11154   if (ival == 0)
11155     FAIL;
11157   /* Clear bits outside mode width.  */
11158   ival &= GET_MODE_MASK (<MODE>mode);
11160   first_nonzero_byte = ctz_hwi (ival) / BITS_PER_UNIT;
11162   ival >>= first_nonzero_byte * BITS_PER_UNIT;
11164   bitsize = sizeof (ival) * BITS_PER_UNIT - clz_hwi (ival);
11166   if (bitsize <= GET_MODE_BITSIZE (QImode))
11167     new_mode = QImode;
11168   else if (bitsize <= GET_MODE_BITSIZE (HImode))
11169     new_mode = HImode;
11170   else if (bitsize <= GET_MODE_BITSIZE (SImode))
11171     new_mode = SImode;
11172   else
11173     new_mode = DImode;
11175   if (GET_MODE_SIZE (new_mode) >= GET_MODE_SIZE (<MODE>mode))
11176     FAIL;
11178   new_addr = adjust_address (operands[0], new_mode, first_nonzero_byte);
11179   new_const = gen_int_mode (ival, new_mode);
11181   operands[2] = gen_rtx_AND (new_mode, new_addr, new_const);
11184 ;; %%% This used to optimize known byte-wide and operations to memory,
11185 ;; and sometimes to QImode registers.  If this is considered useful,
11186 ;; it should be done with splitters.
11188 (define_expand "and<mode>3"
11189   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
11190         (and:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
11191                    (match_operand:SDWIM 2 "<general_szext_operand>")))]
11192   ""
11194   machine_mode mode = <MODE>mode;
11196   if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
11197       && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
11198     operands[2] = force_reg (<MODE>mode, operands[2]);
11200   if (GET_MODE_SIZE (<MODE>mode) <= UNITS_PER_WORD
11201       && const_int_operand (operands[2], <MODE>mode)
11202       && register_operand (operands[0], <MODE>mode)
11203       && !(TARGET_ZERO_EXTEND_WITH_AND
11204            && optimize_function_for_speed_p (cfun)))
11205     {
11206       unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11208       if (ival == GET_MODE_MASK (SImode))
11209         mode = SImode;
11210       else if (ival == GET_MODE_MASK (HImode))
11211         mode = HImode;
11212       else if (ival == GET_MODE_MASK (QImode))
11213         mode = QImode;
11214     }
11216   if (mode != <MODE>mode)
11217     emit_insn (gen_extend_insn
11218                (operands[0], gen_lowpart (mode, operands[1]),
11219                 <MODE>mode, mode, 1));
11220   else
11221     ix86_expand_binary_operator (AND, <MODE>mode, operands);
11223   DONE;
11226 (define_insn_and_split "*and<dwi>3_doubleword"
11227   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
11228         (and:<DWI>
11229          (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
11230          (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
11231    (clobber (reg:CC FLAGS_REG))]
11232   "ix86_binary_operator_ok (AND, <DWI>mode, operands)"
11233   "#"
11234   "&& reload_completed"
11235   [(const_int:DWIH 0)]
11237   bool emit_insn_deleted_note_p = false;
11239   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
11241   if (operands[2] == const0_rtx)
11242     emit_move_insn (operands[0], const0_rtx);
11243   else if (operands[2] == constm1_rtx)
11244     emit_insn_deleted_note_p = true;
11245   else
11246     ix86_expand_binary_operator (AND, <MODE>mode, &operands[0]);
11248   if (operands[5] == const0_rtx)
11249     emit_move_insn (operands[3], const0_rtx);
11250   else if (operands[5] == constm1_rtx)
11251     {
11252       if (emit_insn_deleted_note_p)
11253         emit_note (NOTE_INSN_DELETED);
11254     }
11255   else
11256     ix86_expand_binary_operator (AND, <MODE>mode, &operands[3]);
11258   DONE;
11261 (define_insn "*anddi_1"
11262   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,?k")
11263         (and:DI
11264          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
11265          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L,k")))
11266    (clobber (reg:CC FLAGS_REG))]
11267   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
11268   "@
11269    and{l}\t{%k2, %k0|%k0, %k2}
11270    and{q}\t{%2, %0|%0, %2}
11271    and{q}\t{%2, %0|%0, %2}
11272    #
11273    #"
11274   [(set_attr "isa" "x64,x64,x64,x64,avx512bw_512")
11275    (set_attr "type" "alu,alu,alu,imovx,msklog")
11276    (set_attr "length_immediate" "*,*,*,0,*")
11277    (set (attr "prefix_rex")
11278      (if_then_else
11279        (and (eq_attr "type" "imovx")
11280             (and (match_test "INTVAL (operands[2]) == 0xff")
11281                  (match_operand 1 "ext_QIreg_operand")))
11282        (const_string "1")
11283        (const_string "*")))
11284    (set_attr "mode" "SI,DI,DI,SI,DI")])
11286 (define_insn_and_split "*anddi_1_btr"
11287   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11288         (and:DI
11289          (match_operand:DI 1 "nonimmediate_operand" "%0")
11290          (match_operand:DI 2 "const_int_operand" "n")))
11291    (clobber (reg:CC FLAGS_REG))]
11292   "TARGET_64BIT && TARGET_USE_BT
11293    && ix86_binary_operator_ok (AND, DImode, operands)
11294    && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
11295   "#"
11296   "&& reload_completed"
11297   [(parallel [(set (zero_extract:DI (match_dup 0)
11298                                     (const_int 1)
11299                                     (match_dup 3))
11300                    (const_int 0))
11301               (clobber (reg:CC FLAGS_REG))])]
11302   "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
11303   [(set_attr "type" "alu1")
11304    (set_attr "prefix_0f" "1")
11305    (set_attr "znver1_decode" "double")
11306    (set_attr "mode" "DI")])
11308 ;; Turn *anddi_1 into *andsi_1_zext if possible.
11309 (define_split
11310   [(set (match_operand:DI 0 "register_operand")
11311         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
11312                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
11313    (clobber (reg:CC FLAGS_REG))]
11314   "TARGET_64BIT"
11315   [(parallel [(set (match_dup 0)
11316                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
11317               (clobber (reg:CC FLAGS_REG))])]
11319   if (GET_CODE (operands[2]) == SYMBOL_REF
11320       || GET_CODE (operands[2]) == LABEL_REF)
11321     {
11322       operands[2] = shallow_copy_rtx (operands[2]);
11323       PUT_MODE (operands[2], SImode);
11324     }
11325   else if (GET_CODE (operands[2]) == CONST)
11326     {
11327       /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
11328       operands[2] = copy_rtx (operands[2]);
11329       PUT_MODE (operands[2], SImode);
11330       PUT_MODE (XEXP (operands[2], 0), SImode);
11331       PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
11332     }    
11333   else
11334     operands[2] = gen_lowpart (SImode, operands[2]);
11337 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11338 (define_insn "*andsi_1_zext"
11339   [(set (match_operand:DI 0 "register_operand" "=r")
11340         (zero_extend:DI
11341           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
11342                   (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
11343    (clobber (reg:CC FLAGS_REG))]
11344   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
11345   "and{l}\t{%2, %k0|%k0, %2}"
11346   [(set_attr "type" "alu")
11347    (set_attr "mode" "SI")])
11349 (define_insn "*and<mode>_1"
11350   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya,?k")
11351         (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm,k")
11352                    (match_operand:SWI24 2 "<general_operand>" "r<i>,<m>,L,k")))
11353    (clobber (reg:CC FLAGS_REG))]
11354   "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11355   "@
11356    and{<imodesuffix>}\t{%2, %0|%0, %2}
11357    and{<imodesuffix>}\t{%2, %0|%0, %2}
11358    #
11359    #"
11360   [(set (attr "isa")
11361         (cond [(eq_attr "alternative" "3")
11362                  (if_then_else (eq_attr "mode" "SI")
11363                    (const_string "avx512bw")
11364                    (const_string "avx512f"))
11365               ]
11366               (const_string "*")))
11367    (set_attr "type" "alu,alu,imovx,msklog")
11368    (set_attr "length_immediate" "*,*,0,*")
11369    (set (attr "prefix_rex")
11370      (if_then_else
11371        (and (eq_attr "type" "imovx")
11372             (and (match_test "INTVAL (operands[2]) == 0xff")
11373                  (match_operand 1 "ext_QIreg_operand")))
11374        (const_string "1")
11375        (const_string "*")))
11376    (set_attr "mode" "<MODE>,<MODE>,SI,<MODE>")])
11378 (define_insn "*andqi_1"
11379   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11380         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11381                 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
11382    (clobber (reg:CC FLAGS_REG))]
11383   "ix86_binary_operator_ok (AND, QImode, operands)"
11384   "@
11385    and{b}\t{%2, %0|%0, %2}
11386    and{b}\t{%2, %0|%0, %2}
11387    and{l}\t{%k2, %k0|%k0, %k2}
11388    #"
11389   [(set_attr "type" "alu,alu,alu,msklog")
11390    (set (attr "mode")
11391         (cond [(eq_attr "alternative" "2")
11392                  (const_string "SI")
11393                 (and (eq_attr "alternative" "3")
11394                      (match_test "!TARGET_AVX512DQ"))
11395                  (const_string "HI")
11396                ]
11397                (const_string "QI")))
11398    ;; Potential partial reg stall on alternative 2.
11399    (set (attr "preferred_for_speed")
11400      (cond [(eq_attr "alternative" "2")
11401               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11402            (symbol_ref "true")))])
11404 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11405 (define_insn_and_split "*<code><mode>_1_slp"
11406   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
11407         (any_logic:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
11408                       (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
11409    (clobber (reg:CC FLAGS_REG))]
11410   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11411   "@
11412    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11413    #"
11414   "&& reload_completed
11415    && !(rtx_equal_p (operands[0], operands[1])
11416         || rtx_equal_p (operands[0], operands[2]))"
11417   [(set (strict_low_part (match_dup 0)) (match_dup 1))
11418    (parallel
11419      [(set (strict_low_part (match_dup 0))
11420            (any_logic:SWI12 (match_dup 0) (match_dup 2)))
11421       (clobber (reg:CC FLAGS_REG))])]
11422   ""
11423   [(set_attr "type" "alu")
11424    (set_attr "mode" "<MODE>")])
11426 (define_split
11427   [(set (match_operand:SWI248 0 "register_operand")
11428         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
11429                     (match_operand:SWI248 2 "const_int_operand")))
11430    (clobber (reg:CC FLAGS_REG))]
11431   "reload_completed
11432    && (!REG_P (operands[1])
11433        || REGNO (operands[0]) != REGNO (operands[1]))"
11434   [(const_int 0)]
11436   unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11437   machine_mode mode;
11439   if (ival == GET_MODE_MASK (SImode))
11440     mode = SImode;
11441   else if (ival == GET_MODE_MASK (HImode))
11442     mode = HImode;
11443   else if (ival == GET_MODE_MASK (QImode))
11444     mode = QImode;
11445   else
11446     gcc_unreachable ();
11448   /* Zero extend to SImode to avoid partial register stalls.  */
11449   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
11450     operands[0] = gen_lowpart (SImode, operands[0]);
11452   emit_insn (gen_extend_insn
11453              (operands[0], gen_lowpart (mode, operands[1]),
11454               GET_MODE (operands[0]), mode, 1));
11455   DONE;
11458 (define_split
11459   [(set (match_operand:SWI48 0 "register_operand")
11460         (and:SWI48 (match_dup 0)
11461                    (const_int -65536)))
11462    (clobber (reg:CC FLAGS_REG))]
11463   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
11464     || optimize_function_for_size_p (cfun)"
11465   [(set (strict_low_part (match_dup 1)) (const_int 0))]
11466   "operands[1] = gen_lowpart (HImode, operands[0]);")
11468 (define_split
11469   [(set (match_operand:SWI248 0 "any_QIreg_operand")
11470         (and:SWI248 (match_dup 0)
11471                     (const_int -256)))
11472    (clobber (reg:CC FLAGS_REG))]
11473   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11474    && reload_completed"
11475   [(set (strict_low_part (match_dup 1)) (const_int 0))]
11476   "operands[1] = gen_lowpart (QImode, operands[0]);")
11478 (define_split
11479   [(set (match_operand:SWI248 0 "QIreg_operand")
11480         (and:SWI248 (match_dup 0)
11481                     (const_int -65281)))
11482    (clobber (reg:CC FLAGS_REG))]
11483   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11484    && reload_completed"
11485   [(parallel
11486      [(set (zero_extract:HI (match_dup 0)
11487                             (const_int 8)
11488                             (const_int 8))
11489            (subreg:HI
11490              (xor:QI
11491                (subreg:QI
11492                  (zero_extract:HI (match_dup 0)
11493                                   (const_int 8)
11494                                   (const_int 8)) 0)
11495                (subreg:QI
11496                  (zero_extract:HI (match_dup 0)
11497                                   (const_int 8)
11498                                   (const_int 8)) 0)) 0))
11499       (clobber (reg:CC FLAGS_REG))])]
11500   "operands[0] = gen_lowpart (HImode, operands[0]);")
11502 (define_insn "*anddi_2"
11503   [(set (reg FLAGS_REG)
11504         (compare
11505          (and:DI
11506           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
11507           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m"))
11508          (const_int 0)))
11509    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
11510         (and:DI (match_dup 1) (match_dup 2)))]
11511   "TARGET_64BIT
11512    && ix86_match_ccmode
11513         (insn,
11514          /* If we are going to emit andl instead of andq, and the operands[2]
11515             constant might have the SImode sign bit set, make sure the sign
11516             flag isn't tested, because the instruction will set the sign flag
11517             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
11518             conservatively assume it might have bit 31 set.  */
11519          (satisfies_constraint_Z (operands[2])
11520           && (!CONST_INT_P (operands[2])
11521               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
11522          ? CCZmode : CCNOmode)
11523    && ix86_binary_operator_ok (AND, DImode, operands)"
11524   "@
11525    and{l}\t{%k2, %k0|%k0, %k2}
11526    and{q}\t{%2, %0|%0, %2}
11527    and{q}\t{%2, %0|%0, %2}"
11528   [(set_attr "type" "alu")
11529    (set_attr "mode" "SI,DI,DI")])
11531 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11532 (define_insn "*andsi_2_zext"
11533   [(set (reg FLAGS_REG)
11534         (compare (and:SI
11535                   (match_operand:SI 1 "nonimmediate_operand" "%0")
11536                   (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
11537                  (const_int 0)))
11538    (set (match_operand:DI 0 "register_operand" "=r")
11539         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
11540   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11541    && ix86_binary_operator_ok (AND, SImode, operands)"
11542   "and{l}\t{%2, %k0|%k0, %2}"
11543   [(set_attr "type" "alu")
11544    (set_attr "mode" "SI")])
11546 (define_insn "*andqi_2_maybe_si"
11547   [(set (reg FLAGS_REG)
11548         (compare (and:QI
11549                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
11550                   (match_operand:QI 2 "general_operand" "qn,m,n"))
11551                  (const_int 0)))
11552    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
11553         (and:QI (match_dup 1) (match_dup 2)))]
11554   "ix86_binary_operator_ok (AND, QImode, operands)
11555    && ix86_match_ccmode (insn,
11556                          CONST_INT_P (operands[2])
11557                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
11559   if (get_attr_mode (insn) == MODE_SI)
11560     {
11561       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
11562         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
11563       return "and{l}\t{%2, %k0|%k0, %2}";
11564     }
11565   return "and{b}\t{%2, %0|%0, %2}";
11567   [(set_attr "type" "alu")
11568    (set (attr "mode")
11569      (cond [(eq_attr "alternative" "2")
11570               (const_string "SI")
11571             (and (match_test "optimize_insn_for_size_p ()")
11572                  (and (match_operand 0 "ext_QIreg_operand")
11573                       (match_operand 2 "const_0_to_127_operand")))
11574               (const_string "SI")
11575            ]
11576            (const_string "QI")))
11577    ;; Potential partial reg stall on alternative 2.
11578    (set (attr "preferred_for_speed")
11579      (cond [(eq_attr "alternative" "2")
11580               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11581            (symbol_ref "true")))])
11583 (define_insn "*and<mode>_2"
11584   [(set (reg FLAGS_REG)
11585         (compare (and:SWI124
11586                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
11587                   (match_operand:SWI124 2 "<general_operand>" "<r><i>,<m>"))
11588                  (const_int 0)))
11589    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>")
11590         (and:SWI124 (match_dup 1) (match_dup 2)))]
11591   "ix86_match_ccmode (insn, CCNOmode)
11592    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11593   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
11594   [(set_attr "type" "alu")
11595    (set_attr "mode" "<MODE>")])
11597 (define_insn "*<code>qi_ext<mode>_0"
11598   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
11599         (any_logic:QI
11600           (subreg:QI
11601             (match_operator:SWI248 3 "extract_operator"
11602               [(match_operand 2 "int248_register_operand" "Q")
11603                (const_int 8)
11604                (const_int 8)]) 0)
11605           (match_operand:QI 1 "nonimmediate_operand" "0")))
11606    (clobber (reg:CC FLAGS_REG))]
11607   ""
11608   "<logic>{b}\t{%h2, %0|%0, %h2}"
11609   [(set_attr "addr" "gpr8")
11610    (set_attr "type" "alu")
11611    (set_attr "mode" "QI")])
11613 (define_expand "andqi_ext_1"
11614   [(parallel
11615      [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
11616                             (const_int 8)
11617                             (const_int 8))
11618            (subreg:HI
11619              (and:QI
11620                (subreg:QI
11621                  (zero_extract:HI (match_operand:HI 1 "register_operand")
11622                                   (const_int 8)
11623                                   (const_int 8)) 0)
11624                (match_operand:QI 2 "const_int_operand")) 0))
11625       (clobber (reg:CC FLAGS_REG))])])
11627 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11628 (define_insn_and_split "*<code>qi_ext<mode>_1"
11629   [(set (zero_extract:SWI248
11630           (match_operand 0 "int248_register_operand" "+Q,&Q")
11631           (const_int 8)
11632           (const_int 8))
11633         (subreg:SWI248
11634           (any_logic:QI
11635             (subreg:QI
11636               (match_operator:SWI248 3 "extract_operator"
11637                 [(match_operand 1 "int248_register_operand" "0,!Q")
11638                  (const_int 8)
11639                  (const_int 8)]) 0)
11640             (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
11641    (clobber (reg:CC FLAGS_REG))]
11642   ""
11643   "@
11644    <logic>{b}\t{%2, %h0|%h0, %2}
11645    #"
11646   "reload_completed
11647    && !(rtx_equal_p (operands[0], operands[1]))"
11648   [(set (zero_extract:SWI248
11649           (match_dup 0) (const_int 8) (const_int 8))
11650         (zero_extract:SWI248
11651           (match_dup 1) (const_int 8) (const_int 8)))
11652    (parallel
11653      [(set (zero_extract:SWI248
11654              (match_dup 0) (const_int 8) (const_int 8))
11655            (subreg:SWI248
11656              (any_logic:QI
11657                (subreg:QI
11658                  (match_op_dup 3
11659                    [(match_dup 0) (const_int 8) (const_int 8)]) 0)
11660                (match_dup 2)) 0))
11661       (clobber (reg:CC FLAGS_REG))])]
11662   ""
11663   [(set_attr "addr" "gpr8")
11664    (set_attr "type" "alu")
11665    (set_attr "mode" "QI")])
11667 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11668 (define_insn_and_split "*<code>qi_ext<mode>_1_cc"
11669   [(set (match_operand 4 "flags_reg_operand")
11670         (match_operator 5 "compare_operator"
11671           [(any_logic:QI
11672              (subreg:QI
11673                (match_operator:SWI248 3 "extract_operator"
11674                  [(match_operand 1 "int248_register_operand" "0,!Q")
11675                   (const_int 8)
11676                   (const_int 8)]) 0)
11677              (match_operand:QI 2 "general_operand" "QnBn,QnBn"))
11678           (const_int 0)]))
11679    (set (zero_extract:SWI248
11680           (match_operand 0 "int248_register_operand" "+Q,&Q")
11681           (const_int 8)
11682           (const_int 8))
11683         (subreg:SWI248
11684           (any_logic:QI
11685             (subreg:QI
11686               (match_op_dup 3
11687                 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
11688             (match_dup 2)) 0))]
11689   "ix86_match_ccmode (insn, CCNOmode)"
11690   "@
11691    <logic>{b}\t{%2, %h0|%h0, %2}
11692    #"
11693   "&& reload_completed
11694    && !(rtx_equal_p (operands[0], operands[1]))"
11695   [(set (zero_extract:SWI248
11696           (match_dup 0) (const_int 8) (const_int 8))
11697         (zero_extract:SWI248
11698           (match_dup 1) (const_int 8) (const_int 8)))
11699    (parallel
11700      [(set (match_dup 4)
11701            (match_op_dup 5
11702              [(any_logic:QI
11703                 (subreg:QI
11704                   (match_op_dup 3
11705                     [(match_dup 0) (const_int 8) (const_int 8)]) 0)
11706                 (match_dup 2))
11707               (const_int 0)]))
11708       (set (zero_extract:SWI248
11709              (match_dup 0) (const_int 8) (const_int 8))
11710            (subreg:SWI248
11711              (any_logic:QI
11712                (subreg:QI
11713                  (match_op_dup 3
11714                    [(match_dup 1) (const_int 8) (const_int 8)]) 0)
11715                (match_dup 2)) 0))])]
11716   ""
11717   [(set_attr "addr" "gpr8")
11718    (set_attr "type" "alu")
11719    (set_attr "mode" "QI")])
11721 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11722 (define_insn_and_split "*<code>qi_ext<mode>_2"
11723   [(set (zero_extract:SWI248
11724           (match_operand 0 "int248_register_operand" "+Q,&Q")
11725           (const_int 8)
11726           (const_int 8))
11727         (subreg:SWI248
11728           (any_logic:QI
11729             (subreg:QI
11730               (match_operator:SWI248 3 "extract_operator"
11731                 [(match_operand 1 "int248_register_operand" "%0,!Q")
11732                  (const_int 8)
11733                  (const_int 8)]) 0)
11734             (subreg:QI
11735               (match_operator:SWI248 4 "extract_operator"
11736                 [(match_operand 2 "int248_register_operand" "Q,Q")
11737                  (const_int 8)
11738                  (const_int 8)]) 0)) 0))
11739    (clobber (reg:CC FLAGS_REG))]
11740   ""
11741   "@
11742    <logic>{b}\t{%h2, %h0|%h0, %h2}
11743    #"
11744   "reload_completed
11745    && !(rtx_equal_p (operands[0], operands[1])
11746         || rtx_equal_p (operands[0], operands[2]))"
11747   [(set (zero_extract:SWI248
11748           (match_dup 0) (const_int 8) (const_int 8))
11749         (zero_extract:SWI248
11750           (match_dup 1) (const_int 8) (const_int 8)))
11751    (parallel
11752      [(set (zero_extract:SWI248
11753              (match_dup 0) (const_int 8) (const_int 8))
11754            (subreg:SWI248
11755              (any_logic:QI
11756                (subreg:QI
11757                  (match_op_dup 3
11758                    [(match_dup 0) (const_int 8) (const_int 8)]) 0)
11759                (subreg:QI
11760                  (match_op_dup 4
11761                    [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
11762       (clobber (reg:CC FLAGS_REG))])]
11763   ""
11764   [(set_attr "type" "alu")
11765    (set_attr "mode" "QI")])
11767 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11768 (define_insn_and_split "*<code>qi_ext<mode>_3"
11769   [(set (zero_extract:SWI248
11770           (match_operand 0 "int248_register_operand" "+Q,&Q")
11771           (const_int 8)
11772           (const_int 8))
11773         (match_operator:SWI248 3 "extract_operator"
11774           [(any_logic
11775              (match_operand 1 "int248_register_operand" "%0,!Q")
11776              (match_operand 2 "int248_register_operand" "Q,Q"))
11777            (const_int 8)
11778            (const_int 8)]))
11779    (clobber (reg:CC FLAGS_REG))]
11780   "GET_MODE (operands[1]) == GET_MODE (operands[2])"
11781   "@
11782    <logic>{b}\t{%h2, %h0|%h0, %h2}
11783    #"
11784   "&& reload_completed
11785    && !(rtx_equal_p (operands[0], operands[1])
11786         || rtx_equal_p (operands[0], operands[2]))"
11787   [(set (zero_extract:SWI248
11788           (match_dup 0) (const_int 8) (const_int 8))
11789         (zero_extract:SWI248
11790           (match_dup 1) (const_int 8) (const_int 8)))
11791    (parallel
11792      [(set (zero_extract:SWI248
11793              (match_dup 0) (const_int 8) (const_int 8))
11794            (match_op_dup 3
11795              [(any_logic (match_dup 4) (match_dup 2))
11796               (const_int 8) (const_int 8)]))
11797       (clobber (reg:CC FLAGS_REG))])]
11798   "operands[4] = gen_lowpart (GET_MODE (operands[1]), operands[0]);"
11799   [(set_attr "type" "alu")
11800    (set_attr "mode" "QI")])
11802 ;; Convert wide AND instructions with immediate operand to shorter QImode
11803 ;; equivalents when possible.
11804 ;; Don't do the splitting with memory operands, since it introduces risk
11805 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
11806 ;; for size, but that can (should?) be handled by generic code instead.
11807 (define_split
11808   [(set (match_operand:SWI248 0 "QIreg_operand")
11809         (and:SWI248 (match_operand:SWI248 1 "register_operand")
11810                     (match_operand:SWI248 2 "const_int_operand")))
11811    (clobber (reg:CC FLAGS_REG))]
11812    "reload_completed
11813     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11814     && !(~INTVAL (operands[2]) & ~(255 << 8))"
11815   [(parallel
11816      [(set (zero_extract:HI (match_dup 0)
11817                             (const_int 8)
11818                             (const_int 8))
11819            (subreg:HI
11820              (and:QI
11821                (subreg:QI
11822                  (zero_extract:HI (match_dup 1)
11823                                   (const_int 8)
11824                                   (const_int 8)) 0)
11825                (match_dup 2)) 0))
11826       (clobber (reg:CC FLAGS_REG))])]
11828   operands[0] = gen_lowpart (HImode, operands[0]);
11829   operands[1] = gen_lowpart (HImode, operands[1]);
11830   operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
11833 ;; Since AND can be encoded with sign extended immediate, this is only
11834 ;; profitable when 7th bit is not set.
11835 (define_split
11836   [(set (match_operand:SWI248 0 "any_QIreg_operand")
11837         (and:SWI248 (match_operand:SWI248 1 "general_operand")
11838                     (match_operand:SWI248 2 "const_int_operand")))
11839    (clobber (reg:CC FLAGS_REG))]
11840    "reload_completed
11841     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11842     && !(~INTVAL (operands[2]) & ~255)
11843     && !(INTVAL (operands[2]) & 128)"
11844   [(parallel [(set (strict_low_part (match_dup 0))
11845                    (and:QI (match_dup 1)
11846                            (match_dup 2)))
11847               (clobber (reg:CC FLAGS_REG))])]
11849   operands[0] = gen_lowpart (QImode, operands[0]);
11850   operands[1] = gen_lowpart (QImode, operands[1]);
11851   operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
11854 (define_insn_and_split "*andn<dwi>3_doubleword_bmi"
11855   [(set (match_operand:<DWI> 0 "register_operand" "=&r,r,r")
11856         (and:<DWI>
11857           (not:<DWI> (match_operand:<DWI> 1 "register_operand" "r,0,r"))
11858           (match_operand:<DWI> 2 "nonimmediate_operand" "ro,ro,0")))
11859    (clobber (reg:CC FLAGS_REG))]
11860   "TARGET_BMI"
11861   "#"
11862   "&& reload_completed"
11863   [(parallel [(set (match_dup 0)
11864                    (and:DWIH (not:DWIH (match_dup 1)) (match_dup 2)))
11865               (clobber (reg:CC FLAGS_REG))])
11866    (parallel [(set (match_dup 3)
11867                    (and:DWIH (not:DWIH (match_dup 4)) (match_dup 5)))
11868               (clobber (reg:CC FLAGS_REG))])]
11869   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
11871 (define_insn_and_split "*andn<mode>3_doubleword"
11872   [(set (match_operand:DWI 0 "register_operand")
11873         (and:DWI
11874           (not:DWI (match_operand:DWI 1 "register_operand"))
11875           (match_operand:DWI 2 "nonimmediate_operand")))
11876    (clobber (reg:CC FLAGS_REG))]
11877   "!TARGET_BMI
11878    && ix86_pre_reload_split ()"
11879   "#"
11880   "&& 1"
11881   [(set (match_dup 3) (not:DWI (match_dup 1)))
11882    (parallel [(set (match_dup 0)
11883                    (and:DWI (match_dup 3) (match_dup 2)))
11884               (clobber (reg:CC FLAGS_REG))])]
11885   "operands[3] = gen_reg_rtx (<MODE>mode);")
11887 (define_insn "*andn<mode>_1"
11888   [(set (match_operand:SWI48 0 "register_operand" "=r,r,?k")
11889         (and:SWI48
11890           (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r,k"))
11891           (match_operand:SWI48 2 "nonimmediate_operand" "r,m,k")))
11892    (clobber (reg:CC FLAGS_REG))]
11893   "TARGET_BMI
11894    || (TARGET_AVX512BW && (<MODE>mode == SImode || TARGET_EVEX512))"
11895   "@
11896    andn\t{%2, %1, %0|%0, %1, %2}
11897    andn\t{%2, %1, %0|%0, %1, %2}
11898    #"
11899   [(set_attr "isa" "bmi,bmi,<kmov_isa>")
11900    (set_attr "type" "bitmanip,bitmanip,msklog")
11901    (set_attr "btver2_decode" "direct, double,*")
11902    (set_attr "mode" "<MODE>")])
11904 (define_insn "*andn<mode>_1"
11905   [(set (match_operand:SWI12 0 "register_operand" "=r,?k")
11906         (and:SWI12
11907           (not:SWI12 (match_operand:SWI12 1 "register_operand" "r,k"))
11908           (match_operand:SWI12 2 "register_operand" "r,k")))
11909    (clobber (reg:CC FLAGS_REG))]
11910   "TARGET_BMI || TARGET_AVX512BW"
11911   "@
11912    andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
11913    #"
11914   [(set_attr "isa" "bmi,avx512f")
11915    (set_attr "type" "bitmanip,msklog")
11916    (set_attr "btver2_decode" "direct,*")
11917    (set (attr "mode")
11918         (cond [(eq_attr "alternative" "0")
11919                  (const_string "SI")
11920                (and (eq_attr "alternative" "1")
11921                     (match_test "!TARGET_AVX512DQ"))
11922                   (const_string "HI")
11923               ]
11924               (const_string "<MODE>")))])
11926 (define_insn "*andn_<mode>_ccno"
11927   [(set (reg FLAGS_REG)
11928         (compare
11929           (and:SWI48
11930             (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
11931             (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
11932           (const_int 0)))
11933    (clobber (match_scratch:SWI48 0 "=r,r"))]
11934   "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
11935   "andn\t{%2, %1, %0|%0, %1, %2}"
11936   [(set_attr "type" "bitmanip")
11937    (set_attr "btver2_decode" "direct, double")
11938    (set_attr "mode" "<MODE>")])
11940 ;; Split *andnsi_1 after reload with -Oz when not;and is shorter.
11941 (define_split
11942   [(set (match_operand:SI 0 "register_operand")
11943         (and:SI (not:SI (match_operand:SI 1 "register_operand"))
11944                 (match_operand:SI 2 "nonimmediate_operand")))
11945    (clobber (reg:CC FLAGS_REG))]
11946   "reload_completed
11947    && optimize_insn_for_size_p () && optimize_size > 1
11948    && REGNO (operands[0]) == REGNO (operands[1])
11949    && LEGACY_INT_REG_P (operands[0])
11950    && !REX_INT_REG_P (operands[2])
11951    && !reg_overlap_mentioned_p (operands[0], operands[2])"
11952   [(set (match_dup 0) (not:SI (match_dup 1)))
11953    (parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
11954               (clobber (reg:CC FLAGS_REG))])])
11956 ;; Split *andn_si_ccno with -Oz when not;test is shorter.
11957 (define_split
11958   [(set (match_operand 0 "flags_reg_operand")
11959         (match_operator 1 "compare_operator"
11960           [(and:SI (not:SI (match_operand:SI 2 "general_reg_operand"))
11961                    (match_operand:SI 3 "nonimmediate_operand"))
11962            (const_int 0)]))
11963    (clobber (match_dup 2))]
11964   "reload_completed
11965    && optimize_insn_for_size_p () && optimize_size > 1
11966    && LEGACY_INT_REG_P (operands[2])
11967    && !REX_INT_REG_P (operands[3])
11968    && !reg_overlap_mentioned_p (operands[2], operands[3])"
11969   [(set (match_dup 2) (not:SI (match_dup 2)))
11970    (set (match_dup 0) (match_op_dup 1
11971                         [(and:SI (match_dup 3) (match_dup 2))
11972                          (const_int 0)]))])
11974 ;; Variant 1 of 4: Split ((A | B) ^ A) ^ C as (B & ~A) ^ C.
11975 (define_split
11976   [(set (match_operand:SWI48 0 "register_operand")
11977         (xor:SWI48
11978            (xor:SWI48
11979               (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11980                          (match_operand:SWI48 2 "nonimmediate_operand"))
11981               (match_dup 1))
11982            (match_operand:SWI48 3 "nonimmediate_operand")))
11983    (clobber (reg:CC FLAGS_REG))]
11984   "TARGET_BMI"
11985   [(parallel
11986       [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
11987        (clobber (reg:CC FLAGS_REG))])
11988    (parallel
11989       [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11990        (clobber (reg:CC FLAGS_REG))])]
11991   "operands[4] = gen_reg_rtx (<MODE>mode);")
11993 ;; Variant 2 of 4: Split ((A | B) ^ B) ^ C as (A & ~B) ^ C.
11994 (define_split
11995   [(set (match_operand:SWI48 0 "register_operand")
11996         (xor:SWI48
11997            (xor:SWI48
11998               (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11999                          (match_operand:SWI48 2 "register_operand"))
12000               (match_dup 2))
12001            (match_operand:SWI48 3 "nonimmediate_operand")))
12002    (clobber (reg:CC FLAGS_REG))]
12003   "TARGET_BMI"
12004   [(parallel
12005       [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
12006        (clobber (reg:CC FLAGS_REG))])
12007    (parallel
12008       [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12009        (clobber (reg:CC FLAGS_REG))])]
12010   "operands[4] = gen_reg_rtx (<MODE>mode);")
12012 ;; Variant 3 of 4: Split ((A | B) ^ C) ^ A as (B & ~A) ^ C.
12013 (define_split
12014   [(set (match_operand:SWI48 0 "register_operand")
12015         (xor:SWI48
12016            (xor:SWI48
12017               (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12018                          (match_operand:SWI48 2 "nonimmediate_operand"))
12019               (match_operand:SWI48 3 "nonimmediate_operand"))
12020            (match_dup 1)))
12021    (clobber (reg:CC FLAGS_REG))]
12022   "TARGET_BMI"
12023   [(parallel
12024       [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
12025        (clobber (reg:CC FLAGS_REG))])
12026    (parallel
12027       [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12028        (clobber (reg:CC FLAGS_REG))])]
12029   "operands[4] = gen_reg_rtx (<MODE>mode);")
12031 ;; Variant 4 of 4: Split ((A | B) ^ C) ^ B as (A & ~B) ^ C.
12032 (define_split
12033   [(set (match_operand:SWI48 0 "register_operand")
12034         (xor:SWI48
12035            (xor:SWI48
12036               (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12037                          (match_operand:SWI48 2 "register_operand"))
12038               (match_operand:SWI48 3 "nonimmediate_operand"))
12039            (match_dup 2)))
12040    (clobber (reg:CC FLAGS_REG))]
12041   "TARGET_BMI"
12042   [(parallel
12043       [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
12044        (clobber (reg:CC FLAGS_REG))])
12045    (parallel
12046       [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12047        (clobber (reg:CC FLAGS_REG))])]
12048   "operands[4] = gen_reg_rtx (<MODE>mode);")
12050 ;; Logical inclusive and exclusive OR instructions
12052 ;; %%% This used to optimize known byte-wide and operations to memory.
12053 ;; If this is considered useful, it should be done with splitters.
12055 (define_expand "<code><mode>3"
12056   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12057         (any_or:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
12058                       (match_operand:SDWIM 2 "<general_operand>")))]
12059   ""
12061   if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
12062       && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
12063     operands[2] = force_reg (<MODE>mode, operands[2]);
12065   ix86_expand_binary_operator (<CODE>, <MODE>mode, operands);
12066   DONE;
12069 (define_insn_and_split "*<code><dwi>3_doubleword"
12070   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12071         (any_or:<DWI>
12072          (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
12073          (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
12074    (clobber (reg:CC FLAGS_REG))]
12075   "ix86_binary_operator_ok (<CODE>, <DWI>mode, operands)"
12076   "#"
12077   "&& reload_completed"
12078   [(const_int:DWIH 0)]
12080   /* This insn may disappear completely when operands[2] == const0_rtx
12081      and operands[0] == operands[1], which requires a NOTE_INSN_DELETED.  */
12082   bool emit_insn_deleted_note_p = false;
12084   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
12086   if (operands[2] == const0_rtx)
12087     emit_insn_deleted_note_p = true;
12088   else if (operands[2] == constm1_rtx)
12089     {
12090       if (<CODE> == IOR)
12091         emit_move_insn (operands[0], constm1_rtx);
12092       else
12093         ix86_expand_unary_operator (NOT, <MODE>mode, &operands[0]);
12094     }
12095   else
12096     ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[0]);
12098   if (operands[5] == const0_rtx)
12099     {
12100       if (emit_insn_deleted_note_p)
12101         emit_note (NOTE_INSN_DELETED);
12102     }
12103   else if (operands[5] == constm1_rtx)
12104     {
12105       if (<CODE> == IOR)
12106         emit_move_insn (operands[3], constm1_rtx);
12107       else
12108         ix86_expand_unary_operator (NOT, <MODE>mode, &operands[3]);
12109     }
12110   else
12111     ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[3]);
12113   DONE;
12116 (define_insn "*<code><mode>_1"
12117   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
12118         (any_or:SWI248
12119          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
12120          (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k")))
12121    (clobber (reg:CC FLAGS_REG))]
12122   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12123   "@
12124    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12125    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12126    #"
12127   [(set_attr "isa" "*,*,<kmov_isa>")
12128    (set_attr "type" "alu, alu, msklog")
12129    (set_attr "mode" "<MODE>")])
12131 (define_insn_and_split "*notxor<mode>_1"
12132   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
12133         (not:SWI248
12134           (xor:SWI248
12135             (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
12136             (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k"))))
12137    (clobber (reg:CC FLAGS_REG))]
12138   "ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
12139   "#"
12140   "&& reload_completed"
12141   [(parallel
12142     [(set (match_dup 0)
12143           (xor:SWI248 (match_dup 1) (match_dup 2)))
12144      (clobber (reg:CC FLAGS_REG))])
12145    (set (match_dup 0)
12146         (not:SWI248 (match_dup 0)))]
12148   if (MASK_REG_P (operands[0]))
12149     {
12150       emit_insn (gen_kxnor<mode> (operands[0], operands[1], operands[2]));
12151       DONE;
12152     }
12154   [(set_attr "isa" "*,*,<kmov_isa>")
12155    (set_attr "type" "alu, alu, msklog")
12156    (set_attr "mode" "<MODE>")])
12158 (define_insn_and_split "*iordi_1_bts"
12159   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12160         (ior:DI
12161          (match_operand:DI 1 "nonimmediate_operand" "%0")
12162          (match_operand:DI 2 "const_int_operand" "n")))
12163    (clobber (reg:CC FLAGS_REG))]
12164   "TARGET_64BIT && TARGET_USE_BT
12165    && ix86_binary_operator_ok (IOR, DImode, operands)
12166    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
12167   "#"
12168   "&& reload_completed"
12169   [(parallel [(set (zero_extract:DI (match_dup 0)
12170                                     (const_int 1)
12171                                     (match_dup 3))
12172                    (const_int 1))
12173               (clobber (reg:CC FLAGS_REG))])]
12174   "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
12175   [(set_attr "type" "alu1")
12176    (set_attr "prefix_0f" "1")
12177    (set_attr "znver1_decode" "double")
12178    (set_attr "mode" "DI")])
12180 (define_insn_and_split "*xordi_1_btc"
12181   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12182         (xor:DI
12183          (match_operand:DI 1 "nonimmediate_operand" "%0")
12184          (match_operand:DI 2 "const_int_operand" "n")))
12185    (clobber (reg:CC FLAGS_REG))]
12186   "TARGET_64BIT && TARGET_USE_BT
12187    && ix86_binary_operator_ok (XOR, DImode, operands)
12188    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
12189   "#"
12190   "&& reload_completed"
12191   [(parallel [(set (zero_extract:DI (match_dup 0)
12192                                     (const_int 1)
12193                                     (match_dup 3))
12194                    (not:DI (zero_extract:DI (match_dup 0)
12195                                             (const_int 1)
12196                                             (match_dup 3))))
12197               (clobber (reg:CC FLAGS_REG))])]
12198   "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
12199   [(set_attr "type" "alu1")
12200    (set_attr "prefix_0f" "1")
12201    (set_attr "znver1_decode" "double")
12202    (set_attr "mode" "DI")])
12204 ;; Optimize a ^ ((a ^ b) & mask) to (~mask & a) | (b & mask)
12205 (define_insn_and_split "*xor2andn"
12206   [(set (match_operand:SWI248 0 "register_operand")
12207         (xor:SWI248
12208           (and:SWI248
12209             (xor:SWI248
12210               (match_operand:SWI248 1 "nonimmediate_operand")
12211               (match_operand:SWI248 2 "nonimmediate_operand"))
12212             (match_operand:SWI248 3 "nonimmediate_operand"))
12213           (match_dup 1)))
12214     (clobber (reg:CC FLAGS_REG))]
12215   "TARGET_BMI && ix86_pre_reload_split ()"
12216   "#"
12217   "&& 1"
12218   [(parallel [(set (match_dup 4)
12219                 (and:SWI248
12220                   (not:SWI248
12221                     (match_dup 3))
12222                   (match_dup 1)))
12223               (clobber (reg:CC FLAGS_REG))])
12224    (parallel [(set (match_dup 5)
12225                 (and:SWI248
12226                   (match_dup 3)
12227                   (match_dup 2)))
12228               (clobber (reg:CC FLAGS_REG))])
12229    (parallel [(set (match_dup 0)
12230                 (ior:SWI248
12231                   (match_dup 4)
12232                   (match_dup 5)))
12233               (clobber (reg:CC FLAGS_REG))])]
12235   operands[1] = force_reg (<MODE>mode, operands[1]);
12236   operands[3] = force_reg (<MODE>mode, operands[3]);
12237   operands[4] = gen_reg_rtx (<MODE>mode);
12238   operands[5] = gen_reg_rtx (<MODE>mode);
12241 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12242 (define_insn "*<code>si_1_zext"
12243   [(set (match_operand:DI 0 "register_operand" "=r")
12244         (zero_extend:DI
12245          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12246                     (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
12247    (clobber (reg:CC FLAGS_REG))]
12248   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12249   "<logic>{l}\t{%2, %k0|%k0, %2}"
12250   [(set_attr "type" "alu")
12251    (set_attr "mode" "SI")])
12253 (define_insn "*<code>si_1_zext_imm"
12254   [(set (match_operand:DI 0 "register_operand" "=r")
12255         (any_or:DI
12256          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
12257          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
12258    (clobber (reg:CC FLAGS_REG))]
12259   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12260   "<logic>{l}\t{%2, %k0|%k0, %2}"
12261   [(set_attr "type" "alu")
12262    (set_attr "mode" "SI")])
12264 (define_insn "*<code>qi_1"
12265   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
12266         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
12267                    (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
12268    (clobber (reg:CC FLAGS_REG))]
12269   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
12270   "@
12271    <logic>{b}\t{%2, %0|%0, %2}
12272    <logic>{b}\t{%2, %0|%0, %2}
12273    <logic>{l}\t{%k2, %k0|%k0, %k2}
12274    #"
12275   [(set_attr "isa" "*,*,*,avx512f")
12276    (set_attr "type" "alu,alu,alu,msklog")
12277    (set (attr "mode")
12278         (cond [(eq_attr "alternative" "2")
12279                  (const_string "SI")
12280                 (and (eq_attr "alternative" "3")
12281                      (match_test "!TARGET_AVX512DQ"))
12282                  (const_string "HI")
12283                ]
12284                (const_string "QI")))
12285    ;; Potential partial reg stall on alternative 2.
12286    (set (attr "preferred_for_speed")
12287      (cond [(eq_attr "alternative" "2")
12288               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12289            (symbol_ref "true")))])
12291 (define_insn_and_split "*notxorqi_1"
12292   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
12293         (not:QI
12294           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
12295                   (match_operand:QI 2 "general_operand" "qn,m,rn,k"))))
12296    (clobber (reg:CC FLAGS_REG))]
12297   "ix86_binary_operator_ok (XOR, QImode, operands)"
12298   "#"
12299   "&& reload_completed"
12300   [(parallel
12301     [(set (match_dup 0)
12302           (xor:QI (match_dup 1) (match_dup 2)))
12303      (clobber (reg:CC FLAGS_REG))])
12304    (set (match_dup 0)
12305         (not:QI (match_dup 0)))]
12307   if (mask_reg_operand (operands[0], QImode))
12308     {
12309       emit_insn (gen_kxnorqi (operands[0], operands[1], operands[2]));
12310       DONE;
12311     }
12313   [(set_attr "isa" "*,*,*,avx512f")
12314    (set_attr "type" "alu,alu,alu,msklog")
12315    (set (attr "mode")
12316         (cond [(eq_attr "alternative" "2")
12317                  (const_string "SI")
12318                 (and (eq_attr "alternative" "3")
12319                      (match_test "!TARGET_AVX512DQ"))
12320                  (const_string "HI")
12321                ]
12322                (const_string "QI")))
12323    ;; Potential partial reg stall on alternative 2.
12324    (set (attr "preferred_for_speed")
12325      (cond [(eq_attr "alternative" "2")
12326               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12327            (symbol_ref "true")))])
12329 ;; convert (sign_extend:WIDE (any_logic:NARROW (memory, immediate)))
12330 ;; to (any_logic:WIDE (sign_extend (memory)), (sign_extend (immediate))).
12331 ;; This eliminates sign extension after logic operation.
12333 (define_split
12334   [(set (match_operand:SWI248 0 "register_operand")
12335         (sign_extend:SWI248
12336           (any_logic:QI (match_operand:QI 1 "memory_operand")
12337                         (match_operand:QI 2 "const_int_operand"))))]
12338   ""
12339   [(set (match_dup 3) (sign_extend:SWI248 (match_dup 1)))
12340    (set (match_dup 0) (any_logic:SWI248 (match_dup 3) (match_dup 2)))]
12341   "operands[3] = gen_reg_rtx (<MODE>mode);")
12343 (define_split
12344   [(set (match_operand:SWI48 0 "register_operand")
12345         (sign_extend:SWI48
12346           (any_logic:HI (match_operand:HI 1 "memory_operand")
12347                         (match_operand:HI 2 "const_int_operand"))))]
12348   ""
12349   [(set (match_dup 3) (sign_extend:SWI48 (match_dup 1)))
12350    (set (match_dup 0) (any_logic:SWI48 (match_dup 3) (match_dup 2)))]
12351   "operands[3] = gen_reg_rtx (<MODE>mode);")
12353 (define_split
12354   [(set (match_operand:DI 0 "register_operand")
12355         (sign_extend:DI
12356           (any_logic:SI (match_operand:SI 1 "memory_operand")
12357                         (match_operand:SI 2 "const_int_operand"))))]
12358   "TARGET_64BIT"
12359   [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
12360    (set (match_dup 0) (any_logic:DI (match_dup 3) (match_dup 2)))]
12361   "operands[3] = gen_reg_rtx (DImode);")
12363 (define_insn "*<code><mode>_2"
12364   [(set (reg FLAGS_REG)
12365         (compare (any_or:SWI
12366                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
12367                   (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
12368                  (const_int 0)))
12369    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
12370         (any_or:SWI (match_dup 1) (match_dup 2)))]
12371   "ix86_match_ccmode (insn, CCNOmode)
12372    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12373   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12374   [(set_attr "type" "alu")
12375    (set_attr "mode" "<MODE>")])
12377 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12378 ;; ??? Special case for immediate operand is missing - it is tricky.
12379 (define_insn "*<code>si_2_zext"
12380   [(set (reg FLAGS_REG)
12381         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12382                             (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
12383                  (const_int 0)))
12384    (set (match_operand:DI 0 "register_operand" "=r")
12385         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
12386   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12387    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12388   "<logic>{l}\t{%2, %k0|%k0, %2}"
12389   [(set_attr "type" "alu")
12390    (set_attr "mode" "SI")])
12392 (define_insn "*<code>si_2_zext_imm"
12393   [(set (reg FLAGS_REG)
12394         (compare (any_or:SI
12395                   (match_operand:SI 1 "nonimmediate_operand" "%0")
12396                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
12397                  (const_int 0)))
12398    (set (match_operand:DI 0 "register_operand" "=r")
12399         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12400   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12401    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12402   "<logic>{l}\t{%2, %k0|%k0, %2}"
12403   [(set_attr "type" "alu")
12404    (set_attr "mode" "SI")])
12406 (define_insn "*<code><mode>_3"
12407   [(set (reg FLAGS_REG)
12408         (compare (any_or:SWI
12409                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
12410                   (match_operand:SWI 2 "<general_operand>" "<g>"))
12411                  (const_int 0)))
12412    (clobber (match_scratch:SWI 0 "=<r>"))]
12413   "ix86_match_ccmode (insn, CCNOmode)
12414    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12415   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12416   [(set_attr "type" "alu")
12417    (set_attr "mode" "<MODE>")])
12419 ;; Convert wide OR instructions with immediate operand to shorter QImode
12420 ;; equivalents when possible.
12421 ;; Don't do the splitting with memory operands, since it introduces risk
12422 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
12423 ;; for size, but that can (should?) be handled by generic code instead.
12424 (define_split
12425   [(set (match_operand:SWI248 0 "QIreg_operand")
12426         (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
12427                        (match_operand:SWI248 2 "const_int_operand")))
12428    (clobber (reg:CC FLAGS_REG))]
12429    "reload_completed
12430     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12431     && !(INTVAL (operands[2]) & ~(255 << 8))"
12432   [(parallel
12433      [(set (zero_extract:HI (match_dup 0)
12434                             (const_int 8)
12435                             (const_int 8))
12436            (subreg:HI
12437              (any_or:QI
12438                (subreg:QI
12439                  (zero_extract:HI (match_dup 1)
12440                                   (const_int 8)
12441                                   (const_int 8)) 0)
12442                (match_dup 2)) 0))
12443       (clobber (reg:CC FLAGS_REG))])]
12445   /* Handle the case where INTVAL (operands[2]) == 0.  */
12446   if (operands[2] == const0_rtx)
12447     {
12448       if (!rtx_equal_p (operands[0], operands[1]))
12449         emit_move_insn (operands[0], operands[1]);
12450       else
12451         emit_note (NOTE_INSN_DELETED);
12452       DONE;
12453     }
12454   operands[0] = gen_lowpart (HImode, operands[0]);
12455   operands[1] = gen_lowpart (HImode, operands[1]);
12456   operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
12459 ;; Since OR can be encoded with sign extended immediate, this is only
12460 ;; profitable when 7th bit is set.
12461 (define_split
12462   [(set (match_operand:SWI248 0 "any_QIreg_operand")
12463         (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
12464                        (match_operand:SWI248 2 "const_int_operand")))
12465    (clobber (reg:CC FLAGS_REG))]
12466    "reload_completed
12467     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12468     && !(INTVAL (operands[2]) & ~255)
12469     && (INTVAL (operands[2]) & 128)"
12470   [(parallel [(set (strict_low_part (match_dup 0))
12471                    (any_or:QI (match_dup 1)
12472                               (match_dup 2)))
12473               (clobber (reg:CC FLAGS_REG))])]
12475   operands[0] = gen_lowpart (QImode, operands[0]);
12476   operands[1] = gen_lowpart (QImode, operands[1]);
12477   operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
12480 (define_expand "xorqi_ext_1_cc"
12481   [(parallel
12482      [(set (reg:CCNO FLAGS_REG)
12483            (compare:CCNO
12484              (xor:QI
12485                (subreg:QI
12486                  (zero_extract:HI (match_operand:HI 1 "register_operand")
12487                                   (const_int 8)
12488                                   (const_int 8)) 0)
12489                (match_operand:QI 2 "const_int_operand"))
12490              (const_int 0)))
12491       (set (zero_extract:HI (match_operand:HI 0 "register_operand")
12492                             (const_int 8)
12493                             (const_int 8))
12494            (subreg:HI
12495              (xor:QI
12496                (subreg:QI
12497                  (zero_extract:HI (match_dup 1)
12498                                   (const_int 8)
12499                                   (const_int 8)) 0)
12500              (match_dup 2)) 0))])])
12502 ;; Peephole2 rega = 0; rega op= regb into rega = regb.
12503 (define_peephole2
12504   [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12505                    (const_int 0))
12506               (clobber (reg:CC FLAGS_REG))])
12507    (parallel [(set (match_dup 0)
12508                    (any_or_plus:SWI (match_dup 0)
12509                                     (match_operand:SWI 1 "<general_operand>")))
12510               (clobber (reg:CC FLAGS_REG))])]
12511   "!reg_mentioned_p (operands[0], operands[1])"
12512   [(set (match_dup 0) (match_dup 1))])
12514 ;; Peephole2 dead instruction in rega = 0; rega op= rega.
12515 (define_peephole2
12516   [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12517                    (const_int 0))
12518               (clobber (reg:CC FLAGS_REG))])
12519    (parallel [(set (match_dup 0)
12520                    (any_or_plus:SWI (match_dup 0) (match_dup 0)))
12521               (clobber (reg:CC FLAGS_REG))])]
12522   ""
12523   [(parallel [(set (match_dup 0) (const_int 0))
12524               (clobber (reg:CC FLAGS_REG))])])
12526 ;; Split DST = (HI<<32)|LO early to minimize register usage.
12527 (define_insn_and_split "*concat<mode><dwi>3_1"
12528   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12529         (any_or_plus:<DWI>
12530           (ashift:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r")
12531                         (match_operand:QI 2 "const_int_operand"))
12532           (zero_extend:<DWI>
12533             (match_operand:DWIH 3 "nonimmediate_operand" "r,m"))))]
12534   "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12535   "#"
12536   "&& reload_completed"
12537   [(const_int 0)]
12539   split_double_concat (<DWI>mode, operands[0], operands[3],
12540                        gen_lowpart (<MODE>mode, operands[1]));
12541   DONE;
12544 (define_insn_and_split "*concat<mode><dwi>3_2"
12545   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12546         (any_or_plus:<DWI>
12547           (zero_extend:<DWI>
12548             (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
12549           (ashift:<DWI> (match_operand:<DWI> 2 "register_operand" "r,r")
12550                         (match_operand:QI 3 "const_int_operand"))))]
12551   "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12552   "#"
12553   "&& reload_completed"
12554   [(const_int 0)]
12556   split_double_concat (<DWI>mode, operands[0], operands[1],
12557                        gen_lowpart (<MODE>mode, operands[2]));
12558   DONE;
12561 (define_insn_and_split "*concat<mode><dwi>3_3"
12562   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r,x")
12563         (any_or_plus:<DWI>
12564           (ashift:<DWI>
12565             (zero_extend:<DWI>
12566               (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m,x"))
12567             (match_operand:QI 2 "const_int_operand"))
12568           (zero_extend:<DWI>
12569             (match_operand:DWIH 3 "nonimmediate_operand" "r,r,m,m,0"))))]
12570   "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12571   "#"
12572   "&& reload_completed"
12573   [(const_int 0)]
12575   if (SSE_REG_P (operands[0]))
12576     {
12577       rtx tmp = gen_rtx_REG (V2DImode, REGNO (operands[0]));
12578       emit_insn (gen_vec_concatv2di (tmp, operands[3], operands[1]));
12579     }
12580   else
12581     split_double_concat (<DWI>mode, operands[0], operands[3], operands[1]);
12582   DONE;
12584   [(set_attr "isa" "*,*,*,x64,x64")])
12586 (define_insn_and_split "*concat<mode><dwi>3_4"
12587   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
12588         (any_or_plus:<DWI>
12589           (zero_extend:<DWI>
12590             (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
12591           (ashift:<DWI>
12592             (zero_extend:<DWI>
12593               (match_operand:DWIH 2 "nonimmediate_operand" "r,r,m,m"))
12594             (match_operand:QI 3 "const_int_operand"))))]
12595   "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12596   "#"
12597   "&& reload_completed"
12598   [(const_int 0)]
12600   split_double_concat (<DWI>mode, operands[0], operands[1], operands[2]);
12601   DONE;
12603   [(set_attr "isa" "*,*,*,x64")])
12605 (define_insn_and_split "*concat<half><mode>3_5"
12606   [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o,o")
12607         (any_or_plus:DWI
12608           (ashift:DWI (match_operand:DWI 1 "register_operand" "r,r,r")
12609                       (match_operand:QI 2 "const_int_operand"))
12610           (match_operand:DWI 3 "const_scalar_int_operand" "n,n,Wd")))]
12611   "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT / 2
12612    && (<MODE>mode == DImode
12613        ? CONST_INT_P (operands[3])
12614          && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12615        : CONST_INT_P (operands[3])
12616        ? INTVAL (operands[3]) >= 0
12617        : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12618          && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12619    && !(CONST_INT_P (operands[3])
12620         ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12621         : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12622                                                                      0)),
12623                                         VOIDmode))"
12624   "#"
12625   "&& reload_completed"
12626   [(const_int 0)]
12628   rtx op3 = simplify_subreg (<HALF>mode, operands[3], <MODE>mode, 0);
12629   split_double_concat (<MODE>mode, operands[0], op3,
12630                        gen_lowpart (<HALF>mode, operands[1]));
12631   DONE;
12633   [(set_attr "isa" "*,nox64,x64")])
12635 (define_insn_and_split "*concat<mode><dwi>3_6"
12636   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12637         (any_or_plus:<DWI>
12638           (ashift:<DWI>
12639             (zero_extend:<DWI>
12640               (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12641             (match_operand:QI 2 "const_int_operand"))
12642           (match_operand:<DWI> 3 "const_scalar_int_operand" "n,n,Wd,n")))]
12643   "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT
12644    && (<DWI>mode == DImode
12645        ? CONST_INT_P (operands[3])
12646          && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12647        : CONST_INT_P (operands[3])
12648        ? INTVAL (operands[3]) >= 0
12649        : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12650          && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12651    && !(CONST_INT_P (operands[3])
12652         ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12653         : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12654                                                                      0)),
12655                                         VOIDmode))"
12656   "#"
12657   "&& reload_completed"
12658   [(const_int 0)]
12660   rtx op3 = simplify_subreg (<MODE>mode, operands[3], <DWI>mode, 0);
12661   split_double_concat (<DWI>mode, operands[0], op3, operands[1]);
12662   DONE;
12664   [(set_attr "isa" "*,nox64,x64,*")])
12666 (define_insn_and_split "*concat<mode><dwi>3_7"
12667   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12668         (any_or_plus:<DWI>
12669           (zero_extend:<DWI>
12670             (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12671           (match_operand:<DWI> 2 "const_scalar_int_operand" "n,n,Wd,n")))]
12672   "<DWI>mode == DImode
12673    ? CONST_INT_P (operands[2])
12674      && (UINTVAL (operands[2]) & GET_MODE_MASK (SImode)) == 0
12675      && !ix86_endbr_immediate_operand (operands[2], VOIDmode)
12676    : CONST_WIDE_INT_P (operands[2])
12677      && CONST_WIDE_INT_NUNITS (operands[2]) == 2
12678      && CONST_WIDE_INT_ELT (operands[2], 0) == 0
12679      && !ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[2],
12680                                                                     1)),
12681                                        VOIDmode)"
12682   "#"
12683   "&& reload_completed"
12684   [(const_int 0)]
12686   rtx op2;
12687   if (<DWI>mode == DImode)
12688     op2 = gen_int_mode (INTVAL (operands[2]) >> 32, <MODE>mode);
12689   else
12690     op2 = gen_int_mode (CONST_WIDE_INT_ELT (operands[2], 1), <MODE>mode);
12691   split_double_concat (<DWI>mode, operands[0], operands[1], op2);
12692   DONE;
12694   [(set_attr "isa" "*,nox64,x64,*")])
12696 ;; Negation instructions
12698 (define_expand "neg<mode>2"
12699   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12700         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
12701   ""
12702   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
12704 (define_insn_and_split "*neg<dwi>2_doubleword"
12705   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
12706         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
12707    (clobber (reg:CC FLAGS_REG))]
12708   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
12709   "#"
12710   "&& reload_completed"
12711   [(parallel
12712     [(set (reg:CCC FLAGS_REG)
12713           (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12714      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
12715    (parallel
12716     [(set (match_dup 2)
12717           (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12718                                 (match_dup 3))
12719                      (const_int 0)))
12720      (clobber (reg:CC FLAGS_REG))])
12721    (parallel
12722     [(set (match_dup 2)
12723           (neg:DWIH (match_dup 2)))
12724      (clobber (reg:CC FLAGS_REG))])]
12725   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
12727 ;; Convert:
12728 ;;   mov %esi, %edx
12729 ;;   negl %eax
12730 ;;   adcl $0, %edx
12731 ;;   negl %edx
12732 ;; to:
12733 ;;   xorl %edx, %edx
12734 ;;   negl %eax
12735 ;;   sbbl %esi, %edx
12737 (define_peephole2
12738   [(set (match_operand:SWI48 0 "general_reg_operand")
12739         (match_operand:SWI48 1 "nonimmediate_gr_operand"))
12740    (parallel
12741     [(set (reg:CCC FLAGS_REG)
12742           (unspec:CCC [(match_operand:SWI48 2 "general_reg_operand")
12743                        (const_int 0)] UNSPEC_CC_NE))
12744      (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12745    (parallel
12746     [(set (match_dup 0)
12747           (plus:SWI48 (plus:SWI48
12748                         (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12749                         (match_dup 0))
12750                       (const_int 0)))
12751      (clobber (reg:CC FLAGS_REG))])
12752    (parallel
12753     [(set (match_dup 0)
12754           (neg:SWI48 (match_dup 0)))
12755      (clobber (reg:CC FLAGS_REG))])]
12756   "REGNO (operands[0]) != REGNO (operands[2])
12757    && !reg_mentioned_p (operands[0], operands[1])
12758    && !reg_mentioned_p (operands[2], operands[1])"
12759   [(parallel
12760     [(set (reg:CCC FLAGS_REG)
12761           (unspec:CCC [(match_dup 2) (const_int 0)] UNSPEC_CC_NE))
12762      (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12763    (parallel
12764     [(set (match_dup 0)
12765           (minus:SWI48 (minus:SWI48
12766                          (match_dup 0)
12767                          (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0)))
12768                        (match_dup 1)))
12769      (clobber (reg:CC FLAGS_REG))])]
12770   "ix86_expand_clear (operands[0]);")
12772 ;; Convert:
12773 ;;   xorl %edx, %edx
12774 ;;   negl %eax
12775 ;;   adcl $0, %edx
12776 ;;   negl %edx
12777 ;; to:
12778 ;;   negl %eax
12779 ;;   sbbl %edx, %edx    // *x86_mov<mode>cc_0_m1
12781 (define_peephole2
12782   [(parallel
12783     [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
12784      (clobber (reg:CC FLAGS_REG))])
12785    (parallel
12786     [(set (reg:CCC FLAGS_REG)
12787           (unspec:CCC [(match_operand:SWI48 1 "general_reg_operand")
12788                        (const_int 0)] UNSPEC_CC_NE))
12789      (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12790    (parallel
12791     [(set (match_dup 0)
12792           (plus:SWI48 (plus:SWI48
12793                         (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12794                         (match_dup 0))
12795                       (const_int 0)))
12796      (clobber (reg:CC FLAGS_REG))])
12797    (parallel
12798     [(set (match_dup 0)
12799           (neg:SWI48 (match_dup 0)))
12800      (clobber (reg:CC FLAGS_REG))])]
12801   "REGNO (operands[0]) != REGNO (operands[1])"
12802   [(parallel
12803     [(set (reg:CCC FLAGS_REG)
12804           (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12805      (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12806    (parallel
12807     [(set (match_dup 0)
12808           (if_then_else:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12809                               (const_int -1)
12810                               (const_int 0)))
12811      (clobber (reg:CC FLAGS_REG))])])
12813 (define_insn "*neg<mode>_1"
12814   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12815         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
12816    (clobber (reg:CC FLAGS_REG))]
12817   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12818   "neg{<imodesuffix>}\t%0"
12819   [(set_attr "type" "negnot")
12820    (set_attr "mode" "<MODE>")])
12822 (define_insn "*negsi_1_zext"
12823   [(set (match_operand:DI 0 "register_operand" "=r")
12824         (zero_extend:DI
12825           (neg:SI (match_operand:SI 1 "register_operand" "0"))))
12826    (clobber (reg:CC FLAGS_REG))]
12827   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
12828   "neg{l}\t%k0"
12829   [(set_attr "type" "negnot")
12830    (set_attr "mode" "SI")])
12832 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12833 (define_insn_and_split "*neg<mode>_1_slp"
12834   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
12835         (neg:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))
12836    (clobber (reg:CC FLAGS_REG))]
12837   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12838   "@
12839    neg{<imodesuffix>}\t%0
12840    #"
12841   "&& reload_completed
12842    && !(rtx_equal_p (operands[0], operands[1]))"
12843   [(set (strict_low_part (match_dup 0)) (match_dup 1))
12844    (parallel
12845      [(set (strict_low_part (match_dup 0))
12846            (neg:SWI12 (match_dup 0)))
12847       (clobber (reg:CC FLAGS_REG))])]
12848   ""
12849   [(set_attr "type" "negnot")
12850    (set_attr "mode" "<MODE>")])
12852 (define_insn "*neg<mode>_2"
12853   [(set (reg FLAGS_REG)
12854         (compare
12855           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
12856           (const_int 0)))
12857    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12858         (neg:SWI (match_dup 1)))]
12859   "ix86_match_ccmode (insn, CCGOCmode)
12860    && ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12861   "neg{<imodesuffix>}\t%0"
12862   [(set_attr "type" "negnot")
12863    (set_attr "mode" "<MODE>")])
12865 (define_insn "*negsi_2_zext"
12866   [(set (reg FLAGS_REG)
12867         (compare
12868           (neg:SI (match_operand:SI 1 "register_operand" "0"))
12869           (const_int 0)))
12870    (set (match_operand:DI 0 "register_operand" "=r")
12871         (zero_extend:DI
12872           (neg:SI (match_dup 1))))]
12873   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12874    && ix86_unary_operator_ok (NEG, SImode, operands)"
12875   "neg{l}\t%k0"
12876   [(set_attr "type" "negnot")
12877    (set_attr "mode" "SI")])
12879 (define_insn "*neg<mode>_ccc_1"
12880   [(set (reg:CCC FLAGS_REG)
12881         (unspec:CCC
12882           [(match_operand:SWI 1 "nonimmediate_operand" "0")
12883            (const_int 0)] UNSPEC_CC_NE))
12884    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12885         (neg:SWI (match_dup 1)))]
12886   ""
12887   "neg{<imodesuffix>}\t%0"
12888   [(set_attr "type" "negnot")
12889    (set_attr "mode" "<MODE>")])
12891 (define_insn "*neg<mode>_ccc_2"
12892   [(set (reg:CCC FLAGS_REG)
12893         (unspec:CCC
12894           [(match_operand:SWI 1 "nonimmediate_operand" "0")
12895            (const_int 0)] UNSPEC_CC_NE))
12896    (clobber (match_scratch:SWI 0 "=<r>"))]
12897   ""
12898   "neg{<imodesuffix>}\t%0"
12899   [(set_attr "type" "negnot")
12900    (set_attr "mode" "<MODE>")])
12902 (define_expand "x86_neg<mode>_ccc"
12903   [(parallel
12904     [(set (reg:CCC FLAGS_REG)
12905           (unspec:CCC [(match_operand:SWI48 1 "register_operand")
12906                        (const_int 0)] UNSPEC_CC_NE))
12907      (set (match_operand:SWI48 0 "register_operand")
12908           (neg:SWI48 (match_dup 1)))])])
12910 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12911 (define_insn_and_split "*negqi_ext<mode>_1"
12912   [(set (zero_extract:SWI248
12913           (match_operand 0 "int248_register_operand" "+Q,&Q")
12914           (const_int 8)
12915           (const_int 8))
12916         (subreg:SWI248
12917           (neg:QI
12918             (subreg:QI
12919               (match_operator:SWI248 2 "extract_operator"
12920                 [(match_operand 1 "int248_register_operand" "0,!Q")
12921                  (const_int 8)
12922                  (const_int 8)]) 0)) 0))
12923    (clobber (reg:CC FLAGS_REG))]
12924   ""
12925   "@
12926    neg{b}\t%h0
12927    #"
12928   "reload_completed
12929    && !(rtx_equal_p (operands[0], operands[1]))"
12930   [(set (zero_extract:SWI248
12931           (match_dup 0) (const_int 8) (const_int 8))
12932         (zero_extract:SWI248
12933           (match_dup 1) (const_int 8) (const_int 8)))
12934    (parallel
12935      [(set (zero_extract:SWI248
12936              (match_dup 0) (const_int 8) (const_int 8))
12937            (subreg:SWI248
12938              (neg:QI
12939                (subreg:QI
12940                  (match_op_dup 2
12941                    [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))
12942       (clobber (reg:CC FLAGS_REG))])]
12943   ""
12944   [(set_attr "type" "negnot")
12945    (set_attr "mode" "QI")])
12947 ;; Negate with jump on overflow.
12948 (define_expand "negv<mode>3"
12949   [(parallel [(set (reg:CCO FLAGS_REG)
12950                    (unspec:CCO
12951                      [(match_operand:SWI 1 "register_operand")
12952                       (match_dup 3)] UNSPEC_CC_NE))
12953               (set (match_operand:SWI 0 "register_operand")
12954                    (neg:SWI (match_dup 1)))])
12955    (set (pc) (if_then_else
12956                (eq (reg:CCO FLAGS_REG) (const_int 0))
12957                (label_ref (match_operand 2))
12958                (pc)))]
12959   ""
12961   operands[3]
12962     = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
12963                     <MODE>mode);
12966 (define_insn "*negv<mode>3"
12967   [(set (reg:CCO FLAGS_REG)
12968         (unspec:CCO [(match_operand:SWI 1 "nonimmediate_operand" "0")
12969                      (match_operand:SWI 2 "const_int_operand")]
12970                     UNSPEC_CC_NE))
12971    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12972         (neg:SWI (match_dup 1)))]
12973   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
12974    && mode_signbit_p (<MODE>mode, operands[2])"
12975   "neg{<imodesuffix>}\t%0"
12976   [(set_attr "type" "negnot")
12977    (set_attr "mode" "<MODE>")])
12979 ;; Optimize *negsi_1 followed by *cmpsi_ccno_1 (PR target/91384)
12980 (define_peephole2
12981   [(set (match_operand:SWI 0 "general_reg_operand")
12982         (match_operand:SWI 1 "general_reg_operand"))
12983    (parallel [(set (match_dup 0) (neg:SWI (match_dup 0)))
12984               (clobber (reg:CC FLAGS_REG))])
12985    (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))]
12986   ""
12987   [(set (match_dup 0) (match_dup 1))
12988    (parallel [(set (reg:CCZ FLAGS_REG)
12989                    (compare:CCZ (neg:SWI (match_dup 0)) (const_int 0)))
12990               (set (match_dup 0) (neg:SWI (match_dup 0)))])])
12992 ;; Special expand pattern to handle integer mode abs
12994 (define_expand "abs<mode>2"
12995   [(parallel
12996     [(set (match_operand:SDWIM 0 "register_operand")
12997           (abs:SDWIM
12998             (match_operand:SDWIM 1 "general_operand")))
12999      (clobber (reg:CC FLAGS_REG))])]
13000   "TARGET_CMOVE
13001    && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)"
13003   if (TARGET_EXPAND_ABS)
13004     {
13005       machine_mode mode = <MODE>mode;
13006       operands[1] = force_reg (mode, operands[1]);
13008       /* Generate rtx abs using:
13009          abs (x) = (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)) */
13011       rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
13012       rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
13013                                            shift_amount, NULL_RTX,
13014                                            0, OPTAB_DIRECT);
13015       rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
13016                                          operands[0], 0, OPTAB_DIRECT);
13017       rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
13018                                            operands[0], 0, OPTAB_DIRECT);
13019       if (!rtx_equal_p (minus_dst, operands[0]))
13020         emit_move_insn (operands[0], minus_dst);
13021       DONE;
13022     }
13025 (define_insn_and_split "*abs<dwi>2_doubleword"
13026   [(set (match_operand:<DWI> 0 "register_operand")
13027         (abs:<DWI>
13028           (match_operand:<DWI> 1 "general_operand")))
13029    (clobber (reg:CC FLAGS_REG))]
13030   "TARGET_CMOVE
13031    && ix86_pre_reload_split ()"
13032    "#"
13033    "&& 1"
13034   [(parallel
13035     [(set (reg:CCC FLAGS_REG)
13036           (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13037      (set (match_dup 2) (neg:DWIH (match_dup 1)))])
13038    (parallel
13039     [(set (match_dup 5)
13040           (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
13041                                 (match_dup 4))
13042                      (const_int 0)))
13043      (clobber (reg:CC FLAGS_REG))])
13044    (parallel
13045      [(set (reg:CCGOC FLAGS_REG)
13046            (compare:CCGOC
13047              (neg:DWIH (match_dup 5))
13048              (const_int 0)))
13049       (set (match_dup 5)
13050            (neg:DWIH (match_dup 5)))])
13051    (set (match_dup 0)
13052         (if_then_else:DWIH
13053           (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13054           (match_dup 2)
13055           (match_dup 1)))
13056    (set (match_dup 3)
13057         (if_then_else:DWIH
13058           (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13059           (match_dup 5)
13060           (match_dup 4)))]
13062   operands[1] = force_reg (<DWI>mode, operands[1]);
13063   operands[2] = gen_reg_rtx (<DWI>mode);
13065   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13068 (define_insn_and_split "*nabs<dwi>2_doubleword"
13069   [(set (match_operand:<DWI> 0 "register_operand")
13070         (neg:<DWI>
13071           (abs:<DWI>
13072             (match_operand:<DWI> 1 "general_operand"))))
13073    (clobber (reg:CC FLAGS_REG))]
13074   "TARGET_CMOVE
13075    && ix86_pre_reload_split ()"
13076    "#"
13077    "&& 1"
13078   [(parallel
13079     [(set (reg:CCC FLAGS_REG)
13080           (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13081      (set (match_dup 2) (neg:DWIH (match_dup 1)))])
13082    (parallel
13083     [(set (match_dup 5)
13084           (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
13085                                 (match_dup 4))
13086                      (const_int 0)))
13087      (clobber (reg:CC FLAGS_REG))])
13088    (parallel
13089      [(set (reg:CCGOC FLAGS_REG)
13090            (compare:CCGOC
13091              (neg:DWIH (match_dup 5))
13092              (const_int 0)))
13093       (set (match_dup 5)
13094            (neg:DWIH (match_dup 5)))])
13095    (set (match_dup 0)
13096         (if_then_else:DWIH
13097           (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13098           (match_dup 2)
13099           (match_dup 1)))
13100    (set (match_dup 3)
13101         (if_then_else:DWIH
13102           (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13103           (match_dup 5)
13104           (match_dup 4)))]
13106   operands[1] = force_reg (<DWI>mode, operands[1]);
13107   operands[2] = gen_reg_rtx (<DWI>mode);
13109   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13112 (define_insn_and_split "*abs<mode>2_1"
13113   [(set (match_operand:SWI 0 "register_operand")
13114         (abs:SWI
13115           (match_operand:SWI 1 "general_operand")))
13116    (clobber (reg:CC FLAGS_REG))]
13117   "TARGET_CMOVE
13118    && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
13119    && ix86_pre_reload_split ()"
13120    "#"
13121    "&& 1"
13122   [(parallel
13123      [(set (reg:CCGOC FLAGS_REG)
13124            (compare:CCGOC
13125              (neg:SWI (match_dup 1))
13126              (const_int 0)))
13127       (set (match_dup 2)
13128            (neg:SWI (match_dup 1)))])
13129    (set (match_dup 0)
13130         (if_then_else:SWI
13131           (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13132           (match_dup 2)
13133           (match_dup 1)))]
13135   operands[1] = force_reg (<MODE>mode, operands[1]);
13136   operands[2] = gen_reg_rtx (<MODE>mode);
13139 (define_insn_and_split "*nabs<mode>2_1"
13140   [(set (match_operand:SWI 0 "register_operand")
13141         (neg:SWI
13142           (abs:SWI
13143             (match_operand:SWI 1 "general_operand"))))
13144    (clobber (reg:CC FLAGS_REG))]
13145   "TARGET_CMOVE
13146    && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
13147    && ix86_pre_reload_split ()"
13148    "#"
13149    "&& 1"
13150   [(parallel
13151      [(set (reg:CCGOC FLAGS_REG)
13152            (compare:CCGOC
13153              (neg:SWI (match_dup 1))
13154              (const_int 0)))
13155       (set (match_dup 2)
13156            (neg:SWI (match_dup 1)))])
13157    (set (match_dup 0)
13158         (if_then_else:SWI
13159           (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13160           (match_dup 2)
13161           (match_dup 1)))]
13163   operands[1] = force_reg (<MODE>mode, operands[1]);
13164   operands[2] = gen_reg_rtx (<MODE>mode);
13167 (define_expand "<code>tf2"
13168   [(set (match_operand:TF 0 "register_operand")
13169         (absneg:TF (match_operand:TF 1 "register_operand")))]
13170   "TARGET_SSE"
13171   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
13173 (define_insn_and_split "*<code>tf2_1"
13174   [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13175         (absneg:TF
13176           (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
13177    (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13178   "TARGET_SSE"
13179   "#"
13180   "&& reload_completed"
13181   [(set (match_dup 0)
13182         (<absneg_op>:TF (match_dup 1) (match_dup 2)))]
13184   if (TARGET_AVX)
13185     {
13186       if (MEM_P (operands[1]))
13187         std::swap (operands[1], operands[2]);
13188     }
13189   else
13190    {
13191      if (operands_match_p (operands[0], operands[2]))
13192        std::swap (operands[1], operands[2]);
13193    }
13195   [(set_attr "isa" "noavx,noavx,avx,avx")])
13197 (define_insn_and_split "*nabstf2_1"
13198   [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13199         (neg:TF
13200           (abs:TF
13201             (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
13202    (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13203   "TARGET_SSE"
13204   "#"
13205   "&& reload_completed"
13206   [(set (match_dup 0)
13207         (ior:TF (match_dup 1) (match_dup 2)))]
13209   if (TARGET_AVX)
13210     {
13211       if (MEM_P (operands[1]))
13212         std::swap (operands[1], operands[2]);
13213     }
13214   else
13215    {
13216      if (operands_match_p (operands[0], operands[2]))
13217        std::swap (operands[1], operands[2]);
13218    }
13220   [(set_attr "isa" "noavx,noavx,avx,avx")])
13222 (define_expand "<code>hf2"
13223   [(set (match_operand:HF 0 "register_operand")
13224         (absneg:HF (match_operand:HF 1 "register_operand")))]
13225   "TARGET_AVX512FP16"
13226   "ix86_expand_fp_absneg_operator (<CODE>, HFmode, operands); DONE;")
13228 (define_expand "<code><mode>2"
13229   [(set (match_operand:X87MODEF 0 "register_operand")
13230         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
13231   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13232   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13234 ;; Changing of sign for FP values is doable using integer unit too.
13235 (define_insn "*<code><mode>2_i387_1"
13236   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
13237         (absneg:X87MODEF
13238           (match_operand:X87MODEF 1 "register_operand" "0,0")))
13239    (clobber (reg:CC FLAGS_REG))]
13240   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13241   "#")
13243 (define_split
13244   [(set (match_operand:X87MODEF 0 "fp_register_operand")
13245         (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
13246    (clobber (reg:CC FLAGS_REG))]
13247   "TARGET_80387 && reload_completed"
13248   [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
13250 (define_split
13251   [(set (match_operand:X87MODEF 0 "general_reg_operand")
13252         (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
13253    (clobber (reg:CC FLAGS_REG))]
13254   "TARGET_80387 && reload_completed"
13255   [(const_int 0)]
13256   "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13258 (define_insn_and_split "*<code>hf2_1"
13259   [(set (match_operand:HF 0 "register_operand" "=Yv")
13260         (absneg:HF
13261           (match_operand:HF 1 "register_operand" "Yv")))
13262    (use (match_operand:V8HF 2 "vector_operand" "Yvm"))
13263    (clobber (reg:CC FLAGS_REG))]
13264   "TARGET_AVX512FP16"
13265   "#"
13266   "&& reload_completed"
13267   [(set (match_dup 0)
13268         (<absneg_op>:V8HF (match_dup 1) (match_dup 2)))]
13270   operands[0] = lowpart_subreg (V8HFmode, operands[0], HFmode);
13271   operands[1] = lowpart_subreg (V8HFmode, operands[1], HFmode);
13274 (define_insn "*<code><mode>2_1"
13275   [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
13276         (absneg:MODEF
13277           (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
13278    (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
13279    (clobber (reg:CC FLAGS_REG))]
13280   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13281   "#"
13282   [(set_attr "isa" "noavx,noavx,avx,*,*")
13283    (set (attr "enabled")
13284      (if_then_else
13285        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
13286        (if_then_else
13287          (eq_attr "alternative" "3,4")
13288          (symbol_ref "TARGET_MIX_SSE_I387")
13289          (const_string "*"))
13290        (if_then_else
13291          (eq_attr "alternative" "3,4")
13292          (symbol_ref "true")
13293          (symbol_ref "false"))))])
13295 (define_split
13296   [(set (match_operand:MODEF 0 "sse_reg_operand")
13297         (absneg:MODEF
13298           (match_operand:MODEF 1 "sse_reg_operand")))
13299    (use (match_operand:<ssevecmodef> 2 "vector_operand"))
13300    (clobber (reg:CC FLAGS_REG))]
13301   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13302    && reload_completed"
13303   [(set (match_dup 0)
13304         (<absneg_op>:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13306   machine_mode mode = <MODE>mode;
13307   machine_mode vmode = <ssevecmodef>mode;
13309   operands[0] = lowpart_subreg (vmode, operands[0], mode);
13310   operands[1] = lowpart_subreg (vmode, operands[1], mode);
13312   if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13313     std::swap (operands[1], operands[2]);
13316 (define_split
13317   [(set (match_operand:MODEF 0 "fp_register_operand")
13318         (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
13319    (use (match_operand 2))
13320    (clobber (reg:CC FLAGS_REG))]
13321   "TARGET_80387 && reload_completed"
13322   [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
13324 (define_split
13325   [(set (match_operand:MODEF 0 "general_reg_operand")
13326         (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
13327    (use (match_operand 2))
13328    (clobber (reg:CC FLAGS_REG))]
13329   "TARGET_80387 && reload_completed"
13330   [(const_int 0)]
13331   "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13333 (define_insn_and_split "*nabs<mode>2_1"
13334   [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
13335         (neg:MODEF
13336           (abs:MODEF
13337             (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
13338    (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
13339   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13340   "#"
13341   "&& reload_completed"
13342   [(set (match_dup 0)
13343         (ior:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13345   machine_mode mode = <MODE>mode;
13346   machine_mode vmode = <ssevecmodef>mode;
13348   operands[0] = lowpart_subreg (vmode, operands[0], mode);
13349   operands[1] = lowpart_subreg (vmode, operands[1], mode);
13351   if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13352     std::swap (operands[1], operands[2]);
13354   [(set_attr "isa" "noavx,noavx,avx")])
13356 ;; Conditionalize these after reload. If they match before reload, we
13357 ;; lose the clobber and ability to use integer instructions.
13359 (define_insn "*<code><mode>2_i387"
13360   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
13361         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
13362   "TARGET_80387 && reload_completed"
13363   "<absneg_mnemonic>"
13364   [(set_attr "type" "fsgn")
13365    (set_attr "mode" "<MODE>")])
13367 ;; Copysign instructions
13369 (define_expand "copysign<mode>3"
13370   [(match_operand:SSEMODEF 0 "register_operand")
13371    (match_operand:SSEMODEF 1 "nonmemory_operand")
13372    (match_operand:SSEMODEF 2 "register_operand")]
13373   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13374    || (TARGET_SSE && (<MODE>mode == TFmode))
13375    || (TARGET_AVX512FP16 && (<MODE>mode ==HFmode))"
13376   "ix86_expand_copysign (operands); DONE;")
13378 (define_expand "xorsign<mode>3"
13379   [(match_operand:MODEFH 0 "register_operand")
13380    (match_operand:MODEFH 1 "register_operand")
13381    (match_operand:MODEFH 2 "register_operand")]
13382   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13383   || <MODE>mode == HFmode"
13385   if (rtx_equal_p (operands[1], operands[2]))
13386     emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
13387   else
13388     ix86_expand_xorsign (operands);
13389   DONE;
13392 ;; One complement instructions
13394 (define_expand "one_cmpl<mode>2"
13395   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
13396         (not:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
13397   ""
13398   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
13400 (define_insn_and_split "*one_cmpl<dwi>2_doubleword"
13401   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
13402         (not:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))]
13403   "ix86_unary_operator_ok (NOT, <DWI>mode, operands)"
13404   "#"
13405   "&& reload_completed"
13406   [(set (match_dup 0)
13407         (not:DWIH (match_dup 1)))
13408    (set (match_dup 2)
13409         (not:DWIH (match_dup 3)))]
13410   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
13412 (define_insn "*one_cmpl<mode>2_1"
13413   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,?k")
13414         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,k")))]
13415   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13416   "@
13417    not{<imodesuffix>}\t%0
13418    #"
13419   [(set_attr "isa" "*,<kmov_isa>")
13420    (set_attr "type" "negnot,msklog")
13421    (set_attr "mode" "<MODE>")])
13423 (define_insn "*one_cmplsi2_1_zext"
13424   [(set (match_operand:DI 0 "register_operand" "=r,?k")
13425         (zero_extend:DI
13426           (not:SI (match_operand:SI 1 "register_operand" "0,k"))))]
13427   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
13428   "@
13429    not{l}\t%k0
13430    #"
13431   [(set_attr "isa" "x64,avx512bw_512")
13432    (set_attr "type" "negnot,msklog")
13433    (set_attr "mode" "SI,SI")])
13435 (define_insn "*one_cmplqi2_1"
13436   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,?k")
13437         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
13438   "ix86_unary_operator_ok (NOT, QImode, operands)"
13439   "@
13440    not{b}\t%0
13441    not{l}\t%k0
13442    #"
13443   [(set_attr "isa" "*,*,avx512f")
13444    (set_attr "type" "negnot,negnot,msklog")
13445    (set (attr "mode")
13446         (cond [(eq_attr "alternative" "1")
13447                  (const_string "SI")
13448                 (and (eq_attr "alternative" "2")
13449                      (match_test "!TARGET_AVX512DQ"))
13450                  (const_string "HI")
13451                ]
13452                (const_string "QI")))
13453    ;; Potential partial reg stall on alternative 1.
13454    (set (attr "preferred_for_speed")
13455      (cond [(eq_attr "alternative" "1")
13456               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
13457            (symbol_ref "true")))])
13459 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13460 (define_insn_and_split "*one_cmpl<mode>_1_slp"
13461   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
13462         (not:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))]
13463   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
13464   "@
13465    not{<imodesuffix>}\t%0
13466    #"
13467   "&& reload_completed
13468    && !(rtx_equal_p (operands[0], operands[1]))"
13469   [(set (strict_low_part (match_dup 0)) (match_dup 1))
13470    (set (strict_low_part (match_dup 0))
13471         (not:SWI12 (match_dup 0)))]
13472   ""
13473   [(set_attr "type" "negnot")
13474    (set_attr "mode" "<MODE>")])
13476 (define_insn "*one_cmpl<mode>2_2"
13477   [(set (reg FLAGS_REG)
13478         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
13479                  (const_int 0)))
13480    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13481         (not:SWI (match_dup 1)))]
13482   "ix86_match_ccmode (insn, CCNOmode)
13483    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13484   "#"
13485   [(set_attr "type" "alu1")
13486    (set_attr "mode" "<MODE>")])
13488 (define_split
13489   [(set (match_operand 0 "flags_reg_operand")
13490         (match_operator 2 "compare_operator"
13491           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
13492            (const_int 0)]))
13493    (set (match_operand:SWI 1 "nonimmediate_operand")
13494         (not:SWI (match_dup 3)))]
13495   "ix86_match_ccmode (insn, CCNOmode)"
13496   [(parallel [(set (match_dup 0)
13497                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
13498                                     (const_int 0)]))
13499               (set (match_dup 1)
13500                    (xor:SWI (match_dup 3) (const_int -1)))])])
13502 (define_insn "*one_cmplsi2_2_zext"
13503   [(set (reg FLAGS_REG)
13504         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
13505                  (const_int 0)))
13506    (set (match_operand:DI 0 "register_operand" "=r")
13507         (zero_extend:DI (not:SI (match_dup 1))))]
13508   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
13509    && ix86_unary_operator_ok (NOT, SImode, operands)"
13510   "#"
13511   [(set_attr "type" "alu1")
13512    (set_attr "mode" "SI")])
13514 (define_split
13515   [(set (match_operand 0 "flags_reg_operand")
13516         (match_operator 2 "compare_operator"
13517           [(not:SI (match_operand:SI 3 "register_operand"))
13518            (const_int 0)]))
13519    (set (match_operand:DI 1 "register_operand")
13520         (zero_extend:DI (not:SI (match_dup 3))))]
13521   "ix86_match_ccmode (insn, CCNOmode)"
13522   [(parallel [(set (match_dup 0)
13523                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
13524                                     (const_int 0)]))
13525               (set (match_dup 1)
13526                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
13528 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13529 (define_insn_and_split "*one_cmplqi_ext<mode>_1"
13530   [(set (zero_extract:SWI248
13531           (match_operand 0 "int248_register_operand" "+Q,&Q")
13532           (const_int 8)
13533           (const_int 8))
13534         (subreg:SWI248
13535           (not:QI
13536             (subreg:QI
13537               (match_operator:SWI248 2 "extract_operator"
13538                 [(match_operand 1 "int248_register_operand" "0,!Q")
13539                  (const_int 8)
13540                  (const_int 8)]) 0)) 0))]
13541   ""
13542   "@
13543    not{b}\t%h0
13544    #"
13545   "reload_completed
13546    && !(rtx_equal_p (operands[0], operands[1]))"
13547   [(set (zero_extract:SWI248
13548           (match_dup 0) (const_int 8) (const_int 8))
13549         (zero_extract:SWI248
13550           (match_dup 1) (const_int 8) (const_int 8)))
13551    (set (zero_extract:SWI248
13552           (match_dup 0) (const_int 8) (const_int 8))
13553         (subreg:SWI248
13554           (not:QI
13555             (subreg:QI
13556               (match_op_dup 2
13557                 [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))]
13558   ""
13559   [(set_attr "type" "negnot")
13560    (set_attr "mode" "QI")])
13562 ;; Shift instructions
13564 ;; DImode shifts are implemented using the i386 "shift double" opcode,
13565 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
13566 ;; is variable, then the count is in %cl and the "imm" operand is dropped
13567 ;; from the assembler input.
13569 ;; This instruction shifts the target reg/mem as usual, but instead of
13570 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
13571 ;; is a left shift double, bits are taken from the high order bits of
13572 ;; reg, else if the insn is a shift right double, bits are taken from the
13573 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
13574 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
13576 ;; Since sh[lr]d does not change the `reg' operand, that is done
13577 ;; separately, making all shifts emit pairs of shift double and normal
13578 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
13579 ;; support a 63 bit shift, each shift where the count is in a reg expands
13580 ;; to a pair of shifts, a branch, a shift by 32 and a label.
13582 ;; If the shift count is a constant, we need never emit more than one
13583 ;; shift pair, instead using moves and sign extension for counts greater
13584 ;; than 31.
13586 (define_expand "ashl<mode>3"
13587   [(set (match_operand:SDWIM 0 "<shift_operand>")
13588         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
13589                       (match_operand:QI 2 "nonmemory_operand")))]
13590   ""
13591   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
13593 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
13594   [(set (match_operand:<DWI> 0 "register_operand")
13595         (ashift:<DWI>
13596           (match_operand:<DWI> 1 "register_operand")
13597           (subreg:QI
13598             (and
13599               (match_operand 2 "int248_register_operand" "c")
13600               (match_operand 3 "const_int_operand")) 0)))
13601    (clobber (reg:CC FLAGS_REG))]
13602   "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13603     || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13604          == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13605    && ix86_pre_reload_split ()"
13606   "#"
13607   "&& 1"
13608   [(parallel
13609      [(set (match_dup 6)
13610            (ior:DWIH (ashift:DWIH (match_dup 6)
13611                        (and:QI (match_dup 2) (match_dup 8)))
13612                      (subreg:DWIH
13613                        (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13614                          (minus:QI (match_dup 9)
13615                                    (and:QI (match_dup 2) (match_dup 8)))) 0)))
13616       (clobber (reg:CC FLAGS_REG))])
13617    (parallel
13618      [(set (match_dup 4)
13619            (ashift:DWIH (match_dup 5) (match_dup 2)))
13620       (clobber (reg:CC FLAGS_REG))])]
13622   if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13623     {
13624       operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13625       operands[2] = gen_lowpart (QImode, operands[2]);
13626       emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13627                                             operands[2]));
13628       DONE;
13629     }
13631   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13633   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13634   operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13636   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13637       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13638     {
13639       rtx xops[3];
13640       xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
13641       xops[1] = operands[2];
13642       xops[2] = GEN_INT (INTVAL (operands[3])
13643                          & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
13644       ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
13645       operands[2] = xops[0];
13646     }
13648   operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13649   operands[2] = gen_lowpart (QImode, operands[2]);
13651   if (!rtx_equal_p (operands[6], operands[7]))
13652     emit_move_insn (operands[6], operands[7]);
13655 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
13656   [(set (match_operand:<DWI> 0 "register_operand")
13657         (ashift:<DWI>
13658           (match_operand:<DWI> 1 "register_operand")
13659           (and:QI
13660             (match_operand:QI 2 "register_operand" "c")
13661             (match_operand:QI 3 "const_int_operand"))))
13662    (clobber (reg:CC FLAGS_REG))]
13663   "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13664     || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13665          == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13666    && ix86_pre_reload_split ()"
13667   "#"
13668   "&& 1"
13669   [(parallel
13670      [(set (match_dup 6)
13671            (ior:DWIH (ashift:DWIH (match_dup 6)
13672                        (and:QI (match_dup 2) (match_dup 8)))
13673                      (subreg:DWIH
13674                        (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13675                          (minus:QI (match_dup 9)
13676                                    (and:QI (match_dup 2) (match_dup 8)))) 0)))
13677       (clobber (reg:CC FLAGS_REG))])
13678    (parallel
13679      [(set (match_dup 4)
13680            (ashift:DWIH (match_dup 5) (match_dup 2)))
13681       (clobber (reg:CC FLAGS_REG))])]
13683   if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13684     {
13685       emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13686                                             operands[2]));
13687       DONE;
13688     }
13690   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13692   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13693   operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13695   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13696       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13697     {
13698       rtx tem = gen_reg_rtx (QImode);
13699       emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
13700       operands[2] = tem;
13701     }
13703   if (!rtx_equal_p (operands[6], operands[7]))
13704     emit_move_insn (operands[6], operands[7]);
13707 (define_insn "ashl<mode>3_doubleword"
13708   [(set (match_operand:DWI 0 "register_operand" "=&r")
13709         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
13710                     (match_operand:QI 2 "nonmemory_operand" "<S>c")))
13711    (clobber (reg:CC FLAGS_REG))]
13712   ""
13713   "#"
13714   [(set_attr "type" "multi")])
13716 (define_split
13717   [(set (match_operand:DWI 0 "register_operand")
13718         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
13719                     (match_operand:QI 2 "nonmemory_operand")))
13720    (clobber (reg:CC FLAGS_REG))]
13721   "epilogue_completed"
13722   [(const_int 0)]
13723   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
13725 ;; By default we don't ask for a scratch register, because when DWImode
13726 ;; values are manipulated, registers are already at a premium.  But if
13727 ;; we have one handy, we won't turn it away.
13729 (define_peephole2
13730   [(match_scratch:DWIH 3 "r")
13731    (parallel [(set (match_operand:<DWI> 0 "register_operand")
13732                    (ashift:<DWI>
13733                      (match_operand:<DWI> 1 "nonmemory_operand")
13734                      (match_operand:QI 2 "nonmemory_operand")))
13735               (clobber (reg:CC FLAGS_REG))])
13736    (match_dup 3)]
13737   "TARGET_CMOVE"
13738   [(const_int 0)]
13739   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
13741 (define_insn_and_split "*ashl<dwi>3_doubleword_highpart"
13742   [(set (match_operand:<DWI> 0 "register_operand" "=r")
13743         (ashift:<DWI>
13744           (any_extend:<DWI> (match_operand:DWIH 1 "nonimmediate_operand" "rm"))
13745           (match_operand:QI 2 "const_int_operand")))
13746    (clobber (reg:CC FLAGS_REG))]
13747   "INTVAL (operands[2]) >= <MODE_SIZE> * BITS_PER_UNIT
13748    && INTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT * 2"
13749   "#"
13750   "&& reload_completed"
13751   [(const_int 0)]
13753   split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[3]);
13754   int bits = INTVAL (operands[2]) - (<MODE_SIZE> * BITS_PER_UNIT);
13755   if (!rtx_equal_p (operands[3], operands[1]))
13756     emit_move_insn (operands[3], operands[1]);
13757   if (bits > 0)
13758     emit_insn (gen_ashl<mode>3 (operands[3], operands[3], GEN_INT (bits)));
13759   ix86_expand_clear (operands[0]);
13760   DONE;
13763 (define_insn "x86_64_shld"
13764   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13765         (ior:DI (ashift:DI (match_dup 0)
13766                   (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
13767                           (const_int 63)))
13768                 (subreg:DI
13769                   (lshiftrt:TI
13770                     (zero_extend:TI
13771                       (match_operand:DI 1 "register_operand" "r"))
13772                     (minus:QI (const_int 64)
13773                               (and:QI (match_dup 2) (const_int 63)))) 0)))
13774    (clobber (reg:CC FLAGS_REG))]
13775   "TARGET_64BIT"
13776   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
13777   [(set_attr "type" "ishift")
13778    (set_attr "prefix_0f" "1")
13779    (set_attr "mode" "DI")
13780    (set_attr "athlon_decode" "vector")
13781    (set_attr "amdfam10_decode" "vector")
13782    (set_attr "bdver1_decode" "vector")])
13784 (define_insn "x86_64_shld_1"
13785   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13786         (ior:DI (ashift:DI (match_dup 0)
13787                            (match_operand:QI 2 "const_0_to_63_operand"))
13788                 (subreg:DI
13789                   (lshiftrt:TI
13790                     (zero_extend:TI
13791                       (match_operand:DI 1 "register_operand" "r"))
13792                     (match_operand:QI 3 "const_0_to_255_operand")) 0)))
13793    (clobber (reg:CC FLAGS_REG))]
13794   "TARGET_64BIT
13795    && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
13796   "shld{q}\t{%2, %1, %0|%0, %1, %2}"
13797   [(set_attr "type" "ishift")
13798    (set_attr "prefix_0f" "1")
13799    (set_attr "mode" "DI")
13800    (set_attr "length_immediate" "1")
13801    (set_attr "athlon_decode" "vector")
13802    (set_attr "amdfam10_decode" "vector")
13803    (set_attr "bdver1_decode" "vector")])
13805 (define_insn_and_split "*x86_64_shld_shrd_1_nozext"
13806   [(set (match_operand:DI 0 "nonimmediate_operand")
13807         (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
13808                              (match_operand:QI 2 "const_0_to_63_operand"))
13809                 (lshiftrt:DI
13810                   (match_operand:DI 1 "nonimmediate_operand")
13811                   (match_operand:QI 3 "const_0_to_63_operand"))))
13812    (clobber (reg:CC FLAGS_REG))]
13813   "TARGET_64BIT
13814    && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
13815    && ix86_pre_reload_split ()"
13816   "#"
13817   "&& 1"
13818   [(const_int 0)]
13820   if (rtx_equal_p (operands[4], operands[0]))
13821     {
13822       operands[1] = force_reg (DImode, operands[1]);
13823       emit_insn (gen_x86_64_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13824     }
13825   else if (rtx_equal_p (operands[1], operands[0]))
13826     {
13827       operands[4] = force_reg (DImode, operands[4]);
13828       emit_insn (gen_x86_64_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13829     }
13830   else
13831    {
13832      operands[1] = force_reg (DImode, operands[1]);
13833      rtx tmp = gen_reg_rtx (DImode);
13834      emit_move_insn (tmp, operands[4]);
13835      emit_insn (gen_x86_64_shld_1 (tmp, operands[1], operands[2], operands[3]));
13836      emit_move_insn (operands[0], tmp);
13837    }
13838    DONE;
13841 (define_insn_and_split "*x86_64_shld_2"
13842   [(set (match_operand:DI 0 "nonimmediate_operand")
13843         (ior:DI (ashift:DI (match_dup 0)
13844                            (match_operand:QI 2 "nonmemory_operand"))
13845                 (lshiftrt:DI (match_operand:DI 1 "register_operand")
13846                              (minus:QI (const_int 64) (match_dup 2)))))
13847    (clobber (reg:CC FLAGS_REG))]
13848   "TARGET_64BIT && ix86_pre_reload_split ()"
13849   "#"
13850   "&& 1"
13851   [(parallel [(set (match_dup 0)
13852                    (ior:DI (ashift:DI (match_dup 0)
13853                                       (and:QI (match_dup 2) (const_int 63)))
13854                            (subreg:DI
13855                              (lshiftrt:TI
13856                                (zero_extend:TI (match_dup 1))
13857                                  (minus:QI (const_int 64)
13858                                            (and:QI (match_dup 2)
13859                                                    (const_int 63)))) 0)))
13860               (clobber (reg:CC FLAGS_REG))])])
13862 (define_insn "x86_shld"
13863   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13864         (ior:SI (ashift:SI (match_dup 0)
13865                   (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
13866                           (const_int 31)))
13867                 (subreg:SI
13868                   (lshiftrt:DI
13869                     (zero_extend:DI
13870                       (match_operand:SI 1 "register_operand" "r"))
13871                     (minus:QI (const_int 32)
13872                               (and:QI (match_dup 2) (const_int 31)))) 0)))
13873    (clobber (reg:CC FLAGS_REG))]
13874   ""
13875   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
13876   [(set_attr "type" "ishift")
13877    (set_attr "prefix_0f" "1")
13878    (set_attr "mode" "SI")
13879    (set_attr "pent_pair" "np")
13880    (set_attr "athlon_decode" "vector")
13881    (set_attr "amdfam10_decode" "vector")
13882    (set_attr "bdver1_decode" "vector")])
13884 (define_insn "x86_shld_1"
13885   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13886         (ior:SI (ashift:SI (match_dup 0)
13887                            (match_operand:QI 2 "const_0_to_31_operand"))
13888                 (subreg:SI
13889                   (lshiftrt:DI
13890                     (zero_extend:DI
13891                       (match_operand:SI 1 "register_operand" "r"))
13892                     (match_operand:QI 3 "const_0_to_63_operand")) 0)))
13893    (clobber (reg:CC FLAGS_REG))]
13894   "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
13895   "shld{l}\t{%2, %1, %0|%0, %1, %2}"
13896   [(set_attr "type" "ishift")
13897    (set_attr "prefix_0f" "1")
13898    (set_attr "length_immediate" "1")
13899    (set_attr "mode" "SI")
13900    (set_attr "pent_pair" "np")
13901    (set_attr "athlon_decode" "vector")
13902    (set_attr "amdfam10_decode" "vector")
13903    (set_attr "bdver1_decode" "vector")])
13905 (define_insn_and_split "*x86_shld_shrd_1_nozext"
13906   [(set (match_operand:SI 0 "nonimmediate_operand")
13907         (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
13908                              (match_operand:QI 2 "const_0_to_31_operand"))
13909                (lshiftrt:SI
13910                    (match_operand:SI 1 "nonimmediate_operand")
13911                    (match_operand:QI 3 "const_0_to_31_operand"))))
13912    (clobber (reg:CC FLAGS_REG))]
13913   "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
13914    && ix86_pre_reload_split ()"
13915   "#"
13916   "&& 1"
13917   [(const_int 0)]
13919   if (rtx_equal_p (operands[4], operands[0]))
13920     {
13921       operands[1] = force_reg (SImode, operands[1]);
13922       emit_insn (gen_x86_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13923     }
13924   else if (rtx_equal_p (operands[1], operands[0]))
13925     {
13926       operands[4] = force_reg (SImode, operands[4]);
13927       emit_insn (gen_x86_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13928     }
13929   else
13930    {
13931      operands[1] = force_reg (SImode, operands[1]);
13932      rtx tmp = gen_reg_rtx (SImode);
13933      emit_move_insn (tmp, operands[4]);
13934      emit_insn (gen_x86_shld_1 (tmp, operands[1], operands[2], operands[3]));
13935      emit_move_insn (operands[0], tmp);
13936    }
13937    DONE;
13940 (define_insn_and_split "*x86_shld_2"
13941   [(set (match_operand:SI 0 "nonimmediate_operand")
13942         (ior:SI (ashift:SI (match_dup 0)
13943                            (match_operand:QI 2 "nonmemory_operand"))
13944                 (lshiftrt:SI (match_operand:SI 1 "register_operand")
13945                              (minus:QI (const_int 32) (match_dup 2)))))
13946    (clobber (reg:CC FLAGS_REG))]
13947   "TARGET_64BIT && ix86_pre_reload_split ()"
13948   "#"
13949   "&& 1"
13950   [(parallel [(set (match_dup 0)
13951                    (ior:SI (ashift:SI (match_dup 0)
13952                                       (and:QI (match_dup 2) (const_int 31)))
13953                            (subreg:SI
13954                              (lshiftrt:DI
13955                                (zero_extend:DI (match_dup 1))
13956                                  (minus:QI (const_int 32)
13957                                            (and:QI (match_dup 2)
13958                                                    (const_int 31)))) 0)))
13959               (clobber (reg:CC FLAGS_REG))])])
13961 (define_expand "@x86_shift<mode>_adj_1"
13962   [(set (reg:CCZ FLAGS_REG)
13963         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
13964                              (match_dup 4))
13965                      (const_int 0)))
13966    (set (match_operand:SWI48 0 "register_operand")
13967         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
13968                             (match_operand:SWI48 1 "register_operand")
13969                             (match_dup 0)))
13970    (set (match_dup 1)
13971         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
13972                             (match_operand:SWI48 3 "register_operand")
13973                             (match_dup 1)))]
13974   "TARGET_CMOVE"
13975   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
13977 (define_expand "@x86_shift<mode>_adj_2"
13978   [(use (match_operand:SWI48 0 "register_operand"))
13979    (use (match_operand:SWI48 1 "register_operand"))
13980    (use (match_operand:QI 2 "register_operand"))]
13981   ""
13983   rtx_code_label *label = gen_label_rtx ();
13984   rtx tmp;
13986   emit_insn (gen_testqi_ccz_1 (operands[2],
13987                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
13989   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
13990   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
13991   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
13992                               gen_rtx_LABEL_REF (VOIDmode, label),
13993                               pc_rtx);
13994   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
13995   JUMP_LABEL (tmp) = label;
13997   emit_move_insn (operands[0], operands[1]);
13998   ix86_expand_clear (operands[1]);
14000   emit_label (label);
14001   LABEL_NUSES (label) = 1;
14003   DONE;
14006 ;; Avoid useless masking of count operand.
14007 (define_insn_and_split "*ashl<mode>3_mask"
14008   [(set (match_operand:SWI48 0 "nonimmediate_operand")
14009         (ashift:SWI48
14010           (match_operand:SWI48 1 "nonimmediate_operand")
14011           (subreg:QI
14012             (and
14013               (match_operand 2 "int248_register_operand" "c,r")
14014               (match_operand 3 "const_int_operand")) 0)))
14015    (clobber (reg:CC FLAGS_REG))]
14016   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
14017    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14018       == GET_MODE_BITSIZE (<MODE>mode)-1
14019    && ix86_pre_reload_split ()"
14020   "#"
14021   "&& 1"
14022   [(parallel
14023      [(set (match_dup 0)
14024            (ashift:SWI48 (match_dup 1)
14025                          (match_dup 2)))
14026       (clobber (reg:CC FLAGS_REG))])]
14028   operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14029   operands[2] = gen_lowpart (QImode, operands[2]);
14031   [(set_attr "isa" "*,bmi2")])
14033 (define_insn_and_split "*ashl<mode>3_mask_1"
14034   [(set (match_operand:SWI48 0 "nonimmediate_operand")
14035         (ashift:SWI48
14036           (match_operand:SWI48 1 "nonimmediate_operand")
14037           (and:QI
14038             (match_operand:QI 2 "register_operand" "c,r")
14039             (match_operand:QI 3 "const_int_operand"))))
14040    (clobber (reg:CC FLAGS_REG))]
14041   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
14042    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14043       == GET_MODE_BITSIZE (<MODE>mode)-1
14044    && ix86_pre_reload_split ()"
14045   "#"
14046   "&& 1"
14047   [(parallel
14048      [(set (match_dup 0)
14049            (ashift:SWI48 (match_dup 1)
14050                          (match_dup 2)))
14051       (clobber (reg:CC FLAGS_REG))])]
14052   ""
14053   [(set_attr "isa" "*,bmi2")])
14055 (define_insn "*bmi2_ashl<mode>3_1"
14056   [(set (match_operand:SWI48 0 "register_operand" "=r")
14057         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14058                       (match_operand:SWI48 2 "register_operand" "r")))]
14059   "TARGET_BMI2"
14060   "shlx\t{%2, %1, %0|%0, %1, %2}"
14061   [(set_attr "type" "ishiftx")
14062    (set_attr "mode" "<MODE>")])
14064 (define_insn "*ashl<mode>3_1"
14065   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,?k")
14066         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm,k")
14067                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r,<KS>")))
14068    (clobber (reg:CC FLAGS_REG))]
14069   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
14071   switch (get_attr_type (insn))
14072     {
14073     case TYPE_LEA:
14074     case TYPE_ISHIFTX:
14075     case TYPE_MSKLOG:
14076       return "#";
14078     case TYPE_ALU:
14079       gcc_assert (operands[2] == const1_rtx);
14080       gcc_assert (rtx_equal_p (operands[0], operands[1]));
14081       return "add{<imodesuffix>}\t%0, %0";
14083     default:
14084       if (operands[2] == const1_rtx
14085           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14086         return "sal{<imodesuffix>}\t%0";
14087       else
14088         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14089     }
14091   [(set_attr "isa" "*,*,bmi2,<kmov_isa>")
14092    (set (attr "type")
14093      (cond [(eq_attr "alternative" "1")
14094               (const_string "lea")
14095             (eq_attr "alternative" "2")
14096               (const_string "ishiftx")
14097             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14098                       (match_operand 0 "register_operand"))
14099                  (match_operand 2 "const1_operand"))
14100               (const_string "alu")
14101             (eq_attr "alternative" "3")
14102               (const_string "msklog")
14103            ]
14104            (const_string "ishift")))
14105    (set (attr "length_immediate")
14106      (if_then_else
14107        (ior (eq_attr "type" "alu")
14108             (and (eq_attr "type" "ishift")
14109                  (and (match_operand 2 "const1_operand")
14110                       (ior (match_test "TARGET_SHIFT1")
14111                            (match_test "optimize_function_for_size_p (cfun)")))))
14112        (const_string "0")
14113        (const_string "*")))
14114    (set_attr "mode" "<MODE>")])
14116 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14117 (define_split
14118   [(set (match_operand:SWI48 0 "register_operand")
14119         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
14120                       (match_operand:QI 2 "register_operand")))
14121    (clobber (reg:CC FLAGS_REG))]
14122   "TARGET_BMI2 && reload_completed"
14123   [(set (match_dup 0)
14124         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
14125   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
14127 (define_insn "*bmi2_ashlsi3_1_zext"
14128   [(set (match_operand:DI 0 "register_operand" "=r")
14129         (zero_extend:DI
14130           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
14131                      (match_operand:SI 2 "register_operand" "r"))))]
14132   "TARGET_64BIT && TARGET_BMI2"
14133   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
14134   [(set_attr "type" "ishiftx")
14135    (set_attr "mode" "SI")])
14137 (define_insn "*ashlsi3_1_zext"
14138   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
14139         (zero_extend:DI
14140           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
14141                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
14142    (clobber (reg:CC FLAGS_REG))]
14143   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14145   switch (get_attr_type (insn))
14146     {
14147     case TYPE_LEA:
14148     case TYPE_ISHIFTX:
14149       return "#";
14151     case TYPE_ALU:
14152       gcc_assert (operands[2] == const1_rtx);
14153       return "add{l}\t%k0, %k0";
14155     default:
14156       if (operands[2] == const1_rtx
14157           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14158         return "sal{l}\t%k0";
14159       else
14160         return "sal{l}\t{%2, %k0|%k0, %2}";
14161     }
14163   [(set_attr "isa" "*,*,bmi2")
14164    (set (attr "type")
14165      (cond [(eq_attr "alternative" "1")
14166               (const_string "lea")
14167             (eq_attr "alternative" "2")
14168               (const_string "ishiftx")
14169             (and (match_test "TARGET_DOUBLE_WITH_ADD")
14170                  (match_operand 2 "const1_operand"))
14171               (const_string "alu")
14172            ]
14173            (const_string "ishift")))
14174    (set (attr "length_immediate")
14175      (if_then_else
14176        (ior (eq_attr "type" "alu")
14177             (and (eq_attr "type" "ishift")
14178                  (and (match_operand 2 "const1_operand")
14179                       (ior (match_test "TARGET_SHIFT1")
14180                            (match_test "optimize_function_for_size_p (cfun)")))))
14181        (const_string "0")
14182        (const_string "*")))
14183    (set_attr "mode" "SI")])
14185 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14186 (define_split
14187   [(set (match_operand:DI 0 "register_operand")
14188         (zero_extend:DI
14189           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
14190                      (match_operand:QI 2 "register_operand"))))
14191    (clobber (reg:CC FLAGS_REG))]
14192   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
14193   [(set (match_dup 0)
14194         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14195   "operands[2] = gen_lowpart (SImode, operands[2]);")
14197 (define_insn "*ashlhi3_1"
14198   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp,?k")
14199         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l,k")
14200                    (match_operand:QI 2 "nonmemory_operand" "cI,M,Ww")))
14201    (clobber (reg:CC FLAGS_REG))]
14202   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
14204   switch (get_attr_type (insn))
14205     {
14206     case TYPE_LEA:
14207     case TYPE_MSKLOG:
14208       return "#";
14210     case TYPE_ALU:
14211       gcc_assert (operands[2] == const1_rtx);
14212       return "add{w}\t%0, %0";
14214     default:
14215       if (operands[2] == const1_rtx
14216           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14217         return "sal{w}\t%0";
14218       else
14219         return "sal{w}\t{%2, %0|%0, %2}";
14220     }
14222   [(set_attr "isa" "*,*,avx512f")
14223    (set (attr "type")
14224      (cond [(eq_attr "alternative" "1")
14225               (const_string "lea")
14226             (eq_attr "alternative" "2")
14227               (const_string "msklog")
14228             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14229                       (match_operand 0 "register_operand"))
14230                  (match_operand 2 "const1_operand"))
14231               (const_string "alu")
14232            ]
14233            (const_string "ishift")))
14234    (set (attr "length_immediate")
14235      (if_then_else
14236        (ior (eq_attr "type" "alu")
14237             (and (eq_attr "type" "ishift")
14238                  (and (match_operand 2 "const1_operand")
14239                       (ior (match_test "TARGET_SHIFT1")
14240                            (match_test "optimize_function_for_size_p (cfun)")))))
14241        (const_string "0")
14242        (const_string "*")))
14243    (set_attr "mode" "HI,SI,HI")])
14245 (define_insn "*ashlqi3_1"
14246   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp,?k")
14247         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l,k")
14248                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M,Wb")))
14249    (clobber (reg:CC FLAGS_REG))]
14250   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
14252   switch (get_attr_type (insn))
14253     {
14254     case TYPE_LEA:
14255     case TYPE_MSKLOG:
14256       return "#";
14258     case TYPE_ALU:
14259       gcc_assert (operands[2] == const1_rtx);
14260       if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
14261         return "add{l}\t%k0, %k0";
14262       else
14263         return "add{b}\t%0, %0";
14265     default:
14266       if (operands[2] == const1_rtx
14267           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14268         {
14269           if (get_attr_mode (insn) == MODE_SI)
14270             return "sal{l}\t%k0";
14271           else
14272             return "sal{b}\t%0";
14273         }
14274       else
14275         {
14276           if (get_attr_mode (insn) == MODE_SI)
14277             return "sal{l}\t{%2, %k0|%k0, %2}";
14278           else
14279             return "sal{b}\t{%2, %0|%0, %2}";
14280         }
14281     }
14283   [(set_attr "isa" "*,*,*,avx512dq")
14284    (set (attr "type")
14285      (cond [(eq_attr "alternative" "2")
14286               (const_string "lea")
14287             (eq_attr "alternative" "3")
14288               (const_string "msklog")
14289             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14290                       (match_operand 0 "register_operand"))
14291                  (match_operand 2 "const1_operand"))
14292               (const_string "alu")
14293            ]
14294            (const_string "ishift")))
14295    (set (attr "length_immediate")
14296      (if_then_else
14297        (ior (eq_attr "type" "alu")
14298             (and (eq_attr "type" "ishift")
14299                  (and (match_operand 2 "const1_operand")
14300                       (ior (match_test "TARGET_SHIFT1")
14301                            (match_test "optimize_function_for_size_p (cfun)")))))
14302        (const_string "0")
14303        (const_string "*")))
14304    (set_attr "mode" "QI,SI,SI,QI")
14305    ;; Potential partial reg stall on alternative 1.
14306    (set (attr "preferred_for_speed")
14307      (cond [(eq_attr "alternative" "1")
14308               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
14309            (symbol_ref "true")))])
14311 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14312 (define_insn_and_split "*ashl<mode>3_1_slp"
14313   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
14314         (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
14315                       (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
14316    (clobber (reg:CC FLAGS_REG))]
14317   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
14319   if (which_alternative)
14320     return "#";
14322   switch (get_attr_type (insn))
14323     {
14324     case TYPE_ALU:
14325       gcc_assert (operands[2] == const1_rtx);
14326       return "add{<imodesuffix>}\t%0, %0";
14328     default:
14329       if (operands[2] == const1_rtx
14330           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14331         return "sal{<imodesuffix>}\t%0";
14332       else
14333         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14334     }
14336   "&& reload_completed
14337    && !(rtx_equal_p (operands[0], operands[1]))"
14338   [(set (strict_low_part (match_dup 0)) (match_dup 1))
14339    (parallel
14340      [(set (strict_low_part (match_dup 0))
14341            (ashift:SWI12 (match_dup 0) (match_dup 2)))
14342       (clobber (reg:CC FLAGS_REG))])]
14343   ""
14344   [(set (attr "type")
14345      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14346                  (match_operand 2 "const1_operand"))
14347               (const_string "alu")
14348            ]
14349            (const_string "ishift")))
14350    (set (attr "length_immediate")
14351      (if_then_else
14352        (ior (eq_attr "type" "alu")
14353             (and (eq_attr "type" "ishift")
14354                  (and (match_operand 2 "const1_operand")
14355                       (ior (match_test "TARGET_SHIFT1")
14356                            (match_test "optimize_function_for_size_p (cfun)")))))
14357        (const_string "0")
14358        (const_string "*")))
14359    (set_attr "mode" "<MODE>")])
14361 ;; Convert ashift to the lea pattern to avoid flags dependency.
14362 (define_split
14363   [(set (match_operand:SWI 0 "general_reg_operand")
14364         (ashift:SWI (match_operand:SWI 1 "index_reg_operand")
14365                     (match_operand 2 "const_0_to_3_operand")))
14366    (clobber (reg:CC FLAGS_REG))]
14367   "reload_completed
14368    && REGNO (operands[0]) != REGNO (operands[1])"
14369   [(set (match_dup 0)
14370         (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
14372   if (<MODE>mode != <LEAMODE>mode)
14373     {
14374       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
14375       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
14376     }
14377   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14380 ;; Convert ashift to the lea pattern to avoid flags dependency.
14381 (define_split
14382   [(set (match_operand:DI 0 "general_reg_operand")
14383         (zero_extend:DI
14384           (ashift:SI (match_operand:SI 1 "index_reg_operand")
14385                      (match_operand 2 "const_0_to_3_operand"))))
14386    (clobber (reg:CC FLAGS_REG))]
14387   "TARGET_64BIT && reload_completed
14388    && REGNO (operands[0]) != REGNO (operands[1])"
14389   [(set (match_dup 0)
14390         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
14392   operands[1] = gen_lowpart (SImode, operands[1]);
14393   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14396 ;; This pattern can't accept a variable shift count, since shifts by
14397 ;; zero don't affect the flags.  We assume that shifts by constant
14398 ;; zero are optimized away.
14399 (define_insn "*ashl<mode>3_cmp"
14400   [(set (reg FLAGS_REG)
14401         (compare
14402           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
14403                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14404           (const_int 0)))
14405    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
14406         (ashift:SWI (match_dup 1) (match_dup 2)))]
14407   "(optimize_function_for_size_p (cfun)
14408     || !TARGET_PARTIAL_FLAG_REG_STALL
14409     || (operands[2] == const1_rtx
14410         && (TARGET_SHIFT1
14411             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
14412    && ix86_match_ccmode (insn, CCGOCmode)
14413    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
14415   switch (get_attr_type (insn))
14416     {
14417     case TYPE_ALU:
14418       gcc_assert (operands[2] == const1_rtx);
14419       return "add{<imodesuffix>}\t%0, %0";
14421     default:
14422       if (operands[2] == const1_rtx
14423           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14424         return "sal{<imodesuffix>}\t%0";
14425       else
14426         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14427     }
14429   [(set (attr "type")
14430      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14431                       (match_operand 0 "register_operand"))
14432                  (match_operand 2 "const1_operand"))
14433               (const_string "alu")
14434            ]
14435            (const_string "ishift")))
14436    (set (attr "length_immediate")
14437      (if_then_else
14438        (ior (eq_attr "type" "alu")
14439             (and (eq_attr "type" "ishift")
14440                  (and (match_operand 2 "const1_operand")
14441                       (ior (match_test "TARGET_SHIFT1")
14442                            (match_test "optimize_function_for_size_p (cfun)")))))
14443        (const_string "0")
14444        (const_string "*")))
14445    (set_attr "mode" "<MODE>")])
14447 (define_insn "*ashlsi3_cmp_zext"
14448   [(set (reg FLAGS_REG)
14449         (compare
14450           (ashift:SI (match_operand:SI 1 "register_operand" "0")
14451                      (match_operand:QI 2 "const_1_to_31_operand"))
14452           (const_int 0)))
14453    (set (match_operand:DI 0 "register_operand" "=r")
14454         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14455   "TARGET_64BIT
14456    && (optimize_function_for_size_p (cfun)
14457        || !TARGET_PARTIAL_FLAG_REG_STALL
14458        || (operands[2] == const1_rtx
14459            && (TARGET_SHIFT1
14460                || TARGET_DOUBLE_WITH_ADD)))
14461    && ix86_match_ccmode (insn, CCGOCmode)
14462    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14464   switch (get_attr_type (insn))
14465     {
14466     case TYPE_ALU:
14467       gcc_assert (operands[2] == const1_rtx);
14468       return "add{l}\t%k0, %k0";
14470     default:
14471       if (operands[2] == const1_rtx
14472           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14473         return "sal{l}\t%k0";
14474       else
14475         return "sal{l}\t{%2, %k0|%k0, %2}";
14476     }
14478   [(set (attr "type")
14479      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14480                  (match_operand 2 "const1_operand"))
14481               (const_string "alu")
14482            ]
14483            (const_string "ishift")))
14484    (set (attr "length_immediate")
14485      (if_then_else
14486        (ior (eq_attr "type" "alu")
14487             (and (eq_attr "type" "ishift")
14488                  (and (match_operand 2 "const1_operand")
14489                       (ior (match_test "TARGET_SHIFT1")
14490                            (match_test "optimize_function_for_size_p (cfun)")))))
14491        (const_string "0")
14492        (const_string "*")))
14493    (set_attr "mode" "SI")])
14495 (define_insn "*ashl<mode>3_cconly"
14496   [(set (reg FLAGS_REG)
14497         (compare
14498           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
14499                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14500           (const_int 0)))
14501    (clobber (match_scratch:SWI 0 "=<r>"))]
14502   "(optimize_function_for_size_p (cfun)
14503     || !TARGET_PARTIAL_FLAG_REG_STALL
14504     || (operands[2] == const1_rtx
14505         && (TARGET_SHIFT1
14506             || TARGET_DOUBLE_WITH_ADD)))
14507    && ix86_match_ccmode (insn, CCGOCmode)"
14509   switch (get_attr_type (insn))
14510     {
14511     case TYPE_ALU:
14512       gcc_assert (operands[2] == const1_rtx);
14513       return "add{<imodesuffix>}\t%0, %0";
14515     default:
14516       if (operands[2] == const1_rtx
14517           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14518         return "sal{<imodesuffix>}\t%0";
14519       else
14520         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14521     }
14523   [(set (attr "type")
14524      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14525                       (match_operand 0 "register_operand"))
14526                  (match_operand 2 "const1_operand"))
14527               (const_string "alu")
14528            ]
14529            (const_string "ishift")))
14530    (set (attr "length_immediate")
14531      (if_then_else
14532        (ior (eq_attr "type" "alu")
14533             (and (eq_attr "type" "ishift")
14534                  (and (match_operand 2 "const1_operand")
14535                       (ior (match_test "TARGET_SHIFT1")
14536                            (match_test "optimize_function_for_size_p (cfun)")))))
14537        (const_string "0")
14538        (const_string "*")))
14539    (set_attr "mode" "<MODE>")])
14541 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14542 (define_insn_and_split "*ashlqi_ext<mode>_1"
14543   [(set (zero_extract:SWI248
14544           (match_operand 0 "int248_register_operand" "+Q,&Q")
14545           (const_int 8)
14546           (const_int 8))
14547         (subreg:SWI248
14548           (ashift:QI
14549             (subreg:QI
14550               (match_operator:SWI248 3 "extract_operator"
14551                 [(match_operand 1 "int248_register_operand" "0,!Q")
14552                  (const_int 8)
14553                  (const_int 8)]) 0)
14554             (match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
14555    (clobber (reg:CC FLAGS_REG))]
14556   ""
14558   if (which_alternative)
14559     return "#";
14561   switch (get_attr_type (insn))
14562     {
14563     case TYPE_ALU:
14564       gcc_assert (operands[2] == const1_rtx);
14565       return "add{b}\t%h0, %h0";
14567     default:
14568       if (operands[2] == const1_rtx
14569           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14570         return "sal{b}\t%h0";
14571       else
14572         return "sal{b}\t{%2, %h0|%h0, %2}";
14573     }
14575   "reload_completed
14576    && !(rtx_equal_p (operands[0], operands[1]))"
14577   [(set (zero_extract:SWI248
14578           (match_dup 0) (const_int 8) (const_int 8))
14579         (match_dup 1))
14580    (parallel
14581      [(set (zero_extract:SWI248
14582              (match_dup 0) (const_int 8) (const_int 8))
14583            (subreg:SWI248
14584              (ashift:QI
14585                (subreg:QI
14586                  (match_op_dup 3
14587                    [(match_dup 0) (const_int 8) (const_int 8)]) 0)
14588                (match_dup 2)) 0))
14589       (clobber (reg:CC FLAGS_REG))])]
14590   ""
14591   [(set (attr "type")
14592      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14593                  (match_operand 2 "const1_operand"))
14594               (const_string "alu")
14595            ]
14596            (const_string "ishift")))
14597    (set (attr "length_immediate")
14598      (if_then_else
14599        (ior (eq_attr "type" "alu")
14600             (and (eq_attr "type" "ishift")
14601                  (and (match_operand 2 "const1_operand")
14602                       (ior (match_test "TARGET_SHIFT1")
14603                            (match_test "optimize_function_for_size_p (cfun)")))))
14604        (const_string "0")
14605        (const_string "*")))
14606    (set_attr "mode" "QI")])
14608 ;; See comment above `ashl<mode>3' about how this works.
14610 (define_expand "<insn><mode>3"
14611   [(set (match_operand:SDWIM 0 "<shift_operand>")
14612         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
14613                            (match_operand:QI 2 "nonmemory_operand")))]
14614   ""
14615   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
14617 ;; Avoid useless masking of count operand.
14618 (define_insn_and_split "*<insn><mode>3_mask"
14619   [(set (match_operand:SWI48 0 "nonimmediate_operand")
14620         (any_shiftrt:SWI48
14621           (match_operand:SWI48 1 "nonimmediate_operand")
14622           (subreg:QI
14623             (and
14624               (match_operand 2 "int248_register_operand" "c,r")
14625               (match_operand 3 "const_int_operand")) 0)))
14626    (clobber (reg:CC FLAGS_REG))]
14627   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14628    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14629       == GET_MODE_BITSIZE (<MODE>mode)-1
14630    && ix86_pre_reload_split ()"
14631   "#"
14632   "&& 1"
14633   [(parallel
14634      [(set (match_dup 0)
14635            (any_shiftrt:SWI48 (match_dup 1)
14636                               (match_dup 2)))
14637       (clobber (reg:CC FLAGS_REG))])]
14639   operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14640   operands[2] = gen_lowpart (QImode, operands[2]);
14642   [(set_attr "isa" "*,bmi2")])
14644 (define_insn_and_split "*<insn><mode>3_mask_1"
14645   [(set (match_operand:SWI48 0 "nonimmediate_operand")
14646         (any_shiftrt:SWI48
14647           (match_operand:SWI48 1 "nonimmediate_operand")
14648           (and:QI
14649             (match_operand:QI 2 "register_operand" "c,r")
14650             (match_operand:QI 3 "const_int_operand"))))
14651    (clobber (reg:CC FLAGS_REG))]
14652   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14653    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14654       == GET_MODE_BITSIZE (<MODE>mode)-1
14655    && ix86_pre_reload_split ()"
14656   "#"
14657   "&& 1"
14658   [(parallel
14659      [(set (match_dup 0)
14660            (any_shiftrt:SWI48 (match_dup 1)
14661                               (match_dup 2)))
14662       (clobber (reg:CC FLAGS_REG))])]
14663   ""
14664   [(set_attr "isa" "*,bmi2")])
14666 (define_insn_and_split "*<insn><dwi>3_doubleword_mask"
14667   [(set (match_operand:<DWI> 0 "register_operand")
14668         (any_shiftrt:<DWI>
14669           (match_operand:<DWI> 1 "register_operand")
14670           (subreg:QI
14671             (and
14672               (match_operand 2 "int248_register_operand" "c")
14673               (match_operand 3 "const_int_operand")) 0)))
14674    (clobber (reg:CC FLAGS_REG))]
14675   "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14676     || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14677          == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14678    && ix86_pre_reload_split ()"
14679   "#"
14680   "&& 1"
14681   [(parallel
14682      [(set (match_dup 4)
14683            (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14684                        (and:QI (match_dup 2) (match_dup 8)))
14685                      (subreg:DWIH
14686                        (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14687                          (minus:QI (match_dup 9)
14688                                    (and:QI (match_dup 2) (match_dup 8)))) 0)))
14689       (clobber (reg:CC FLAGS_REG))])
14690    (parallel
14691      [(set (match_dup 6)
14692            (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14693       (clobber (reg:CC FLAGS_REG))])]
14695   if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14696     {
14697       operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14698       operands[2] = gen_lowpart (QImode, operands[2]);
14699       emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14700                                               operands[2]));
14701       DONE;
14702     }
14704   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14706   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14707   operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14709   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14710       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14711     {
14712       rtx xops[3];
14713       xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
14714       xops[1] = operands[2];
14715       xops[2] = GEN_INT (INTVAL (operands[3])
14716                          & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
14717       ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
14718       operands[2] = xops[0];
14719     }
14721   operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14722   operands[2] = gen_lowpart (QImode, operands[2]);
14724   if (!rtx_equal_p (operands[4], operands[5]))
14725     emit_move_insn (operands[4], operands[5]);
14728 (define_insn_and_split "*<insn><dwi>3_doubleword_mask_1"
14729   [(set (match_operand:<DWI> 0 "register_operand")
14730         (any_shiftrt:<DWI>
14731           (match_operand:<DWI> 1 "register_operand")
14732           (and:QI
14733             (match_operand:QI 2 "register_operand" "c")
14734             (match_operand:QI 3 "const_int_operand"))))
14735    (clobber (reg:CC FLAGS_REG))]
14736   "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14737     || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14738          == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14739    && ix86_pre_reload_split ()"
14740   "#"
14741   "&& 1"
14742   [(parallel
14743      [(set (match_dup 4)
14744            (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14745                        (and:QI (match_dup 2) (match_dup 8)))
14746                      (subreg:DWIH
14747                        (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14748                          (minus:QI (match_dup 9)
14749                                    (and:QI (match_dup 2) (match_dup 8)))) 0)))
14750       (clobber (reg:CC FLAGS_REG))])
14751    (parallel
14752      [(set (match_dup 6)
14753            (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14754       (clobber (reg:CC FLAGS_REG))])]
14756   if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14757     {
14758       emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14759                                               operands[2]));
14760       DONE;
14761     }
14763   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14765   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14766   operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14768   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14769       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14770     {
14771       rtx tem = gen_reg_rtx (QImode);
14772       emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
14773       operands[2] = tem;
14774     }
14776   if (!rtx_equal_p (operands[4], operands[5]))
14777     emit_move_insn (operands[4], operands[5]);
14780 (define_insn_and_split "<insn><mode>3_doubleword"
14781   [(set (match_operand:DWI 0 "register_operand" "=&r")
14782         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
14783                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
14784    (clobber (reg:CC FLAGS_REG))]
14785   ""
14786   "#"
14787   "epilogue_completed"
14788   [(const_int 0)]
14789   "ix86_split_<insn> (operands, NULL_RTX, <MODE>mode); DONE;"
14790   [(set_attr "type" "multi")])
14792 ;; By default we don't ask for a scratch register, because when DWImode
14793 ;; values are manipulated, registers are already at a premium.  But if
14794 ;; we have one handy, we won't turn it away.
14796 (define_peephole2
14797   [(match_scratch:DWIH 3 "r")
14798    (parallel [(set (match_operand:<DWI> 0 "register_operand")
14799                    (any_shiftrt:<DWI>
14800                      (match_operand:<DWI> 1 "register_operand")
14801                      (match_operand:QI 2 "nonmemory_operand")))
14802               (clobber (reg:CC FLAGS_REG))])
14803    (match_dup 3)]
14804   "TARGET_CMOVE"
14805   [(const_int 0)]
14806   "ix86_split_<insn> (operands, operands[3], <DWI>mode); DONE;")
14808 ;; Split truncations of double word right shifts into x86_shrd_1.
14809 (define_insn_and_split "<insn><dwi>3_doubleword_lowpart"
14810   [(set (match_operand:DWIH 0 "register_operand" "=&r")
14811         (subreg:DWIH
14812           (any_shiftrt:<DWI> (match_operand:<DWI> 1 "register_operand" "r")
14813                              (match_operand:QI 2 "const_int_operand")) 0))
14814    (clobber (reg:CC FLAGS_REG))]
14815   "UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
14816   "#"
14817   "&& reload_completed"
14818   [(parallel
14819       [(set (match_dup 0)
14820             (ior:DWIH (lshiftrt:DWIH (match_dup 0) (match_dup 2))
14821                       (subreg:DWIH
14822                         (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
14823                                       (match_dup 4)) 0)))
14824        (clobber (reg:CC FLAGS_REG))])]
14826   split_double_mode (<DWI>mode, &operands[1], 1, &operands[1], &operands[3]);
14827   operands[4] = GEN_INT ((<MODE_SIZE> * BITS_PER_UNIT) - INTVAL (operands[2]));
14828   if (!rtx_equal_p (operands[0], operands[3]))
14829     emit_move_insn (operands[0], operands[3]);
14832 (define_insn "x86_64_shrd"
14833   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14834         (ior:DI (lshiftrt:DI (match_dup 0)
14835                   (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
14836                           (const_int 63)))
14837                 (subreg:DI
14838                   (ashift:TI
14839                     (zero_extend:TI
14840                       (match_operand:DI 1 "register_operand" "r"))
14841                     (minus:QI (const_int 64)
14842                               (and:QI (match_dup 2) (const_int 63)))) 0)))
14843    (clobber (reg:CC FLAGS_REG))]
14844   "TARGET_64BIT"
14845   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
14846   [(set_attr "type" "ishift")
14847    (set_attr "prefix_0f" "1")
14848    (set_attr "mode" "DI")
14849    (set_attr "athlon_decode" "vector")
14850    (set_attr "amdfam10_decode" "vector")
14851    (set_attr "bdver1_decode" "vector")])
14853 (define_insn "x86_64_shrd_1"
14854   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14855         (ior:DI (lshiftrt:DI (match_dup 0)
14856                              (match_operand:QI 2 "const_0_to_63_operand"))
14857                 (subreg:DI
14858                   (ashift:TI
14859                     (zero_extend:TI
14860                       (match_operand:DI 1 "register_operand" "r"))
14861                     (match_operand:QI 3 "const_0_to_255_operand")) 0)))
14862    (clobber (reg:CC FLAGS_REG))]
14863   "TARGET_64BIT
14864    && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
14865   "shrd{q}\t{%2, %1, %0|%0, %1, %2}"
14866   [(set_attr "type" "ishift")
14867    (set_attr "prefix_0f" "1")
14868    (set_attr "length_immediate" "1")
14869    (set_attr "mode" "DI")
14870    (set_attr "athlon_decode" "vector")
14871    (set_attr "amdfam10_decode" "vector")
14872    (set_attr "bdver1_decode" "vector")])
14874 (define_insn_and_split "*x86_64_shrd_shld_1_nozext"
14875   [(set (match_operand:DI 0 "nonimmediate_operand")
14876         (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
14877                              (match_operand:QI 2 "const_0_to_63_operand"))
14878                 (ashift:DI
14879                   (match_operand:DI 1 "nonimmediate_operand")
14880                   (match_operand:QI 3 "const_0_to_63_operand"))))
14881    (clobber (reg:CC FLAGS_REG))]
14882   "TARGET_64BIT
14883    && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
14884    && ix86_pre_reload_split ()"
14885   "#"
14886   "&& 1"
14887   [(const_int 0)]
14889   if (rtx_equal_p (operands[4], operands[0]))
14890     {
14891       operands[1] = force_reg (DImode, operands[1]);
14892       emit_insn (gen_x86_64_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14893     }
14894   else if (rtx_equal_p (operands[1], operands[0]))
14895     {
14896       operands[4] = force_reg (DImode, operands[4]);
14897       emit_insn (gen_x86_64_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14898     }
14899   else
14900    {
14901      operands[1] = force_reg (DImode, operands[1]);
14902      rtx tmp = gen_reg_rtx (DImode);
14903      emit_move_insn (tmp, operands[4]);
14904      emit_insn (gen_x86_64_shrd_1 (tmp, operands[1], operands[2], operands[3]));
14905      emit_move_insn (operands[0], tmp);
14906    }
14907    DONE;
14910 (define_insn_and_split "*x86_64_shrd_2"
14911   [(set (match_operand:DI 0 "nonimmediate_operand")
14912         (ior:DI (lshiftrt:DI (match_dup 0)
14913                              (match_operand:QI 2 "nonmemory_operand"))
14914                 (ashift:DI (match_operand:DI 1 "register_operand")
14915                            (minus:QI (const_int 64) (match_dup 2)))))
14916    (clobber (reg:CC FLAGS_REG))]
14917   "TARGET_64BIT && ix86_pre_reload_split ()"
14918   "#"
14919   "&& 1"
14920   [(parallel [(set (match_dup 0)
14921                    (ior:DI (lshiftrt:DI (match_dup 0)
14922                                         (and:QI (match_dup 2) (const_int 63)))
14923                            (subreg:DI
14924                              (ashift:TI
14925                                (zero_extend:TI (match_dup 1))
14926                                  (minus:QI (const_int 64)
14927                                            (and:QI (match_dup 2)
14928                                                    (const_int 63)))) 0)))
14929               (clobber (reg:CC FLAGS_REG))])])
14931 (define_insn "x86_shrd"
14932   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14933         (ior:SI (lshiftrt:SI (match_dup 0)
14934                   (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
14935                           (const_int 31)))
14936                 (subreg:SI
14937                   (ashift:DI
14938                     (zero_extend:DI
14939                       (match_operand:SI 1 "register_operand" "r"))
14940                     (minus:QI (const_int 32)
14941                               (and:QI (match_dup 2) (const_int 31)))) 0)))
14942    (clobber (reg:CC FLAGS_REG))]
14943   ""
14944   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
14945   [(set_attr "type" "ishift")
14946    (set_attr "prefix_0f" "1")
14947    (set_attr "mode" "SI")
14948    (set_attr "pent_pair" "np")
14949    (set_attr "athlon_decode" "vector")
14950    (set_attr "amdfam10_decode" "vector")
14951    (set_attr "bdver1_decode" "vector")])
14953 (define_insn "x86_shrd_1"
14954   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14955         (ior:SI (lshiftrt:SI (match_dup 0)
14956                              (match_operand:QI 2 "const_0_to_31_operand"))
14957                 (subreg:SI
14958                   (ashift:DI
14959                     (zero_extend:DI
14960                       (match_operand:SI 1 "register_operand" "r"))
14961                     (match_operand:QI 3 "const_0_to_63_operand")) 0)))
14962    (clobber (reg:CC FLAGS_REG))]
14963   "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
14964   "shrd{l}\t{%2, %1, %0|%0, %1, %2}"
14965   [(set_attr "type" "ishift")
14966    (set_attr "prefix_0f" "1")
14967    (set_attr "length_immediate" "1")
14968    (set_attr "mode" "SI")
14969    (set_attr "pent_pair" "np")
14970    (set_attr "athlon_decode" "vector")
14971    (set_attr "amdfam10_decode" "vector")
14972    (set_attr "bdver1_decode" "vector")])
14974 (define_insn_and_split "*x86_shrd_shld_1_nozext"
14975   [(set (match_operand:SI 0 "nonimmediate_operand")
14976         (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
14977                              (match_operand:QI 2 "const_0_to_31_operand"))
14978                (ashift:SI
14979                    (match_operand:SI 1 "nonimmediate_operand")
14980                    (match_operand:QI 3 "const_0_to_31_operand"))))
14981    (clobber (reg:CC FLAGS_REG))]
14982   "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
14983    && ix86_pre_reload_split ()"
14984   "#"
14985   "&& 1"
14986   [(const_int 0)]
14988   if (rtx_equal_p (operands[4], operands[0]))
14989     {
14990       operands[1] = force_reg (SImode, operands[1]);
14991       emit_insn (gen_x86_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14992     }
14993   else if (rtx_equal_p (operands[1], operands[0]))
14994     {
14995       operands[4] = force_reg (SImode, operands[4]);
14996       emit_insn (gen_x86_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14997     }
14998   else
14999    {
15000      operands[1] = force_reg (SImode, operands[1]);
15001      rtx tmp = gen_reg_rtx (SImode);
15002      emit_move_insn (tmp, operands[4]);
15003      emit_insn (gen_x86_shrd_1 (tmp, operands[1], operands[2], operands[3]));
15004      emit_move_insn (operands[0], tmp);
15005    }
15006    DONE;
15009 (define_insn_and_split "*x86_shrd_2"
15010   [(set (match_operand:SI 0 "nonimmediate_operand")
15011         (ior:SI (lshiftrt:SI (match_dup 0)
15012                              (match_operand:QI 2 "nonmemory_operand"))
15013                 (ashift:SI (match_operand:SI 1 "register_operand")
15014                            (minus:QI (const_int 32) (match_dup 2)))))
15015    (clobber (reg:CC FLAGS_REG))]
15016   "TARGET_64BIT && ix86_pre_reload_split ()"
15017   "#"
15018   "&& 1"
15019   [(parallel [(set (match_dup 0)
15020                    (ior:SI (lshiftrt:SI (match_dup 0)
15021                                         (and:QI (match_dup 2) (const_int 31)))
15022                            (subreg:SI
15023                              (ashift:DI
15024                                (zero_extend:DI (match_dup 1))
15025                                  (minus:QI (const_int 32)
15026                                            (and:QI (match_dup 2)
15027                                                    (const_int 31)))) 0)))
15028               (clobber (reg:CC FLAGS_REG))])])
15030 ;; Base name for insn mnemonic.
15031 (define_mode_attr cvt_mnemonic
15032   [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
15034 (define_insn "ashr<mode>3_cvt"
15035   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
15036         (ashiftrt:SWI48
15037           (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
15038           (match_operand:QI 2 "const_int_operand")))
15039    (clobber (reg:CC FLAGS_REG))]
15040   "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
15041    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
15042    && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15043   "@
15044    <cvt_mnemonic>
15045    sar{<imodesuffix>}\t{%2, %0|%0, %2}"
15046   [(set_attr "type" "imovx,ishift")
15047    (set_attr "prefix_0f" "0,*")
15048    (set_attr "length_immediate" "0,*")
15049    (set_attr "modrm" "0,1")
15050    (set_attr "mode" "<MODE>")])
15052 (define_insn "*ashrsi3_cvt_zext"
15053   [(set (match_operand:DI 0 "register_operand" "=*d,r")
15054         (zero_extend:DI
15055           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
15056                        (match_operand:QI 2 "const_int_operand"))))
15057    (clobber (reg:CC FLAGS_REG))]
15058   "TARGET_64BIT && INTVAL (operands[2]) == 31
15059    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
15060    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
15061   "@
15062    {cltd|cdq}
15063    sar{l}\t{%2, %k0|%k0, %2}"
15064   [(set_attr "type" "imovx,ishift")
15065    (set_attr "prefix_0f" "0,*")
15066    (set_attr "length_immediate" "0,*")
15067    (set_attr "modrm" "0,1")
15068    (set_attr "mode" "SI")])
15070 (define_expand "@x86_shift<mode>_adj_3"
15071   [(use (match_operand:SWI48 0 "register_operand"))
15072    (use (match_operand:SWI48 1 "register_operand"))
15073    (use (match_operand:QI 2 "register_operand"))]
15074   ""
15076   rtx_code_label *label = gen_label_rtx ();
15077   rtx tmp;
15079   emit_insn (gen_testqi_ccz_1 (operands[2],
15080                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
15082   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
15083   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
15084   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
15085                               gen_rtx_LABEL_REF (VOIDmode, label),
15086                               pc_rtx);
15087   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
15088   JUMP_LABEL (tmp) = label;
15090   emit_move_insn (operands[0], operands[1]);
15091   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
15092                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
15093   emit_label (label);
15094   LABEL_NUSES (label) = 1;
15096   DONE;
15099 (define_insn "*bmi2_<insn><mode>3_1"
15100   [(set (match_operand:SWI48 0 "register_operand" "=r")
15101         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
15102                            (match_operand:SWI48 2 "register_operand" "r")))]
15103   "TARGET_BMI2"
15104   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
15105   [(set_attr "type" "ishiftx")
15106    (set_attr "mode" "<MODE>")])
15108 (define_insn "*ashr<mode>3_1"
15109   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
15110         (ashiftrt:SWI48
15111           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
15112           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
15113    (clobber (reg:CC FLAGS_REG))]
15114   "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15116   switch (get_attr_type (insn))
15117     {
15118     case TYPE_ISHIFTX:
15119       return "#";
15121     default:
15122       if (operands[2] == const1_rtx
15123           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15124         return "sar{<imodesuffix>}\t%0";
15125       else
15126         return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
15127     }
15129   [(set_attr "isa" "*,bmi2")
15130    (set_attr "type" "ishift,ishiftx")
15131    (set (attr "length_immediate")
15132      (if_then_else
15133        (and (match_operand 2 "const1_operand")
15134             (ior (match_test "TARGET_SHIFT1")
15135                  (match_test "optimize_function_for_size_p (cfun)")))
15136        (const_string "0")
15137        (const_string "*")))
15138    (set_attr "mode" "<MODE>")])
15140 ;; Specialization of *lshr<mode>3_1 below, extracting the SImode
15141 ;; highpart of a DI to be extracted, but allowing it to be clobbered.
15142 (define_insn_and_split "*highpartdisi2"
15143   [(set (subreg:DI (match_operand:SI 0 "register_operand" "=r,x,?k") 0)
15144         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,k")
15145                      (const_int 32)))
15146    (clobber (reg:CC FLAGS_REG))]
15147   "TARGET_64BIT"
15148   "#"
15149   "&& reload_completed"
15150   [(parallel
15151     [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 32)))
15152      (clobber (reg:CC FLAGS_REG))])]
15154   if (SSE_REG_P (operands[0]))
15155     {
15156       rtx tmp = gen_rtx_REG (V4SImode, REGNO (operands[0]));
15157       emit_insn (gen_sse_shufps_v4si (tmp, tmp, tmp,
15158                                       const1_rtx, const1_rtx,
15159                                       GEN_INT (5), GEN_INT (5)));
15160       DONE;
15161     }
15162   operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
15165 (define_insn "*lshr<mode>3_1"
15166   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,?k")
15167         (lshiftrt:SWI48
15168           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,k")
15169           (match_operand:QI 2 "nonmemory_operand" "c<S>,r,<KS>")))
15170    (clobber (reg:CC FLAGS_REG))]
15171   "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands)"
15173   switch (get_attr_type (insn))
15174     {
15175     case TYPE_ISHIFTX:
15176     case TYPE_MSKLOG:
15177       return "#";
15179     default:
15180       if (operands[2] == const1_rtx
15181           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15182         return "shr{<imodesuffix>}\t%0";
15183       else
15184         return "shr{<imodesuffix>}\t{%2, %0|%0, %2}";
15185     }
15187   [(set_attr "isa" "*,bmi2,<kmov_isa>")
15188    (set_attr "type" "ishift,ishiftx,msklog")
15189    (set (attr "length_immediate")
15190      (if_then_else
15191        (and (and (match_operand 2 "const1_operand")
15192                  (eq_attr "alternative" "0"))
15193             (ior (match_test "TARGET_SHIFT1")
15194                  (match_test "optimize_function_for_size_p (cfun)")))
15195        (const_string "0")
15196        (const_string "*")))
15197    (set_attr "mode" "<MODE>")])
15199 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15200 (define_split
15201   [(set (match_operand:SWI48 0 "register_operand")
15202         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15203                            (match_operand:QI 2 "register_operand")))
15204    (clobber (reg:CC FLAGS_REG))]
15205   "TARGET_BMI2 && reload_completed"
15206   [(set (match_dup 0)
15207         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
15208   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
15210 (define_insn "*bmi2_<insn>si3_1_zext"
15211   [(set (match_operand:DI 0 "register_operand" "=r")
15212         (zero_extend:DI
15213           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15214                           (match_operand:SI 2 "register_operand" "r"))))]
15215   "TARGET_64BIT && TARGET_BMI2"
15216   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
15217   [(set_attr "type" "ishiftx")
15218    (set_attr "mode" "SI")])
15220 (define_insn "*<insn>si3_1_zext"
15221   [(set (match_operand:DI 0 "register_operand" "=r,r")
15222         (zero_extend:DI
15223           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15224                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
15225    (clobber (reg:CC FLAGS_REG))]
15226   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15228   switch (get_attr_type (insn))
15229     {
15230     case TYPE_ISHIFTX:
15231       return "#";
15233     default:
15234       if (operands[2] == const1_rtx
15235           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15236         return "<shift>{l}\t%k0";
15237       else
15238         return "<shift>{l}\t{%2, %k0|%k0, %2}";
15239     }
15241   [(set_attr "isa" "*,bmi2")
15242    (set_attr "type" "ishift,ishiftx")
15243    (set (attr "length_immediate")
15244      (if_then_else
15245        (and (match_operand 2 "const1_operand")
15246             (ior (match_test "TARGET_SHIFT1")
15247                  (match_test "optimize_function_for_size_p (cfun)")))
15248        (const_string "0")
15249        (const_string "*")))
15250    (set_attr "mode" "SI")])
15252 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15253 (define_split
15254   [(set (match_operand:DI 0 "register_operand")
15255         (zero_extend:DI
15256           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
15257                           (match_operand:QI 2 "register_operand"))))
15258    (clobber (reg:CC FLAGS_REG))]
15259   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
15260   [(set (match_dup 0)
15261         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15262   "operands[2] = gen_lowpart (SImode, operands[2]);")
15264 (define_insn "*ashr<mode>3_1"
15265   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
15266         (ashiftrt:SWI12
15267           (match_operand:SWI12 1 "nonimmediate_operand" "0")
15268           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
15269    (clobber (reg:CC FLAGS_REG))]
15270   "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15272   if (operands[2] == const1_rtx
15273       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15274     return "sar{<imodesuffix>}\t%0";
15275   else
15276     return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
15278   [(set_attr "type" "ishift")
15279    (set (attr "length_immediate")
15280      (if_then_else
15281        (and (match_operand 2 "const1_operand")
15282             (ior (match_test "TARGET_SHIFT1")
15283                  (match_test "optimize_function_for_size_p (cfun)")))
15284        (const_string "0")
15285        (const_string "*")))
15286    (set_attr "mode" "<MODE>")])
15288 (define_insn "*lshrqi3_1"
15289   [(set (match_operand:QI 0 "nonimmediate_operand"  "=qm,?k")
15290         (lshiftrt:QI
15291           (match_operand:QI 1 "nonimmediate_operand" "0, k")
15292           (match_operand:QI 2 "nonmemory_operand"    "cI,Wb")))
15293    (clobber (reg:CC FLAGS_REG))]
15294   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
15296   switch (get_attr_type (insn))
15297     {
15298     case TYPE_ISHIFT:
15299       if (operands[2] == const1_rtx
15300           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15301         return "shr{b}\t%0";
15302       else
15303         return "shr{b}\t{%2, %0|%0, %2}";
15304     case TYPE_MSKLOG:
15305       return "#";
15306     default:
15307       gcc_unreachable ();
15308     }
15310   [(set_attr "isa" "*,avx512dq")
15311    (set_attr "type" "ishift,msklog")
15312    (set (attr "length_immediate")
15313      (if_then_else
15314        (and (and (match_operand 2 "const1_operand")
15315                  (eq_attr "alternative" "0"))
15316             (ior (match_test "TARGET_SHIFT1")
15317                  (match_test "optimize_function_for_size_p (cfun)")))
15318        (const_string "0")
15319        (const_string "*")))
15320    (set_attr "mode" "QI")])
15322 (define_insn "*lshrhi3_1"
15323   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm, ?k")
15324         (lshiftrt:HI
15325           (match_operand:HI 1 "nonimmediate_operand" "0, k")
15326           (match_operand:QI 2 "nonmemory_operand" "cI, Ww")))
15327    (clobber (reg:CC FLAGS_REG))]
15328   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
15330   switch (get_attr_type (insn))
15331     {
15332     case TYPE_ISHIFT:
15333       if (operands[2] == const1_rtx
15334           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15335         return "shr{w}\t%0";
15336       else
15337         return "shr{w}\t{%2, %0|%0, %2}";
15338     case TYPE_MSKLOG:
15339       return "#";
15340     default:
15341       gcc_unreachable ();
15342     }
15344   [(set_attr "isa" "*, avx512f")
15345    (set_attr "type" "ishift,msklog")
15346    (set (attr "length_immediate")
15347      (if_then_else
15348        (and (and (match_operand 2 "const1_operand")
15349                  (eq_attr "alternative" "0"))
15350             (ior (match_test "TARGET_SHIFT1")
15351                  (match_test "optimize_function_for_size_p (cfun)")))
15352        (const_string "0")
15353        (const_string "*")))
15354    (set_attr "mode" "HI")])
15356 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15357 (define_insn_and_split "*<insn><mode>3_1_slp"
15358   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15359         (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15360                            (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15361    (clobber (reg:CC FLAGS_REG))]
15362   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15364   if (which_alternative)
15365     return "#";
15367   if (operands[2] == const1_rtx
15368       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15369     return "<shift>{<imodesuffix>}\t%0";
15370   else
15371     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15373   "&& reload_completed
15374    && !(rtx_equal_p (operands[0], operands[1]))"
15375   [(set (strict_low_part (match_dup 0)) (match_dup 1))
15376    (parallel
15377      [(set (strict_low_part (match_dup 0))
15378            (any_shiftrt:SWI12 (match_dup 0) (match_dup 2)))
15379       (clobber (reg:CC FLAGS_REG))])]
15380   ""
15381   [(set_attr "type" "ishift")
15382    (set (attr "length_immediate")
15383      (if_then_else
15384        (and (match_operand 2 "const1_operand")
15385             (ior (match_test "TARGET_SHIFT1")
15386                  (match_test "optimize_function_for_size_p (cfun)")))
15387        (const_string "0")
15388        (const_string "*")))
15389    (set_attr "mode" "<MODE>")])
15391 ;; This pattern can't accept a variable shift count, since shifts by
15392 ;; zero don't affect the flags.  We assume that shifts by constant
15393 ;; zero are optimized away.
15394 (define_insn "*<insn><mode>3_cmp"
15395   [(set (reg FLAGS_REG)
15396         (compare
15397           (any_shiftrt:SWI
15398             (match_operand:SWI 1 "nonimmediate_operand" "0")
15399             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15400           (const_int 0)))
15401    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
15402         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
15403   "(optimize_function_for_size_p (cfun)
15404     || !TARGET_PARTIAL_FLAG_REG_STALL
15405     || (operands[2] == const1_rtx
15406         && TARGET_SHIFT1))
15407    && ix86_match_ccmode (insn, CCGOCmode)
15408    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15410   if (operands[2] == const1_rtx
15411       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15412     return "<shift>{<imodesuffix>}\t%0";
15413   else
15414     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15416   [(set_attr "type" "ishift")
15417    (set (attr "length_immediate")
15418      (if_then_else
15419        (and (match_operand 2 "const1_operand")
15420             (ior (match_test "TARGET_SHIFT1")
15421                  (match_test "optimize_function_for_size_p (cfun)")))
15422        (const_string "0")
15423        (const_string "*")))
15424    (set_attr "mode" "<MODE>")])
15426 (define_insn "*<insn>si3_cmp_zext"
15427   [(set (reg FLAGS_REG)
15428         (compare
15429           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
15430                           (match_operand:QI 2 "const_1_to_31_operand"))
15431           (const_int 0)))
15432    (set (match_operand:DI 0 "register_operand" "=r")
15433         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15434   "TARGET_64BIT
15435    && (optimize_function_for_size_p (cfun)
15436        || !TARGET_PARTIAL_FLAG_REG_STALL
15437        || (operands[2] == const1_rtx
15438            && TARGET_SHIFT1))
15439    && ix86_match_ccmode (insn, CCGOCmode)
15440    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15442   if (operands[2] == const1_rtx
15443       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15444     return "<shift>{l}\t%k0";
15445   else
15446     return "<shift>{l}\t{%2, %k0|%k0, %2}";
15448   [(set_attr "type" "ishift")
15449    (set (attr "length_immediate")
15450      (if_then_else
15451        (and (match_operand 2 "const1_operand")
15452             (ior (match_test "TARGET_SHIFT1")
15453                  (match_test "optimize_function_for_size_p (cfun)")))
15454        (const_string "0")
15455        (const_string "*")))
15456    (set_attr "mode" "SI")])
15458 (define_insn "*<insn><mode>3_cconly"
15459   [(set (reg FLAGS_REG)
15460         (compare
15461           (any_shiftrt:SWI
15462             (match_operand:SWI 1 "register_operand" "0")
15463             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15464           (const_int 0)))
15465    (clobber (match_scratch:SWI 0 "=<r>"))]
15466   "(optimize_function_for_size_p (cfun)
15467     || !TARGET_PARTIAL_FLAG_REG_STALL
15468     || (operands[2] == const1_rtx
15469         && TARGET_SHIFT1))
15470    && ix86_match_ccmode (insn, CCGOCmode)"
15472   if (operands[2] == const1_rtx
15473       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15474     return "<shift>{<imodesuffix>}\t%0";
15475   else
15476     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15478   [(set_attr "type" "ishift")
15479    (set (attr "length_immediate")
15480      (if_then_else
15481        (and (match_operand 2 "const1_operand")
15482             (ior (match_test "TARGET_SHIFT1")
15483                  (match_test "optimize_function_for_size_p (cfun)")))
15484        (const_string "0")
15485        (const_string "*")))
15486    (set_attr "mode" "<MODE>")])
15488 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15489 (define_insn_and_split "*<insn>qi_ext<mode>_1"
15490   [(set (zero_extract:SWI248
15491           (match_operand 0 "int248_register_operand" "+Q,&Q")
15492           (const_int 8)
15493           (const_int 8))
15494         (subreg:SWI248
15495           (any_shiftrt:QI
15496             (subreg:QI
15497               (match_operator:SWI248 3 "extract_operator"
15498                 [(match_operand 1 "int248_register_operand" "0,!Q")
15499                  (const_int 8)
15500                  (const_int 8)]) 0)
15501             (match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
15502    (clobber (reg:CC FLAGS_REG))]
15503   ""
15505   if (which_alternative)
15506     return "#";
15508   if (operands[2] == const1_rtx
15509       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15510     return "<shift>{b}\t%h0";
15511   else
15512     return "<shift>{b}\t{%2, %h0|%h0, %2}";
15514   "reload_completed
15515    && !(rtx_equal_p (operands[0], operands[1]))"
15516   [(set (zero_extract:SWI248
15517           (match_dup 0) (const_int 8) (const_int 8))
15518         (match_dup 1))
15519    (parallel
15520      [(set (zero_extract:SWI248
15521              (match_dup 0) (const_int 8) (const_int 8))
15522            (subreg:SWI248
15523              (any_shiftrt:QI
15524                (subreg:QI
15525                  (match_op_dup 3
15526                    [(match_dup 0) (const_int 8) (const_int 8)]) 0)
15527                (match_dup 2)) 0))
15528       (clobber (reg:CC FLAGS_REG))])]
15529   ""
15530   [(set_attr "type" "ishift")
15531    (set (attr "length_immediate")
15532      (if_then_else
15533        (and (match_operand 2 "const1_operand")
15534             (ior (match_test "TARGET_SHIFT1")
15535                  (match_test "optimize_function_for_size_p (cfun)")))
15536        (const_string "0")
15537        (const_string "*")))
15538    (set_attr "mode" "QI")])
15540 (define_insn_and_split "*extend<dwi>2_doubleword_highpart"
15541   [(set (match_operand:<DWI> 0 "register_operand" "=r")
15542         (ashiftrt:<DWI>
15543           (ashift:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")
15544                         (match_operand:QI 2 "const_int_operand"))
15545           (match_operand:QI 3 "const_int_operand")))
15546    (clobber (reg:CC FLAGS_REG))]
15547   "INTVAL (operands[2]) == INTVAL (operands[3])
15548    && UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
15549   "#"
15550   "&& reload_completed"
15551   [(parallel [(set (match_dup 4)
15552                    (ashift:DWIH (match_dup 4) (match_dup 2)))
15553               (clobber (reg:CC FLAGS_REG))])
15554    (parallel [(set (match_dup 4)
15555                    (ashiftrt:DWIH (match_dup 4) (match_dup 2)))
15556               (clobber (reg:CC FLAGS_REG))])]
15557   "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[4]);")
15559 (define_insn_and_split "*extendv2di2_highpart_stv"
15560   [(set (match_operand:V2DI 0 "register_operand" "=v")
15561         (ashiftrt:V2DI
15562           (ashift:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "vm")
15563                        (match_operand:QI 2 "const_int_operand"))
15564           (match_operand:QI 3 "const_int_operand")))]
15565   "!TARGET_64BIT && TARGET_STV && TARGET_AVX512VL
15566    && INTVAL (operands[2]) == INTVAL (operands[3])
15567    && UINTVAL (operands[2]) < 32"
15568   "#"
15569   "&& reload_completed"
15570   [(set (match_dup 0)
15571         (ashift:V2DI (match_dup 1) (match_dup 2)))
15572    (set (match_dup 0)
15573         (ashiftrt:V2DI (match_dup 0) (match_dup 2)))])
15575 ;; Rotate instructions
15577 (define_expand "<insn>ti3"
15578   [(set (match_operand:TI 0 "register_operand")
15579         (any_rotate:TI (match_operand:TI 1 "register_operand")
15580                        (match_operand:QI 2 "nonmemory_operand")))]
15581   "TARGET_64BIT"
15583   if (const_1_to_63_operand (operands[2], VOIDmode))
15584     emit_insn (gen_ix86_<insn>ti3_doubleword
15585                 (operands[0], operands[1], operands[2]));
15586   else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 64)
15587     {
15588       operands[1] = force_reg (TImode, operands[1]);
15589       emit_insn (gen_<insn>64ti2_doubleword (operands[0], operands[1]));
15590     }
15591   else
15592     {
15593       rtx amount = force_reg (QImode, operands[2]);
15594       rtx src_lo = gen_lowpart (DImode, operands[1]);
15595       rtx src_hi = gen_highpart (DImode, operands[1]);
15596       rtx tmp_lo = gen_reg_rtx (DImode);
15597       rtx tmp_hi = gen_reg_rtx (DImode);
15598       emit_move_insn (tmp_lo, src_lo);
15599       emit_move_insn (tmp_hi, src_hi);
15600       rtx (*shiftd) (rtx, rtx, rtx)
15601             = (<CODE> == ROTATE) ? gen_x86_64_shld : gen_x86_64_shrd;
15602       emit_insn (shiftd (tmp_lo, src_hi, amount));
15603       emit_insn (shiftd (tmp_hi, src_lo, amount));
15604       rtx dst_lo = gen_lowpart (DImode, operands[0]);
15605       rtx dst_hi = gen_highpart (DImode, operands[0]);
15606       emit_move_insn (dst_lo, tmp_lo);
15607       emit_move_insn (dst_hi, tmp_hi);
15608       emit_insn (gen_x86_shiftdi_adj_1 (dst_lo, dst_hi, amount, tmp_lo));
15609     }
15610   DONE;
15613 (define_expand "<insn>di3"
15614   [(set (match_operand:DI 0 "shiftdi_operand")
15615         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
15616                        (match_operand:QI 2 "nonmemory_operand")))]
15617  ""
15619   if (TARGET_64BIT)
15620     ix86_expand_binary_operator (<CODE>, DImode, operands);
15621   else if (const_1_to_31_operand (operands[2], VOIDmode))
15622     emit_insn (gen_ix86_<insn>di3_doubleword
15623                 (operands[0], operands[1], operands[2]));
15624   else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 32)
15625     {
15626       operands[1] = force_reg (DImode, operands[1]);
15627       emit_insn (gen_<insn>32di2_doubleword (operands[0], operands[1]));
15628     }
15629   else
15630     FAIL;
15632   DONE;
15635 (define_expand "<insn><mode>3"
15636   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
15637         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
15638                             (match_operand:QI 2 "nonmemory_operand")))]
15639   ""
15640   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
15642 ;; Avoid useless masking of count operand.
15643 (define_insn_and_split "*<insn><mode>3_mask"
15644   [(set (match_operand:SWI 0 "nonimmediate_operand")
15645         (any_rotate:SWI
15646           (match_operand:SWI 1 "nonimmediate_operand")
15647           (subreg:QI
15648             (and
15649               (match_operand 2 "int248_register_operand" "c")
15650               (match_operand 3 "const_int_operand")) 0)))
15651    (clobber (reg:CC FLAGS_REG))]
15652   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15653    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15654       == GET_MODE_BITSIZE (<MODE>mode)-1
15655    && ix86_pre_reload_split ()"
15656   "#"
15657   "&& 1"
15658   [(parallel
15659      [(set (match_dup 0)
15660            (any_rotate:SWI (match_dup 1)
15661                            (match_dup 2)))
15662       (clobber (reg:CC FLAGS_REG))])]
15664   operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15665   operands[2] = gen_lowpart (QImode, operands[2]);
15668 (define_split
15669   [(set (match_operand:SWI 0 "register_operand")
15670         (any_rotate:SWI
15671           (match_operand:SWI 1 "const_int_operand")
15672           (subreg:QI
15673             (and
15674               (match_operand 2 "int248_register_operand")
15675               (match_operand 3 "const_int_operand")) 0)))]
15676  "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15677    == GET_MODE_BITSIZE (<MODE>mode) - 1"
15678  [(set (match_dup 4) (match_dup 1))
15679   (set (match_dup 0)
15680        (any_rotate:SWI (match_dup 4)
15681                        (subreg:QI (match_dup 2) 0)))]
15682  "operands[4] = gen_reg_rtx (<MODE>mode);")
15684 (define_insn_and_split "*<insn><mode>3_mask_1"
15685   [(set (match_operand:SWI 0 "nonimmediate_operand")
15686         (any_rotate:SWI
15687           (match_operand:SWI 1 "nonimmediate_operand")
15688           (and:QI
15689             (match_operand:QI 2 "register_operand" "c")
15690             (match_operand:QI 3 "const_int_operand"))))
15691    (clobber (reg:CC FLAGS_REG))]
15692   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15693    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15694       == GET_MODE_BITSIZE (<MODE>mode)-1
15695    && ix86_pre_reload_split ()"
15696   "#"
15697   "&& 1"
15698   [(parallel
15699      [(set (match_dup 0)
15700            (any_rotate:SWI (match_dup 1)
15701                            (match_dup 2)))
15702       (clobber (reg:CC FLAGS_REG))])])
15704 (define_split
15705   [(set (match_operand:SWI 0 "register_operand")
15706         (any_rotate:SWI
15707           (match_operand:SWI 1 "const_int_operand")
15708           (and:QI
15709             (match_operand:QI 2 "register_operand")
15710             (match_operand:QI 3 "const_int_operand"))))]
15711  "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15712   == GET_MODE_BITSIZE (<MODE>mode) - 1"
15713  [(set (match_dup 4) (match_dup 1))
15714   (set (match_dup 0)
15715        (any_rotate:SWI (match_dup 4) (match_dup 2)))]
15716  "operands[4] = gen_reg_rtx (<MODE>mode);")
15718 ;; Implement rotation using two double-precision
15719 ;; shift instructions and a scratch register.
15721 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
15722  [(set (match_operand:<DWI> 0 "register_operand" "=r")
15723        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15724                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15725   (clobber (reg:CC FLAGS_REG))
15726   (clobber (match_scratch:DWIH 3 "=&r"))]
15727  ""
15728  "#"
15729  "reload_completed"
15730  [(set (match_dup 3) (match_dup 4))
15731   (parallel
15732    [(set (match_dup 4)
15733          (ior:DWIH (ashift:DWIH (match_dup 4)
15734                                 (and:QI (match_dup 2) (match_dup 6)))
15735                    (subreg:DWIH
15736                      (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
15737                                      (minus:QI (match_dup 7)
15738                                                (and:QI (match_dup 2)
15739                                                        (match_dup 6)))) 0)))
15740     (clobber (reg:CC FLAGS_REG))])
15741   (parallel
15742    [(set (match_dup 5)
15743          (ior:DWIH (ashift:DWIH (match_dup 5)
15744                                 (and:QI (match_dup 2) (match_dup 6)))
15745                    (subreg:DWIH
15746                      (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 3))
15747                                      (minus:QI (match_dup 7)
15748                                                (and:QI (match_dup 2)
15749                                                        (match_dup 6)))) 0)))
15750     (clobber (reg:CC FLAGS_REG))])]
15752   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15753   operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15755   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15758 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
15759  [(set (match_operand:<DWI> 0 "register_operand" "=r")
15760        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15761                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15762   (clobber (reg:CC FLAGS_REG))
15763   (clobber (match_scratch:DWIH 3 "=&r"))]
15764  ""
15765  "#"
15766  "reload_completed"
15767  [(set (match_dup 3) (match_dup 4))
15768   (parallel
15769    [(set (match_dup 4)
15770          (ior:DWIH (lshiftrt:DWIH (match_dup 4)
15771                                   (and:QI (match_dup 2) (match_dup 6)))
15772                    (subreg:DWIH
15773                      (ashift:<DWI> (zero_extend:<DWI> (match_dup 5))
15774                                    (minus:QI (match_dup 7)
15775                                              (and:QI (match_dup 2)
15776                                                      (match_dup 6)))) 0)))
15777     (clobber (reg:CC FLAGS_REG))])
15778   (parallel
15779    [(set (match_dup 5)
15780          (ior:DWIH (lshiftrt:DWIH (match_dup 5)
15781                                   (and:QI (match_dup 2) (match_dup 6)))
15782                    (subreg:DWIH
15783                      (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
15784                                    (minus:QI (match_dup 7)
15785                                              (and:QI (match_dup 2)
15786                                                      (match_dup 6)))) 0)))
15787     (clobber (reg:CC FLAGS_REG))])]
15789   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15790   operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15792   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15795 (define_insn_and_split "<insn>32di2_doubleword"
15796  [(set (match_operand:DI 0 "register_operand" "=r,r")
15797        (any_rotate:DI (match_operand:DI 1 "register_operand" "0,r")
15798                       (const_int 32)))]
15799  "!TARGET_64BIT"
15800  "#"
15801  "&& reload_completed"
15802  [(set (match_dup 0) (match_dup 3))
15803   (set (match_dup 2) (match_dup 1))]
15805   split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
15806   if (rtx_equal_p (operands[0], operands[1]))
15807     {
15808       emit_insn (gen_swapsi (operands[0], operands[2]));
15809       DONE;
15810     }
15813 (define_insn_and_split "<insn>64ti2_doubleword"
15814  [(set (match_operand:TI 0 "register_operand" "=r,r")
15815        (any_rotate:TI (match_operand:TI 1 "register_operand" "0,r")
15816                       (const_int 64)))]
15817  "TARGET_64BIT"
15818  "#"
15819  "&& reload_completed"
15820  [(set (match_dup 0) (match_dup 3))
15821   (set (match_dup 2) (match_dup 1))]
15823   split_double_mode (TImode, &operands[0], 2, &operands[0], &operands[2]);
15824   if (rtx_equal_p (operands[0], operands[1]))
15825     {
15826       emit_insn (gen_swapdi (operands[0], operands[2]));
15827       DONE;
15828     }
15831 (define_mode_attr rorx_immediate_operand
15832         [(SI "const_0_to_31_operand")
15833          (DI "const_0_to_63_operand")])
15835 (define_insn "*bmi2_rorx<mode>3_1"
15836   [(set (match_operand:SWI48 0 "register_operand" "=r")
15837         (rotatert:SWI48
15838           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
15839           (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
15840   "TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15841   "rorx\t{%2, %1, %0|%0, %1, %2}"
15842   [(set_attr "type" "rotatex")
15843    (set_attr "mode" "<MODE>")])
15845 (define_insn "*<insn><mode>3_1"
15846   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
15847         (any_rotate:SWI48
15848           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
15849           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
15850    (clobber (reg:CC FLAGS_REG))]
15851   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15853   switch (get_attr_type (insn))
15854     {
15855     case TYPE_ROTATEX:
15856       return "#";
15858     default:
15859       if (operands[2] == const1_rtx
15860           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15861         return "<rotate>{<imodesuffix>}\t%0";
15862       else
15863         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15864     }
15866   [(set_attr "isa" "*,bmi2")
15867    (set_attr "type" "rotate,rotatex")
15868    (set (attr "preferred_for_size")
15869      (cond [(eq_attr "alternative" "0")
15870               (symbol_ref "true")]
15871            (symbol_ref "false")))
15872    (set (attr "length_immediate")
15873      (if_then_else
15874        (and (eq_attr "type" "rotate")
15875             (and (match_operand 2 "const1_operand")
15876                  (ior (match_test "TARGET_SHIFT1")
15877                       (match_test "optimize_function_for_size_p (cfun)"))))
15878        (const_string "0")
15879        (const_string "*")))
15880    (set_attr "mode" "<MODE>")])
15882 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15883 (define_split
15884   [(set (match_operand:SWI48 0 "register_operand")
15885         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15886                       (match_operand:QI 2 "const_int_operand")))
15887    (clobber (reg:CC FLAGS_REG))]
15888   "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15889   [(set (match_dup 0)
15890         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
15892   int bitsize = GET_MODE_BITSIZE (<MODE>mode);
15894   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15897 (define_split
15898   [(set (match_operand:SWI48 0 "register_operand")
15899         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15900                         (match_operand:QI 2 "const_int_operand")))
15901    (clobber (reg:CC FLAGS_REG))]
15902   "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15903   [(set (match_dup 0)
15904         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
15906 (define_insn "*bmi2_rorxsi3_1_zext"
15907   [(set (match_operand:DI 0 "register_operand" "=r")
15908         (zero_extend:DI
15909           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15910                        (match_operand:QI 2 "const_0_to_31_operand"))))]
15911   "TARGET_64BIT && TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15912   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
15913   [(set_attr "type" "rotatex")
15914    (set_attr "mode" "SI")])
15916 (define_insn "*<insn>si3_1_zext"
15917   [(set (match_operand:DI 0 "register_operand" "=r,r")
15918         (zero_extend:DI
15919           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15920                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
15921    (clobber (reg:CC FLAGS_REG))]
15922   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15924   switch (get_attr_type (insn))
15925     {
15926     case TYPE_ROTATEX:
15927       return "#";
15929     default:
15930       if (operands[2] == const1_rtx
15931           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15932         return "<rotate>{l}\t%k0";
15933       else
15934         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
15935     }
15937   [(set_attr "isa" "*,bmi2")
15938    (set_attr "type" "rotate,rotatex")
15939    (set (attr "preferred_for_size")
15940      (cond [(eq_attr "alternative" "0")
15941               (symbol_ref "true")]
15942            (symbol_ref "false")))
15943    (set (attr "length_immediate")
15944      (if_then_else
15945        (and (eq_attr "type" "rotate")
15946             (and (match_operand 2 "const1_operand")
15947                  (ior (match_test "TARGET_SHIFT1")
15948                       (match_test "optimize_function_for_size_p (cfun)"))))
15949        (const_string "0")
15950        (const_string "*")))
15951    (set_attr "mode" "SI")])
15953 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15954 (define_split
15955   [(set (match_operand:DI 0 "register_operand")
15956         (zero_extend:DI
15957           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
15958                      (match_operand:QI 2 "const_int_operand"))))
15959    (clobber (reg:CC FLAGS_REG))]
15960   "TARGET_64BIT && TARGET_BMI2 && reload_completed
15961    && !optimize_function_for_size_p (cfun)"
15962   [(set (match_dup 0)
15963         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
15965   int bitsize = GET_MODE_BITSIZE (SImode);
15967   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15970 (define_split
15971   [(set (match_operand:DI 0 "register_operand")
15972         (zero_extend:DI
15973           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
15974                        (match_operand:QI 2 "const_int_operand"))))
15975    (clobber (reg:CC FLAGS_REG))]
15976   "TARGET_64BIT && TARGET_BMI2 && reload_completed
15977    && !optimize_function_for_size_p (cfun)"
15978   [(set (match_dup 0)
15979         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
15981 (define_insn "*<insn><mode>3_1"
15982   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
15983         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
15984                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
15985    (clobber (reg:CC FLAGS_REG))]
15986   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15988   if (operands[2] == const1_rtx
15989       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15990     return "<rotate>{<imodesuffix>}\t%0";
15991   else
15992     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15994   [(set_attr "type" "rotate")
15995    (set (attr "length_immediate")
15996      (if_then_else
15997        (and (match_operand 2 "const1_operand")
15998             (ior (match_test "TARGET_SHIFT1")
15999                  (match_test "optimize_function_for_size_p (cfun)")))
16000        (const_string "0")
16001        (const_string "*")))
16002    (set_attr "mode" "<MODE>")])
16004 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
16005 (define_insn_and_split "*<insn><mode>3_1_slp"
16006   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
16007         (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
16008                           (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
16009    (clobber (reg:CC FLAGS_REG))]
16010   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
16012   if (which_alternative)
16013     return "#";
16015   if (operands[2] == const1_rtx
16016       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
16017     return "<rotate>{<imodesuffix>}\t%0";
16018   else
16019     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
16021   "&& reload_completed
16022    && !(rtx_equal_p (operands[0], operands[1]))"
16023   [(set (strict_low_part (match_dup 0)) (match_dup 1))
16024    (parallel
16025      [(set (strict_low_part (match_dup 0))
16026            (any_rotate:SWI12 (match_dup 0) (match_dup 2)))
16027       (clobber (reg:CC FLAGS_REG))])]
16028   ""
16029   [(set_attr "type" "rotate")
16030    (set (attr "length_immediate")
16031      (if_then_else
16032        (and (match_operand 2 "const1_operand")
16033             (ior (match_test "TARGET_SHIFT1")
16034                  (match_test "optimize_function_for_size_p (cfun)")))
16035        (const_string "0")
16036        (const_string "*")))
16037    (set_attr "mode" "<MODE>")])
16039 (define_split
16040  [(set (match_operand:HI 0 "QIreg_operand")
16041        (any_rotate:HI (match_dup 0) (const_int 8)))
16042   (clobber (reg:CC FLAGS_REG))]
16043  "reload_completed
16044   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
16045  [(parallel [(set (strict_low_part (match_dup 0))
16046                   (bswap:HI (match_dup 0)))
16047              (clobber (reg:CC FLAGS_REG))])])
16049 ;; Rotations through carry flag
16050 (define_insn "rcrsi2"
16051   [(set (match_operand:SI 0 "register_operand" "=r")
16052         (plus:SI
16053           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
16054                        (const_int 1))
16055           (ashift:SI (ltu:SI (reg:CCC FLAGS_REG) (const_int 0))
16056                      (const_int 31))))
16057    (clobber (reg:CC FLAGS_REG))]
16058   ""
16059   "rcr{l}\t%0"
16060   [(set_attr "type" "ishift1")
16061    (set_attr "memory" "none")
16062    (set_attr "length_immediate" "0")
16063    (set_attr "mode" "SI")])
16065 (define_insn "rcrdi2"
16066   [(set (match_operand:DI 0 "register_operand" "=r")
16067         (plus:DI
16068           (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
16069                        (const_int 1))
16070           (ashift:DI (ltu:DI (reg:CCC FLAGS_REG) (const_int 0))
16071                      (const_int 63))))
16072    (clobber (reg:CC FLAGS_REG))]
16073   "TARGET_64BIT"
16074   "rcr{q}\t%0"
16075   [(set_attr "type" "ishift1")
16076    (set_attr "length_immediate" "0")
16077    (set_attr "mode" "DI")])
16079 ;; Versions of sar and shr that set the carry flag.
16080 (define_insn "<insn><mode>3_carry"
16081   [(set (reg:CCC FLAGS_REG)
16082         (unspec:CCC [(and:SWI48 (match_operand:SWI48 1 "register_operand" "0")
16083                                 (const_int 1))
16084                      (const_int 0)] UNSPEC_CC_NE))
16085    (set (match_operand:SWI48 0 "register_operand" "=r")
16086         (any_shiftrt:SWI48 (match_dup 1) (const_int 1)))]
16087   ""
16089   if (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16090     return "<shift>{<imodesuffix>}\t%0";
16091   return "<shift>{<imodesuffix>}\t{1, %0|%0, 1}";
16093   [(set_attr "type" "ishift1")
16094    (set (attr "length_immediate")
16095      (if_then_else
16096        (ior (match_test "TARGET_SHIFT1")
16097             (match_test "optimize_function_for_size_p (cfun)"))
16098        (const_string "0")
16099        (const_string "*")))
16100    (set_attr "mode" "<MODE>")])
16102 ;; Bit set / bit test instructions
16104 ;; %%% bts, btr, btc
16106 ;; These instructions are *slow* when applied to memory.
16108 (define_code_attr btsc [(ior "bts") (xor "btc")])
16110 (define_insn "*<btsc><mode>"
16111   [(set (match_operand:SWI48 0 "register_operand" "=r")
16112         (any_or:SWI48
16113           (ashift:SWI48 (const_int 1)
16114                         (match_operand:QI 2 "register_operand" "r"))
16115           (match_operand:SWI48 1 "register_operand" "0")))
16116    (clobber (reg:CC FLAGS_REG))]
16117   "TARGET_USE_BT"
16118   "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
16119   [(set_attr "type" "alu1")
16120    (set_attr "prefix_0f" "1")
16121    (set_attr "znver1_decode" "double")
16122    (set_attr "mode" "<MODE>")])
16124 ;; Avoid useless masking of count operand.
16125 (define_insn_and_split "*<btsc><mode>_mask"
16126   [(set (match_operand:SWI48 0 "register_operand")
16127         (any_or:SWI48
16128           (ashift:SWI48
16129             (const_int 1)
16130             (subreg:QI
16131               (and
16132                 (match_operand 1 "int248_register_operand")
16133                 (match_operand 2 "const_int_operand")) 0))
16134           (match_operand:SWI48 3 "register_operand")))
16135    (clobber (reg:CC FLAGS_REG))]
16136   "TARGET_USE_BT
16137    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16138       == GET_MODE_BITSIZE (<MODE>mode)-1
16139    && ix86_pre_reload_split ()"
16140   "#"
16141   "&& 1"
16142   [(parallel
16143      [(set (match_dup 0)
16144            (any_or:SWI48
16145              (ashift:SWI48 (const_int 1)
16146                            (match_dup 1))
16147              (match_dup 3)))
16148       (clobber (reg:CC FLAGS_REG))])]
16150   operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
16151   operands[1] = gen_lowpart (QImode, operands[1]);
16154 (define_insn_and_split "*<btsc><mode>_mask_1"
16155   [(set (match_operand:SWI48 0 "register_operand")
16156         (any_or:SWI48
16157           (ashift:SWI48
16158             (const_int 1)
16159             (and:QI
16160               (match_operand:QI 1 "register_operand")
16161               (match_operand:QI 2 "const_int_operand")))
16162           (match_operand:SWI48 3 "register_operand")))
16163    (clobber (reg:CC FLAGS_REG))]
16164   "TARGET_USE_BT
16165    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16166       == GET_MODE_BITSIZE (<MODE>mode)-1
16167    && ix86_pre_reload_split ()"
16168   "#"
16169   "&& 1"
16170   [(parallel
16171      [(set (match_dup 0)
16172            (any_or:SWI48
16173              (ashift:SWI48 (const_int 1)
16174                            (match_dup 1))
16175              (match_dup 3)))
16176       (clobber (reg:CC FLAGS_REG))])])
16178 (define_insn "*btr<mode>"
16179   [(set (match_operand:SWI48 0 "register_operand" "=r")
16180         (and:SWI48
16181           (rotate:SWI48 (const_int -2)
16182                         (match_operand:QI 2 "register_operand" "r"))
16183         (match_operand:SWI48 1 "register_operand" "0")))
16184    (clobber (reg:CC FLAGS_REG))]
16185   "TARGET_USE_BT"
16186   "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
16187   [(set_attr "type" "alu1")
16188    (set_attr "prefix_0f" "1")
16189    (set_attr "znver1_decode" "double")
16190    (set_attr "mode" "<MODE>")])
16192 ;; Avoid useless masking of count operand.
16193 (define_insn_and_split "*btr<mode>_mask"
16194   [(set (match_operand:SWI48 0 "register_operand")
16195         (and:SWI48
16196           (rotate:SWI48
16197             (const_int -2)
16198             (subreg:QI
16199               (and
16200                 (match_operand 1 "int248_register_operand")
16201                 (match_operand 2 "const_int_operand")) 0))
16202           (match_operand:SWI48 3 "register_operand")))
16203    (clobber (reg:CC FLAGS_REG))]
16204   "TARGET_USE_BT
16205    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16206       == GET_MODE_BITSIZE (<MODE>mode)-1
16207    && ix86_pre_reload_split ()"
16208   "#"
16209   "&& 1"
16210   [(parallel
16211      [(set (match_dup 0)
16212            (and:SWI48
16213              (rotate:SWI48 (const_int -2)
16214                            (match_dup 1))
16215              (match_dup 3)))
16216       (clobber (reg:CC FLAGS_REG))])]
16218   operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
16219   operands[1] = gen_lowpart (QImode, operands[1]);
16222 (define_insn_and_split "*btr<mode>_mask_1"
16223   [(set (match_operand:SWI48 0 "register_operand")
16224         (and:SWI48
16225           (rotate:SWI48
16226             (const_int -2)
16227             (and:QI
16228               (match_operand:QI 1 "register_operand")
16229               (match_operand:QI 2 "const_int_operand")))
16230           (match_operand:SWI48 3 "register_operand")))
16231    (clobber (reg:CC FLAGS_REG))]
16232   "TARGET_USE_BT
16233    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16234       == GET_MODE_BITSIZE (<MODE>mode)-1
16235    && ix86_pre_reload_split ()"
16236   "#"
16237   "&& 1"
16238   [(parallel
16239      [(set (match_dup 0)
16240            (and:SWI48
16241              (rotate:SWI48 (const_int -2)
16242                            (match_dup 1))
16243              (match_dup 3)))
16244       (clobber (reg:CC FLAGS_REG))])])
16246 (define_insn_and_split "*btr<mode>_1"
16247   [(set (match_operand:SWI12 0 "register_operand")
16248         (and:SWI12
16249           (subreg:SWI12
16250             (rotate:SI (const_int -2)
16251                        (match_operand:QI 2 "register_operand")) 0)
16252           (match_operand:SWI12 1 "nonimmediate_operand")))
16253    (clobber (reg:CC FLAGS_REG))]
16254   "TARGET_USE_BT && ix86_pre_reload_split ()"
16255   "#"
16256   "&& 1"
16257   [(parallel
16258      [(set (match_dup 0)
16259            (and:SI (rotate:SI (const_int -2) (match_dup 2))
16260                    (match_dup 1)))
16261       (clobber (reg:CC FLAGS_REG))])]
16263   operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16264   operands[1] = force_reg (<MODE>mode, operands[1]);
16265   operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
16268 (define_insn_and_split "*btr<mode>_2"
16269   [(set (zero_extract:HI
16270           (match_operand:SWI12 0 "nonimmediate_operand")
16271           (const_int 1)
16272           (match_operand:QI 1 "register_operand"))
16273         (const_int 0))
16274    (clobber (reg:CC FLAGS_REG))]
16275   "TARGET_USE_BT && ix86_pre_reload_split ()"
16276   "#"
16277   "&& MEM_P (operands[0])"
16278   [(set (match_dup 2) (match_dup 0))
16279    (parallel
16280      [(set (match_dup 3)
16281            (and:SI (rotate:SI (const_int -2) (match_dup 1))
16282                    (match_dup 4)))
16283       (clobber (reg:CC FLAGS_REG))])
16284    (set (match_dup 0) (match_dup 5))]
16286   operands[2] = gen_reg_rtx (<MODE>mode);
16287   operands[5] = gen_reg_rtx (<MODE>mode);
16288   operands[3] = lowpart_subreg (SImode, operands[5], <MODE>mode);
16289   operands[4] = lowpart_subreg (SImode, operands[2], <MODE>mode);
16292 (define_split
16293   [(set (zero_extract:HI
16294           (match_operand:SWI12 0 "register_operand")
16295           (const_int 1)
16296           (match_operand:QI 1 "register_operand"))
16297         (const_int 0))
16298    (clobber (reg:CC FLAGS_REG))]
16299   "TARGET_USE_BT && ix86_pre_reload_split ()"
16300   [(parallel
16301      [(set (match_dup 0)
16302            (and:SI (rotate:SI (const_int -2) (match_dup 1))
16303                    (match_dup 2)))
16304       (clobber (reg:CC FLAGS_REG))])]
16306   operands[2] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16307   operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16310 ;; These instructions are never faster than the corresponding
16311 ;; and/ior/xor operations when using immediate operand, so with
16312 ;; 32-bit there's no point.  But in 64-bit, we can't hold the
16313 ;; relevant immediates within the instruction itself, so operating
16314 ;; on bits in the high 32-bits of a register becomes easier.
16316 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
16317 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
16318 ;; negdf respectively, so they can never be disabled entirely.
16320 (define_insn "*btsq_imm"
16321   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16322                          (const_int 1)
16323                          (match_operand:QI 1 "const_0_to_63_operand"))
16324         (const_int 1))
16325    (clobber (reg:CC FLAGS_REG))]
16326   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16327   "bts{q}\t{%1, %0|%0, %1}"
16328   [(set_attr "type" "alu1")
16329    (set_attr "prefix_0f" "1")
16330    (set_attr "znver1_decode" "double")
16331    (set_attr "mode" "DI")])
16333 (define_insn "*btrq_imm"
16334   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16335                          (const_int 1)
16336                          (match_operand:QI 1 "const_0_to_63_operand"))
16337         (const_int 0))
16338    (clobber (reg:CC FLAGS_REG))]
16339   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16340   "btr{q}\t{%1, %0|%0, %1}"
16341   [(set_attr "type" "alu1")
16342    (set_attr "prefix_0f" "1")
16343    (set_attr "znver1_decode" "double")
16344    (set_attr "mode" "DI")])
16346 (define_insn "*btcq_imm"
16347   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16348                          (const_int 1)
16349                          (match_operand:QI 1 "const_0_to_63_operand"))
16350         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
16351    (clobber (reg:CC FLAGS_REG))]
16352   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16353   "btc{q}\t{%1, %0|%0, %1}"
16354   [(set_attr "type" "alu1")
16355    (set_attr "prefix_0f" "1")
16356    (set_attr "znver1_decode" "double")
16357    (set_attr "mode" "DI")])
16359 ;; Allow Nocona to avoid these instructions if a register is available.
16361 (define_peephole2
16362   [(match_scratch:DI 2 "r")
16363    (parallel [(set (zero_extract:DI
16364                      (match_operand:DI 0 "nonimmediate_operand")
16365                      (const_int 1)
16366                      (match_operand:QI 1 "const_0_to_63_operand"))
16367                    (const_int 1))
16368               (clobber (reg:CC FLAGS_REG))])]
16369   "TARGET_64BIT && !TARGET_USE_BT"
16370   [(parallel [(set (match_dup 0)
16371                    (ior:DI (match_dup 0) (match_dup 3)))
16372               (clobber (reg:CC FLAGS_REG))])]
16374   int i = INTVAL (operands[1]);
16376   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16378   if (!x86_64_immediate_operand (operands[3], DImode))
16379     {
16380       emit_move_insn (operands[2], operands[3]);
16381       operands[3] = operands[2];
16382     }
16385 (define_peephole2
16386   [(match_scratch:DI 2 "r")
16387    (parallel [(set (zero_extract:DI
16388                      (match_operand:DI 0 "nonimmediate_operand")
16389                      (const_int 1)
16390                      (match_operand:QI 1 "const_0_to_63_operand"))
16391                    (const_int 0))
16392               (clobber (reg:CC FLAGS_REG))])]
16393   "TARGET_64BIT && !TARGET_USE_BT"
16394   [(parallel [(set (match_dup 0)
16395                    (and:DI (match_dup 0) (match_dup 3)))
16396               (clobber (reg:CC FLAGS_REG))])]
16398   int i = INTVAL (operands[1]);
16400   operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
16402   if (!x86_64_immediate_operand (operands[3], DImode))
16403     {
16404       emit_move_insn (operands[2], operands[3]);
16405       operands[3] = operands[2];
16406     }
16409 (define_peephole2
16410   [(match_scratch:DI 2 "r")
16411    (parallel [(set (zero_extract:DI
16412                      (match_operand:DI 0 "nonimmediate_operand")
16413                      (const_int 1)
16414                      (match_operand:QI 1 "const_0_to_63_operand"))
16415               (not:DI (zero_extract:DI
16416                         (match_dup 0) (const_int 1) (match_dup 1))))
16417               (clobber (reg:CC FLAGS_REG))])]
16418   "TARGET_64BIT && !TARGET_USE_BT"
16419   [(parallel [(set (match_dup 0)
16420                    (xor:DI (match_dup 0) (match_dup 3)))
16421               (clobber (reg:CC FLAGS_REG))])]
16423   int i = INTVAL (operands[1]);
16425   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16427   if (!x86_64_immediate_operand (operands[3], DImode))
16428     {
16429       emit_move_insn (operands[2], operands[3]);
16430       operands[3] = operands[2];
16431     }
16434 ;; %%% bt
16436 (define_insn "*bt<mode>"
16437   [(set (reg:CCC FLAGS_REG)
16438         (compare:CCC
16439           (zero_extract:SWI48
16440             (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
16441             (const_int 1)
16442             (match_operand:QI 1 "nonmemory_operand" "q<S>,<S>"))
16443           (const_int 0)))]
16444   ""
16446   switch (get_attr_mode (insn))
16447     {
16448     case MODE_SI:
16449       return "bt{l}\t{%k1, %k0|%k0, %k1}";
16451     case MODE_DI:
16452       return "bt{q}\t{%q1, %0|%0, %q1}";
16454     default:
16455       gcc_unreachable ();
16456     }
16458   [(set_attr "type" "alu1")
16459    (set_attr "prefix_0f" "1")
16460    (set (attr "mode")
16461         (if_then_else
16462           (and (match_test "CONST_INT_P (operands[1])")
16463                (match_test "INTVAL (operands[1]) < 32"))
16464           (const_string "SI")
16465           (const_string "<MODE>")))])
16467 (define_insn_and_split "*bt<SWI48:mode>_mask"
16468   [(set (reg:CCC FLAGS_REG)
16469         (compare:CCC
16470           (zero_extract:SWI48
16471             (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
16472             (const_int 1)
16473             (subreg:QI
16474               (and:SWI248
16475                 (match_operand:SWI248 1 "register_operand")
16476                 (match_operand 2 "const_int_operand")) 0))
16477           (const_int 0)))]
16478   "TARGET_USE_BT
16479    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
16480       == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
16481    && ix86_pre_reload_split ()"
16482   "#"
16483   "&& 1"
16484   [(set (reg:CCC FLAGS_REG)
16485         (compare:CCC
16486          (zero_extract:SWI48 (match_dup 0) (const_int 1) (match_dup 1))
16487          (const_int 0)))]
16488   "operands[1] = gen_lowpart (QImode, operands[1]);")
16490 (define_insn_and_split "*jcc_bt<mode>"
16491   [(set (pc)
16492         (if_then_else (match_operator 0 "bt_comparison_operator"
16493                         [(zero_extract:SWI48
16494                            (match_operand:SWI48 1 "nonimmediate_operand")
16495                            (const_int 1)
16496                            (match_operand:QI 2 "nonmemory_operand"))
16497                          (const_int 0)])
16498                       (label_ref (match_operand 3))
16499                       (pc)))
16500    (clobber (reg:CC FLAGS_REG))]
16501   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16502    && (CONST_INT_P (operands[2])
16503        ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
16504           && INTVAL (operands[2])
16505                >= (optimize_function_for_size_p (cfun) ? 8 : 32))
16506        : !memory_operand (operands[1], <MODE>mode))
16507    && ix86_pre_reload_split ()"
16508   "#"
16509   "&& 1"
16510   [(set (reg:CCC FLAGS_REG)
16511         (compare:CCC
16512           (zero_extract:SWI48
16513             (match_dup 1)
16514             (const_int 1)
16515             (match_dup 2))
16516           (const_int 0)))
16517    (set (pc)
16518         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16519                       (label_ref (match_dup 3))
16520                       (pc)))]
16522   operands[0] = shallow_copy_rtx (operands[0]);
16523   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16526 ;; Avoid useless masking of bit offset operand.
16527 (define_insn_and_split "*jcc_bt<mode>_mask"
16528   [(set (pc)
16529         (if_then_else (match_operator 0 "bt_comparison_operator"
16530                         [(zero_extract:SWI48
16531                            (match_operand:SWI48 1 "register_operand")
16532                            (const_int 1)
16533                            (and:QI
16534                              (match_operand:QI 2 "register_operand")
16535                              (match_operand 3 "const_int_operand")))])
16536                       (label_ref (match_operand 4))
16537                       (pc)))
16538    (clobber (reg:CC FLAGS_REG))]
16539   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16540    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16541       == GET_MODE_BITSIZE (<MODE>mode)-1
16542    && ix86_pre_reload_split ()"
16543   "#"
16544   "&& 1"
16545   [(set (reg:CCC FLAGS_REG)
16546         (compare:CCC
16547           (zero_extract:SWI48
16548             (match_dup 1)
16549             (const_int 1)
16550             (match_dup 2))
16551           (const_int 0)))
16552    (set (pc)
16553         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16554                       (label_ref (match_dup 4))
16555                       (pc)))]
16557   operands[0] = shallow_copy_rtx (operands[0]);
16558   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16561 ;; Avoid useless masking of bit offset operand.
16562 (define_insn_and_split "*jcc_bt<SWI48:mode>_mask_1"
16563   [(set (pc)
16564         (if_then_else (match_operator 0 "bt_comparison_operator"
16565                         [(zero_extract:SWI48
16566                            (match_operand:SWI48 1 "register_operand")
16567                            (const_int 1)
16568                            (subreg:QI
16569                              (and:SWI248
16570                                (match_operand:SWI248 2 "register_operand")
16571                                (match_operand 3 "const_int_operand")) 0))])
16572                       (label_ref (match_operand 4))
16573                       (pc)))
16574    (clobber (reg:CC FLAGS_REG))]
16575   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16576    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
16577       == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
16578    && ix86_pre_reload_split ()"
16579   "#"
16580   "&& 1"
16581   [(set (reg:CCC FLAGS_REG)
16582         (compare:CCC
16583           (zero_extract:SWI48
16584             (match_dup 1)
16585             (const_int 1)
16586             (match_dup 2))
16587           (const_int 0)))
16588    (set (pc)
16589         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16590                       (label_ref (match_dup 4))
16591                       (pc)))]
16593   operands[0] = shallow_copy_rtx (operands[0]);
16594   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16595   operands[2] = gen_lowpart (QImode, operands[2]);
16598 ;; Help combine recognize bt followed by cmov
16599 (define_split
16600   [(set (match_operand:SWI248 0 "register_operand")
16601         (if_then_else:SWI248
16602          (match_operator 5 "bt_comparison_operator"
16603           [(zero_extract:SWI48
16604             (match_operand:SWI48 1 "register_operand")
16605             (const_int 1)
16606             (match_operand:QI 2 "register_operand"))
16607            (const_int 0)])
16608          (match_operand:SWI248 3 "nonimmediate_operand")
16609          (match_operand:SWI248 4 "nonimmediate_operand")))]
16610   "TARGET_USE_BT && TARGET_CMOVE
16611    && !(MEM_P (operands[3]) && MEM_P (operands[4]))
16612    && ix86_pre_reload_split ()"
16613   [(set (reg:CCC FLAGS_REG)
16614         (compare:CCC
16615          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16616          (const_int 0)))
16617    (set (match_dup 0)
16618         (if_then_else:SWI248 (eq (reg:CCC FLAGS_REG) (const_int 0))
16619                              (match_dup 3)
16620                              (match_dup 4)))]
16622   if (GET_CODE (operands[5]) == EQ)
16623     std::swap (operands[3], operands[4]);
16626 ;; Help combine recognize bt followed by setc
16627 (define_insn_and_split "*bt<mode>_setcqi"
16628   [(set (subreg:SWI48 (match_operand:QI 0 "register_operand") 0)
16629         (zero_extract:SWI48
16630          (match_operand:SWI48 1 "register_operand")
16631          (const_int 1)
16632          (match_operand:QI 2 "register_operand")))
16633    (clobber (reg:CC FLAGS_REG))]
16634   "TARGET_USE_BT && ix86_pre_reload_split ()"
16635   "#"
16636   "&& 1"
16637   [(set (reg:CCC FLAGS_REG)
16638         (compare:CCC
16639          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16640          (const_int 0)))
16641    (set (match_dup 0)
16642         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16644 ;; Help combine recognize bt followed by setnc
16645 (define_insn_and_split "*bt<mode>_setncqi"
16646   [(set (match_operand:QI 0 "register_operand")
16647         (and:QI
16648          (not:QI
16649           (subreg:QI
16650            (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16651                            (match_operand:QI 2 "register_operand")) 0))
16652          (const_int 1)))
16653    (clobber (reg:CC FLAGS_REG))]
16654   "TARGET_USE_BT && ix86_pre_reload_split ()"
16655   "#"
16656   "&& 1"
16657   [(set (reg:CCC FLAGS_REG)
16658         (compare:CCC
16659          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16660          (const_int 0)))
16661    (set (match_dup 0)
16662         (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16664 (define_insn_and_split "*bt<mode>_setnc<mode>"
16665   [(set (match_operand:SWI48 0 "register_operand")
16666         (and:SWI48
16667          (not:SWI48
16668           (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16669                           (match_operand:QI 2 "register_operand")))
16670          (const_int 1)))
16671    (clobber (reg:CC FLAGS_REG))]
16672   "TARGET_USE_BT && ix86_pre_reload_split ()"
16673   "#"
16674   "&& 1"
16675   [(set (reg:CCC FLAGS_REG)
16676         (compare:CCC
16677          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16678          (const_int 0)))
16679    (set (match_dup 3)
16680         (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
16681    (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16682   "operands[3] = gen_reg_rtx (QImode);")
16684 ;; Help combine recognize bt followed by setnc (PR target/110588)
16685 (define_insn_and_split "*bt<mode>_setncqi_2"
16686   [(set (match_operand:QI 0 "register_operand")
16687         (eq:QI
16688           (zero_extract:SWI48
16689             (match_operand:SWI48 1 "register_operand")
16690             (const_int 1)
16691             (match_operand:QI 2 "register_operand"))
16692           (const_int 0)))
16693    (clobber (reg:CC FLAGS_REG))]
16694   "TARGET_USE_BT && ix86_pre_reload_split ()"
16695   "#"
16696   "&& 1"
16697   [(set (reg:CCC FLAGS_REG)
16698         (compare:CCC
16699          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16700          (const_int 0)))
16701    (set (match_dup 0)
16702         (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16704 ;; Help combine recognize bt followed by setc
16705 (define_insn_and_split "*bt<mode>_setc<mode>_mask"
16706   [(set (match_operand:SWI48 0 "register_operand")
16707         (zero_extract:SWI48
16708           (match_operand:SWI48 1 "register_operand")
16709           (const_int 1)
16710           (subreg:QI
16711             (and:SWI48
16712               (match_operand:SWI48 2 "register_operand")
16713               (match_operand 3 "const_int_operand")) 0)))
16714    (clobber (reg:CC FLAGS_REG))]
16715   "TARGET_USE_BT
16716    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16717       == GET_MODE_BITSIZE (<MODE>mode)-1
16718    && ix86_pre_reload_split ()"
16719   "#"
16720   "&& 1"
16721   [(set (reg:CCC FLAGS_REG)
16722         (compare:CCC
16723          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16724          (const_int 0)))
16725    (set (match_dup 3)
16726         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))
16727    (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16729   operands[2] = gen_lowpart (QImode, operands[2]);
16730   operands[3] = gen_reg_rtx (QImode);
16733 ;; Store-flag instructions.
16735 (define_split
16736   [(set (match_operand:QI 0 "nonimmediate_operand")
16737         (match_operator:QI 1 "add_comparison_operator"
16738           [(not:SWI (match_operand:SWI 2 "register_operand"))
16739            (match_operand:SWI 3 "nonimmediate_operand")]))]
16740   ""
16741   [(set (reg:CCC FLAGS_REG)
16742         (compare:CCC
16743           (plus:SWI (match_dup 2) (match_dup 3))
16744           (match_dup 2)))
16745    (set (match_dup 0)
16746         (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))])
16748 (define_split
16749   [(set (match_operand:QI 0 "nonimmediate_operand")
16750         (match_operator:QI 1 "shr_comparison_operator"
16751           [(match_operand:DI 2 "register_operand")
16752            (match_operand 3 "const_int_operand")]))]
16753   "TARGET_64BIT
16754    && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16755   [(set (reg:CCZ FLAGS_REG)
16756         (compare:CCZ
16757           (lshiftrt:DI (match_dup 2) (match_dup 4))
16758           (const_int 0)))
16759    (set (match_dup 0)
16760         (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))]
16762   enum rtx_code new_code;
16764   operands[1] = shallow_copy_rtx (operands[1]);
16765   switch (GET_CODE (operands[1]))
16766     {
16767     case GTU: new_code = NE; break;
16768     case LEU: new_code = EQ; break;
16769     default: gcc_unreachable ();
16770     }
16771   PUT_CODE (operands[1], new_code);
16773   operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16776 ;; For all sCOND expanders, also expand the compare or test insn that
16777 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
16779 (define_insn_and_split "*setcc_di_1"
16780   [(set (match_operand:DI 0 "register_operand" "=q")
16781         (match_operator:DI 1 "ix86_comparison_operator"
16782           [(reg FLAGS_REG) (const_int 0)]))]
16783   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
16784   "#"
16785   "&& reload_completed"
16786   [(set (match_dup 2) (match_dup 1))
16787    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
16789   operands[1] = shallow_copy_rtx (operands[1]);
16790   PUT_MODE (operands[1], QImode);
16791   operands[2] = gen_lowpart (QImode, operands[0]);
16794 (define_insn_and_split "*setcc_<mode>_1_and"
16795   [(set (match_operand:SWI24 0 "register_operand" "=q")
16796         (match_operator:SWI24 1 "ix86_comparison_operator"
16797           [(reg FLAGS_REG) (const_int 0)]))
16798    (clobber (reg:CC FLAGS_REG))]
16799   "!TARGET_PARTIAL_REG_STALL
16800    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
16801   "#"
16802   "&& reload_completed"
16803   [(set (match_dup 2) (match_dup 1))
16804    (parallel [(set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))
16805               (clobber (reg:CC FLAGS_REG))])]
16807   operands[1] = shallow_copy_rtx (operands[1]);
16808   PUT_MODE (operands[1], QImode);
16809   operands[2] = gen_lowpart (QImode, operands[0]);
16812 (define_insn_and_split "*setcc_<mode>_1_movzbl"
16813   [(set (match_operand:SWI24 0 "register_operand" "=q")
16814         (match_operator:SWI24 1 "ix86_comparison_operator"
16815           [(reg FLAGS_REG) (const_int 0)]))]
16816   "!TARGET_PARTIAL_REG_STALL
16817    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
16818   "#"
16819   "&& reload_completed"
16820   [(set (match_dup 2) (match_dup 1))
16821    (set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))]
16823   operands[1] = shallow_copy_rtx (operands[1]);
16824   PUT_MODE (operands[1], QImode);
16825   operands[2] = gen_lowpart (QImode, operands[0]);
16828 (define_insn "*setcc_qi"
16829   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
16830         (match_operator:QI 1 "ix86_comparison_operator"
16831           [(reg FLAGS_REG) (const_int 0)]))]
16832   ""
16833   "set%C1\t%0"
16834   [(set_attr "type" "setcc")
16835    (set_attr "mode" "QI")])
16837 (define_insn "*setcc_qi_slp"
16838   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
16839         (match_operator:QI 1 "ix86_comparison_operator"
16840           [(reg FLAGS_REG) (const_int 0)]))]
16841   ""
16842   "set%C1\t%0"
16843   [(set_attr "type" "setcc")
16844    (set_attr "mode" "QI")])
16846 ;; In general it is not safe to assume too much about CCmode registers,
16847 ;; so simplify-rtx stops when it sees a second one.  Under certain
16848 ;; conditions this is safe on x86, so help combine not create
16850 ;;      seta    %al
16851 ;;      testb   %al, %al
16852 ;;      sete    %al
16854 (define_split
16855   [(set (match_operand:QI 0 "nonimmediate_operand")
16856         (ne:QI (match_operator 1 "ix86_comparison_operator"
16857                  [(reg FLAGS_REG) (const_int 0)])
16858             (const_int 0)))]
16859   ""
16860   [(set (match_dup 0) (match_dup 1))]
16862   operands[1] = shallow_copy_rtx (operands[1]);
16863   PUT_MODE (operands[1], QImode);
16866 (define_split
16867   [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16868         (ne:QI (match_operator 1 "ix86_comparison_operator"
16869                  [(reg FLAGS_REG) (const_int 0)])
16870             (const_int 0)))]
16871   ""
16872   [(set (match_dup 0) (match_dup 1))]
16874   operands[1] = shallow_copy_rtx (operands[1]);
16875   PUT_MODE (operands[1], QImode);
16878 (define_split
16879   [(set (match_operand:QI 0 "nonimmediate_operand")
16880         (eq:QI (match_operator 1 "ix86_comparison_operator"
16881                  [(reg FLAGS_REG) (const_int 0)])
16882             (const_int 0)))]
16883   ""
16884   [(set (match_dup 0) (match_dup 1))]
16886   operands[1] = shallow_copy_rtx (operands[1]);
16887   PUT_MODE (operands[1], QImode);
16888   PUT_CODE (operands[1],
16889             ix86_reverse_condition (GET_CODE (operands[1]),
16890                                     GET_MODE (XEXP (operands[1], 0))));
16892   /* Make sure that (a) the CCmode we have for the flags is strong
16893      enough for the reversed compare or (b) we have a valid FP compare.  */
16894   if (! ix86_comparison_operator (operands[1], VOIDmode))
16895     FAIL;
16898 (define_split
16899   [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16900         (eq:QI (match_operator 1 "ix86_comparison_operator"
16901                  [(reg FLAGS_REG) (const_int 0)])
16902             (const_int 0)))]
16903   ""
16904   [(set (match_dup 0) (match_dup 1))]
16906   operands[1] = shallow_copy_rtx (operands[1]);
16907   PUT_MODE (operands[1], QImode);
16908   PUT_CODE (operands[1],
16909             ix86_reverse_condition (GET_CODE (operands[1]),
16910                                     GET_MODE (XEXP (operands[1], 0))));
16912   /* Make sure that (a) the CCmode we have for the flags is strong
16913      enough for the reversed compare or (b) we have a valid FP compare.  */
16914   if (! ix86_comparison_operator (operands[1], VOIDmode))
16915     FAIL;
16918 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
16919 ;; subsequent logical operations are used to imitate conditional moves.
16920 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
16921 ;; it directly.
16923 (define_insn "setcc_<mode>_sse"
16924   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16925         (match_operator:MODEF 3 "sse_comparison_operator"
16926           [(match_operand:MODEF 1 "register_operand" "0,x")
16927            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xjm")]))]
16928   "SSE_FLOAT_MODE_P (<MODE>mode)"
16929   "@
16930    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
16931    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16932   [(set_attr "isa" "noavx,avx")
16933    (set_attr "addr" "*,gpr16")
16934    (set_attr "type" "ssecmp")
16935    (set_attr "length_immediate" "1")
16936    (set_attr "prefix" "orig,vex")
16937    (set_attr "mode" "<MODE>")])
16939 (define_insn "setcc_hf_mask"
16940   [(set (match_operand:QI 0 "register_operand" "=k")
16941         (unspec:QI
16942           [(match_operand:HF 1 "register_operand" "v")
16943            (match_operand:HF 2 "nonimmediate_operand" "vm")
16944            (match_operand:SI 3 "const_0_to_31_operand")]
16945           UNSPEC_PCMP))]
16946   "TARGET_AVX512FP16"
16947   "vcmpsh\t{%3, %2, %1, %0|%0, %1, %2, %3}"
16948   [(set_attr "type" "ssecmp")
16949    (set_attr "prefix" "evex")
16950    (set_attr "mode" "HF")])
16953 ;; Basic conditional jump instructions.
16955 (define_split
16956   [(set (pc)
16957         (if_then_else
16958           (match_operator 1 "add_comparison_operator"
16959             [(not:SWI (match_operand:SWI 2 "register_operand"))
16960              (match_operand:SWI 3 "nonimmediate_operand")])
16961           (label_ref (match_operand 0))
16962           (pc)))]
16963   ""
16964   [(set (reg:CCC FLAGS_REG)
16965         (compare:CCC
16966           (plus:SWI (match_dup 2) (match_dup 3))
16967           (match_dup 2)))
16968    (set (pc)
16969         (if_then_else (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)])
16970                       (label_ref (match_operand 0))
16971                       (pc)))])
16973 (define_split
16974   [(set (pc)
16975         (if_then_else
16976           (match_operator 1 "shr_comparison_operator"
16977             [(match_operand:DI 2 "register_operand")
16978              (match_operand 3 "const_int_operand")])
16979           (label_ref (match_operand 0))
16980           (pc)))]
16981   "TARGET_64BIT
16982    && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16983   [(set (reg:CCZ FLAGS_REG)
16984         (compare:CCZ
16985           (lshiftrt:DI (match_dup 2) (match_dup 4))
16986           (const_int 0)))
16987    (set (pc)
16988         (if_then_else (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)])
16989                       (label_ref (match_operand 0))
16990                       (pc)))]
16992   enum rtx_code new_code;
16994   operands[1] = shallow_copy_rtx (operands[1]);
16995   switch (GET_CODE (operands[1]))
16996     {
16997     case GTU: new_code = NE; break;
16998     case LEU: new_code = EQ; break;
16999     default: gcc_unreachable ();
17000     }
17001   PUT_CODE (operands[1], new_code);
17003   operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
17006 ;; We ignore the overflow flag for signed branch instructions.
17008 (define_insn "*jcc"
17009   [(set (pc)
17010         (if_then_else (match_operator 1 "ix86_comparison_operator"
17011                                       [(reg FLAGS_REG) (const_int 0)])
17012                       (label_ref (match_operand 0))
17013                       (pc)))]
17014   ""
17015   "%!%+j%C1\t%l0"
17016   [(set_attr "type" "ibr")
17017    (set_attr "modrm" "0")
17018    (set (attr "length")
17019         (if_then_else
17020           (and (ge (minus (match_dup 0) (pc))
17021                    (const_int -126))
17022                (lt (minus (match_dup 0) (pc))
17023                    (const_int 128)))
17024           (const_int 2)
17025           (const_int 6)))])
17027 ;; In general it is not safe to assume too much about CCmode registers,
17028 ;; so simplify-rtx stops when it sees a second one.  Under certain
17029 ;; conditions this is safe on x86, so help combine not create
17031 ;;      seta    %al
17032 ;;      testb   %al, %al
17033 ;;      je      Lfoo
17035 (define_split
17036   [(set (pc)
17037         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
17038                                       [(reg FLAGS_REG) (const_int 0)])
17039                           (const_int 0))
17040                       (label_ref (match_operand 1))
17041                       (pc)))]
17042   ""
17043   [(set (pc)
17044         (if_then_else (match_dup 0)
17045                       (label_ref (match_dup 1))
17046                       (pc)))]
17048   operands[0] = shallow_copy_rtx (operands[0]);
17049   PUT_MODE (operands[0], VOIDmode);
17052 (define_split
17053   [(set (pc)
17054         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
17055                                       [(reg FLAGS_REG) (const_int 0)])
17056                           (const_int 0))
17057                       (label_ref (match_operand 1))
17058                       (pc)))]
17059   ""
17060   [(set (pc)
17061         (if_then_else (match_dup 0)
17062                       (label_ref (match_dup 1))
17063                       (pc)))]
17065   operands[0] = shallow_copy_rtx (operands[0]);
17066   PUT_MODE (operands[0], VOIDmode);
17067   PUT_CODE (operands[0],
17068             ix86_reverse_condition (GET_CODE (operands[0]),
17069                                     GET_MODE (XEXP (operands[0], 0))));
17071   /* Make sure that (a) the CCmode we have for the flags is strong
17072      enough for the reversed compare or (b) we have a valid FP compare.  */
17073   if (! ix86_comparison_operator (operands[0], VOIDmode))
17074     FAIL;
17077 ;; Unconditional and other jump instructions
17079 (define_insn "jump"
17080   [(set (pc)
17081         (label_ref (match_operand 0)))]
17082   ""
17083   "%!jmp\t%l0"
17084   [(set_attr "type" "ibr")
17085    (set_attr "modrm" "0")
17086    (set (attr "length")
17087         (if_then_else
17088           (and (ge (minus (match_dup 0) (pc))
17089                    (const_int -126))
17090                (lt (minus (match_dup 0) (pc))
17091                    (const_int 128)))
17092           (const_int 2)
17093           (const_int 5)))])
17095 (define_expand "indirect_jump"
17096   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
17097   ""
17099   if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
17100     operands[0] = convert_memory_address (word_mode, operands[0]);
17101   cfun->machine->has_local_indirect_jump = true;
17104 (define_insn "*indirect_jump"
17105   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
17106   ""
17107   "* return ix86_output_indirect_jmp (operands[0]);"
17108   [(set (attr "type")
17109      (if_then_else (match_test "(cfun->machine->indirect_branch_type
17110                                  != indirect_branch_keep)")
17111         (const_string "multi")
17112         (const_string "ibr")))
17113    (set_attr "length_immediate" "0")])
17115 (define_expand "tablejump"
17116   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
17117               (use (label_ref (match_operand 1)))])]
17118   ""
17120   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
17121      relative.  Convert the relative address to an absolute address.  */
17122   if (flag_pic)
17123     {
17124       rtx op0, op1;
17125       enum rtx_code code;
17127       /* We can't use @GOTOFF for text labels on VxWorks;
17128          see gotoff_operand.  */
17129       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
17130         {
17131           code = PLUS;
17132           op0 = operands[0];
17133           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
17134         }
17135       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
17136         {
17137           code = PLUS;
17138           op0 = operands[0];
17139           op1 = pic_offset_table_rtx;
17140         }
17141       else
17142         {
17143           code = MINUS;
17144           op0 = pic_offset_table_rtx;
17145           op1 = operands[0];
17146         }
17148       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
17149                                          OPTAB_DIRECT);
17150     }
17152   if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
17153     operands[0] = convert_memory_address (word_mode, operands[0]);
17154   cfun->machine->has_local_indirect_jump = true;
17157 (define_insn "*tablejump_1"
17158   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
17159    (use (label_ref (match_operand 1)))]
17160   ""
17161   "* return ix86_output_indirect_jmp (operands[0]);"
17162   [(set (attr "type")
17163      (if_then_else (match_test "(cfun->machine->indirect_branch_type
17164                                  != indirect_branch_keep)")
17165         (const_string "multi")
17166         (const_string "ibr")))
17167    (set_attr "length_immediate" "0")])
17169 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
17171 (define_peephole2
17172   [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
17173    (set (match_operand:QI 1 "register_operand")
17174         (match_operator:QI 2 "ix86_comparison_operator"
17175           [(reg FLAGS_REG) (const_int 0)]))
17176    (set (match_operand 3 "any_QIreg_operand")
17177         (zero_extend (match_dup 1)))]
17178   "(peep2_reg_dead_p (3, operands[1])
17179     || operands_match_p (operands[1], operands[3]))
17180    && ! reg_overlap_mentioned_p (operands[3], operands[0])
17181    && peep2_regno_dead_p (0, FLAGS_REG)"
17182   [(set (match_dup 4) (match_dup 0))
17183    (set (strict_low_part (match_dup 5))
17184         (match_dup 2))]
17186   operands[5] = gen_lowpart (QImode, operands[3]);
17187   ix86_expand_clear (operands[3]);
17190 (define_peephole2
17191   [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
17192               (match_operand 4)])
17193    (set (match_operand:QI 1 "register_operand")
17194         (match_operator:QI 2 "ix86_comparison_operator"
17195           [(reg FLAGS_REG) (const_int 0)]))
17196    (set (match_operand 3 "any_QIreg_operand")
17197         (zero_extend (match_dup 1)))]
17198   "(peep2_reg_dead_p (3, operands[1])
17199     || operands_match_p (operands[1], operands[3]))
17200    && ! reg_overlap_mentioned_p (operands[3], operands[0])
17201    && ! reg_overlap_mentioned_p (operands[3], operands[4])
17202    && ! reg_set_p (operands[3], operands[4])
17203    && peep2_regno_dead_p (0, FLAGS_REG)"
17204   [(parallel [(set (match_dup 5) (match_dup 0))
17205               (match_dup 4)])
17206    (set (strict_low_part (match_dup 6))
17207         (match_dup 2))]
17209   operands[6] = gen_lowpart (QImode, operands[3]);
17210   ix86_expand_clear (operands[3]);
17213 (define_peephole2
17214   [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
17215    (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
17216               (match_operand 5)])
17217    (set (match_operand:QI 2 "register_operand")
17218         (match_operator:QI 3 "ix86_comparison_operator"
17219           [(reg FLAGS_REG) (const_int 0)]))
17220    (set (match_operand 4 "any_QIreg_operand")
17221         (zero_extend (match_dup 2)))]
17222   "(peep2_reg_dead_p (4, operands[2])
17223     || operands_match_p (operands[2], operands[4]))
17224    && ! reg_overlap_mentioned_p (operands[4], operands[0])
17225    && ! reg_overlap_mentioned_p (operands[4], operands[1])
17226    && ! reg_overlap_mentioned_p (operands[4], operands[5])
17227    && ! reg_set_p (operands[4], operands[5])
17228    && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
17229    && peep2_regno_dead_p (0, FLAGS_REG)"
17230   [(set (match_dup 6) (match_dup 0))
17231    (parallel [(set (match_dup 7) (match_dup 1))
17232               (match_dup 5)])
17233    (set (strict_low_part (match_dup 8))
17234         (match_dup 3))]
17236   operands[8] = gen_lowpart (QImode, operands[4]);
17237   ix86_expand_clear (operands[4]);
17240 ;; Similar, but match zero extend with andsi3.
17242 (define_peephole2
17243   [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
17244    (set (match_operand:QI 1 "register_operand")
17245         (match_operator:QI 2 "ix86_comparison_operator"
17246           [(reg FLAGS_REG) (const_int 0)]))
17247    (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
17248                    (and:SI (match_dup 3) (const_int 255)))
17249               (clobber (reg:CC FLAGS_REG))])]
17250   "REGNO (operands[1]) == REGNO (operands[3])
17251    && ! reg_overlap_mentioned_p (operands[3], operands[0])
17252    && peep2_regno_dead_p (0, FLAGS_REG)"
17253   [(set (match_dup 4) (match_dup 0))
17254    (set (strict_low_part (match_dup 5))
17255         (match_dup 2))]
17257   operands[5] = gen_lowpart (QImode, operands[3]);
17258   ix86_expand_clear (operands[3]);
17261 (define_peephole2
17262   [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
17263               (match_operand 4)])
17264    (set (match_operand:QI 1 "register_operand")
17265         (match_operator:QI 2 "ix86_comparison_operator"
17266           [(reg FLAGS_REG) (const_int 0)]))
17267    (parallel [(set (match_operand 3 "any_QIreg_operand")
17268                    (zero_extend (match_dup 1)))
17269               (clobber (reg:CC FLAGS_REG))])]
17270   "(peep2_reg_dead_p (3, operands[1])
17271     || operands_match_p (operands[1], operands[3]))
17272    && ! reg_overlap_mentioned_p (operands[3], operands[0])
17273    && ! reg_overlap_mentioned_p (operands[3], operands[4])
17274    && ! reg_set_p (operands[3], operands[4])
17275    && peep2_regno_dead_p (0, FLAGS_REG)"
17276   [(parallel [(set (match_dup 5) (match_dup 0))
17277               (match_dup 4)])
17278    (set (strict_low_part (match_dup 6))
17279         (match_dup 2))]
17281   operands[6] = gen_lowpart (QImode, operands[3]);
17282   ix86_expand_clear (operands[3]);
17285 (define_peephole2
17286   [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
17287    (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
17288               (match_operand 5)])
17289    (set (match_operand:QI 2 "register_operand")
17290         (match_operator:QI 3 "ix86_comparison_operator"
17291           [(reg FLAGS_REG) (const_int 0)]))
17292    (parallel [(set (match_operand 4 "any_QIreg_operand")
17293                    (zero_extend (match_dup 2)))
17294               (clobber (reg:CC FLAGS_REG))])]
17295   "(peep2_reg_dead_p (4, operands[2])
17296     || operands_match_p (operands[2], operands[4]))
17297    && ! reg_overlap_mentioned_p (operands[4], operands[0])
17298    && ! reg_overlap_mentioned_p (operands[4], operands[1])
17299    && ! reg_overlap_mentioned_p (operands[4], operands[5])
17300    && ! reg_set_p (operands[4], operands[5])
17301    && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
17302    && peep2_regno_dead_p (0, FLAGS_REG)"
17303   [(set (match_dup 6) (match_dup 0))
17304    (parallel [(set (match_dup 7) (match_dup 1))
17305               (match_dup 5)])
17306    (set (strict_low_part (match_dup 8))
17307         (match_dup 3))]
17309   operands[8] = gen_lowpart (QImode, operands[4]);
17310   ix86_expand_clear (operands[4]);
17313 ;; Call instructions.
17315 ;; The predicates normally associated with named expanders are not properly
17316 ;; checked for calls.  This is a bug in the generic code, but it isn't that
17317 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
17319 ;; P6 processors will jump to the address after the decrement when %esp
17320 ;; is used as a call operand, so they will execute return address as a code.
17321 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
17323 ;; Register constraint for call instruction.
17324 (define_mode_attr c [(SI "l") (DI "r")])
17326 ;; Call subroutine returning no value.
17328 (define_expand "call"
17329   [(call (match_operand:QI 0)
17330          (match_operand 1))
17331    (use (match_operand 2))]
17332   ""
17334   ix86_expand_call (NULL, operands[0], operands[1],
17335                     operands[2], NULL, false);
17336   DONE;
17339 (define_expand "sibcall"
17340   [(call (match_operand:QI 0)
17341          (match_operand 1))
17342    (use (match_operand 2))]
17343   ""
17345   ix86_expand_call (NULL, operands[0], operands[1],
17346                     operands[2], NULL, true);
17347   DONE;
17350 (define_insn "*call"
17351   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
17352          (match_operand 1))]
17353   "!SIBLING_CALL_P (insn)"
17354   "* return ix86_output_call_insn (insn, operands[0]);"
17355   [(set_attr "type" "call")])
17357 ;; This covers both call and sibcall since only GOT slot is allowed.
17358 (define_insn "*call_got_x32"
17359   [(call (mem:QI (zero_extend:DI
17360                    (match_operand:SI 0 "GOT_memory_operand" "Bg")))
17361          (match_operand 1))]
17362   "TARGET_X32"
17364   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
17365   return ix86_output_call_insn (insn, fnaddr);
17367   [(set_attr "type" "call")])
17369 ;; Since sibcall never returns, we can only use call-clobbered register
17370 ;; as GOT base.
17371 (define_insn "*sibcall_GOT_32"
17372   [(call (mem:QI
17373            (mem:SI (plus:SI
17374                      (match_operand:SI 0 "register_no_elim_operand" "U")
17375                      (match_operand:SI 1 "GOT32_symbol_operand"))))
17376          (match_operand 2))]
17377   "!TARGET_MACHO
17378   && !TARGET_64BIT
17379   && !TARGET_INDIRECT_BRANCH_REGISTER
17380   && SIBLING_CALL_P (insn)"
17382   rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
17383   fnaddr = gen_const_mem (SImode, fnaddr);
17384   return ix86_output_call_insn (insn, fnaddr);
17386   [(set_attr "type" "call")])
17388 (define_insn "*sibcall"
17389   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
17390          (match_operand 1))]
17391   "SIBLING_CALL_P (insn)"
17392   "* return ix86_output_call_insn (insn, operands[0]);"
17393   [(set_attr "type" "call")])
17395 (define_insn "*sibcall_memory"
17396   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
17397          (match_operand 1))
17398    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17399   "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17400   "* return ix86_output_call_insn (insn, operands[0]);"
17401   [(set_attr "type" "call")])
17403 (define_peephole2
17404   [(set (match_operand:W 0 "register_operand")
17405         (match_operand:W 1 "memory_operand"))
17406    (call (mem:QI (match_dup 0))
17407          (match_operand 3))]
17408   "!TARGET_X32
17409    && !TARGET_INDIRECT_BRANCH_REGISTER
17410    && SIBLING_CALL_P (peep2_next_insn (1))
17411    && !reg_mentioned_p (operands[0],
17412                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17413   [(parallel [(call (mem:QI (match_dup 1))
17414                     (match_dup 3))
17415               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17417 (define_peephole2
17418   [(set (match_operand:W 0 "register_operand")
17419         (match_operand:W 1 "memory_operand"))
17420    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17421    (call (mem:QI (match_dup 0))
17422          (match_operand 3))]
17423   "!TARGET_X32
17424    && !TARGET_INDIRECT_BRANCH_REGISTER
17425    && SIBLING_CALL_P (peep2_next_insn (2))
17426    && !reg_mentioned_p (operands[0],
17427                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17428   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17429    (parallel [(call (mem:QI (match_dup 1))
17430                     (match_dup 3))
17431               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17433 (define_expand "call_pop"
17434   [(parallel [(call (match_operand:QI 0)
17435                     (match_operand:SI 1))
17436               (set (reg:SI SP_REG)
17437                    (plus:SI (reg:SI SP_REG)
17438                             (match_operand:SI 3)))])]
17439   "!TARGET_64BIT"
17441   ix86_expand_call (NULL, operands[0], operands[1],
17442                     operands[2], operands[3], false);
17443   DONE;
17446 (define_insn "*call_pop"
17447   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
17448          (match_operand 1))
17449    (set (reg:SI SP_REG)
17450         (plus:SI (reg:SI SP_REG)
17451                  (match_operand:SI 2 "immediate_operand" "i")))]
17452   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17453   "* return ix86_output_call_insn (insn, operands[0]);"
17454   [(set_attr "type" "call")])
17456 (define_insn "*sibcall_pop"
17457   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
17458          (match_operand 1))
17459    (set (reg:SI SP_REG)
17460         (plus:SI (reg:SI SP_REG)
17461                  (match_operand:SI 2 "immediate_operand" "i")))]
17462   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17463   "* return ix86_output_call_insn (insn, operands[0]);"
17464   [(set_attr "type" "call")])
17466 (define_insn "*sibcall_pop_memory"
17467   [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
17468          (match_operand 1))
17469    (set (reg:SI SP_REG)
17470         (plus:SI (reg:SI SP_REG)
17471                  (match_operand:SI 2 "immediate_operand" "i")))
17472    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17473   "!TARGET_64BIT"
17474   "* return ix86_output_call_insn (insn, operands[0]);"
17475   [(set_attr "type" "call")])
17477 (define_peephole2
17478   [(set (match_operand:SI 0 "register_operand")
17479         (match_operand:SI 1 "memory_operand"))
17480    (parallel [(call (mem:QI (match_dup 0))
17481                     (match_operand 3))
17482               (set (reg:SI SP_REG)
17483                    (plus:SI (reg:SI SP_REG)
17484                             (match_operand:SI 4 "immediate_operand")))])]
17485   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17486    && !reg_mentioned_p (operands[0],
17487                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17488   [(parallel [(call (mem:QI (match_dup 1))
17489                     (match_dup 3))
17490               (set (reg:SI SP_REG)
17491                    (plus:SI (reg:SI SP_REG)
17492                             (match_dup 4)))
17493               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17495 (define_peephole2
17496   [(set (match_operand:SI 0 "register_operand")
17497         (match_operand:SI 1 "memory_operand"))
17498    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17499    (parallel [(call (mem:QI (match_dup 0))
17500                     (match_operand 3))
17501               (set (reg:SI SP_REG)
17502                    (plus:SI (reg:SI SP_REG)
17503                             (match_operand:SI 4 "immediate_operand")))])]
17504   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17505    && !reg_mentioned_p (operands[0],
17506                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17507   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17508    (parallel [(call (mem:QI (match_dup 1))
17509                     (match_dup 3))
17510               (set (reg:SI SP_REG)
17511                    (plus:SI (reg:SI SP_REG)
17512                             (match_dup 4)))
17513               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17515 ;; Combining simple memory jump instruction
17517 (define_peephole2
17518   [(set (match_operand:W 0 "register_operand")
17519         (match_operand:W 1 "memory_operand"))
17520    (set (pc) (match_dup 0))]
17521   "!TARGET_X32
17522    && !TARGET_INDIRECT_BRANCH_REGISTER
17523    && peep2_reg_dead_p (2, operands[0])"
17524   [(set (pc) (match_dup 1))])
17526 ;; Call subroutine, returning value in operand 0
17528 (define_expand "call_value"
17529   [(set (match_operand 0)
17530         (call (match_operand:QI 1)
17531               (match_operand 2)))
17532    (use (match_operand 3))]
17533   ""
17535   ix86_expand_call (operands[0], operands[1], operands[2],
17536                     operands[3], NULL, false);
17537   DONE;
17540 (define_expand "sibcall_value"
17541   [(set (match_operand 0)
17542         (call (match_operand:QI 1)
17543               (match_operand 2)))
17544    (use (match_operand 3))]
17545   ""
17547   ix86_expand_call (operands[0], operands[1], operands[2],
17548                     operands[3], NULL, true);
17549   DONE;
17552 (define_insn "*call_value"
17553   [(set (match_operand 0)
17554         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
17555               (match_operand 2)))]
17556   "!SIBLING_CALL_P (insn)"
17557   "* return ix86_output_call_insn (insn, operands[1]);"
17558   [(set_attr "type" "callv")])
17560 ;; This covers both call and sibcall since only GOT slot is allowed.
17561 (define_insn "*call_value_got_x32"
17562   [(set (match_operand 0)
17563         (call (mem:QI
17564                 (zero_extend:DI
17565                   (match_operand:SI 1 "GOT_memory_operand" "Bg")))
17566               (match_operand 2)))]
17567   "TARGET_X32"
17569   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
17570   return ix86_output_call_insn (insn, fnaddr);
17572   [(set_attr "type" "callv")])
17574 ;; Since sibcall never returns, we can only use call-clobbered register
17575 ;; as GOT base.
17576 (define_insn "*sibcall_value_GOT_32"
17577   [(set (match_operand 0)
17578         (call (mem:QI
17579                 (mem:SI (plus:SI
17580                           (match_operand:SI 1 "register_no_elim_operand" "U")
17581                           (match_operand:SI 2 "GOT32_symbol_operand"))))
17582          (match_operand 3)))]
17583   "!TARGET_MACHO
17584    && !TARGET_64BIT
17585    && !TARGET_INDIRECT_BRANCH_REGISTER
17586    && SIBLING_CALL_P (insn)"
17588   rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
17589   fnaddr = gen_const_mem (SImode, fnaddr);
17590   return ix86_output_call_insn (insn, fnaddr);
17592   [(set_attr "type" "callv")])
17594 (define_insn "*sibcall_value"
17595   [(set (match_operand 0)
17596         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
17597               (match_operand 2)))]
17598   "SIBLING_CALL_P (insn)"
17599   "* return ix86_output_call_insn (insn, operands[1]);"
17600   [(set_attr "type" "callv")])
17602 (define_insn "*sibcall_value_memory"
17603   [(set (match_operand 0)
17604         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
17605               (match_operand 2)))
17606    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17607   "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17608   "* return ix86_output_call_insn (insn, operands[1]);"
17609   [(set_attr "type" "callv")])
17611 (define_peephole2
17612   [(set (match_operand:W 0 "register_operand")
17613         (match_operand:W 1 "memory_operand"))
17614    (set (match_operand 2)
17615    (call (mem:QI (match_dup 0))
17616                  (match_operand 3)))]
17617   "!TARGET_X32
17618    && !TARGET_INDIRECT_BRANCH_REGISTER
17619    && SIBLING_CALL_P (peep2_next_insn (1))
17620    && !reg_mentioned_p (operands[0],
17621                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17622   [(parallel [(set (match_dup 2)
17623                    (call (mem:QI (match_dup 1))
17624                          (match_dup 3)))
17625               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17627 (define_peephole2
17628   [(set (match_operand:W 0 "register_operand")
17629         (match_operand:W 1 "memory_operand"))
17630    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17631    (set (match_operand 2)
17632         (call (mem:QI (match_dup 0))
17633               (match_operand 3)))]
17634   "!TARGET_X32
17635    && !TARGET_INDIRECT_BRANCH_REGISTER
17636    && SIBLING_CALL_P (peep2_next_insn (2))
17637    && !reg_mentioned_p (operands[0],
17638                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17639   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17640    (parallel [(set (match_dup 2)
17641                    (call (mem:QI (match_dup 1))
17642                          (match_dup 3)))
17643               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17645 (define_expand "call_value_pop"
17646   [(parallel [(set (match_operand 0)
17647                    (call (match_operand:QI 1)
17648                          (match_operand:SI 2)))
17649               (set (reg:SI SP_REG)
17650                    (plus:SI (reg:SI SP_REG)
17651                             (match_operand:SI 4)))])]
17652   "!TARGET_64BIT"
17654   ix86_expand_call (operands[0], operands[1], operands[2],
17655                     operands[3], operands[4], false);
17656   DONE;
17659 (define_insn "*call_value_pop"
17660   [(set (match_operand 0)
17661         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
17662               (match_operand 2)))
17663    (set (reg:SI SP_REG)
17664         (plus:SI (reg:SI SP_REG)
17665                  (match_operand:SI 3 "immediate_operand" "i")))]
17666   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17667   "* return ix86_output_call_insn (insn, operands[1]);"
17668   [(set_attr "type" "callv")])
17670 (define_insn "*sibcall_value_pop"
17671   [(set (match_operand 0)
17672         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
17673               (match_operand 2)))
17674    (set (reg:SI SP_REG)
17675         (plus:SI (reg:SI SP_REG)
17676                  (match_operand:SI 3 "immediate_operand" "i")))]
17677   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17678   "* return ix86_output_call_insn (insn, operands[1]);"
17679   [(set_attr "type" "callv")])
17681 (define_insn "*sibcall_value_pop_memory"
17682   [(set (match_operand 0)
17683         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
17684               (match_operand 2)))
17685    (set (reg:SI SP_REG)
17686         (plus:SI (reg:SI SP_REG)
17687                  (match_operand:SI 3 "immediate_operand" "i")))
17688    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17689   "!TARGET_64BIT"
17690   "* return ix86_output_call_insn (insn, operands[1]);"
17691   [(set_attr "type" "callv")])
17693 (define_peephole2
17694   [(set (match_operand:SI 0 "register_operand")
17695         (match_operand:SI 1 "memory_operand"))
17696    (parallel [(set (match_operand 2)
17697                    (call (mem:QI (match_dup 0))
17698                          (match_operand 3)))
17699               (set (reg:SI SP_REG)
17700                    (plus:SI (reg:SI SP_REG)
17701                             (match_operand:SI 4 "immediate_operand")))])]
17702   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17703    && !reg_mentioned_p (operands[0],
17704                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17705   [(parallel [(set (match_dup 2)
17706                    (call (mem:QI (match_dup 1))
17707                          (match_dup 3)))
17708               (set (reg:SI SP_REG)
17709                    (plus:SI (reg:SI SP_REG)
17710                             (match_dup 4)))
17711               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17713 (define_peephole2
17714   [(set (match_operand:SI 0 "register_operand")
17715         (match_operand:SI 1 "memory_operand"))
17716    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17717    (parallel [(set (match_operand 2)
17718                    (call (mem:QI (match_dup 0))
17719                          (match_operand 3)))
17720               (set (reg:SI SP_REG)
17721                    (plus:SI (reg:SI SP_REG)
17722                             (match_operand:SI 4 "immediate_operand")))])]
17723   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17724    && !reg_mentioned_p (operands[0],
17725                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17726   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17727    (parallel [(set (match_dup 2)
17728                    (call (mem:QI (match_dup 1))
17729                          (match_dup 3)))
17730               (set (reg:SI SP_REG)
17731                    (plus:SI (reg:SI SP_REG)
17732                             (match_dup 4)))
17733               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17735 ;; Call subroutine returning any type.
17737 (define_expand "untyped_call"
17738   [(parallel [(call (match_operand 0)
17739                     (const_int 0))
17740               (match_operand 1)
17741               (match_operand 2)])]
17742   ""
17744   int i;
17746   /* In order to give reg-stack an easier job in validating two
17747      coprocessor registers as containing a possible return value,
17748      simply pretend the untyped call returns a complex long double
17749      value. 
17751      We can't use SSE_REGPARM_MAX here since callee is unprototyped
17752      and should have the default ABI.  */
17754   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
17755                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
17756                     operands[0], const0_rtx,
17757                     GEN_INT ((TARGET_64BIT
17758                               ? (ix86_abi == SYSV_ABI
17759                                  ? X86_64_SSE_REGPARM_MAX
17760                                  : X86_64_MS_SSE_REGPARM_MAX)
17761                               : X86_32_SSE_REGPARM_MAX)
17762                              - 1),
17763                     NULL, false);
17765   for (i = 0; i < XVECLEN (operands[2], 0); i++)
17766     {
17767       rtx set = XVECEXP (operands[2], 0, i);
17768       emit_move_insn (SET_DEST (set), SET_SRC (set));
17769     }
17771   /* The optimizer does not know that the call sets the function value
17772      registers we stored in the result block.  We avoid problems by
17773      claiming that all hard registers are used and clobbered at this
17774      point.  */
17775   emit_insn (gen_blockage ());
17777   DONE;
17780 ;; Prologue and epilogue instructions
17782 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
17783 ;; all of memory.  This blocks insns from being moved across this point.
17785 (define_insn "blockage"
17786   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
17787   ""
17788   ""
17789   [(set_attr "length" "0")])
17791 ;; Do not schedule instructions accessing memory across this point.
17793 (define_expand "memory_blockage"
17794   [(set (match_dup 0)
17795         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17796   ""
17798   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17799   MEM_VOLATILE_P (operands[0]) = 1;
17802 (define_insn "*memory_blockage"
17803   [(set (match_operand:BLK 0)
17804         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17805   ""
17806   ""
17807   [(set_attr "length" "0")])
17809 ;; As USE insns aren't meaningful after reload, this is used instead
17810 ;; to prevent deleting instructions setting registers for PIC code
17811 (define_insn "prologue_use"
17812   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
17813   ""
17814   ""
17815   [(set_attr "length" "0")])
17817 ;; Insn emitted into the body of a function to return from a function.
17818 ;; This is only done if the function's epilogue is known to be simple.
17819 ;; See comments for ix86_can_use_return_insn_p in i386.cc.
17821 (define_expand "return"
17822   [(simple_return)]
17823   "ix86_can_use_return_insn_p ()"
17825   if (crtl->args.pops_args)
17826     {
17827       rtx popc = GEN_INT (crtl->args.pops_args);
17828       emit_jump_insn (gen_simple_return_pop_internal (popc));
17829       DONE;
17830     }
17833 ;; We need to disable this for TARGET_SEH, as otherwise
17834 ;; shrink-wrapped prologue gets enabled too.  This might exceed
17835 ;; the maximum size of prologue in unwind information.
17836 ;; Also disallow shrink-wrapping if using stack slot to pass the
17837 ;; static chain pointer - the first instruction has to be pushl %esi
17838 ;; and it can't be moved around, as we use alternate entry points
17839 ;; in that case.
17840 ;; Also disallow for ms_hook_prologue functions which have frame
17841 ;; pointer set up in function label which is correctly handled in
17842 ;; ix86_expand_{prologue|epligoue}() only.
17844 (define_expand "simple_return"
17845   [(simple_return)]
17846   "!TARGET_SEH && !ix86_static_chain_on_stack && !ix86_function_ms_hook_prologue (cfun->decl)"
17848   if (crtl->args.pops_args)
17849     {
17850       rtx popc = GEN_INT (crtl->args.pops_args);
17851       emit_jump_insn (gen_simple_return_pop_internal (popc));
17852       DONE;
17853     }
17856 (define_insn "simple_return_internal"
17857   [(simple_return)]
17858   "reload_completed"
17859   "* return ix86_output_function_return (false);"
17860   [(set_attr "length" "1")
17861    (set_attr "atom_unit" "jeu")
17862    (set_attr "length_immediate" "0")
17863    (set_attr "modrm" "0")])
17865 (define_insn "interrupt_return"
17866   [(simple_return)
17867    (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
17868   "reload_completed"
17870   return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret";
17873 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
17874 ;; instruction Athlon and K8 have.
17876 (define_insn "simple_return_internal_long"
17877   [(simple_return)
17878    (unspec [(const_int 0)] UNSPEC_REP)]
17879   "reload_completed"
17880   "* return ix86_output_function_return (true);"
17881   [(set_attr "length" "2")
17882    (set_attr "atom_unit" "jeu")
17883    (set_attr "length_immediate" "0")
17884    (set_attr "prefix_rep" "1")
17885    (set_attr "modrm" "0")])
17887 (define_insn_and_split "simple_return_pop_internal"
17888   [(simple_return)
17889    (use (match_operand:SI 0 "const_int_operand"))]
17890   "reload_completed"
17891   "ret\t%0"
17892   "&& cfun->machine->function_return_type != indirect_branch_keep"
17893   [(const_int 0)]
17894   "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
17895   [(set_attr "length" "3")
17896    (set_attr "atom_unit" "jeu")
17897    (set_attr "length_immediate" "2")
17898    (set_attr "modrm" "0")])
17900 (define_expand "simple_return_indirect_internal"
17901   [(parallel
17902      [(simple_return)
17903       (use (match_operand 0 "register_operand"))])])
17905 (define_insn "*simple_return_indirect_internal<mode>"
17906   [(simple_return)
17907    (use (match_operand:W 0 "register_operand" "r"))]
17908   "reload_completed"
17909   "* return ix86_output_indirect_function_return (operands[0]);"
17910   [(set (attr "type")
17911      (if_then_else (match_test "(cfun->machine->indirect_branch_type
17912                                  != indirect_branch_keep)")
17913         (const_string "multi")
17914         (const_string "ibr")))
17915    (set_attr "length_immediate" "0")])
17917 (define_insn "nop"
17918   [(const_int 0)]
17919   ""
17920   "nop"
17921   [(set_attr "length" "1")
17922    (set_attr "length_immediate" "0")
17923    (set_attr "modrm" "0")])
17925 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
17926 (define_insn "nops"
17927   [(unspec_volatile [(match_operand 0 "const_int_operand")]
17928                     UNSPECV_NOPS)]
17929   "reload_completed"
17931   int num = INTVAL (operands[0]);
17933   gcc_assert (IN_RANGE (num, 1, 8));
17935   while (num--)
17936     fputs ("\tnop\n", asm_out_file);
17938   return "";
17940   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
17941    (set_attr "length_immediate" "0")
17942    (set_attr "modrm" "0")])
17944 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
17945 ;; branch prediction penalty for the third jump in a 16-byte
17946 ;; block on K8.
17948 (define_insn "pad"
17949   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
17950   ""
17952 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
17953   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
17954 #else
17955   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
17956      The align insn is used to avoid 3 jump instructions in the row to improve
17957      branch prediction and the benefits hardly outweigh the cost of extra 8
17958      nops on the average inserted by full alignment pseudo operation.  */
17959 #endif
17960   return "";
17962   [(set_attr "length" "16")])
17964 (define_expand "prologue"
17965   [(const_int 0)]
17966   ""
17967   "ix86_expand_prologue (); DONE;")
17969 (define_expand "set_got"
17970   [(parallel
17971      [(set (match_operand:SI 0 "register_operand")
17972            (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
17973       (clobber (reg:CC FLAGS_REG))])]
17974   "!TARGET_64BIT"
17976   if (flag_pic && !TARGET_VXWORKS_RTP)
17977     ix86_pc_thunk_call_expanded = true;
17980 (define_insn "*set_got"
17981   [(set (match_operand:SI 0 "register_operand" "=r")
17982         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
17983    (clobber (reg:CC FLAGS_REG))]
17984   "!TARGET_64BIT"
17985   "* return output_set_got (operands[0], NULL_RTX);"
17986   [(set_attr "type" "multi")
17987    (set_attr "length" "12")])
17989 (define_expand "set_got_labelled"
17990   [(parallel
17991      [(set (match_operand:SI 0 "register_operand")
17992            (unspec:SI [(label_ref (match_operand 1))]
17993                       UNSPEC_SET_GOT))
17994       (clobber (reg:CC FLAGS_REG))])]
17995   "!TARGET_64BIT"
17997   if (flag_pic && !TARGET_VXWORKS_RTP)
17998     ix86_pc_thunk_call_expanded = true;
18001 (define_insn "*set_got_labelled"
18002   [(set (match_operand:SI 0 "register_operand" "=r")
18003         (unspec:SI [(label_ref (match_operand 1))]
18004          UNSPEC_SET_GOT))
18005    (clobber (reg:CC FLAGS_REG))]
18006   "!TARGET_64BIT"
18007   "* return output_set_got (operands[0], operands[1]);"
18008   [(set_attr "type" "multi")
18009    (set_attr "length" "12")])
18011 (define_insn "set_got_rex64"
18012   [(set (match_operand:DI 0 "register_operand" "=r")
18013         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
18014   "TARGET_64BIT"
18015   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
18016   [(set_attr "type" "lea")
18017    (set_attr "length_address" "4")
18018    (set_attr "mode" "DI")])
18020 (define_insn "set_rip_rex64"
18021   [(set (match_operand:DI 0 "register_operand" "=r")
18022         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
18023   "TARGET_64BIT"
18024   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
18025   [(set_attr "type" "lea")
18026    (set_attr "length_address" "4")
18027    (set_attr "mode" "DI")])
18029 (define_insn "set_got_offset_rex64"
18030   [(set (match_operand:DI 0 "register_operand" "=r")
18031         (unspec:DI
18032           [(label_ref (match_operand 1))]
18033           UNSPEC_SET_GOT_OFFSET))]
18034   "TARGET_LP64"
18035   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
18036   [(set_attr "type" "imov")
18037    (set_attr "length_immediate" "0")
18038    (set_attr "length_address" "8")
18039    (set_attr "mode" "DI")])
18041 (define_expand "epilogue"
18042   [(const_int 0)]
18043   ""
18044   "ix86_expand_epilogue (1); DONE;")
18046 (define_expand "sibcall_epilogue"
18047   [(const_int 0)]
18048   ""
18049   "ix86_expand_epilogue (0); DONE;")
18051 (define_expand "eh_return"
18052   [(use (match_operand 0 "register_operand"))]
18053   ""
18055   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
18057   /* Tricky bit: we write the address of the handler to which we will
18058      be returning into someone else's stack frame, one word below the
18059      stack address we wish to restore.  */
18060   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
18061   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
18062   /* Return address is always in word_mode.  */
18063   tmp = gen_rtx_MEM (word_mode, tmp);
18064   if (GET_MODE (ra) != word_mode)
18065     ra = convert_to_mode (word_mode, ra, 1);
18066   emit_move_insn (tmp, ra);
18068   emit_jump_insn (gen_eh_return_internal ());
18069   emit_barrier ();
18070   DONE;
18073 (define_insn_and_split "eh_return_internal"
18074   [(eh_return)]
18075   ""
18076   "#"
18077   "epilogue_completed"
18078   [(const_int 0)]
18079   "ix86_expand_epilogue (2); DONE;")
18081 (define_expand "@leave_<mode>"
18082   [(parallel
18083     [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
18084      (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
18085      (clobber (mem:BLK (scratch)))])]
18086   ""
18087   "operands[0] = GEN_INT (<MODE_SIZE>);")
18089 (define_insn "*leave"
18090   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
18091    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
18092    (clobber (mem:BLK (scratch)))]
18093   "!TARGET_64BIT"
18094   "leave"
18095   [(set_attr "type" "leave")])
18097 (define_insn "*leave_rex64"
18098   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
18099    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
18100    (clobber (mem:BLK (scratch)))]
18101   "TARGET_64BIT"
18102   "leave"
18103   [(set_attr "type" "leave")])
18105 ;; Handle -fsplit-stack.
18107 (define_expand "split_stack_prologue"
18108   [(const_int 0)]
18109   ""
18111   ix86_expand_split_stack_prologue ();
18112   DONE;
18115 ;; In order to support the call/return predictor, we use a return
18116 ;; instruction which the middle-end doesn't see.
18117 (define_insn "split_stack_return"
18118   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
18119                      UNSPECV_SPLIT_STACK_RETURN)]
18120   ""
18122   if (operands[0] == const0_rtx)
18123     return "ret";
18124   else
18125     return "ret\t%0";
18127   [(set_attr "atom_unit" "jeu")
18128    (set_attr "modrm" "0")
18129    (set (attr "length")
18130         (if_then_else (match_operand:SI 0 "const0_operand")
18131                       (const_int 1)
18132                       (const_int 3)))
18133    (set (attr "length_immediate")
18134         (if_then_else (match_operand:SI 0 "const0_operand")
18135                       (const_int 0)
18136                       (const_int 2)))])
18138 ;; If there are operand 0 bytes available on the stack, jump to
18139 ;; operand 1.
18141 (define_expand "split_stack_space_check"
18142   [(set (pc) (if_then_else
18143               (ltu (minus (reg SP_REG)
18144                           (match_operand 0 "register_operand"))
18145                    (match_dup 2))
18146               (label_ref (match_operand 1))
18147               (pc)))]
18148   ""
18150   rtx reg = gen_reg_rtx (Pmode);
18152   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
18154   operands[2] = ix86_split_stack_guard ();
18155   ix86_expand_branch (GEU, reg, operands[2], operands[1]);
18157   DONE;
18160 ;; Bit manipulation instructions.
18162 (define_expand "ffs<mode>2"
18163   [(set (match_dup 2) (const_int -1))
18164    (parallel [(set (match_dup 3) (match_dup 4))
18165               (set (match_operand:SWI48 0 "register_operand")
18166                    (ctz:SWI48
18167                      (match_operand:SWI48 1 "nonimmediate_operand")))])
18168    (set (match_dup 0) (if_then_else:SWI48
18169                         (eq (match_dup 3) (const_int 0))
18170                         (match_dup 2)
18171                         (match_dup 0)))
18172    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
18173               (clobber (reg:CC FLAGS_REG))])]
18174   ""
18176   machine_mode flags_mode;
18178   if (<MODE>mode == SImode && !TARGET_CMOVE)
18179     {
18180       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
18181       DONE;
18182     }
18184   flags_mode = TARGET_BMI ? CCCmode : CCZmode;
18186   operands[2] = gen_reg_rtx (<MODE>mode);
18187   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
18188   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
18191 (define_insn_and_split "ffssi2_no_cmove"
18192   [(set (match_operand:SI 0 "register_operand" "=r")
18193         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
18194    (clobber (match_scratch:SI 2 "=&q"))
18195    (clobber (reg:CC FLAGS_REG))]
18196   "!TARGET_CMOVE"
18197   "#"
18198   "&& reload_completed"
18199   [(parallel [(set (match_dup 4) (match_dup 5))
18200               (set (match_dup 0) (ctz:SI (match_dup 1)))])
18201    (set (strict_low_part (match_dup 3))
18202         (eq:QI (match_dup 4) (const_int 0)))
18203    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
18204               (clobber (reg:CC FLAGS_REG))])
18205    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
18206               (clobber (reg:CC FLAGS_REG))])
18207    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
18208               (clobber (reg:CC FLAGS_REG))])]
18210   machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
18212   operands[3] = gen_lowpart (QImode, operands[2]);
18213   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
18214   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
18216   ix86_expand_clear (operands[2]);
18219 (define_insn_and_split "*tzcnt<mode>_1"
18220   [(set (reg:CCC FLAGS_REG)
18221         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18222                      (const_int 0)))
18223    (set (match_operand:SWI48 0 "register_operand" "=r")
18224         (ctz:SWI48 (match_dup 1)))]
18225   "TARGET_BMI"
18226   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18227   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18228    && optimize_function_for_speed_p (cfun)
18229    && !reg_mentioned_p (operands[0], operands[1])"
18230   [(parallel
18231     [(set (reg:CCC FLAGS_REG)
18232           (compare:CCC (match_dup 1) (const_int 0)))
18233      (set (match_dup 0)
18234           (ctz:SWI48 (match_dup 1)))
18235      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
18236   "ix86_expand_clear (operands[0]);"
18237   [(set_attr "type" "alu1")
18238    (set_attr "prefix_0f" "1")
18239    (set_attr "prefix_rep" "1")
18240    (set_attr "btver2_decode" "double")
18241    (set_attr "mode" "<MODE>")])
18243 ; False dependency happens when destination is only updated by tzcnt,
18244 ; lzcnt or popcnt.  There is no false dependency when destination is
18245 ; also used in source.
18246 (define_insn "*tzcnt<mode>_1_falsedep"
18247   [(set (reg:CCC FLAGS_REG)
18248         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18249                      (const_int 0)))
18250    (set (match_operand:SWI48 0 "register_operand" "=r")
18251         (ctz:SWI48 (match_dup 1)))
18252    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18253            UNSPEC_INSN_FALSE_DEP)]
18254   "TARGET_BMI"
18255   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18256   [(set_attr "type" "alu1")
18257    (set_attr "prefix_0f" "1")
18258    (set_attr "prefix_rep" "1")
18259    (set_attr "btver2_decode" "double")
18260    (set_attr "mode" "<MODE>")])
18262 (define_insn "*bsf<mode>_1"
18263   [(set (reg:CCZ FLAGS_REG)
18264         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18265                      (const_int 0)))
18266    (set (match_operand:SWI48 0 "register_operand" "=r")
18267         (ctz:SWI48 (match_dup 1)))]
18268   ""
18269   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
18270   [(set_attr "type" "alu1")
18271    (set_attr "prefix_0f" "1")
18272    (set_attr "btver2_decode" "double")
18273    (set_attr "znver1_decode" "vector")
18274    (set_attr "mode" "<MODE>")])
18276 (define_insn_and_split "ctz<mode>2"
18277   [(set (match_operand:SWI48 0 "register_operand" "=r")
18278         (ctz:SWI48
18279           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18280    (clobber (reg:CC FLAGS_REG))]
18281   ""
18283   if (TARGET_BMI)
18284     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18285   else if (optimize_function_for_size_p (cfun))
18286     ;
18287   else if (TARGET_CPU_P (GENERIC))
18288     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
18289     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18291   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18293   "(TARGET_BMI || TARGET_CPU_P (GENERIC))
18294    && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18295    && optimize_function_for_speed_p (cfun)
18296    && !reg_mentioned_p (operands[0], operands[1])"
18297   [(parallel
18298     [(set (match_dup 0)
18299           (ctz:SWI48 (match_dup 1)))
18300      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18301      (clobber (reg:CC FLAGS_REG))])]
18302   "ix86_expand_clear (operands[0]);"
18303   [(set_attr "type" "alu1")
18304    (set_attr "prefix_0f" "1")
18305    (set (attr "prefix_rep")
18306      (if_then_else
18307        (ior (match_test "TARGET_BMI")
18308             (and (not (match_test "optimize_function_for_size_p (cfun)"))
18309                  (match_test "TARGET_CPU_P (GENERIC)")))
18310        (const_string "1")
18311        (const_string "0")))
18312    (set_attr "mode" "<MODE>")])
18314 ; False dependency happens when destination is only updated by tzcnt,
18315 ; lzcnt or popcnt.  There is no false dependency when destination is
18316 ; also used in source.
18317 (define_insn "*ctz<mode>2_falsedep"
18318   [(set (match_operand:SWI48 0 "register_operand" "=r")
18319         (ctz:SWI48
18320           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18321    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18322            UNSPEC_INSN_FALSE_DEP)
18323    (clobber (reg:CC FLAGS_REG))]
18324   ""
18326   if (TARGET_BMI)
18327     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18328   else if (TARGET_CPU_P (GENERIC))
18329     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
18330     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18331   else
18332     gcc_unreachable ();
18334   [(set_attr "type" "alu1")
18335    (set_attr "prefix_0f" "1")
18336    (set_attr "prefix_rep" "1")
18337    (set_attr "mode" "<MODE>")])
18339 (define_insn_and_split "*ctzsi2_zext"
18340   [(set (match_operand:DI 0 "register_operand" "=r")
18341         (and:DI
18342           (subreg:DI
18343             (ctz:SI
18344               (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18345           (const_int 63)))
18346    (clobber (reg:CC FLAGS_REG))]
18347   "TARGET_BMI && TARGET_64BIT"
18348   "tzcnt{l}\t{%1, %k0|%k0, %1}"
18349   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18350    && optimize_function_for_speed_p (cfun)
18351    && !reg_mentioned_p (operands[0], operands[1])"
18352   [(parallel
18353     [(set (match_dup 0)
18354           (and:DI (subreg:DI (ctz:SI (match_dup 1)) 0) (const_int 63)))
18355      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18356      (clobber (reg:CC FLAGS_REG))])]
18357   "ix86_expand_clear (operands[0]);"
18358   [(set_attr "type" "alu1")
18359    (set_attr "prefix_0f" "1")
18360    (set_attr "prefix_rep" "1")
18361    (set_attr "mode" "SI")])
18363 ; False dependency happens when destination is only updated by tzcnt,
18364 ; lzcnt or popcnt.  There is no false dependency when destination is
18365 ; also used in source.
18366 (define_insn "*ctzsi2_zext_falsedep"
18367   [(set (match_operand:DI 0 "register_operand" "=r")
18368         (and:DI
18369           (subreg:DI
18370             (ctz:SI
18371               (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18372           (const_int 63)))
18373    (unspec [(match_operand:DI 2 "register_operand" "0")]
18374            UNSPEC_INSN_FALSE_DEP)
18375    (clobber (reg:CC FLAGS_REG))]
18376   "TARGET_BMI && TARGET_64BIT"
18377   "tzcnt{l}\t{%1, %k0|%k0, %1}"
18378   [(set_attr "type" "alu1")
18379    (set_attr "prefix_0f" "1")
18380    (set_attr "prefix_rep" "1")
18381    (set_attr "mode" "SI")])
18383 (define_insn_and_split "*ctzsidi2_<s>ext"
18384   [(set (match_operand:DI 0 "register_operand" "=r")
18385         (any_extend:DI
18386           (ctz:SI
18387             (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18388    (clobber (reg:CC FLAGS_REG))]
18389   "TARGET_64BIT"
18391   if (TARGET_BMI)
18392     return "tzcnt{l}\t{%1, %k0|%k0, %1}";
18393   else if (TARGET_CPU_P (GENERIC)
18394            && !optimize_function_for_size_p (cfun))
18395     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
18396     return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
18397   return "bsf{l}\t{%1, %k0|%k0, %1}";
18399   "(TARGET_BMI || TARGET_CPU_P (GENERIC))
18400    && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18401    && optimize_function_for_speed_p (cfun)
18402    && !reg_mentioned_p (operands[0], operands[1])"
18403   [(parallel
18404     [(set (match_dup 0)
18405           (any_extend:DI (ctz:SI (match_dup 1))))
18406      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18407      (clobber (reg:CC FLAGS_REG))])]
18408   "ix86_expand_clear (operands[0]);"
18409   [(set_attr "type" "alu1")
18410    (set_attr "prefix_0f" "1")
18411    (set (attr "prefix_rep")
18412      (if_then_else
18413        (ior (match_test "TARGET_BMI")
18414             (and (not (match_test "optimize_function_for_size_p (cfun)"))
18415                  (match_test "TARGET_CPU_P (GENERIC)")))
18416        (const_string "1")
18417        (const_string "0")))
18418    (set_attr "mode" "SI")])
18420 (define_insn "*ctzsidi2_<s>ext_falsedep"
18421   [(set (match_operand:DI 0 "register_operand" "=r")
18422         (any_extend:DI
18423           (ctz:SI
18424             (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18425    (unspec [(match_operand:DI 2 "register_operand" "0")]
18426            UNSPEC_INSN_FALSE_DEP)
18427    (clobber (reg:CC FLAGS_REG))]
18428   "TARGET_64BIT"
18430   if (TARGET_BMI)
18431     return "tzcnt{l}\t{%1, %k0|%k0, %1}";
18432   else if (TARGET_CPU_P (GENERIC))
18433     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
18434     return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
18435   else
18436     gcc_unreachable ();
18438   [(set_attr "type" "alu1")
18439    (set_attr "prefix_0f" "1")
18440    (set_attr "prefix_rep" "1")
18441    (set_attr "mode" "SI")])
18443 (define_insn "bsr_rex64"
18444   [(set (reg:CCZ FLAGS_REG)
18445         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
18446                      (const_int 0)))
18447    (set (match_operand:DI 0 "register_operand" "=r")
18448         (minus:DI (const_int 63)
18449                   (clz:DI (match_dup 1))))]
18450   "TARGET_64BIT"
18451   "bsr{q}\t{%1, %0|%0, %1}"
18452   [(set_attr "type" "alu1")
18453    (set_attr "prefix_0f" "1")
18454    (set_attr "znver1_decode" "vector")
18455    (set_attr "mode" "DI")])
18457 (define_insn "bsr_rex64_1"
18458   [(set (match_operand:DI 0 "register_operand" "=r")
18459         (minus:DI (const_int 63)
18460                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
18461    (clobber (reg:CC FLAGS_REG))]
18462   "!TARGET_LZCNT && TARGET_64BIT"
18463   "bsr{q}\t{%1, %0|%0, %1}"
18464   [(set_attr "type" "alu1")
18465    (set_attr "prefix_0f" "1")
18466    (set_attr "znver1_decode" "vector")
18467    (set_attr "mode" "DI")])
18469 (define_insn "bsr_rex64_1_zext"
18470   [(set (match_operand:DI 0 "register_operand" "=r")
18471         (zero_extend:DI
18472           (minus:SI (const_int 63)
18473                     (subreg:SI
18474                       (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
18475                       0))))
18476    (clobber (reg:CC FLAGS_REG))]
18477   "!TARGET_LZCNT && TARGET_64BIT"
18478   "bsr{q}\t{%1, %0|%0, %1}"
18479   [(set_attr "type" "alu1")
18480    (set_attr "prefix_0f" "1")
18481    (set_attr "znver1_decode" "vector")
18482    (set_attr "mode" "DI")])
18484 (define_insn "bsr"
18485   [(set (reg:CCZ FLAGS_REG)
18486         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
18487                      (const_int 0)))
18488    (set (match_operand:SI 0 "register_operand" "=r")
18489         (minus:SI (const_int 31)
18490                   (clz:SI (match_dup 1))))]
18491   ""
18492   "bsr{l}\t{%1, %0|%0, %1}"
18493   [(set_attr "type" "alu1")
18494    (set_attr "prefix_0f" "1")
18495    (set_attr "znver1_decode" "vector")
18496    (set_attr "mode" "SI")])
18498 (define_insn "bsr_1"
18499   [(set (match_operand:SI 0 "register_operand" "=r")
18500         (minus:SI (const_int 31)
18501                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18502    (clobber (reg:CC FLAGS_REG))]
18503   "!TARGET_LZCNT"
18504   "bsr{l}\t{%1, %0|%0, %1}"
18505   [(set_attr "type" "alu1")
18506    (set_attr "prefix_0f" "1")
18507    (set_attr "znver1_decode" "vector")
18508    (set_attr "mode" "SI")])
18510 (define_insn "bsr_zext_1"
18511   [(set (match_operand:DI 0 "register_operand" "=r")
18512         (zero_extend:DI
18513           (minus:SI
18514             (const_int 31)
18515             (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))))
18516    (clobber (reg:CC FLAGS_REG))]
18517   "!TARGET_LZCNT && TARGET_64BIT"
18518   "bsr{l}\t{%1, %k0|%k0, %1}"
18519   [(set_attr "type" "alu1")
18520    (set_attr "prefix_0f" "1")
18521    (set_attr "znver1_decode" "vector")
18522    (set_attr "mode" "SI")])
18524 ; As bsr is undefined behavior on zero and for other input
18525 ; values it is in range 0 to 63, we can optimize away sign-extends.
18526 (define_insn_and_split "*bsr_rex64_2"
18527   [(set (match_operand:DI 0 "register_operand")
18528         (xor:DI
18529           (sign_extend:DI
18530             (minus:SI
18531               (const_int 63)
18532               (subreg:SI (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18533                          0)))
18534           (const_int 63)))
18535     (clobber (reg:CC FLAGS_REG))]
18536   "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18537   "#"
18538   "&& 1"
18539   [(parallel [(set (reg:CCZ FLAGS_REG)
18540                    (compare:CCZ (match_dup 1) (const_int 0)))
18541               (set (match_dup 2)
18542                    (minus:DI (const_int 63) (clz:DI (match_dup 1))))])
18543    (parallel [(set (match_dup 0)
18544                    (zero_extend:DI (xor:SI (match_dup 3) (const_int 63))))
18545               (clobber (reg:CC FLAGS_REG))])]
18547   operands[2] = gen_reg_rtx (DImode);
18548   operands[3] = lowpart_subreg (SImode, operands[2], DImode);
18551 (define_insn_and_split "*bsr_2"
18552   [(set (match_operand:DI 0 "register_operand")
18553         (sign_extend:DI
18554           (xor:SI
18555             (minus:SI
18556               (const_int 31)
18557               (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18558             (const_int 31))))
18559    (clobber (reg:CC FLAGS_REG))]
18560   "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18561   "#"
18562   "&& 1"
18563   [(parallel [(set (reg:CCZ FLAGS_REG)
18564                    (compare:CCZ (match_dup 1) (const_int 0)))
18565               (set (match_dup 2)
18566                    (minus:SI (const_int 31) (clz:SI (match_dup 1))))])
18567    (parallel [(set (match_dup 0)
18568                    (zero_extend:DI (xor:SI (match_dup 2) (const_int 31))))
18569               (clobber (reg:CC FLAGS_REG))])]
18570   "operands[2] = gen_reg_rtx (SImode);")
18572 ; Splitters to optimize 64 - __builtin_clzl (x) or 32 - __builtin_clz (x).
18573 ; Again, as for !TARGET_LZCNT CLZ is UB at zero, CLZ is guaranteed to be
18574 ; in [0, 63] or [0, 31] range.
18575 (define_split
18576   [(set (match_operand:SI 0 "register_operand")
18577         (minus:SI
18578           (match_operand:SI 2 "const_int_operand")
18579           (xor:SI
18580             (minus:SI (const_int 63)
18581                       (subreg:SI
18582                         (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18583                         0))
18584             (const_int 63))))]
18585   "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18586   [(set (match_dup 3)
18587         (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18588    (set (match_dup 0)
18589         (plus:SI (match_dup 5) (match_dup 4)))]
18591   operands[3] = gen_reg_rtx (DImode);
18592   operands[5] = lowpart_subreg (SImode, operands[3], DImode);
18593   if (INTVAL (operands[2]) == 63)
18594     {
18595       emit_insn (gen_bsr_rex64_1_zext (operands[3], operands[1]));
18596       emit_move_insn (operands[0], operands[5]);
18597       DONE;
18598     }
18599   operands[4] = gen_int_mode (UINTVAL (operands[2]) - 63, SImode);
18602 (define_split
18603   [(set (match_operand:SI 0 "register_operand")
18604         (minus:SI
18605           (match_operand:SI 2 "const_int_operand")
18606           (xor:SI
18607             (minus:SI (const_int 31)
18608                       (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18609             (const_int 31))))]
18610   "!TARGET_LZCNT && ix86_pre_reload_split ()"
18611   [(set (match_dup 3)
18612         (minus:SI (const_int 31) (clz:SI (match_dup 1))))
18613    (set (match_dup 0)
18614         (plus:SI (match_dup 3) (match_dup 4)))]
18616   if (INTVAL (operands[2]) == 31)
18617     {
18618       emit_insn (gen_bsr_1 (operands[0], operands[1]));
18619       DONE;
18620     }
18621   operands[3] = gen_reg_rtx (SImode);
18622   operands[4] = gen_int_mode (UINTVAL (operands[2]) - 31, SImode);
18625 (define_split
18626   [(set (match_operand:DI 0 "register_operand")
18627         (minus:DI
18628           (match_operand:DI 2 "const_int_operand")
18629           (xor:DI
18630             (sign_extend:DI
18631               (minus:SI (const_int 63)
18632                         (subreg:SI
18633                           (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18634                           0)))
18635             (const_int 63))))]
18636   "!TARGET_LZCNT
18637    && TARGET_64BIT
18638    && ix86_pre_reload_split ()
18639    && ((unsigned HOST_WIDE_INT)
18640        trunc_int_for_mode (UINTVAL (operands[2]) - 63, SImode)
18641        == UINTVAL (operands[2]) - 63)"
18642   [(set (match_dup 3)
18643         (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18644    (set (match_dup 0)
18645         (plus:DI (match_dup 3) (match_dup 4)))]
18647   if (INTVAL (operands[2]) == 63)
18648     {
18649       emit_insn (gen_bsr_rex64_1 (operands[0], operands[1]));
18650       DONE;
18651     }
18652   operands[3] = gen_reg_rtx (DImode);
18653   operands[4] = GEN_INT (UINTVAL (operands[2]) - 63);
18656 (define_split
18657   [(set (match_operand:DI 0 "register_operand")
18658         (minus:DI
18659           (match_operand:DI 2 "const_int_operand")
18660           (sign_extend:DI
18661             (xor:SI
18662               (minus:SI (const_int 31)
18663                         (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18664               (const_int 31)))))]
18665   "!TARGET_LZCNT
18666    && TARGET_64BIT
18667    && ix86_pre_reload_split ()
18668    && ((unsigned HOST_WIDE_INT)
18669        trunc_int_for_mode (UINTVAL (operands[2]) - 31, SImode)
18670        == UINTVAL (operands[2]) - 31)"
18671   [(set (match_dup 3)
18672         (zero_extend:DI (minus:SI (const_int 31) (clz:SI (match_dup 1)))))
18673    (set (match_dup 0)
18674         (plus:DI (match_dup 3) (match_dup 4)))]
18676   if (INTVAL (operands[2]) == 31)
18677     {
18678       emit_insn (gen_bsr_zext_1 (operands[0], operands[1]));
18679       DONE;
18680     }
18681   operands[3] = gen_reg_rtx (DImode);
18682   operands[4] = GEN_INT (UINTVAL (operands[2]) - 31);
18685 (define_expand "clz<mode>2"
18686   [(parallel
18687      [(set (reg:CCZ FLAGS_REG)
18688         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18689                      (const_int 0)))
18690       (set (match_dup 3) (minus:SWI48
18691                            (match_dup 2)
18692                            (clz:SWI48 (match_dup 1))))])
18693    (parallel
18694      [(set (match_operand:SWI48 0 "register_operand")
18695            (xor:SWI48 (match_dup 3) (match_dup 2)))
18696       (clobber (reg:CC FLAGS_REG))])]
18697   ""
18699   if (TARGET_LZCNT)
18700     {
18701       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
18702       DONE;
18703     }
18704   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
18705   operands[3] = gen_reg_rtx (<MODE>mode);
18708 (define_insn_and_split "clz<mode>2_lzcnt"
18709   [(set (match_operand:SWI48 0 "register_operand" "=r")
18710         (clz:SWI48
18711           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18712    (clobber (reg:CC FLAGS_REG))]
18713   "TARGET_LZCNT"
18714   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18715   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18716    && optimize_function_for_speed_p (cfun)
18717    && !reg_mentioned_p (operands[0], operands[1])"
18718   [(parallel
18719     [(set (match_dup 0)
18720           (clz:SWI48 (match_dup 1)))
18721      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18722      (clobber (reg:CC FLAGS_REG))])]
18723   "ix86_expand_clear (operands[0]);"
18724   [(set_attr "prefix_rep" "1")
18725    (set_attr "type" "bitmanip")
18726    (set_attr "mode" "<MODE>")])
18728 ; False dependency happens when destination is only updated by tzcnt,
18729 ; lzcnt or popcnt.  There is no false dependency when destination is
18730 ; also used in source.
18731 (define_insn "*clz<mode>2_lzcnt_falsedep"
18732   [(set (match_operand:SWI48 0 "register_operand" "=r")
18733         (clz:SWI48
18734           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18735    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18736            UNSPEC_INSN_FALSE_DEP)
18737    (clobber (reg:CC FLAGS_REG))]
18738   "TARGET_LZCNT"
18739   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18740   [(set_attr "prefix_rep" "1")
18741    (set_attr "type" "bitmanip")
18742    (set_attr "mode" "<MODE>")])
18744 (define_insn_and_split "*clzsi2_lzcnt_zext"
18745   [(set (match_operand:DI 0 "register_operand" "=r")
18746         (and:DI
18747           (subreg:DI
18748             (clz:SI
18749               (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18750           (const_int 63)))
18751    (clobber (reg:CC FLAGS_REG))]
18752   "TARGET_LZCNT && TARGET_64BIT"
18753   "lzcnt{l}\t{%1, %k0|%k0, %1}"
18754   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18755    && optimize_function_for_speed_p (cfun)
18756    && !reg_mentioned_p (operands[0], operands[1])"
18757   [(parallel
18758     [(set (match_dup 0)
18759           (and:DI (subreg:DI (clz:SI (match_dup 1)) 0) (const_int 63)))
18760      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18761      (clobber (reg:CC FLAGS_REG))])]
18762   "ix86_expand_clear (operands[0]);"
18763   [(set_attr "prefix_rep" "1")
18764    (set_attr "type" "bitmanip")
18765    (set_attr "mode" "SI")])
18767 ; False dependency happens when destination is only updated by tzcnt,
18768 ; lzcnt or popcnt.  There is no false dependency when destination is
18769 ; also used in source.
18770 (define_insn "*clzsi2_lzcnt_zext_falsedep"
18771   [(set (match_operand:DI 0 "register_operand" "=r")
18772         (and:DI
18773           (subreg:DI
18774             (clz:SI
18775               (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 0)
18776           (const_int 63)))
18777    (unspec [(match_operand:DI 2 "register_operand" "0")]
18778            UNSPEC_INSN_FALSE_DEP)
18779    (clobber (reg:CC FLAGS_REG))]
18780   "TARGET_LZCNT"
18781   "lzcnt{l}\t{%1, %k0|%k0, %1}"
18782   [(set_attr "prefix_rep" "1")
18783    (set_attr "type" "bitmanip")
18784    (set_attr "mode" "SI")])
18786 (define_insn_and_split "*clzsi2_lzcnt_zext_2"
18787   [(set (match_operand:DI 0 "register_operand" "=r")
18788         (zero_extend:DI
18789           (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18790    (clobber (reg:CC FLAGS_REG))]
18791   "TARGET_LZCNT && TARGET_64BIT"
18792   "lzcnt{l}\t{%1, %k0|%k0, %1}"
18793   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18794    && optimize_function_for_speed_p (cfun)
18795    && !reg_mentioned_p (operands[0], operands[1])"
18796   [(parallel
18797     [(set (match_dup 0)
18798           (zero_extend:DI (clz:SI (match_dup 1))))
18799      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18800      (clobber (reg:CC FLAGS_REG))])]
18801   "ix86_expand_clear (operands[0]);"
18802   [(set_attr "prefix_rep" "1")
18803    (set_attr "type" "bitmanip")
18804    (set_attr "mode" "SI")])
18806 ; False dependency happens when destination is only updated by tzcnt,
18807 ; lzcnt or popcnt.  There is no false dependency when destination is
18808 ; also used in source.
18809 (define_insn "*clzsi2_lzcnt_zext_2_falsedep"
18810   [(set (match_operand:DI 0 "register_operand" "=r")
18811         (zero_extend:DI
18812           (clz:SI (match_operand:SWI48 1 "nonimmediate_operand" "rm"))))
18813    (unspec [(match_operand:DI 2 "register_operand" "0")]
18814            UNSPEC_INSN_FALSE_DEP)
18815    (clobber (reg:CC FLAGS_REG))]
18816   "TARGET_LZCNT"
18817   "lzcnt{l}\t{%1, %k0|%k0, %1}"
18818   [(set_attr "prefix_rep" "1")
18819    (set_attr "type" "bitmanip")
18820    (set_attr "mode" "SI")])
18822 (define_int_iterator LT_ZCNT
18823         [(UNSPEC_TZCNT "TARGET_BMI")
18824          (UNSPEC_LZCNT "TARGET_LZCNT")])
18826 (define_int_attr lt_zcnt
18827         [(UNSPEC_TZCNT "tzcnt")
18828          (UNSPEC_LZCNT "lzcnt")])
18830 (define_int_attr lt_zcnt_type
18831         [(UNSPEC_TZCNT "alu1")
18832          (UNSPEC_LZCNT "bitmanip")])
18834 ;; Version of lzcnt/tzcnt that is expanded from intrinsics.  This version
18835 ;; provides operand size as output when source operand is zero. 
18837 (define_insn_and_split "<lt_zcnt>_<mode>"
18838   [(set (match_operand:SWI48 0 "register_operand" "=r")
18839         (unspec:SWI48
18840           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18841    (clobber (reg:CC FLAGS_REG))]
18842   ""
18843   "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18844   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18845    && optimize_function_for_speed_p (cfun)
18846    && !reg_mentioned_p (operands[0], operands[1])"
18847   [(parallel
18848     [(set (match_dup 0)
18849           (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
18850      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18851      (clobber (reg:CC FLAGS_REG))])]
18852   "ix86_expand_clear (operands[0]);"
18853   [(set_attr "type" "<lt_zcnt_type>")
18854    (set_attr "prefix_0f" "1")
18855    (set_attr "prefix_rep" "1")
18856    (set_attr "mode" "<MODE>")])
18858 ; False dependency happens when destination is only updated by tzcnt,
18859 ; lzcnt or popcnt.  There is no false dependency when destination is
18860 ; also used in source.
18861 (define_insn "*<lt_zcnt>_<mode>_falsedep"
18862   [(set (match_operand:SWI48 0 "register_operand" "=r")
18863         (unspec:SWI48
18864           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18865    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18866            UNSPEC_INSN_FALSE_DEP)
18867    (clobber (reg:CC FLAGS_REG))]
18868   ""
18869   "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18870   [(set_attr "type" "<lt_zcnt_type>")
18871    (set_attr "prefix_0f" "1")
18872    (set_attr "prefix_rep" "1")
18873    (set_attr "mode" "<MODE>")])
18875 (define_insn "<lt_zcnt>_hi"
18876   [(set (match_operand:HI 0 "register_operand" "=r")
18877         (unspec:HI
18878           [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18879    (clobber (reg:CC FLAGS_REG))]
18880   ""
18881   "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
18882   [(set_attr "type" "<lt_zcnt_type>")
18883    (set_attr "prefix_0f" "1")
18884    (set_attr "prefix_rep" "1")
18885    (set_attr "mode" "HI")])
18887 ;; BMI instructions.
18889 (define_insn "bmi_bextr_<mode>"
18890   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
18891         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18892                        (match_operand:SWI48 2 "register_operand" "r,r")]
18893                       UNSPEC_BEXTR))
18894    (clobber (reg:CC FLAGS_REG))]
18895   "TARGET_BMI"
18896   "bextr\t{%2, %1, %0|%0, %1, %2}"
18897   [(set_attr "type" "bitmanip")
18898    (set_attr "btver2_decode" "direct, double")
18899    (set_attr "mode" "<MODE>")])
18901 (define_insn "*bmi_bextr_<mode>_ccz"
18902   [(set (reg:CCZ FLAGS_REG)
18903         (compare:CCZ
18904           (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18905                          (match_operand:SWI48 2 "register_operand" "r,r")]
18906                         UNSPEC_BEXTR)
18907           (const_int 0)))
18908    (clobber (match_scratch:SWI48 0 "=r,r"))]
18909   "TARGET_BMI"
18910   "bextr\t{%2, %1, %0|%0, %1, %2}"
18911   [(set_attr "type" "bitmanip")
18912    (set_attr "btver2_decode" "direct, double")
18913    (set_attr "mode" "<MODE>")])
18915 (define_insn "*bmi_blsi_<mode>"
18916   [(set (match_operand:SWI48 0 "register_operand" "=r")
18917         (and:SWI48
18918           (neg:SWI48
18919             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18920           (match_dup 1)))
18921    (clobber (reg:CC FLAGS_REG))]
18922   "TARGET_BMI"
18923   "blsi\t{%1, %0|%0, %1}"
18924   [(set_attr "type" "bitmanip")
18925    (set_attr "btver2_decode" "double")
18926    (set_attr "mode" "<MODE>")])
18928 (define_insn "*bmi_blsi_<mode>_cmp"
18929   [(set (reg FLAGS_REG)
18930         (compare
18931           (and:SWI48
18932             (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18933             (match_dup 1))
18934           (const_int 0)))
18935    (set (match_operand:SWI48 0 "register_operand" "=r")
18936         (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))]
18937    "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
18938    "blsi\t{%1, %0|%0, %1}"
18939   [(set_attr "type" "bitmanip")
18940    (set_attr "btver2_decode" "double")
18941    (set_attr "mode" "<MODE>")])
18943 (define_insn "*bmi_blsi_<mode>_ccno"
18944   [(set (reg FLAGS_REG)
18945         (compare
18946           (and:SWI48
18947             (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18948             (match_dup 1))
18949           (const_int 0)))
18950    (clobber (match_scratch:SWI48 0 "=r"))]
18951    "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
18952    "blsi\t{%1, %0|%0, %1}"
18953   [(set_attr "type" "bitmanip")
18954    (set_attr "btver2_decode" "double")
18955    (set_attr "mode" "<MODE>")])
18957 (define_insn "*bmi_blsmsk_<mode>"
18958   [(set (match_operand:SWI48 0 "register_operand" "=r")
18959         (xor:SWI48
18960           (plus:SWI48
18961             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18962             (const_int -1))
18963           (match_dup 1)))
18964    (clobber (reg:CC FLAGS_REG))]
18965   "TARGET_BMI"
18966   "blsmsk\t{%1, %0|%0, %1}"
18967   [(set_attr "type" "bitmanip")
18968    (set_attr "btver2_decode" "double")
18969    (set_attr "mode" "<MODE>")])
18971 (define_insn "*bmi_blsr_<mode>"
18972   [(set (match_operand:SWI48 0 "register_operand" "=r")
18973         (and:SWI48
18974           (plus:SWI48
18975             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18976             (const_int -1))
18977           (match_dup 1)))
18978    (clobber (reg:CC FLAGS_REG))]
18979    "TARGET_BMI"
18980    "blsr\t{%1, %0|%0, %1}"
18981   [(set_attr "type" "bitmanip")
18982    (set_attr "btver2_decode" "double")
18983    (set_attr "mode" "<MODE>")])
18985 (define_insn "*bmi_blsr_<mode>_cmp"
18986   [(set (reg:CCZ FLAGS_REG)
18987         (compare:CCZ
18988           (and:SWI48
18989             (plus:SWI48
18990               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18991               (const_int -1))
18992             (match_dup 1))
18993           (const_int 0)))
18994    (set (match_operand:SWI48 0 "register_operand" "=r")
18995         (and:SWI48
18996           (plus:SWI48
18997             (match_dup 1)
18998             (const_int -1))
18999           (match_dup 1)))]
19000    "TARGET_BMI"
19001    "blsr\t{%1, %0|%0, %1}"
19002   [(set_attr "type" "bitmanip")
19003    (set_attr "btver2_decode" "double")
19004    (set_attr "mode" "<MODE>")])
19006 (define_insn "*bmi_blsr_<mode>_ccz"
19007   [(set (reg:CCZ FLAGS_REG)
19008         (compare:CCZ
19009           (and:SWI48
19010             (plus:SWI48
19011               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19012               (const_int -1))
19013             (match_dup 1))
19014           (const_int 0)))
19015    (clobber (match_scratch:SWI48 0 "=r"))]
19016    "TARGET_BMI"
19017    "blsr\t{%1, %0|%0, %1}"
19018   [(set_attr "type" "bitmanip")
19019    (set_attr "btver2_decode" "double")
19020    (set_attr "mode" "<MODE>")])
19022 ;; BMI2 instructions.
19023 (define_expand "bmi2_bzhi_<mode>3"
19024   [(parallel
19025     [(set (match_operand:SWI48 0 "register_operand")
19026           (if_then_else:SWI48
19027             (ne:QI (match_operand:QI 2 "register_operand")
19028                    (const_int 0))
19029             (zero_extract:SWI48
19030               (match_operand:SWI48 1 "nonimmediate_operand")
19031               (umin:QI (match_dup 2) (match_dup 3))
19032               (const_int 0))
19033             (const_int 0)))
19034      (clobber (reg:CC FLAGS_REG))])]
19035   "TARGET_BMI2"
19037   operands[2] = gen_lowpart (QImode, operands[2]);
19038   operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
19041 (define_insn "*bmi2_bzhi_<mode>3"
19042   [(set (match_operand:SWI48 0 "register_operand" "=r")
19043         (if_then_else:SWI48
19044           (ne:QI (match_operand:QI 2 "register_operand" "q")
19045                  (const_int 0))
19046           (zero_extract:SWI48
19047             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19048             (umin:QI (match_dup 2)
19049                      (match_operand:QI 3 "const_int_operand"))
19050             (const_int 0))
19051           (const_int 0)))
19052    (clobber (reg:CC FLAGS_REG))]
19053   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
19054   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19055   [(set_attr "type" "bitmanip")
19056    (set_attr "prefix" "vex")
19057    (set_attr "mode" "<MODE>")])
19059 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
19060   [(set (reg:CCZ FLAGS_REG)
19061         (compare:CCZ
19062           (if_then_else:SWI48
19063             (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
19064             (zero_extract:SWI48
19065               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19066               (umin:QI (match_dup 2)
19067                        (match_operand:QI 3 "const_int_operand"))
19068               (const_int 0))
19069             (const_int 0))
19070         (const_int 0)))
19071    (clobber (match_scratch:SWI48 0 "=r"))]
19072   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
19073   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19074   [(set_attr "type" "bitmanip")
19075    (set_attr "prefix" "vex")
19076    (set_attr "mode" "<MODE>")])
19078 (define_insn "*bmi2_bzhi_<mode>3_2"
19079   [(set (match_operand:SWI48 0 "register_operand" "=r")
19080         (and:SWI48
19081           (plus:SWI48
19082             (ashift:SWI48 (const_int 1)
19083                           (match_operand:QI 2 "register_operand" "r"))
19084             (const_int -1))
19085           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19086    (clobber (reg:CC FLAGS_REG))]
19087   "TARGET_BMI2"
19088   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19089   [(set_attr "type" "bitmanip")
19090    (set_attr "prefix" "vex")
19091    (set_attr "mode" "<MODE>")])
19093 (define_insn "*bmi2_bzhi_<mode>3_3"
19094   [(set (match_operand:SWI48 0 "register_operand" "=r")
19095         (and:SWI48
19096           (not:SWI48
19097             (ashift:SWI48 (const_int -1)
19098                           (match_operand:QI 2 "register_operand" "r")))
19099           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19100    (clobber (reg:CC FLAGS_REG))]
19101   "TARGET_BMI2"
19102   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19103   [(set_attr "type" "bitmanip")
19104    (set_attr "prefix" "vex")
19105    (set_attr "mode" "<MODE>")])
19107 (define_insn "*bmi2_bzhi_zero_extendsidi_4"
19108   [(set (match_operand:DI 0 "register_operand" "=r")
19109         (zero_extend:DI
19110           (and:SI
19111             (plus:SI
19112               (ashift:SI (const_int 1)
19113                          (match_operand:QI 2 "register_operand" "r"))
19114               (const_int -1))
19115             (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19116    (clobber (reg:CC FLAGS_REG))]
19117   "TARGET_64BIT && TARGET_BMI2"
19118   "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
19119   [(set_attr "type" "bitmanip")
19120    (set_attr "prefix" "vex")
19121    (set_attr "mode" "DI")])
19123 (define_insn "*bmi2_bzhi_zero_extendsidi_5"
19124   [(set (match_operand:DI 0 "register_operand" "=r")
19125         (and:DI
19126           (zero_extend:DI
19127             (plus:SI
19128               (ashift:SI (const_int 1)
19129                          (match_operand:QI 2 "register_operand" "r"))
19130               (const_int -1)))
19131           (match_operand:DI 1 "nonimmediate_operand" "rm")))
19132    (clobber (reg:CC FLAGS_REG))]
19133   "TARGET_64BIT && TARGET_BMI2"
19134   "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
19135   [(set_attr "type" "bitmanip")
19136    (set_attr "prefix" "vex")
19137    (set_attr "mode" "DI")])
19139 (define_insn "bmi2_pdep_<mode>3"
19140   [(set (match_operand:SWI48 0 "register_operand" "=r")
19141         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
19142                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
19143                        UNSPEC_PDEP))]
19144   "TARGET_BMI2"
19145   "pdep\t{%2, %1, %0|%0, %1, %2}"
19146   [(set_attr "type" "bitmanip")
19147    (set_attr "prefix" "vex")
19148    (set_attr "mode" "<MODE>")])
19150 (define_insn "bmi2_pext_<mode>3"
19151   [(set (match_operand:SWI48 0 "register_operand" "=r")
19152         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
19153                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
19154                        UNSPEC_PEXT))]
19155   "TARGET_BMI2"
19156   "pext\t{%2, %1, %0|%0, %1, %2}"
19157   [(set_attr "type" "bitmanip")
19158    (set_attr "prefix" "vex")
19159    (set_attr "mode" "<MODE>")])
19161 ;; TBM instructions.
19162 (define_insn "@tbm_bextri_<mode>"
19163   [(set (match_operand:SWI48 0 "register_operand" "=r")
19164         (zero_extract:SWI48
19165           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19166           (match_operand:QI 2 "const_0_to_255_operand")
19167           (match_operand:QI 3 "const_0_to_255_operand")))
19168    (clobber (reg:CC FLAGS_REG))]
19169    "TARGET_TBM"
19171   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
19172   return "bextr\t{%2, %1, %0|%0, %1, %2}";
19174   [(set_attr "type" "bitmanip")
19175    (set_attr "mode" "<MODE>")])
19177 (define_insn "*tbm_blcfill_<mode>"
19178   [(set (match_operand:SWI48 0 "register_operand" "=r")
19179         (and:SWI48
19180           (plus:SWI48
19181             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19182             (const_int 1))
19183           (match_dup 1)))
19184    (clobber (reg:CC FLAGS_REG))]
19185    "TARGET_TBM"
19186    "blcfill\t{%1, %0|%0, %1}"
19187   [(set_attr "type" "bitmanip")
19188    (set_attr "mode" "<MODE>")])
19190 (define_insn "*tbm_blci_<mode>"
19191   [(set (match_operand:SWI48 0 "register_operand" "=r")
19192         (ior:SWI48
19193           (not:SWI48
19194             (plus:SWI48
19195               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19196               (const_int 1)))
19197           (match_dup 1)))
19198    (clobber (reg:CC FLAGS_REG))]
19199    "TARGET_TBM"
19200    "blci\t{%1, %0|%0, %1}"
19201   [(set_attr "type" "bitmanip")
19202    (set_attr "mode" "<MODE>")])
19204 (define_insn "*tbm_blcic_<mode>"
19205   [(set (match_operand:SWI48 0 "register_operand" "=r")
19206         (and:SWI48
19207           (plus:SWI48
19208             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19209             (const_int 1))
19210           (not:SWI48
19211             (match_dup 1))))
19212    (clobber (reg:CC FLAGS_REG))]
19213    "TARGET_TBM"
19214    "blcic\t{%1, %0|%0, %1}"
19215   [(set_attr "type" "bitmanip")
19216    (set_attr "mode" "<MODE>")])
19218 (define_insn "*tbm_blcmsk_<mode>"
19219   [(set (match_operand:SWI48 0 "register_operand" "=r")
19220         (xor:SWI48
19221           (plus:SWI48
19222             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19223             (const_int 1))
19224           (match_dup 1)))
19225    (clobber (reg:CC FLAGS_REG))]
19226    "TARGET_TBM"
19227    "blcmsk\t{%1, %0|%0, %1}"
19228   [(set_attr "type" "bitmanip")
19229    (set_attr "mode" "<MODE>")])
19231 (define_insn "*tbm_blcs_<mode>"
19232   [(set (match_operand:SWI48 0 "register_operand" "=r")
19233         (ior:SWI48
19234           (plus:SWI48
19235             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19236             (const_int 1))
19237           (match_dup 1)))
19238    (clobber (reg:CC FLAGS_REG))]
19239    "TARGET_TBM"
19240    "blcs\t{%1, %0|%0, %1}"
19241   [(set_attr "type" "bitmanip")
19242    (set_attr "mode" "<MODE>")])
19244 (define_insn "*tbm_blsfill_<mode>"
19245   [(set (match_operand:SWI48 0 "register_operand" "=r")
19246         (ior:SWI48
19247           (plus:SWI48
19248             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19249             (const_int -1))
19250           (match_dup 1)))
19251    (clobber (reg:CC FLAGS_REG))]
19252    "TARGET_TBM"
19253    "blsfill\t{%1, %0|%0, %1}"
19254   [(set_attr "type" "bitmanip")
19255    (set_attr "mode" "<MODE>")])
19257 (define_insn "*tbm_blsic_<mode>"
19258   [(set (match_operand:SWI48 0 "register_operand" "=r")
19259         (ior:SWI48
19260           (plus:SWI48
19261             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19262             (const_int -1))
19263           (not:SWI48
19264             (match_dup 1))))
19265    (clobber (reg:CC FLAGS_REG))]
19266    "TARGET_TBM"
19267    "blsic\t{%1, %0|%0, %1}"
19268   [(set_attr "type" "bitmanip")
19269    (set_attr "mode" "<MODE>")])
19271 (define_insn "*tbm_t1mskc_<mode>"
19272   [(set (match_operand:SWI48 0 "register_operand" "=r")
19273         (ior:SWI48
19274           (plus:SWI48
19275             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19276             (const_int 1))
19277           (not:SWI48
19278             (match_dup 1))))
19279    (clobber (reg:CC FLAGS_REG))]
19280    "TARGET_TBM"
19281    "t1mskc\t{%1, %0|%0, %1}"
19282   [(set_attr "type" "bitmanip")
19283    (set_attr "mode" "<MODE>")])
19285 (define_insn "*tbm_tzmsk_<mode>"
19286   [(set (match_operand:SWI48 0 "register_operand" "=r")
19287         (and:SWI48
19288           (plus:SWI48
19289             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19290             (const_int -1))
19291           (not:SWI48
19292             (match_dup 1))))
19293    (clobber (reg:CC FLAGS_REG))]
19294    "TARGET_TBM"
19295    "tzmsk\t{%1, %0|%0, %1}"
19296   [(set_attr "type" "bitmanip")
19297    (set_attr "mode" "<MODE>")])
19299 (define_insn_and_split "popcount<mode>2"
19300   [(set (match_operand:SWI48 0 "register_operand" "=r")
19301         (popcount:SWI48
19302           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19303    (clobber (reg:CC FLAGS_REG))]
19304   "TARGET_POPCNT"
19306 #if TARGET_MACHO
19307   return "popcnt\t{%1, %0|%0, %1}";
19308 #else
19309   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19310 #endif
19312   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19313    && optimize_function_for_speed_p (cfun)
19314    && !reg_mentioned_p (operands[0], operands[1])"
19315   [(parallel
19316     [(set (match_dup 0)
19317           (popcount:SWI48 (match_dup 1)))
19318      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19319      (clobber (reg:CC FLAGS_REG))])]
19320   "ix86_expand_clear (operands[0]);"
19321   [(set_attr "prefix_rep" "1")
19322    (set_attr "type" "bitmanip")
19323    (set_attr "mode" "<MODE>")])
19325 ; False dependency happens when destination is only updated by tzcnt,
19326 ; lzcnt or popcnt.  There is no false dependency when destination is
19327 ; also used in source.
19328 (define_insn "*popcount<mode>2_falsedep"
19329   [(set (match_operand:SWI48 0 "register_operand" "=r")
19330         (popcount:SWI48
19331           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19332    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
19333            UNSPEC_INSN_FALSE_DEP)
19334    (clobber (reg:CC FLAGS_REG))]
19335   "TARGET_POPCNT"
19337 #if TARGET_MACHO
19338   return "popcnt\t{%1, %0|%0, %1}";
19339 #else
19340   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19341 #endif
19343   [(set_attr "prefix_rep" "1")
19344    (set_attr "type" "bitmanip")
19345    (set_attr "mode" "<MODE>")])
19347 (define_insn_and_split "*popcountsi2_zext"
19348   [(set (match_operand:DI 0 "register_operand" "=r")
19349         (and:DI
19350           (subreg:DI
19351             (popcount:SI
19352               (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19353           (const_int 63)))
19354    (clobber (reg:CC FLAGS_REG))]
19355   "TARGET_POPCNT && TARGET_64BIT"
19357 #if TARGET_MACHO
19358   return "popcnt\t{%1, %k0|%k0, %1}";
19359 #else
19360   return "popcnt{l}\t{%1, %k0|%k0, %1}";
19361 #endif
19363   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19364    && optimize_function_for_speed_p (cfun)
19365    && !reg_mentioned_p (operands[0], operands[1])"
19366   [(parallel
19367     [(set (match_dup 0)
19368           (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63)))
19369      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19370      (clobber (reg:CC FLAGS_REG))])]
19371   "ix86_expand_clear (operands[0]);"
19372   [(set_attr "prefix_rep" "1")
19373    (set_attr "type" "bitmanip")
19374    (set_attr "mode" "SI")])
19376 ; False dependency happens when destination is only updated by tzcnt,
19377 ; lzcnt or popcnt.  There is no false dependency when destination is
19378 ; also used in source.
19379 (define_insn "*popcountsi2_zext_falsedep"
19380   [(set (match_operand:DI 0 "register_operand" "=r")
19381         (and:DI
19382           (subreg:DI
19383             (popcount:SI
19384               (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19385           (const_int 63)))
19386    (unspec [(match_operand:DI 2 "register_operand" "0")]
19387            UNSPEC_INSN_FALSE_DEP)
19388    (clobber (reg:CC FLAGS_REG))]
19389   "TARGET_POPCNT && TARGET_64BIT"
19391 #if TARGET_MACHO
19392   return "popcnt\t{%1, %k0|%k0, %1}";
19393 #else
19394   return "popcnt{l}\t{%1, %k0|%k0, %1}";
19395 #endif
19397   [(set_attr "prefix_rep" "1")
19398    (set_attr "type" "bitmanip")
19399    (set_attr "mode" "SI")])
19401 (define_insn_and_split "*popcountsi2_zext_2"
19402   [(set (match_operand:DI 0 "register_operand" "=r")
19403         (zero_extend:DI
19404           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19405    (clobber (reg:CC FLAGS_REG))]
19406   "TARGET_POPCNT && TARGET_64BIT"
19408 #if TARGET_MACHO
19409   return "popcnt\t{%1, %k0|%k0, %1}";
19410 #else
19411   return "popcnt{l}\t{%1, %k0|%k0, %1}";
19412 #endif
19414   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19415    && optimize_function_for_speed_p (cfun)
19416    && !reg_mentioned_p (operands[0], operands[1])"
19417   [(parallel
19418     [(set (match_dup 0)
19419           (zero_extend:DI (popcount:SI (match_dup 1))))
19420      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19421      (clobber (reg:CC FLAGS_REG))])]
19422   "ix86_expand_clear (operands[0]);"
19423   [(set_attr "prefix_rep" "1")
19424    (set_attr "type" "bitmanip")
19425    (set_attr "mode" "SI")])
19427 ; False dependency happens when destination is only updated by tzcnt,
19428 ; lzcnt or popcnt.  There is no false dependency when destination is
19429 ; also used in source.
19430 (define_insn "*popcountsi2_zext_2_falsedep"
19431   [(set (match_operand:DI 0 "register_operand" "=r")
19432         (zero_extend:DI
19433           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19434    (unspec [(match_operand:DI 2 "register_operand" "0")]
19435            UNSPEC_INSN_FALSE_DEP)
19436    (clobber (reg:CC FLAGS_REG))]
19437   "TARGET_POPCNT && TARGET_64BIT"
19439 #if TARGET_MACHO
19440   return "popcnt\t{%1, %k0|%k0, %1}";
19441 #else
19442   return "popcnt{l}\t{%1, %k0|%k0, %1}";
19443 #endif
19445   [(set_attr "prefix_rep" "1")
19446    (set_attr "type" "bitmanip")
19447    (set_attr "mode" "SI")])
19449 (define_insn_and_split "*popcounthi2_1"
19450   [(set (match_operand:SI 0 "register_operand")
19451         (popcount:SI
19452           (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
19453    (clobber (reg:CC FLAGS_REG))]
19454   "TARGET_POPCNT
19455    && ix86_pre_reload_split ()"
19456   "#"
19457   "&& 1"
19458   [(const_int 0)]
19460   rtx tmp = gen_reg_rtx (HImode);
19462   emit_insn (gen_popcounthi2 (tmp, operands[1]));
19463   emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19464   DONE;
19467 (define_insn_and_split "*popcounthi2_2"
19468   [(set (match_operand:SI 0 "register_operand")
19469         (zero_extend:SI
19470           (popcount:HI (match_operand:HI 1 "nonimmediate_operand"))))
19471    (clobber (reg:CC FLAGS_REG))]
19472   "TARGET_POPCNT
19473    && ix86_pre_reload_split ()"
19474   "#"
19475   "&& 1"
19476   [(const_int 0)]
19478   rtx tmp = gen_reg_rtx (HImode);
19480   emit_insn (gen_popcounthi2 (tmp, operands[1]));
19481   emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19482   DONE;
19485 (define_insn "popcounthi2"
19486   [(set (match_operand:HI 0 "register_operand" "=r")
19487         (popcount:HI
19488           (match_operand:HI 1 "nonimmediate_operand" "rm")))
19489    (clobber (reg:CC FLAGS_REG))]
19490   "TARGET_POPCNT"
19492 #if TARGET_MACHO
19493   return "popcnt\t{%1, %0|%0, %1}";
19494 #else
19495   return "popcnt{w}\t{%1, %0|%0, %1}";
19496 #endif
19498   [(set_attr "prefix_rep" "1")
19499    (set_attr "type" "bitmanip")
19500    (set_attr "mode" "HI")])
19502 (define_expand "bswapdi2"
19503   [(set (match_operand:DI 0 "register_operand")
19504         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
19505   "TARGET_64BIT"
19507   if (!TARGET_MOVBE)
19508     operands[1] = force_reg (DImode, operands[1]);
19511 (define_expand "bswapsi2"
19512   [(set (match_operand:SI 0 "register_operand")
19513         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
19514   ""
19516   if (TARGET_MOVBE)
19517     ;
19518   else if (TARGET_BSWAP)
19519     operands[1] = force_reg (SImode, operands[1]);
19520   else
19521     {
19522       rtx x = operands[0];
19524       emit_move_insn (x, operands[1]);
19525       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19526       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
19527       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19528       DONE;
19529     }
19532 (define_insn "*bswap<mode>2_movbe"
19533   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
19534         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
19535   "TARGET_MOVBE
19536    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19537   "@
19538     bswap\t%0
19539     movbe{<imodesuffix>}\t{%1, %0|%0, %1}
19540     movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
19541   [(set_attr "type" "bitmanip,imov,imov")
19542    (set_attr "modrm" "0,1,1")
19543    (set_attr "prefix_0f" "*,1,1")
19544    (set_attr "prefix_extra" "*,1,1")
19545    (set_attr "mode" "<MODE>")])
19547 (define_insn "*bswap<mode>2"
19548   [(set (match_operand:SWI48 0 "register_operand" "=r")
19549         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
19550   "TARGET_BSWAP"
19551   "bswap\t%0"
19552   [(set_attr "type" "bitmanip")
19553    (set_attr "modrm" "0")
19554    (set_attr "mode" "<MODE>")])
19556 (define_expand "bswaphi2"
19557   [(set (match_operand:HI 0 "register_operand")
19558         (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
19559   "TARGET_MOVBE")
19561 (define_insn "*bswaphi2_movbe"
19562   [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
19563         (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
19564   "TARGET_MOVBE
19565    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19566   "@
19567     xchg{b}\t{%h0, %b0|%b0, %h0}
19568     movbe{w}\t{%1, %0|%0, %1}
19569     movbe{w}\t{%1, %0|%0, %1}"
19570   [(set_attr "type" "imov")
19571    (set_attr "modrm" "*,1,1")
19572    (set_attr "prefix_0f" "*,1,1")
19573    (set_attr "prefix_extra" "*,1,1")
19574    (set_attr "pent_pair" "np,*,*")
19575    (set_attr "athlon_decode" "vector,*,*")
19576    (set_attr "amdfam10_decode" "double,*,*")
19577    (set_attr "bdver1_decode" "double,*,*")
19578    (set_attr "mode" "QI,HI,HI")])
19580 (define_peephole2
19581   [(set (match_operand:HI 0 "general_reg_operand")
19582         (bswap:HI (match_dup 0)))]
19583   "TARGET_MOVBE
19584    && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
19585    && peep2_regno_dead_p (0, FLAGS_REG)"
19586   [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
19587               (clobber (reg:CC FLAGS_REG))])])
19589 (define_insn "bswaphi_lowpart"
19590   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
19591         (bswap:HI (match_dup 0)))
19592    (clobber (reg:CC FLAGS_REG))]
19593   ""
19594   "@
19595     xchg{b}\t{%h0, %b0|%b0, %h0}
19596     rol{w}\t{$8, %0|%0, 8}"
19597   [(set (attr "preferred_for_size")
19598      (cond [(eq_attr "alternative" "0")
19599               (symbol_ref "true")]
19600            (symbol_ref "false")))
19601    (set (attr "preferred_for_speed")
19602      (cond [(eq_attr "alternative" "0")
19603               (symbol_ref "TARGET_USE_XCHGB")]
19604            (symbol_ref "!TARGET_USE_XCHGB")))
19605    (set_attr "length" "2,4")
19606    (set_attr "mode" "QI,HI")])
19608 (define_expand "paritydi2"
19609   [(set (match_operand:DI 0 "register_operand")
19610         (parity:DI (match_operand:DI 1 "register_operand")))]
19611   "! TARGET_POPCNT"
19613   rtx scratch = gen_reg_rtx (QImode);
19614   rtx hipart1 = gen_reg_rtx (SImode);
19615   rtx lopart1 = gen_reg_rtx (SImode);
19616   rtx xor1 = gen_reg_rtx (SImode);
19617   rtx shift2 = gen_reg_rtx (SImode);
19618   rtx hipart2 = gen_reg_rtx (HImode);
19619   rtx lopart2 = gen_reg_rtx (HImode);
19620   rtx xor2 = gen_reg_rtx (HImode);
19622   if (TARGET_64BIT)
19623     {
19624       rtx shift1 = gen_reg_rtx (DImode);
19625       emit_insn (gen_lshrdi3 (shift1, operands[1], GEN_INT (32)));
19626       emit_move_insn (hipart1, gen_lowpart (SImode, shift1));
19627     }
19628   else
19629     emit_move_insn (hipart1, gen_highpart (SImode, operands[1]));
19631   emit_move_insn (lopart1, gen_lowpart (SImode, operands[1]));
19632   emit_insn (gen_xorsi3 (xor1, hipart1, lopart1));
19634   emit_insn (gen_lshrsi3 (shift2, xor1, GEN_INT (16)));
19635   emit_move_insn (hipart2, gen_lowpart (HImode, shift2));
19636   emit_move_insn (lopart2, gen_lowpart (HImode, xor1));
19637   emit_insn (gen_xorhi3 (xor2, hipart2, lopart2));
19639   emit_insn (gen_parityhi2_cmp (xor2));
19641   ix86_expand_setcc (scratch, ORDERED,
19642                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19644   if (TARGET_64BIT)
19645     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
19646   else
19647     {
19648       rtx tmp = gen_reg_rtx (SImode);
19650       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
19651       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
19652     }
19653   DONE;
19656 (define_expand "paritysi2"
19657   [(set (match_operand:SI 0 "register_operand")
19658         (parity:SI (match_operand:SI 1 "register_operand")))]
19659   "! TARGET_POPCNT"
19661   rtx scratch = gen_reg_rtx (QImode);
19662   rtx shift = gen_reg_rtx (SImode);
19663   rtx hipart = gen_reg_rtx (HImode);
19664   rtx lopart = gen_reg_rtx (HImode);
19665   rtx tmp = gen_reg_rtx (HImode);
19667   emit_insn (gen_lshrsi3 (shift, operands[1], GEN_INT (16)));
19668   emit_move_insn (hipart, gen_lowpart (HImode, shift));
19669   emit_move_insn (lopart, gen_lowpart (HImode, operands[1]));
19670   emit_insn (gen_xorhi3 (tmp, hipart, lopart));
19672   emit_insn (gen_parityhi2_cmp (tmp));
19674   ix86_expand_setcc (scratch, ORDERED,
19675                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19677   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
19678   DONE;
19681 (define_expand "parityhi2"
19682   [(set (match_operand:HI 0 "register_operand")
19683         (parity:HI (match_operand:HI 1 "register_operand")))]
19684   "! TARGET_POPCNT"
19686   rtx scratch = gen_reg_rtx (QImode);
19688   emit_insn (gen_parityhi2_cmp (operands[1]));
19690   ix86_expand_setcc (scratch, ORDERED,
19691                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19693   emit_insn (gen_zero_extendqihi2 (operands[0], scratch));
19694   DONE;
19697 (define_expand "parityqi2"
19698   [(set (match_operand:QI 0 "register_operand")
19699         (parity:QI (match_operand:QI 1 "register_operand")))]
19700   "! TARGET_POPCNT"
19702   emit_insn (gen_parityqi2_cmp (operands[1]));
19704   ix86_expand_setcc (operands[0], ORDERED,
19705                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19706   DONE;
19709 (define_insn "parityhi2_cmp"
19710   [(set (reg:CC FLAGS_REG)
19711         (unspec:CC [(match_operand:HI 0 "register_operand" "+Q")]
19712                    UNSPEC_PARITY))
19713    (clobber (match_dup 0))]
19714   ""
19715   "xor{b}\t{%h0, %b0|%b0, %h0}"
19716   [(set_attr "length" "2")
19717    (set_attr "mode" "QI")])
19719 (define_insn "parityqi2_cmp"
19720   [(set (reg:CC FLAGS_REG)
19721         (unspec:CC [(match_operand:QI 0 "register_operand" "q")]
19722                    UNSPEC_PARITY))]
19723   ""
19724   "test{b}\t%0, %0"
19725   [(set_attr "mode" "QI")])
19727 ;; Replace zero_extend:HI followed by parityhi2_cmp with parityqi2_cmp
19728 (define_peephole2
19729   [(set (match_operand:HI 0 "register_operand")
19730         (zero_extend:HI (match_operand:QI 1 "general_reg_operand")))
19731    (parallel [(set (reg:CC FLAGS_REG)
19732                    (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19733               (clobber (match_dup 0))])]
19734   ""
19735   [(set (reg:CC FLAGS_REG)
19736         (unspec:CC [(match_dup 1)] UNSPEC_PARITY))])
19738 ;; Eliminate QImode popcount&1 using parity flag
19739 (define_peephole2
19740   [(set (match_operand:SI 0 "register_operand")
19741         (zero_extend:SI (match_operand:QI 1 "general_reg_operand")))
19742    (parallel [(set (match_operand:SI 2 "register_operand")
19743                    (popcount:SI (match_dup 0)))
19744               (clobber (reg:CC FLAGS_REG))])
19745    (set (reg:CCZ FLAGS_REG)
19746         (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19747                              (const_int 1))
19748                      (const_int 0)))
19749    (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19750                             [(reg:CCZ FLAGS_REG)
19751                              (const_int 0)])
19752                            (label_ref (match_operand 5))
19753                            (pc)))]
19754   "REGNO (operands[2]) == REGNO (operands[3])
19755    && peep2_reg_dead_p (3, operands[0])
19756    && peep2_reg_dead_p (3, operands[2])
19757    && peep2_regno_dead_p (4, FLAGS_REG)"
19758   [(set (reg:CC FLAGS_REG)
19759         (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
19760    (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19761                                             (const_int 0)])
19762                            (label_ref (match_dup 5))
19763                            (pc)))]
19765   operands[4] = shallow_copy_rtx (operands[4]);
19766   PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19769 ;; Eliminate HImode popcount&1 using parity flag
19770 (define_peephole2
19771   [(match_scratch:HI 0 "Q")
19772    (parallel [(set (match_operand:HI 1 "register_operand")
19773                    (popcount:HI
19774                     (match_operand:HI 2 "nonimmediate_operand")))
19775               (clobber (reg:CC FLAGS_REG))])
19776    (set (match_operand 3 "register_operand")
19777         (zero_extend (match_dup 1)))
19778    (set (reg:CCZ FLAGS_REG)
19779         (compare:CCZ (and:QI (match_operand:QI 4 "register_operand")
19780                              (const_int 1))
19781                      (const_int 0)))
19782    (set (pc) (if_then_else (match_operator 5 "bt_comparison_operator"
19783                             [(reg:CCZ FLAGS_REG)
19784                              (const_int 0)])
19785                            (label_ref (match_operand 6))
19786                            (pc)))]
19787   "REGNO (operands[3]) == REGNO (operands[4])
19788    && peep2_reg_dead_p (3, operands[1])
19789    && peep2_reg_dead_p (3, operands[3])
19790    && peep2_regno_dead_p (4, FLAGS_REG)"
19791   [(set (match_dup 0) (match_dup 2))
19792    (parallel [(set (reg:CC FLAGS_REG)
19793                    (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19794               (clobber (match_dup 0))])
19795    (set (pc) (if_then_else (match_op_dup 5 [(reg:CC FLAGS_REG)
19796                                             (const_int 0)])
19797                            (label_ref (match_dup 6))
19798                            (pc)))]
19800   operands[5] = shallow_copy_rtx (operands[5]);
19801   PUT_CODE (operands[5], GET_CODE (operands[5]) == EQ ? UNORDERED : ORDERED);
19804 ;; Eliminate HImode popcount&1 using parity flag (variant 2)
19805 (define_peephole2
19806   [(match_scratch:HI 0 "Q")
19807    (parallel [(set (match_operand:HI 1 "register_operand")
19808                    (popcount:HI
19809                     (match_operand:HI 2 "nonimmediate_operand")))
19810               (clobber (reg:CC FLAGS_REG))])
19811    (set (reg:CCZ FLAGS_REG)
19812         (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19813                              (const_int 1))
19814                      (const_int 0)))
19815    (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19816                             [(reg:CCZ FLAGS_REG)
19817                              (const_int 0)])
19818                            (label_ref (match_operand 5))
19819                            (pc)))]
19820   "REGNO (operands[1]) == REGNO (operands[3])
19821    && peep2_reg_dead_p (2, operands[1])
19822    && peep2_reg_dead_p (2, operands[3])
19823    && peep2_regno_dead_p (3, FLAGS_REG)"
19824   [(set (match_dup 0) (match_dup 2))
19825    (parallel [(set (reg:CC FLAGS_REG)
19826                    (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19827               (clobber (match_dup 0))])
19828    (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19829                                             (const_int 0)])
19830                            (label_ref (match_dup 5))
19831                            (pc)))]
19833   operands[4] = shallow_copy_rtx (operands[4]);
19834   PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19838 ;; Thread-local storage patterns for ELF.
19840 ;; Note that these code sequences must appear exactly as shown
19841 ;; in order to allow linker relaxation.
19843 (define_insn "*tls_global_dynamic_32_gnu"
19844   [(set (match_operand:SI 0 "register_operand" "=a")
19845         (unspec:SI
19846          [(match_operand:SI 1 "register_operand" "Yb")
19847           (match_operand 2 "tls_symbolic_operand")
19848           (match_operand 3 "constant_call_address_operand" "Bz")
19849           (reg:SI SP_REG)]
19850          UNSPEC_TLS_GD))
19851    (clobber (match_scratch:SI 4 "=d"))
19852    (clobber (match_scratch:SI 5 "=c"))
19853    (clobber (reg:CC FLAGS_REG))]
19854   "!TARGET_64BIT && TARGET_GNU_TLS"
19856   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19857     output_asm_insn
19858       ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
19859   else
19860     output_asm_insn
19861       ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
19862   if (TARGET_SUN_TLS)
19863 #ifdef HAVE_AS_IX86_TLSGDPLT
19864     return "call\t%a2@tlsgdplt";
19865 #else
19866     return "call\t%p3@plt";
19867 #endif
19868   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19869     return "call\t%P3";
19870   return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
19872   [(set_attr "type" "multi")
19873    (set_attr "length" "12")])
19875 (define_expand "tls_global_dynamic_32"
19876   [(parallel
19877     [(set (match_operand:SI 0 "register_operand")
19878           (unspec:SI [(match_operand:SI 2 "register_operand")
19879                       (match_operand 1 "tls_symbolic_operand")
19880                       (match_operand 3 "constant_call_address_operand")
19881                       (reg:SI SP_REG)]
19882                      UNSPEC_TLS_GD))
19883      (clobber (scratch:SI))
19884      (clobber (scratch:SI))
19885      (clobber (reg:CC FLAGS_REG))])]
19886   ""
19887   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19889 (define_insn "*tls_global_dynamic_64_<mode>"
19890   [(set (match_operand:P 0 "register_operand" "=a")
19891         (call:P
19892          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
19893          (match_operand 3)))
19894    (unspec:P [(match_operand 1 "tls_symbolic_operand")
19895               (reg:P SP_REG)]
19896              UNSPEC_TLS_GD)]
19897   "TARGET_64BIT"
19899   if (!TARGET_X32)
19900     /* The .loc directive has effect for 'the immediately following assembly
19901        instruction'.  So for a sequence:
19902          .loc f l
19903          .byte x
19904          insn1
19905        the 'immediately following assembly instruction' is insn1.
19906        We want to emit an insn prefix here, but if we use .byte (as shown in
19907        'ELF Handling For Thread-Local Storage'), a preceding .loc will point
19908        inside the insn sequence, rather than to the start.  After relaxation
19909        of the sequence by the linker, the .loc might point inside an insn.
19910        Use data16 prefix instead, which doesn't have this problem.  */
19911     fputs ("\tdata16", asm_out_file);
19912   output_asm_insn
19913     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
19914   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19915     fputs (ASM_SHORT "0x6666\n", asm_out_file);
19916   else
19917     fputs (ASM_BYTE "0x66\n", asm_out_file);
19918   fputs ("\trex64\n", asm_out_file);
19919   if (TARGET_SUN_TLS)
19920     return "call\t%p2@plt";
19921   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19922     return "call\t%P2";
19923   return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
19925   [(set_attr "type" "multi")
19926    (set (attr "length")
19927         (symbol_ref "TARGET_X32 ? 15 : 16"))])
19929 (define_insn "*tls_global_dynamic_64_largepic"
19930   [(set (match_operand:DI 0 "register_operand" "=a")
19931         (call:DI
19932          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
19933                           (match_operand:DI 3 "immediate_operand" "i")))
19934          (match_operand 4)))
19935    (unspec:DI [(match_operand 1 "tls_symbolic_operand")
19936                (reg:DI SP_REG)]
19937               UNSPEC_TLS_GD)]
19938   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
19939    && GET_CODE (operands[3]) == CONST
19940    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
19941    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
19943   output_asm_insn
19944     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
19945   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
19946   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
19947   return "call\t{*%%rax|rax}";
19949   [(set_attr "type" "multi")
19950    (set_attr "length" "22")])
19952 (define_expand "@tls_global_dynamic_64_<mode>"
19953   [(parallel
19954     [(set (match_operand:P 0 "register_operand")
19955           (call:P
19956            (mem:QI (match_operand 2))
19957            (const_int 0)))
19958      (unspec:P [(match_operand 1 "tls_symbolic_operand")
19959                 (reg:P SP_REG)]
19960                UNSPEC_TLS_GD)])]
19961   "TARGET_64BIT"
19962   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19964 (define_insn "*tls_local_dynamic_base_32_gnu"
19965   [(set (match_operand:SI 0 "register_operand" "=a")
19966         (unspec:SI
19967          [(match_operand:SI 1 "register_operand" "Yb")
19968           (match_operand 2 "constant_call_address_operand" "Bz")
19969           (reg:SI SP_REG)]
19970          UNSPEC_TLS_LD_BASE))
19971    (clobber (match_scratch:SI 3 "=d"))
19972    (clobber (match_scratch:SI 4 "=c"))
19973    (clobber (reg:CC FLAGS_REG))]
19974   "!TARGET_64BIT && TARGET_GNU_TLS"
19976   output_asm_insn
19977     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
19978   if (TARGET_SUN_TLS)
19979     {
19980       if (HAVE_AS_IX86_TLSLDMPLT)
19981         return "call\t%&@tlsldmplt";
19982       else
19983         return "call\t%p2@plt";
19984     }
19985   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19986     return "call\t%P2";
19987   return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
19989   [(set_attr "type" "multi")
19990    (set_attr "length" "11")])
19992 (define_expand "tls_local_dynamic_base_32"
19993   [(parallel
19994      [(set (match_operand:SI 0 "register_operand")
19995            (unspec:SI
19996             [(match_operand:SI 1 "register_operand")
19997              (match_operand 2 "constant_call_address_operand")
19998              (reg:SI SP_REG)]
19999             UNSPEC_TLS_LD_BASE))
20000       (clobber (scratch:SI))
20001       (clobber (scratch:SI))
20002       (clobber (reg:CC FLAGS_REG))])]
20003   ""
20004   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
20006 (define_insn "*tls_local_dynamic_base_64_<mode>"
20007   [(set (match_operand:P 0 "register_operand" "=a")
20008         (call:P
20009          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
20010          (match_operand 2)))
20011    (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
20012   "TARGET_64BIT"
20014   output_asm_insn
20015     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
20016   if (TARGET_SUN_TLS)
20017     return "call\t%p1@plt";
20018   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
20019     return "call\t%P1";
20020   return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
20022   [(set_attr "type" "multi")
20023    (set_attr "length" "12")])
20025 (define_insn "*tls_local_dynamic_base_64_largepic"
20026   [(set (match_operand:DI 0 "register_operand" "=a")
20027         (call:DI
20028          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
20029                           (match_operand:DI 2 "immediate_operand" "i")))
20030          (match_operand 3)))
20031    (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
20032   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
20033    && GET_CODE (operands[2]) == CONST
20034    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
20035    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
20037   output_asm_insn
20038     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
20039   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
20040   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
20041   return "call\t{*%%rax|rax}";
20043   [(set_attr "type" "multi")
20044    (set_attr "length" "22")])
20046 (define_expand "@tls_local_dynamic_base_64_<mode>"
20047   [(parallel
20048      [(set (match_operand:P 0 "register_operand")
20049            (call:P
20050             (mem:QI (match_operand 1))
20051             (const_int 0)))
20052       (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
20053   "TARGET_64BIT"
20054   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
20056 ;; Local dynamic of a single variable is a lose.  Show combine how
20057 ;; to convert that back to global dynamic.
20059 (define_insn_and_split "*tls_local_dynamic_32_once"
20060   [(set (match_operand:SI 0 "register_operand" "=a")
20061         (plus:SI
20062          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
20063                      (match_operand 2 "constant_call_address_operand" "Bz")
20064                      (reg:SI SP_REG)]
20065                     UNSPEC_TLS_LD_BASE)
20066          (const:SI (unspec:SI
20067                     [(match_operand 3 "tls_symbolic_operand")]
20068                     UNSPEC_DTPOFF))))
20069    (clobber (match_scratch:SI 4 "=d"))
20070    (clobber (match_scratch:SI 5 "=c"))
20071    (clobber (reg:CC FLAGS_REG))]
20072   ""
20073   "#"
20074   ""
20075   [(parallel
20076      [(set (match_dup 0)
20077            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
20078                        (reg:SI SP_REG)]
20079                       UNSPEC_TLS_GD))
20080       (clobber (match_dup 4))
20081       (clobber (match_dup 5))
20082       (clobber (reg:CC FLAGS_REG))])])
20084 ;; Load and add the thread base pointer from %<tp_seg>:0.
20085 (define_expand "get_thread_pointer<mode>"
20086   [(set (match_operand:PTR 0 "register_operand")
20087         (unspec:PTR [(const_int 0)] UNSPEC_TP))]
20088   ""
20090   /* targetm is not visible in the scope of the condition.  */
20091   if (!targetm.have_tls)
20092     error ("%<__builtin_thread_pointer%> is not supported on this target");
20095 (define_insn_and_split "*load_tp_<mode>"
20096   [(set (match_operand:PTR 0 "register_operand" "=r")
20097         (unspec:PTR [(const_int 0)] UNSPEC_TP))]
20098   ""
20099   "#"
20100   ""
20101   [(set (match_dup 0)
20102         (match_dup 1))]
20104   addr_space_t as = DEFAULT_TLS_SEG_REG;
20106   operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
20107   set_mem_addr_space (operands[1], as);
20110 (define_insn_and_split "*load_tp_x32_zext"
20111   [(set (match_operand:DI 0 "register_operand" "=r")
20112         (zero_extend:DI
20113           (unspec:SI [(const_int 0)] UNSPEC_TP)))]
20114   "TARGET_X32"
20115   "#"
20116   "&& 1"
20117   [(set (match_dup 0)
20118         (zero_extend:DI (match_dup 1)))]
20120   addr_space_t as = DEFAULT_TLS_SEG_REG;
20122   operands[1] = gen_const_mem (SImode, const0_rtx);
20123   set_mem_addr_space (operands[1], as);
20126 (define_insn_and_split "*add_tp_<mode>"
20127   [(set (match_operand:PTR 0 "register_operand" "=r")
20128         (plus:PTR
20129           (unspec:PTR [(const_int 0)] UNSPEC_TP)
20130           (match_operand:PTR 1 "register_operand" "0")))
20131    (clobber (reg:CC FLAGS_REG))]
20132   ""
20133   "#"
20134   ""
20135   [(parallel
20136      [(set (match_dup 0)
20137            (plus:PTR (match_dup 1) (match_dup 2)))
20138       (clobber (reg:CC FLAGS_REG))])]
20140   addr_space_t as = DEFAULT_TLS_SEG_REG;
20142   operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
20143   set_mem_addr_space (operands[2], as);
20146 (define_insn_and_split "*add_tp_x32_zext"
20147   [(set (match_operand:DI 0 "register_operand" "=r")
20148         (zero_extend:DI
20149           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
20150                    (match_operand:SI 1 "register_operand" "0"))))
20151    (clobber (reg:CC FLAGS_REG))]
20152   "TARGET_X32"
20153   "#"
20154   "&& 1"
20155   [(parallel
20156      [(set (match_dup 0)
20157            (zero_extend:DI
20158              (plus:SI (match_dup 1) (match_dup 2))))
20159       (clobber (reg:CC FLAGS_REG))])]
20161   addr_space_t as = DEFAULT_TLS_SEG_REG;
20163   operands[2] = gen_const_mem (SImode, const0_rtx);
20164   set_mem_addr_space (operands[2], as);
20167 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
20168 ;; %rax as destination of the initial executable code sequence.
20169 (define_insn "tls_initial_exec_64_sun"
20170   [(set (match_operand:DI 0 "register_operand" "=a")
20171         (unspec:DI
20172          [(match_operand 1 "tls_symbolic_operand")]
20173          UNSPEC_TLS_IE_SUN))
20174    (clobber (reg:CC FLAGS_REG))]
20175   "TARGET_64BIT && TARGET_SUN_TLS"
20177   output_asm_insn
20178     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
20179   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
20181   [(set_attr "type" "multi")])
20183 ;; GNU2 TLS patterns can be split.
20185 (define_expand "tls_dynamic_gnu2_32"
20186   [(set (match_dup 3)
20187         (plus:SI (match_operand:SI 2 "register_operand")
20188                  (const:SI
20189                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
20190                              UNSPEC_TLSDESC))))
20191    (parallel
20192     [(set (match_operand:SI 0 "register_operand")
20193           (unspec:SI [(match_dup 1) (match_dup 3)
20194                       (match_dup 2) (reg:SI SP_REG)]
20195                       UNSPEC_TLSDESC))
20196      (clobber (reg:CC FLAGS_REG))])]
20197   "!TARGET_64BIT && TARGET_GNU2_TLS"
20199   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
20200   ix86_tls_descriptor_calls_expanded_in_cfun = true;
20203 (define_insn "*tls_dynamic_gnu2_lea_32"
20204   [(set (match_operand:SI 0 "register_operand" "=r")
20205         (plus:SI (match_operand:SI 1 "register_operand" "b")
20206                  (const:SI
20207                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
20208                               UNSPEC_TLSDESC))))]
20209   "!TARGET_64BIT && TARGET_GNU2_TLS"
20210   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
20211   [(set_attr "type" "lea")
20212    (set_attr "mode" "SI")
20213    (set_attr "length" "6")
20214    (set_attr "length_address" "4")])
20216 (define_insn "*tls_dynamic_gnu2_call_32"
20217   [(set (match_operand:SI 0 "register_operand" "=a")
20218         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
20219                     (match_operand:SI 2 "register_operand" "0")
20220                     ;; we have to make sure %ebx still points to the GOT
20221                     (match_operand:SI 3 "register_operand" "b")
20222                     (reg:SI SP_REG)]
20223                    UNSPEC_TLSDESC))
20224    (clobber (reg:CC FLAGS_REG))]
20225   "!TARGET_64BIT && TARGET_GNU2_TLS"
20226   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
20227   [(set_attr "type" "call")
20228    (set_attr "length" "2")
20229    (set_attr "length_address" "0")])
20231 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
20232   [(set (match_operand:SI 0 "register_operand" "=&a")
20233         (plus:SI
20234          (unspec:SI [(match_operand 3 "tls_modbase_operand")
20235                      (match_operand:SI 4)
20236                      (match_operand:SI 2 "register_operand" "b")
20237                      (reg:SI SP_REG)]
20238                     UNSPEC_TLSDESC)
20239          (const:SI (unspec:SI
20240                     [(match_operand 1 "tls_symbolic_operand")]
20241                     UNSPEC_DTPOFF))))
20242    (clobber (reg:CC FLAGS_REG))]
20243   "!TARGET_64BIT && TARGET_GNU2_TLS"
20244   "#"
20245   "&& 1"
20246   [(set (match_dup 0) (match_dup 5))]
20248   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
20249   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
20252 (define_expand "@tls_dynamic_gnu2_64_<mode>"
20253   [(set (match_dup 2)
20254         (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
20255                     UNSPEC_TLSDESC))
20256    (parallel
20257     [(set (match_operand:PTR 0 "register_operand")
20258           (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)]
20259                       UNSPEC_TLSDESC))
20260      (clobber (reg:CC FLAGS_REG))])]
20261   "TARGET_64BIT && TARGET_GNU2_TLS"
20263   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
20264   ix86_tls_descriptor_calls_expanded_in_cfun = true;
20267 (define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
20268   [(set (match_operand:PTR 0 "register_operand" "=r")
20269         (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
20270                     UNSPEC_TLSDESC))]
20271   "TARGET_64BIT && TARGET_GNU2_TLS"
20272   "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
20273   [(set_attr "type" "lea")
20274    (set_attr "mode" "<MODE>")
20275    (set_attr "length" "7")
20276    (set_attr "length_address" "4")])
20278 (define_insn "*tls_dynamic_gnu2_call_64_<mode>"
20279   [(set (match_operand:PTR 0 "register_operand" "=a")
20280         (unspec:PTR [(match_operand 1 "tls_symbolic_operand")
20281                    (match_operand:PTR 2 "register_operand" "0")
20282                    (reg:PTR SP_REG)]
20283                   UNSPEC_TLSDESC))
20284    (clobber (reg:CC FLAGS_REG))]
20285   "TARGET_64BIT && TARGET_GNU2_TLS"
20286   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
20287   [(set_attr "type" "call")
20288    (set_attr "length" "2")
20289    (set_attr "length_address" "0")])
20291 (define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
20292   [(set (match_operand:PTR 0 "register_operand" "=&a")
20293         (plus:PTR
20294          (unspec:PTR [(match_operand 2 "tls_modbase_operand")
20295                       (match_operand:PTR 3)
20296                       (reg:PTR SP_REG)]
20297                      UNSPEC_TLSDESC)
20298          (const:PTR (unspec:PTR
20299                      [(match_operand 1 "tls_symbolic_operand")]
20300                      UNSPEC_DTPOFF))))
20301    (clobber (reg:CC FLAGS_REG))]
20302   "TARGET_64BIT && TARGET_GNU2_TLS"
20303   "#"
20304   "&& 1"
20305   [(set (match_dup 0) (match_dup 4))]
20307   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
20308   emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1]));
20311 (define_split
20312   [(match_operand 0 "tls_address_pattern")]
20313   "TARGET_TLS_DIRECT_SEG_REFS"
20314   [(match_dup 0)]
20315   "operands[0] = ix86_rewrite_tls_address (operands[0]);")
20318 ;; These patterns match the binary 387 instructions for addM3, subM3,
20319 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
20320 ;; SFmode.  The first is the normal insn, the second the same insn but
20321 ;; with one operand a conversion, and the third the same insn but with
20322 ;; the other operand a conversion.  The conversion may be SFmode or
20323 ;; SImode if the target mode DFmode, but only SImode if the target mode
20324 ;; is SFmode.
20326 ;; Gcc is slightly more smart about handling normal two address instructions
20327 ;; so use special patterns for add and mull.
20329 (define_insn "*fop_xf_comm_i387"
20330   [(set (match_operand:XF 0 "register_operand" "=f")
20331         (match_operator:XF 3 "binary_fp_operator"
20332                         [(match_operand:XF 1 "register_operand" "%0")
20333                          (match_operand:XF 2 "register_operand" "f")]))]
20334   "TARGET_80387
20335    && COMMUTATIVE_ARITH_P (operands[3])"
20336   "* return output_387_binary_op (insn, operands);"
20337   [(set (attr "type")
20338         (if_then_else (match_operand:XF 3 "mult_operator")
20339            (const_string "fmul")
20340            (const_string "fop")))
20341    (set_attr "mode" "XF")])
20343 (define_insn "*fop_<mode>_comm"
20344   [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
20345         (match_operator:MODEF 3 "binary_fp_operator"
20346           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
20347            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
20348   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20349     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20350    && COMMUTATIVE_ARITH_P (operands[3])
20351    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20352   "* return output_387_binary_op (insn, operands);"
20353   [(set (attr "type")
20354         (if_then_else (eq_attr "alternative" "1,2")
20355            (if_then_else (match_operand:MODEF 3 "mult_operator")
20356               (const_string "ssemul")
20357               (const_string "sseadd"))
20358            (if_then_else (match_operand:MODEF 3 "mult_operator")
20359               (const_string "fmul")
20360               (const_string "fop"))))
20361    (set_attr "isa" "*,noavx,avx")
20362    (set_attr "prefix" "orig,orig,vex")
20363    (set_attr "mode" "<MODE>")
20364    (set (attr "enabled")
20365      (if_then_else
20366        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20367        (if_then_else
20368          (eq_attr "alternative" "0")
20369          (symbol_ref "TARGET_MIX_SSE_I387
20370                       && X87_ENABLE_ARITH (<MODE>mode)")
20371          (const_string "*"))
20372        (if_then_else
20373          (eq_attr "alternative" "0")
20374          (symbol_ref "true")
20375          (symbol_ref "false"))))])
20377 (define_insn "*<insn>hf"
20378   [(set (match_operand:HF 0 "register_operand" "=v")
20379         (plusminusmultdiv:HF
20380           (match_operand:HF 1 "nonimmediate_operand" "<comm>v")
20381           (match_operand:HF 2 "nonimmediate_operand" "vm")))]
20382   "TARGET_AVX512FP16
20383    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20384   "v<insn>sh\t{%2, %1, %0|%0, %1, %2}"
20385   [(set_attr "prefix" "evex")
20386    (set_attr "mode" "HF")])
20388 (define_insn "*rcpsf2_sse"
20389   [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
20390         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
20391                    UNSPEC_RCP))]
20392   "TARGET_SSE && TARGET_SSE_MATH"
20393   "@
20394    %vrcpss\t{%d1, %0|%0, %d1}
20395    %vrcpss\t{%d1, %0|%0, %d1}
20396    rcpss\t{%1, %d0|%d0, %1}
20397    vrcpss\t{%1, %d0|%d0, %1}"
20398   [(set_attr "isa" "*,*,noavx,avx")
20399    (set_attr "addr" "*,*,*,gpr16")
20400    (set_attr "type" "sse")
20401    (set_attr "atom_sse_attr" "rcp")
20402    (set_attr "btver2_sse_attr" "rcp")
20403    (set_attr "prefix" "maybe_vex")
20404    (set_attr "mode" "SF")
20405    (set_attr "avx_partial_xmm_update" "false,false,true,true")
20406    (set (attr "preferred_for_speed")
20407       (cond [(match_test "TARGET_AVX")
20408                (symbol_ref "true")
20409              (eq_attr "alternative" "1,2,3")
20410                (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20411             ]
20412             (symbol_ref "true")))])
20414 (define_insn "rcphf2"
20415   [(set (match_operand:HF 0 "register_operand" "=v,v")
20416         (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20417                    UNSPEC_RCP))]
20418   "TARGET_AVX512FP16"
20419   "@
20420    vrcpsh\t{%d1, %0|%0, %d1}
20421    vrcpsh\t{%1, %d0|%d0, %1}"
20422   [(set_attr "type" "sse")
20423    (set_attr "prefix" "evex")
20424    (set_attr "mode" "HF")
20425    (set_attr "avx_partial_xmm_update" "false,true")])
20427 (define_insn "*fop_xf_1_i387"
20428   [(set (match_operand:XF 0 "register_operand" "=f,f")
20429         (match_operator:XF 3 "binary_fp_operator"
20430                         [(match_operand:XF 1 "register_operand" "0,f")
20431                          (match_operand:XF 2 "register_operand" "f,0")]))]
20432   "TARGET_80387
20433    && !COMMUTATIVE_ARITH_P (operands[3])"
20434   "* return output_387_binary_op (insn, operands);"
20435   [(set (attr "type")
20436         (if_then_else (match_operand:XF 3 "div_operator")
20437            (const_string "fdiv")
20438            (const_string "fop")))
20439    (set_attr "mode" "XF")])
20441 (define_insn "*fop_<mode>_1"
20442   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
20443         (match_operator:MODEF 3 "binary_fp_operator"
20444           [(match_operand:MODEF 1
20445              "x87nonimm_ssenomem_operand" "0,fm,0,v")
20446            (match_operand:MODEF 2
20447              "nonimmediate_operand"       "fm,0,xm,vm")]))]
20448   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20449     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20450    && !COMMUTATIVE_ARITH_P (operands[3])
20451    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20452   "* return output_387_binary_op (insn, operands);"
20453   [(set (attr "type")
20454         (if_then_else (eq_attr "alternative" "2,3")
20455            (if_then_else (match_operand:MODEF 3 "div_operator")
20456               (const_string "ssediv")
20457               (const_string "sseadd"))
20458            (if_then_else (match_operand:MODEF 3 "div_operator")
20459               (const_string "fdiv")
20460               (const_string "fop"))))
20461    (set_attr "isa" "*,*,noavx,avx")
20462    (set_attr "prefix" "orig,orig,orig,vex")
20463    (set_attr "mode" "<MODE>")
20464    (set (attr "enabled")
20465      (if_then_else
20466        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20467        (if_then_else
20468          (eq_attr "alternative" "0,1")
20469          (symbol_ref "TARGET_MIX_SSE_I387
20470                       && X87_ENABLE_ARITH (<MODE>mode)")
20471          (const_string "*"))
20472        (if_then_else
20473          (eq_attr "alternative" "0,1")
20474          (symbol_ref "true")
20475          (symbol_ref "false"))))])
20477 (define_insn "*fop_<X87MODEF:mode>_2_i387"
20478   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20479         (match_operator:X87MODEF 3 "binary_fp_operator"
20480           [(float:X87MODEF
20481              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
20482            (match_operand:X87MODEF 2 "register_operand" "0")]))]
20483   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20484    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20485    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20486        || optimize_function_for_size_p (cfun))"
20487   "* return output_387_binary_op (insn, operands);"
20488   [(set (attr "type")
20489         (cond [(match_operand:X87MODEF 3 "mult_operator")
20490                  (const_string "fmul")
20491                (match_operand:X87MODEF 3 "div_operator")
20492                  (const_string "fdiv")
20493               ]
20494               (const_string "fop")))
20495    (set_attr "fp_int_src" "true")
20496    (set_attr "mode" "<SWI24:MODE>")])
20498 (define_insn "*fop_<X87MODEF:mode>_3_i387"
20499   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20500         (match_operator:X87MODEF 3 "binary_fp_operator"
20501           [(match_operand:X87MODEF 1 "register_operand" "0")
20502            (float:X87MODEF
20503              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
20504   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20505    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20506    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20507        || optimize_function_for_size_p (cfun))"
20508   "* return output_387_binary_op (insn, operands);"
20509   [(set (attr "type")
20510         (cond [(match_operand:X87MODEF 3 "mult_operator")
20511                  (const_string "fmul")
20512                (match_operand:X87MODEF 3 "div_operator")
20513                  (const_string "fdiv")
20514               ]
20515               (const_string "fop")))
20516    (set_attr "fp_int_src" "true")
20517    (set_attr "mode" "<SWI24:MODE>")])
20519 (define_insn "*fop_xf_4_i387"
20520   [(set (match_operand:XF 0 "register_operand" "=f,f")
20521         (match_operator:XF 3 "binary_fp_operator"
20522            [(float_extend:XF
20523               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
20524             (match_operand:XF 2 "register_operand" "0,f")]))]
20525   "TARGET_80387"
20526   "* return output_387_binary_op (insn, operands);"
20527   [(set (attr "type")
20528         (cond [(match_operand:XF 3 "mult_operator")
20529                  (const_string "fmul")
20530                (match_operand:XF 3 "div_operator")
20531                  (const_string "fdiv")
20532               ]
20533               (const_string "fop")))
20534    (set_attr "mode" "<MODE>")])
20536 (define_insn "*fop_df_4_i387"
20537   [(set (match_operand:DF 0 "register_operand" "=f,f")
20538         (match_operator:DF 3 "binary_fp_operator"
20539            [(float_extend:DF
20540              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
20541             (match_operand:DF 2 "register_operand" "0,f")]))]
20542   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20543    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20544   "* return output_387_binary_op (insn, operands);"
20545   [(set (attr "type")
20546         (cond [(match_operand:DF 3 "mult_operator")
20547                  (const_string "fmul")
20548                (match_operand:DF 3 "div_operator")
20549                  (const_string "fdiv")
20550               ]
20551               (const_string "fop")))
20552    (set_attr "mode" "SF")])
20554 (define_insn "*fop_xf_5_i387"
20555   [(set (match_operand:XF 0 "register_operand" "=f,f")
20556         (match_operator:XF 3 "binary_fp_operator"
20557           [(match_operand:XF 1 "register_operand" "0,f")
20558            (float_extend:XF
20559              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20560   "TARGET_80387"
20561   "* return output_387_binary_op (insn, operands);"
20562   [(set (attr "type")
20563         (cond [(match_operand:XF 3 "mult_operator")
20564                  (const_string "fmul")
20565                (match_operand:XF 3 "div_operator")
20566                  (const_string "fdiv")
20567               ]
20568               (const_string "fop")))
20569    (set_attr "mode" "<MODE>")])
20571 (define_insn "*fop_df_5_i387"
20572   [(set (match_operand:DF 0 "register_operand" "=f,f")
20573         (match_operator:DF 3 "binary_fp_operator"
20574           [(match_operand:DF 1 "register_operand" "0,f")
20575            (float_extend:DF
20576             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20577   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20578    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20579   "* return output_387_binary_op (insn, operands);"
20580   [(set (attr "type")
20581         (cond [(match_operand:DF 3 "mult_operator")
20582                  (const_string "fmul")
20583                (match_operand:DF 3 "div_operator")
20584                  (const_string "fdiv")
20585               ]
20586               (const_string "fop")))
20587    (set_attr "mode" "SF")])
20589 (define_insn "*fop_xf_6_i387"
20590   [(set (match_operand:XF 0 "register_operand" "=f,f")
20591         (match_operator:XF 3 "binary_fp_operator"
20592           [(float_extend:XF
20593              (match_operand:MODEF 1 "register_operand" "0,f"))
20594            (float_extend:XF
20595              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20596   "TARGET_80387"
20597   "* return output_387_binary_op (insn, operands);"
20598   [(set (attr "type")
20599         (cond [(match_operand:XF 3 "mult_operator")
20600                  (const_string "fmul")
20601                (match_operand:XF 3 "div_operator")
20602                  (const_string "fdiv")
20603               ]
20604               (const_string "fop")))
20605    (set_attr "mode" "<MODE>")])
20607 (define_insn "*fop_df_6_i387"
20608   [(set (match_operand:DF 0 "register_operand" "=f,f")
20609         (match_operator:DF 3 "binary_fp_operator"
20610           [(float_extend:DF
20611             (match_operand:SF 1 "register_operand" "0,f"))
20612            (float_extend:DF
20613             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20614   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20615    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20616   "* return output_387_binary_op (insn, operands);"
20617   [(set (attr "type")
20618         (cond [(match_operand:DF 3 "mult_operator")
20619                  (const_string "fmul")
20620                (match_operand:DF 3 "div_operator")
20621                  (const_string "fdiv")
20622               ]
20623               (const_string "fop")))
20624    (set_attr "mode" "SF")])
20626 ;; FPU special functions.
20628 ;; This pattern implements a no-op XFmode truncation for
20629 ;; all fancy i386 XFmode math functions.
20631 (define_insn "truncxf<mode>2_i387_noop_unspec"
20632   [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
20633         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
20634         UNSPEC_TRUNC_NOOP))]
20635   "TARGET_USE_FANCY_MATH_387"
20636   "* return output_387_reg_move (insn, operands);"
20637   [(set_attr "type" "fmov")
20638    (set_attr "mode" "<MODE>")])
20640 (define_insn "sqrtxf2"
20641   [(set (match_operand:XF 0 "register_operand" "=f")
20642         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
20643   "TARGET_USE_FANCY_MATH_387"
20644   "fsqrt"
20645   [(set_attr "type" "fpspc")
20646    (set_attr "mode" "XF")
20647    (set_attr "athlon_decode" "direct")
20648    (set_attr "amdfam10_decode" "direct")
20649    (set_attr "bdver1_decode" "direct")])
20651 (define_insn "*rsqrtsf2_sse"
20652   [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
20653         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
20654                    UNSPEC_RSQRT))]
20655   "TARGET_SSE && TARGET_SSE_MATH"
20656   "@
20657    %vrsqrtss\t{%d1, %0|%0, %d1}
20658    %vrsqrtss\t{%d1, %0|%0, %d1}
20659    rsqrtss\t{%1, %d0|%d0, %1}
20660    vrsqrtss\t{%1, %d0|%d0, %1}"
20661   [(set_attr "isa" "*,*,noavx,avx")
20662    (set_attr "addr" "*,*,*,gpr16")
20663    (set_attr "type" "sse")
20664    (set_attr "atom_sse_attr" "rcp")
20665    (set_attr "btver2_sse_attr" "rcp")
20666    (set_attr "prefix" "maybe_vex")
20667    (set_attr "mode" "SF")
20668    (set_attr "avx_partial_xmm_update" "false,false,true,true")
20669    (set (attr "preferred_for_speed")
20670       (cond [(match_test "TARGET_AVX")
20671                (symbol_ref "true")
20672              (eq_attr "alternative" "1,2,3")
20673                (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20674             ]
20675             (symbol_ref "true")))])
20677 (define_expand "rsqrtsf2"
20678   [(set (match_operand:SF 0 "register_operand")
20679         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
20680                    UNSPEC_RSQRT))]
20681   "TARGET_SSE && TARGET_SSE_MATH"
20683   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
20684   DONE;
20687 (define_insn "rsqrthf2"
20688   [(set (match_operand:HF 0 "register_operand" "=v,v")
20689         (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20690                    UNSPEC_RSQRT))]
20691   "TARGET_AVX512FP16"
20692   "@
20693    vrsqrtsh\t{%d1, %0|%0, %d1}
20694    vrsqrtsh\t{%1, %d0|%d0, %1}"
20695   [(set_attr "type" "sse")
20696    (set_attr "prefix" "evex")
20697    (set_attr "avx_partial_xmm_update" "false,true")
20698    (set_attr "mode" "HF")])
20700 (define_insn "sqrthf2"
20701   [(set (match_operand:HF 0 "register_operand" "=v,v")
20702         (sqrt:HF
20703           (match_operand:HF 1 "nonimmediate_operand" "v,m")))]
20704   "TARGET_AVX512FP16"
20705   "@
20706    vsqrtsh\t{%d1, %0|%0, %d1}
20707    vsqrtsh\t{%1, %d0|%d0, %1}"
20708   [(set_attr "type" "sse")
20709    (set_attr "prefix" "evex")
20710    (set_attr "avx_partial_xmm_update" "false,true")
20711    (set_attr "mode" "HF")])
20713 (define_insn "*sqrt<mode>2_sse"
20714   [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
20715         (sqrt:MODEF
20716           (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
20717   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20718   "@
20719    %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20720    %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20721    %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
20722   [(set_attr "type" "sse")
20723    (set_attr "atom_sse_attr" "sqrt")
20724    (set_attr "btver2_sse_attr" "sqrt")
20725    (set_attr "prefix" "maybe_vex")
20726    (set_attr "avx_partial_xmm_update" "false,false,true")
20727    (set_attr "mode" "<MODE>")
20728    (set (attr "preferred_for_speed")
20729       (cond [(match_test "TARGET_AVX")
20730                (symbol_ref "true")
20731              (eq_attr "alternative" "1,2")
20732                (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20733             ]
20734             (symbol_ref "true")))])
20736 (define_expand "sqrt<mode>2"
20737   [(set (match_operand:MODEF 0 "register_operand")
20738         (sqrt:MODEF
20739           (match_operand:MODEF 1 "nonimmediate_operand")))]
20740   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
20741    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20743   if (<MODE>mode == SFmode
20744       && TARGET_SSE && TARGET_SSE_MATH
20745       && TARGET_RECIP_SQRT
20746       && !optimize_function_for_size_p (cfun)
20747       && flag_finite_math_only && !flag_trapping_math
20748       && flag_unsafe_math_optimizations)
20749     {
20750       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
20751       DONE;
20752     }
20754   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
20755     {
20756       rtx op0 = gen_reg_rtx (XFmode);
20757       rtx op1 = gen_reg_rtx (XFmode);
20759       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20760       emit_insn (gen_sqrtxf2 (op0, op1));
20761       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
20762       DONE;
20763    }
20766 (define_expand "hypot<mode>3"
20767   [(use (match_operand:MODEF 0 "register_operand"))
20768    (use (match_operand:MODEF 1 "general_operand"))
20769    (use (match_operand:MODEF 2 "general_operand"))]
20770   "TARGET_USE_FANCY_MATH_387
20771    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20772        || TARGET_MIX_SSE_I387)
20773    && flag_finite_math_only
20774    && flag_unsafe_math_optimizations"
20776   rtx op0 = gen_reg_rtx (XFmode);
20777   rtx op1 = gen_reg_rtx (XFmode);
20778   rtx op2 = gen_reg_rtx (XFmode);
20780   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20781   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20783   emit_insn (gen_mulxf3 (op1, op1, op1));
20784   emit_insn (gen_mulxf3 (op2, op2, op2));
20785   emit_insn (gen_addxf3 (op0, op2, op1));
20786   emit_insn (gen_sqrtxf2 (op0, op0));
20788   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20789   DONE;
20792 (define_insn "x86_fnstsw_1"
20793   [(set (match_operand:HI 0 "register_operand" "=a")
20794         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
20795   "TARGET_80387"
20796   "fnstsw\t%0"
20797   [(set_attr "length" "2")
20798    (set_attr "mode" "SI")
20799    (set_attr "unit" "i387")])
20801 (define_insn "fpremxf4_i387"
20802   [(set (match_operand:XF 0 "register_operand" "=f")
20803         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20804                     (match_operand:XF 3 "register_operand" "1")]
20805                    UNSPEC_FPREM_F))
20806    (set (match_operand:XF 1 "register_operand" "=f")
20807         (unspec:XF [(match_dup 2) (match_dup 3)]
20808                    UNSPEC_FPREM_U))
20809    (set (reg:CCFP FPSR_REG)
20810         (unspec:CCFP [(match_dup 2) (match_dup 3)]
20811                      UNSPEC_C2_FLAG))]
20812   "TARGET_USE_FANCY_MATH_387"
20813   "fprem"
20814   [(set_attr "type" "fpspc")
20815    (set_attr "znver1_decode" "vector")
20816    (set_attr "mode" "XF")])
20818 (define_expand "fmodxf3"
20819   [(use (match_operand:XF 0 "register_operand"))
20820    (use (match_operand:XF 1 "general_operand"))
20821    (use (match_operand:XF 2 "general_operand"))]
20822   "TARGET_USE_FANCY_MATH_387"
20824   rtx_code_label *label = gen_label_rtx ();
20826   rtx op1 = gen_reg_rtx (XFmode);
20827   rtx op2 = gen_reg_rtx (XFmode);
20829   emit_move_insn (op2, operands[2]);
20830   emit_move_insn (op1, operands[1]);
20832   emit_label (label);
20833   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20834   ix86_emit_fp_unordered_jump (label);
20835   LABEL_NUSES (label) = 1;
20837   emit_move_insn (operands[0], op1);
20838   DONE;
20841 (define_expand "fmod<mode>3"
20842   [(use (match_operand:MODEF 0 "register_operand"))
20843    (use (match_operand:MODEF 1 "general_operand"))
20844    (use (match_operand:MODEF 2 "general_operand"))]
20845   "TARGET_USE_FANCY_MATH_387"
20847   rtx (*gen_truncxf) (rtx, rtx);
20849   rtx_code_label *label = gen_label_rtx ();
20851   rtx op1 = gen_reg_rtx (XFmode);
20852   rtx op2 = gen_reg_rtx (XFmode);
20854   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20855   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20857   emit_label (label);
20858   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20859   ix86_emit_fp_unordered_jump (label);
20860   LABEL_NUSES (label) = 1;
20862   /* Truncate the result properly for strict SSE math.  */
20863   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20864       && !TARGET_MIX_SSE_I387)
20865     gen_truncxf = gen_truncxf<mode>2;
20866   else
20867     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20869   emit_insn (gen_truncxf (operands[0], op1));
20870   DONE;
20873 (define_insn "fprem1xf4_i387"
20874   [(set (match_operand:XF 0 "register_operand" "=f")
20875         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20876                     (match_operand:XF 3 "register_operand" "1")]
20877                    UNSPEC_FPREM1_F))
20878    (set (match_operand:XF 1 "register_operand" "=f")
20879         (unspec:XF [(match_dup 2) (match_dup 3)]
20880                    UNSPEC_FPREM1_U))
20881    (set (reg:CCFP FPSR_REG)
20882         (unspec:CCFP [(match_dup 2) (match_dup 3)]
20883                      UNSPEC_C2_FLAG))]
20884   "TARGET_USE_FANCY_MATH_387"
20885   "fprem1"
20886   [(set_attr "type" "fpspc")
20887    (set_attr "znver1_decode" "vector")
20888    (set_attr "mode" "XF")])
20890 (define_expand "remainderxf3"
20891   [(use (match_operand:XF 0 "register_operand"))
20892    (use (match_operand:XF 1 "general_operand"))
20893    (use (match_operand:XF 2 "general_operand"))]
20894   "TARGET_USE_FANCY_MATH_387"
20896   rtx_code_label *label = gen_label_rtx ();
20898   rtx op1 = gen_reg_rtx (XFmode);
20899   rtx op2 = gen_reg_rtx (XFmode);
20901   emit_move_insn (op2, operands[2]);
20902   emit_move_insn (op1, operands[1]);
20904   emit_label (label);
20905   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20906   ix86_emit_fp_unordered_jump (label);
20907   LABEL_NUSES (label) = 1;
20909   emit_move_insn (operands[0], op1);
20910   DONE;
20913 (define_expand "remainder<mode>3"
20914   [(use (match_operand:MODEF 0 "register_operand"))
20915    (use (match_operand:MODEF 1 "general_operand"))
20916    (use (match_operand:MODEF 2 "general_operand"))]
20917   "TARGET_USE_FANCY_MATH_387"
20919   rtx (*gen_truncxf) (rtx, rtx);
20921   rtx_code_label *label = gen_label_rtx ();
20923   rtx op1 = gen_reg_rtx (XFmode);
20924   rtx op2 = gen_reg_rtx (XFmode);
20926   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20927   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20929   emit_label (label);
20931   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20932   ix86_emit_fp_unordered_jump (label);
20933   LABEL_NUSES (label) = 1;
20935   /* Truncate the result properly for strict SSE math.  */
20936   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20937       && !TARGET_MIX_SSE_I387)
20938     gen_truncxf = gen_truncxf<mode>2;
20939   else
20940     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20942   emit_insn (gen_truncxf (operands[0], op1));
20943   DONE;
20946 (define_int_iterator SINCOS
20947         [UNSPEC_SIN
20948          UNSPEC_COS])
20950 (define_int_attr sincos
20951         [(UNSPEC_SIN "sin")
20952          (UNSPEC_COS "cos")])
20954 (define_insn "<sincos>xf2"
20955   [(set (match_operand:XF 0 "register_operand" "=f")
20956         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
20957                    SINCOS))]
20958   "TARGET_USE_FANCY_MATH_387
20959    && flag_unsafe_math_optimizations"
20960   "f<sincos>"
20961   [(set_attr "type" "fpspc")
20962    (set_attr "znver1_decode" "vector")
20963    (set_attr "mode" "XF")])
20965 (define_expand "<sincos><mode>2"
20966   [(set (match_operand:MODEF 0 "register_operand")
20967         (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
20968                       SINCOS))]
20969   "TARGET_USE_FANCY_MATH_387
20970    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20971        || TARGET_MIX_SSE_I387)
20972    && flag_unsafe_math_optimizations"
20974   rtx op0 = gen_reg_rtx (XFmode);
20975   rtx op1 = gen_reg_rtx (XFmode);
20977   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20978   emit_insn (gen_<sincos>xf2 (op0, op1));
20979   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20980   DONE;
20983 (define_insn "sincosxf3"
20984   [(set (match_operand:XF 0 "register_operand" "=f")
20985         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
20986                    UNSPEC_SINCOS_COS))
20987    (set (match_operand:XF 1 "register_operand" "=f")
20988         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
20989   "TARGET_USE_FANCY_MATH_387
20990    && flag_unsafe_math_optimizations"
20991   "fsincos"
20992   [(set_attr "type" "fpspc")
20993    (set_attr "znver1_decode" "vector")
20994    (set_attr "mode" "XF")])
20996 (define_expand "sincos<mode>3"
20997   [(use (match_operand:MODEF 0 "register_operand"))
20998    (use (match_operand:MODEF 1 "register_operand"))
20999    (use (match_operand:MODEF 2 "general_operand"))]
21000   "TARGET_USE_FANCY_MATH_387
21001    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21002        || TARGET_MIX_SSE_I387)
21003    && flag_unsafe_math_optimizations"
21005   rtx op0 = gen_reg_rtx (XFmode);
21006   rtx op1 = gen_reg_rtx (XFmode);
21007   rtx op2 = gen_reg_rtx (XFmode);
21009   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21010   emit_insn (gen_sincosxf3 (op0, op1, op2));
21011   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21012   emit_insn (gen_truncxf<mode>2 (operands[1], op1));
21013   DONE;
21016 (define_insn "fptanxf4_i387"
21017   [(set (match_operand:SF 0 "register_operand" "=f")
21018         (match_operand:SF 3 "const1_operand"))
21019    (set (match_operand:XF 1 "register_operand" "=f")
21020         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21021                    UNSPEC_TAN))]
21022   "TARGET_USE_FANCY_MATH_387
21023    && flag_unsafe_math_optimizations"
21024   "fptan"
21025   [(set_attr "type" "fpspc")
21026    (set_attr "znver1_decode" "vector")
21027    (set_attr "mode" "XF")])
21029 (define_expand "tanxf2"
21030   [(use (match_operand:XF 0 "register_operand"))
21031    (use (match_operand:XF 1 "register_operand"))]
21032   "TARGET_USE_FANCY_MATH_387
21033    && flag_unsafe_math_optimizations"
21035   rtx one = gen_reg_rtx (SFmode);
21036   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
21037                                 CONST1_RTX (SFmode)));
21038   DONE;
21041 (define_expand "tan<mode>2"
21042   [(use (match_operand:MODEF 0 "register_operand"))
21043    (use (match_operand:MODEF 1 "general_operand"))]
21044   "TARGET_USE_FANCY_MATH_387
21045    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21046        || TARGET_MIX_SSE_I387)
21047    && flag_unsafe_math_optimizations"
21049   rtx op0 = gen_reg_rtx (XFmode);
21050   rtx op1 = gen_reg_rtx (XFmode);
21052   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21053   emit_insn (gen_tanxf2 (op0, op1));
21054   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21055   DONE;
21058 (define_insn "atan2xf3"
21059   [(set (match_operand:XF 0 "register_operand" "=f")
21060         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21061                     (match_operand:XF 1 "register_operand" "f")]
21062                    UNSPEC_FPATAN))
21063    (clobber (match_scratch:XF 3 "=1"))]
21064   "TARGET_USE_FANCY_MATH_387
21065    && flag_unsafe_math_optimizations"
21066   "fpatan"
21067   [(set_attr "type" "fpspc")
21068    (set_attr "znver1_decode" "vector")
21069    (set_attr "mode" "XF")])
21071 (define_expand "atan2<mode>3"
21072   [(use (match_operand:MODEF 0 "register_operand"))
21073    (use (match_operand:MODEF 1 "general_operand"))
21074    (use (match_operand:MODEF 2 "general_operand"))]
21075   "TARGET_USE_FANCY_MATH_387
21076    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21077        || TARGET_MIX_SSE_I387)
21078    && flag_unsafe_math_optimizations"
21080   rtx op0 = gen_reg_rtx (XFmode);
21081   rtx op1 = gen_reg_rtx (XFmode);
21082   rtx op2 = gen_reg_rtx (XFmode);
21084   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21085   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21087   emit_insn (gen_atan2xf3 (op0, op1, op2));
21088   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21089   DONE;
21092 (define_expand "atanxf2"
21093   [(parallel [(set (match_operand:XF 0 "register_operand")
21094                    (unspec:XF [(match_dup 2)
21095                                (match_operand:XF 1 "register_operand")]
21096                               UNSPEC_FPATAN))
21097               (clobber (scratch:XF))])]
21098   "TARGET_USE_FANCY_MATH_387
21099    && flag_unsafe_math_optimizations"
21100   "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
21102 (define_expand "atan<mode>2"
21103   [(use (match_operand:MODEF 0 "register_operand"))
21104    (use (match_operand:MODEF 1 "general_operand"))]
21105   "TARGET_USE_FANCY_MATH_387
21106    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21107        || TARGET_MIX_SSE_I387)
21108    && flag_unsafe_math_optimizations"
21110   rtx op0 = gen_reg_rtx (XFmode);
21111   rtx op1 = gen_reg_rtx (XFmode);
21113   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21114   emit_insn (gen_atanxf2 (op0, op1));
21115   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21116   DONE;
21119 (define_expand "asinxf2"
21120   [(set (match_dup 2)
21121         (mult:XF (match_operand:XF 1 "register_operand")
21122                  (match_dup 1)))
21123    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
21124    (set (match_dup 5) (sqrt:XF (match_dup 4)))
21125    (parallel [(set (match_operand:XF 0 "register_operand")
21126                    (unspec:XF [(match_dup 5) (match_dup 1)]
21127                               UNSPEC_FPATAN))
21128               (clobber (scratch:XF))])]
21129   "TARGET_USE_FANCY_MATH_387
21130    && flag_unsafe_math_optimizations"
21132   int i;
21134   for (i = 2; i < 6; i++)
21135     operands[i] = gen_reg_rtx (XFmode);
21137   emit_move_insn (operands[3], CONST1_RTX (XFmode));
21140 (define_expand "asin<mode>2"
21141   [(use (match_operand:MODEF 0 "register_operand"))
21142    (use (match_operand:MODEF 1 "general_operand"))]
21143   "TARGET_USE_FANCY_MATH_387
21144    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21145        || TARGET_MIX_SSE_I387)
21146    && flag_unsafe_math_optimizations"
21148   rtx op0 = gen_reg_rtx (XFmode);
21149   rtx op1 = gen_reg_rtx (XFmode);
21151   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21152   emit_insn (gen_asinxf2 (op0, op1));
21153   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21154   DONE;
21157 (define_expand "acosxf2"
21158   [(set (match_dup 2)
21159         (mult:XF (match_operand:XF 1 "register_operand")
21160                  (match_dup 1)))
21161    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
21162    (set (match_dup 5) (sqrt:XF (match_dup 4)))
21163    (parallel [(set (match_operand:XF 0 "register_operand")
21164                    (unspec:XF [(match_dup 1) (match_dup 5)]
21165                               UNSPEC_FPATAN))
21166               (clobber (scratch:XF))])]
21167   "TARGET_USE_FANCY_MATH_387
21168    && flag_unsafe_math_optimizations"
21170   int i;
21172   for (i = 2; i < 6; i++)
21173     operands[i] = gen_reg_rtx (XFmode);
21175   emit_move_insn (operands[3], CONST1_RTX (XFmode));
21178 (define_expand "acos<mode>2"
21179   [(use (match_operand:MODEF 0 "register_operand"))
21180    (use (match_operand:MODEF 1 "general_operand"))]
21181   "TARGET_USE_FANCY_MATH_387
21182    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21183        || TARGET_MIX_SSE_I387)
21184    && flag_unsafe_math_optimizations"
21186   rtx op0 = gen_reg_rtx (XFmode);
21187   rtx op1 = gen_reg_rtx (XFmode);
21189   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21190   emit_insn (gen_acosxf2 (op0, op1));
21191   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21192   DONE;
21195 (define_expand "sinhxf2"
21196   [(use (match_operand:XF 0 "register_operand"))
21197    (use (match_operand:XF 1 "register_operand"))]
21198   "TARGET_USE_FANCY_MATH_387
21199    && flag_finite_math_only
21200    && flag_unsafe_math_optimizations"
21202   ix86_emit_i387_sinh (operands[0], operands[1]);
21203   DONE;
21206 (define_expand "sinh<mode>2"
21207   [(use (match_operand:MODEF 0 "register_operand"))
21208    (use (match_operand:MODEF 1 "general_operand"))]
21209   "TARGET_USE_FANCY_MATH_387
21210    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21211        || TARGET_MIX_SSE_I387)
21212    && flag_finite_math_only
21213    && flag_unsafe_math_optimizations"
21215   rtx op0 = gen_reg_rtx (XFmode);
21216   rtx op1 = gen_reg_rtx (XFmode);
21218   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21219   emit_insn (gen_sinhxf2 (op0, op1));
21220   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21221   DONE;
21224 (define_expand "coshxf2"
21225   [(use (match_operand:XF 0 "register_operand"))
21226    (use (match_operand:XF 1 "register_operand"))]
21227   "TARGET_USE_FANCY_MATH_387
21228    && flag_unsafe_math_optimizations"
21230   ix86_emit_i387_cosh (operands[0], operands[1]);
21231   DONE;
21234 (define_expand "cosh<mode>2"
21235   [(use (match_operand:MODEF 0 "register_operand"))
21236    (use (match_operand:MODEF 1 "general_operand"))]
21237   "TARGET_USE_FANCY_MATH_387
21238    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21239        || TARGET_MIX_SSE_I387)
21240    && flag_unsafe_math_optimizations"
21242   rtx op0 = gen_reg_rtx (XFmode);
21243   rtx op1 = gen_reg_rtx (XFmode);
21245   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21246   emit_insn (gen_coshxf2 (op0, op1));
21247   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21248   DONE;
21251 (define_expand "tanhxf2"
21252   [(use (match_operand:XF 0 "register_operand"))
21253    (use (match_operand:XF 1 "register_operand"))]
21254   "TARGET_USE_FANCY_MATH_387
21255    && flag_unsafe_math_optimizations"
21257   ix86_emit_i387_tanh (operands[0], operands[1]);
21258   DONE;
21261 (define_expand "tanh<mode>2"
21262   [(use (match_operand:MODEF 0 "register_operand"))
21263    (use (match_operand:MODEF 1 "general_operand"))]
21264   "TARGET_USE_FANCY_MATH_387
21265    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21266        || TARGET_MIX_SSE_I387)
21267    && flag_unsafe_math_optimizations"
21269   rtx op0 = gen_reg_rtx (XFmode);
21270   rtx op1 = gen_reg_rtx (XFmode);
21272   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21273   emit_insn (gen_tanhxf2 (op0, op1));
21274   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21275   DONE;
21278 (define_expand "asinhxf2"
21279   [(use (match_operand:XF 0 "register_operand"))
21280    (use (match_operand:XF 1 "register_operand"))]
21281   "TARGET_USE_FANCY_MATH_387
21282    && flag_finite_math_only
21283    && flag_unsafe_math_optimizations"
21285   ix86_emit_i387_asinh (operands[0], operands[1]);
21286   DONE;
21289 (define_expand "asinh<mode>2"
21290   [(use (match_operand:MODEF 0 "register_operand"))
21291    (use (match_operand:MODEF 1 "general_operand"))]
21292   "TARGET_USE_FANCY_MATH_387
21293    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21294        || TARGET_MIX_SSE_I387)
21295    && flag_finite_math_only
21296    && flag_unsafe_math_optimizations"
21298   rtx op0 = gen_reg_rtx (XFmode);
21299   rtx op1 = gen_reg_rtx (XFmode);
21301   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21302   emit_insn (gen_asinhxf2 (op0, op1));
21303   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21304   DONE;
21307 (define_expand "acoshxf2"
21308   [(use (match_operand:XF 0 "register_operand"))
21309    (use (match_operand:XF 1 "register_operand"))]
21310   "TARGET_USE_FANCY_MATH_387
21311    && flag_unsafe_math_optimizations"
21313   ix86_emit_i387_acosh (operands[0], operands[1]);
21314   DONE;
21317 (define_expand "acosh<mode>2"
21318   [(use (match_operand:MODEF 0 "register_operand"))
21319    (use (match_operand:MODEF 1 "general_operand"))]
21320   "TARGET_USE_FANCY_MATH_387
21321    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21322        || TARGET_MIX_SSE_I387)
21323    && flag_unsafe_math_optimizations"
21325   rtx op0 = gen_reg_rtx (XFmode);
21326   rtx op1 = gen_reg_rtx (XFmode);
21328   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21329   emit_insn (gen_acoshxf2 (op0, op1));
21330   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21331   DONE;
21334 (define_expand "atanhxf2"
21335   [(use (match_operand:XF 0 "register_operand"))
21336    (use (match_operand:XF 1 "register_operand"))]
21337   "TARGET_USE_FANCY_MATH_387
21338    && flag_unsafe_math_optimizations"
21340   ix86_emit_i387_atanh (operands[0], operands[1]);
21341   DONE;
21344 (define_expand "atanh<mode>2"
21345   [(use (match_operand:MODEF 0 "register_operand"))
21346    (use (match_operand:MODEF 1 "general_operand"))]
21347   "TARGET_USE_FANCY_MATH_387
21348    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21349        || TARGET_MIX_SSE_I387)
21350    && flag_unsafe_math_optimizations"
21352   rtx op0 = gen_reg_rtx (XFmode);
21353   rtx op1 = gen_reg_rtx (XFmode);
21355   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21356   emit_insn (gen_atanhxf2 (op0, op1));
21357   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21358   DONE;
21361 (define_insn "fyl2xxf3_i387"
21362   [(set (match_operand:XF 0 "register_operand" "=f")
21363         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21364                     (match_operand:XF 2 "register_operand" "f")]
21365                    UNSPEC_FYL2X))
21366    (clobber (match_scratch:XF 3 "=2"))]
21367   "TARGET_USE_FANCY_MATH_387
21368    && flag_unsafe_math_optimizations"
21369   "fyl2x"
21370   [(set_attr "type" "fpspc")
21371    (set_attr "znver1_decode" "vector")
21372    (set_attr "mode" "XF")])
21374 (define_expand "logxf2"
21375   [(parallel [(set (match_operand:XF 0 "register_operand")
21376                    (unspec:XF [(match_operand:XF 1 "register_operand")
21377                                (match_dup 2)] UNSPEC_FYL2X))
21378               (clobber (scratch:XF))])]
21379   "TARGET_USE_FANCY_MATH_387
21380    && flag_unsafe_math_optimizations"
21382   operands[2]
21383     = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
21386 (define_expand "log<mode>2"
21387   [(use (match_operand:MODEF 0 "register_operand"))
21388    (use (match_operand:MODEF 1 "general_operand"))]
21389   "TARGET_USE_FANCY_MATH_387
21390    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21391        || TARGET_MIX_SSE_I387)
21392    && flag_unsafe_math_optimizations"
21394   rtx op0 = gen_reg_rtx (XFmode);
21395   rtx op1 = gen_reg_rtx (XFmode);
21397   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21398   emit_insn (gen_logxf2 (op0, op1));
21399   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21400   DONE;
21403 (define_expand "log10xf2"
21404   [(parallel [(set (match_operand:XF 0 "register_operand")
21405                    (unspec:XF [(match_operand:XF 1 "register_operand")
21406                                (match_dup 2)] UNSPEC_FYL2X))
21407               (clobber (scratch:XF))])]
21408   "TARGET_USE_FANCY_MATH_387
21409    && flag_unsafe_math_optimizations"
21411   operands[2]
21412     = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
21415 (define_expand "log10<mode>2"
21416   [(use (match_operand:MODEF 0 "register_operand"))
21417    (use (match_operand:MODEF 1 "general_operand"))]
21418   "TARGET_USE_FANCY_MATH_387
21419    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21420        || TARGET_MIX_SSE_I387)
21421    && flag_unsafe_math_optimizations"
21423   rtx op0 = gen_reg_rtx (XFmode);
21424   rtx op1 = gen_reg_rtx (XFmode);
21426   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21427   emit_insn (gen_log10xf2 (op0, op1));
21428   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21429   DONE;
21432 (define_expand "log2xf2"
21433   [(parallel [(set (match_operand:XF 0 "register_operand")
21434                    (unspec:XF [(match_operand:XF 1 "register_operand")
21435                                (match_dup 2)] UNSPEC_FYL2X))
21436               (clobber (scratch:XF))])]
21437   "TARGET_USE_FANCY_MATH_387
21438    && flag_unsafe_math_optimizations"
21439   "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
21441 (define_expand "log2<mode>2"
21442   [(use (match_operand:MODEF 0 "register_operand"))
21443    (use (match_operand:MODEF 1 "general_operand"))]
21444   "TARGET_USE_FANCY_MATH_387
21445    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21446        || TARGET_MIX_SSE_I387)
21447    && flag_unsafe_math_optimizations"
21449   rtx op0 = gen_reg_rtx (XFmode);
21450   rtx op1 = gen_reg_rtx (XFmode);
21452   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21453   emit_insn (gen_log2xf2 (op0, op1));
21454   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21455   DONE;
21458 (define_insn "fyl2xp1xf3_i387"
21459   [(set (match_operand:XF 0 "register_operand" "=f")
21460         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21461                     (match_operand:XF 2 "register_operand" "f")]
21462                    UNSPEC_FYL2XP1))
21463    (clobber (match_scratch:XF 3 "=2"))]
21464   "TARGET_USE_FANCY_MATH_387
21465    && flag_unsafe_math_optimizations"
21466   "fyl2xp1"
21467   [(set_attr "type" "fpspc")
21468    (set_attr "znver1_decode" "vector")
21469    (set_attr "mode" "XF")])
21471 (define_expand "log1pxf2"
21472   [(use (match_operand:XF 0 "register_operand"))
21473    (use (match_operand:XF 1 "register_operand"))]
21474   "TARGET_USE_FANCY_MATH_387
21475    && flag_unsafe_math_optimizations"
21477   ix86_emit_i387_log1p (operands[0], operands[1]);
21478   DONE;
21481 (define_expand "log1p<mode>2"
21482   [(use (match_operand:MODEF 0 "register_operand"))
21483    (use (match_operand:MODEF 1 "general_operand"))]
21484   "TARGET_USE_FANCY_MATH_387
21485    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21486        || TARGET_MIX_SSE_I387)
21487    && flag_unsafe_math_optimizations"
21489   rtx op0 = gen_reg_rtx (XFmode);
21490   rtx op1 = gen_reg_rtx (XFmode);
21492   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21493   emit_insn (gen_log1pxf2 (op0, op1));
21494   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21495   DONE;
21498 (define_insn "fxtractxf3_i387"
21499   [(set (match_operand:XF 0 "register_operand" "=f")
21500         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21501                    UNSPEC_XTRACT_FRACT))
21502    (set (match_operand:XF 1 "register_operand" "=f")
21503         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
21504   "TARGET_USE_FANCY_MATH_387
21505    && flag_unsafe_math_optimizations"
21506   "fxtract"
21507   [(set_attr "type" "fpspc")
21508    (set_attr "znver1_decode" "vector")
21509    (set_attr "mode" "XF")])
21511 (define_expand "logbxf2"
21512   [(parallel [(set (match_dup 2)
21513                    (unspec:XF [(match_operand:XF 1 "register_operand")]
21514                               UNSPEC_XTRACT_FRACT))
21515               (set (match_operand:XF 0 "register_operand")
21516                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21517   "TARGET_USE_FANCY_MATH_387
21518    && flag_unsafe_math_optimizations"
21519   "operands[2] = gen_reg_rtx (XFmode);")
21521 (define_expand "logb<mode>2"
21522   [(use (match_operand:MODEF 0 "register_operand"))
21523    (use (match_operand:MODEF 1 "general_operand"))]
21524   "TARGET_USE_FANCY_MATH_387
21525    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21526        || TARGET_MIX_SSE_I387)
21527    && flag_unsafe_math_optimizations"
21529   rtx op0 = gen_reg_rtx (XFmode);
21530   rtx op1 = gen_reg_rtx (XFmode);
21532   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21533   emit_insn (gen_logbxf2 (op0, op1));
21534   emit_insn (gen_truncxf<mode>2 (operands[0], op1));
21535   DONE;
21538 (define_expand "ilogbxf2"
21539   [(use (match_operand:SI 0 "register_operand"))
21540    (use (match_operand:XF 1 "register_operand"))]
21541   "TARGET_USE_FANCY_MATH_387
21542    && flag_unsafe_math_optimizations"
21544   rtx op0, op1;
21546   if (optimize_insn_for_size_p ())
21547     FAIL;
21549   op0 = gen_reg_rtx (XFmode);
21550   op1 = gen_reg_rtx (XFmode);
21552   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
21553   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21554   DONE;
21557 (define_expand "ilogb<mode>2"
21558   [(use (match_operand:SI 0 "register_operand"))
21559    (use (match_operand:MODEF 1 "general_operand"))]
21560   "TARGET_USE_FANCY_MATH_387
21561    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21562        || TARGET_MIX_SSE_I387)
21563    && flag_unsafe_math_optimizations"
21565   rtx op0, op1, op2;
21567   if (optimize_insn_for_size_p ())
21568     FAIL;
21570   op0 = gen_reg_rtx (XFmode);
21571   op1 = gen_reg_rtx (XFmode);
21572   op2 = gen_reg_rtx (XFmode);
21574   emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
21575   emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
21576   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21577   DONE;
21580 (define_insn "*f2xm1xf2_i387"
21581   [(set (match_operand:XF 0 "register_operand" "=f")
21582         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21583                    UNSPEC_F2XM1))]
21584   "TARGET_USE_FANCY_MATH_387
21585    && flag_unsafe_math_optimizations"
21586   "f2xm1"
21587   [(set_attr "type" "fpspc")
21588    (set_attr "znver1_decode" "vector")
21589    (set_attr "mode" "XF")])
21591 (define_insn "fscalexf4_i387"
21592   [(set (match_operand:XF 0 "register_operand" "=f")
21593         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21594                     (match_operand:XF 3 "register_operand" "1")]
21595                    UNSPEC_FSCALE_FRACT))
21596    (set (match_operand:XF 1 "register_operand" "=f")
21597         (unspec:XF [(match_dup 2) (match_dup 3)]
21598                    UNSPEC_FSCALE_EXP))]
21599   "TARGET_USE_FANCY_MATH_387
21600    && flag_unsafe_math_optimizations"
21601   "fscale"
21602   [(set_attr "type" "fpspc")
21603    (set_attr "znver1_decode" "vector")
21604    (set_attr "mode" "XF")])
21606 (define_expand "expNcorexf3"
21607   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21608                                (match_operand:XF 2 "register_operand")))
21609    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21610    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21611    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21612    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
21613    (parallel [(set (match_operand:XF 0 "register_operand")
21614                    (unspec:XF [(match_dup 8) (match_dup 4)]
21615                               UNSPEC_FSCALE_FRACT))
21616               (set (match_dup 9)
21617                    (unspec:XF [(match_dup 8) (match_dup 4)]
21618                               UNSPEC_FSCALE_EXP))])]
21619   "TARGET_USE_FANCY_MATH_387
21620    && flag_unsafe_math_optimizations"
21622   int i;
21624   for (i = 3; i < 10; i++)
21625     operands[i] = gen_reg_rtx (XFmode);
21627   emit_move_insn (operands[7], CONST1_RTX (XFmode));
21630 (define_expand "expxf2"
21631   [(use (match_operand:XF 0 "register_operand"))
21632    (use (match_operand:XF 1 "register_operand"))]
21633   "TARGET_USE_FANCY_MATH_387
21634    && flag_unsafe_math_optimizations"
21636   rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
21638   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21639   DONE;
21642 (define_expand "exp<mode>2"
21643   [(use (match_operand:MODEF 0 "register_operand"))
21644    (use (match_operand:MODEF 1 "general_operand"))]
21645   "TARGET_USE_FANCY_MATH_387
21646    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21647        || TARGET_MIX_SSE_I387)
21648    && flag_unsafe_math_optimizations"
21650   rtx op0 = gen_reg_rtx (XFmode);
21651   rtx op1 = gen_reg_rtx (XFmode);
21653   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21654   emit_insn (gen_expxf2 (op0, op1));
21655   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21656   DONE;
21659 (define_expand "exp10xf2"
21660   [(use (match_operand:XF 0 "register_operand"))
21661    (use (match_operand:XF 1 "register_operand"))]
21662   "TARGET_USE_FANCY_MATH_387
21663    && flag_unsafe_math_optimizations"
21665   rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
21667   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21668   DONE;
21671 (define_expand "exp10<mode>2"
21672   [(use (match_operand:MODEF 0 "register_operand"))
21673    (use (match_operand:MODEF 1 "general_operand"))]
21674   "TARGET_USE_FANCY_MATH_387
21675    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21676        || TARGET_MIX_SSE_I387)
21677    && flag_unsafe_math_optimizations"
21679   rtx op0 = gen_reg_rtx (XFmode);
21680   rtx op1 = gen_reg_rtx (XFmode);
21682   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21683   emit_insn (gen_exp10xf2 (op0, op1));
21684   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21685   DONE;
21688 (define_expand "exp2xf2"
21689   [(use (match_operand:XF 0 "register_operand"))
21690    (use (match_operand:XF 1 "register_operand"))]
21691   "TARGET_USE_FANCY_MATH_387
21692    && flag_unsafe_math_optimizations"
21694   rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
21696   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21697   DONE;
21700 (define_expand "exp2<mode>2"
21701   [(use (match_operand:MODEF 0 "register_operand"))
21702    (use (match_operand:MODEF 1 "general_operand"))]
21703   "TARGET_USE_FANCY_MATH_387
21704    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21705        || TARGET_MIX_SSE_I387)
21706    && flag_unsafe_math_optimizations"
21708   rtx op0 = gen_reg_rtx (XFmode);
21709   rtx op1 = gen_reg_rtx (XFmode);
21711   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21712   emit_insn (gen_exp2xf2 (op0, op1));
21713   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21714   DONE;
21717 (define_expand "expm1xf2"
21718   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21719                                (match_dup 2)))
21720    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21721    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21722    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21723    (parallel [(set (match_dup 7)
21724                    (unspec:XF [(match_dup 6) (match_dup 4)]
21725                               UNSPEC_FSCALE_FRACT))
21726               (set (match_dup 8)
21727                    (unspec:XF [(match_dup 6) (match_dup 4)]
21728                               UNSPEC_FSCALE_EXP))])
21729    (parallel [(set (match_dup 10)
21730                    (unspec:XF [(match_dup 9) (match_dup 8)]
21731                               UNSPEC_FSCALE_FRACT))
21732               (set (match_dup 11)
21733                    (unspec:XF [(match_dup 9) (match_dup 8)]
21734                               UNSPEC_FSCALE_EXP))])
21735    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
21736    (set (match_operand:XF 0 "register_operand")
21737         (plus:XF (match_dup 12) (match_dup 7)))]
21738   "TARGET_USE_FANCY_MATH_387
21739    && flag_unsafe_math_optimizations"
21741   int i;
21743   for (i = 2; i < 13; i++)
21744     operands[i] = gen_reg_rtx (XFmode);
21746   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
21747   emit_move_insn (operands[9], CONST1_RTX (XFmode));
21750 (define_expand "expm1<mode>2"
21751   [(use (match_operand:MODEF 0 "register_operand"))
21752    (use (match_operand:MODEF 1 "general_operand"))]
21753   "TARGET_USE_FANCY_MATH_387
21754    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21755        || TARGET_MIX_SSE_I387)
21756    && flag_unsafe_math_optimizations"
21758   rtx op0 = gen_reg_rtx (XFmode);
21759   rtx op1 = gen_reg_rtx (XFmode);
21761   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21762   emit_insn (gen_expm1xf2 (op0, op1));
21763   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21764   DONE;
21767 (define_insn "avx512f_scalef<mode>2"
21768   [(set (match_operand:MODEF 0 "register_operand" "=v")
21769         (unspec:MODEF
21770           [(match_operand:MODEF 1 "register_operand" "v")
21771            (match_operand:MODEF 2 "nonimmediate_operand" "vm")]
21772           UNSPEC_SCALEF))]
21773   "TARGET_AVX512F"
21774   "vscalef<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
21775   [(set_attr "prefix" "evex")
21776    (set_attr "mode"  "<MODE>")])
21778 (define_expand "ldexpxf3"
21779   [(match_operand:XF 0 "register_operand")
21780    (match_operand:XF 1 "register_operand")
21781    (match_operand:SI 2 "register_operand")]
21782   "TARGET_USE_FANCY_MATH_387
21783    && flag_unsafe_math_optimizations"
21785   rtx tmp1 = gen_reg_rtx (XFmode);
21786   rtx tmp2 = gen_reg_rtx (XFmode);
21788   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
21789   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
21790                                  operands[1], tmp1));
21791   DONE;
21794 (define_expand "ldexp<mode>3"
21795   [(use (match_operand:MODEF 0 "register_operand"))
21796    (use (match_operand:MODEF 1 "general_operand"))
21797    (use (match_operand:SI 2 "register_operand"))]
21798   "((TARGET_USE_FANCY_MATH_387
21799      && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21800          || TARGET_MIX_SSE_I387))
21801     || (TARGET_AVX512F && TARGET_SSE_MATH))
21802    && flag_unsafe_math_optimizations"
21804   /* Prefer avx512f version.  */
21805   if (TARGET_AVX512F && TARGET_SSE_MATH)
21806    {
21807      rtx op2 = gen_reg_rtx (<MODE>mode);
21808      operands[1] = force_reg (<MODE>mode, operands[1]);
21810      emit_insn (gen_floatsi<mode>2 (op2, operands[2]));
21811      emit_insn (gen_avx512f_scalef<mode>2 (operands[0], operands[1], op2));
21812    }
21813   else
21814     {
21815       rtx op0 = gen_reg_rtx (XFmode);
21816       rtx op1 = gen_reg_rtx (XFmode);
21818       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21819       emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
21820       emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21821   }
21822   DONE;
21825 (define_expand "scalbxf3"
21826   [(parallel [(set (match_operand:XF 0 " register_operand")
21827                    (unspec:XF [(match_operand:XF 1 "register_operand")
21828                                (match_operand:XF 2 "register_operand")]
21829                               UNSPEC_FSCALE_FRACT))
21830               (set (match_dup 3)
21831                    (unspec:XF [(match_dup 1) (match_dup 2)]
21832                               UNSPEC_FSCALE_EXP))])]
21833   "TARGET_USE_FANCY_MATH_387
21834    && flag_unsafe_math_optimizations"
21835   "operands[3] = gen_reg_rtx (XFmode);")
21837 (define_expand "scalb<mode>3"
21838   [(use (match_operand:MODEF 0 "register_operand"))
21839    (use (match_operand:MODEF 1 "general_operand"))
21840    (use (match_operand:MODEF 2 "general_operand"))]
21841   "TARGET_USE_FANCY_MATH_387
21842    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21843        || TARGET_MIX_SSE_I387)
21844    && flag_unsafe_math_optimizations"
21846   rtx op0 = gen_reg_rtx (XFmode);
21847   rtx op1 = gen_reg_rtx (XFmode);
21848   rtx op2 = gen_reg_rtx (XFmode);
21850   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21851   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21852   emit_insn (gen_scalbxf3 (op0, op1, op2));
21853   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21854   DONE;
21857 (define_expand "significandxf2"
21858   [(parallel [(set (match_operand:XF 0 "register_operand")
21859                    (unspec:XF [(match_operand:XF 1 "register_operand")]
21860                               UNSPEC_XTRACT_FRACT))
21861               (set (match_dup 2)
21862                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21863   "TARGET_USE_FANCY_MATH_387
21864    && flag_unsafe_math_optimizations"
21865   "operands[2] = gen_reg_rtx (XFmode);")
21867 (define_expand "significand<mode>2"
21868   [(use (match_operand:MODEF 0 "register_operand"))
21869    (use (match_operand:MODEF 1 "general_operand"))]
21870   "TARGET_USE_FANCY_MATH_387
21871    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21872        || TARGET_MIX_SSE_I387)
21873    && flag_unsafe_math_optimizations"
21875   rtx op0 = gen_reg_rtx (XFmode);
21876   rtx op1 = gen_reg_rtx (XFmode);
21878   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21879   emit_insn (gen_significandxf2 (op0, op1));
21880   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21881   DONE;
21885 (define_insn "sse4_1_round<mode>2"
21886   [(set (match_operand:MODEFH 0 "register_operand" "=x,x,x,v,v")
21887         (unspec:MODEFH
21888           [(match_operand:MODEFH 1 "nonimmediate_operand" "0,x,jm,v,m")
21889            (match_operand:SI 2 "const_0_to_15_operand")]
21890           UNSPEC_ROUND))]
21891   "TARGET_SSE4_1"
21892   "@
21893    %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21894    %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21895    %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
21896    vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21897    vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
21898   [(set_attr "type" "ssecvt")
21899    (set_attr "prefix_extra" "1,1,1,*,*")
21900    (set_attr "length_immediate" "1")
21901    (set_attr "addr" "*,*,gpr16,*,*")
21902    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
21903    (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
21904    (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
21905    (set_attr "mode" "<MODE>")
21906    (set (attr "preferred_for_speed")
21907       (cond [(match_test "TARGET_AVX")
21908                (symbol_ref "true")
21909              (eq_attr "alternative" "1,2")
21910                (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
21911             ]
21912             (symbol_ref "true")))])
21914 (define_insn "rintxf2"
21915   [(set (match_operand:XF 0 "register_operand" "=f")
21916         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21917                    UNSPEC_FRNDINT))]
21918   "TARGET_USE_FANCY_MATH_387"
21919   "frndint"
21920   [(set_attr "type" "fpspc")
21921    (set_attr "znver1_decode" "vector")
21922    (set_attr "mode" "XF")])
21924 (define_expand "rinthf2"
21925   [(match_operand:HF 0 "register_operand")
21926    (match_operand:HF 1 "nonimmediate_operand")]
21927   "TARGET_AVX512FP16"
21929   emit_insn (gen_sse4_1_roundhf2 (operands[0],
21930                                   operands[1],
21931                                   GEN_INT (ROUND_MXCSR)));
21932   DONE;
21935 (define_expand "rint<mode>2"
21936   [(use (match_operand:MODEF 0 "register_operand"))
21937    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
21938   "TARGET_USE_FANCY_MATH_387
21939    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
21941   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21942     {
21943       if (TARGET_SSE4_1)
21944         emit_insn (gen_sse4_1_round<mode>2
21945                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
21946       else
21947         ix86_expand_rint (operands[0], operands[1]);
21948     }
21949   else
21950     {
21951       rtx op0 = gen_reg_rtx (XFmode);
21952       rtx op1 = gen_reg_rtx (XFmode);
21954       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21955       emit_insn (gen_rintxf2 (op0, op1));
21956       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21957     }
21958   DONE;
21961 (define_expand "nearbyintxf2"
21962   [(set (match_operand:XF 0 "register_operand")
21963         (unspec:XF [(match_operand:XF 1 "register_operand")]
21964                    UNSPEC_FRNDINT))]
21965   "TARGET_USE_FANCY_MATH_387
21966    && !flag_trapping_math")
21968 (define_expand "nearbyinthf2"
21969   [(match_operand:HF 0 "register_operand")
21970    (match_operand:HF 1 "nonimmediate_operand")]
21971   "TARGET_AVX512FP16"
21973   emit_insn (gen_sse4_1_roundhf2 (operands[0],
21974                                   operands[1],
21975                                   GEN_INT (ROUND_MXCSR | ROUND_NO_EXC)));
21976   DONE;
21979 (define_expand "nearbyint<mode>2"
21980   [(use (match_operand:MODEF 0 "register_operand"))
21981    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
21982   "(TARGET_USE_FANCY_MATH_387
21983     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21984           || TARGET_MIX_SSE_I387)
21985     && !flag_trapping_math)
21986    || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
21988   if (TARGET_SSE4_1 && TARGET_SSE_MATH)
21989     emit_insn (gen_sse4_1_round<mode>2
21990                (operands[0], operands[1], GEN_INT (ROUND_MXCSR
21991                                                    | ROUND_NO_EXC)));
21992   else
21993     {
21994       rtx op0 = gen_reg_rtx (XFmode);
21995       rtx op1 = gen_reg_rtx (XFmode);
21997       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21998       emit_insn (gen_nearbyintxf2 (op0, op1));
21999       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
22000     }
22001   DONE;
22004 (define_expand "roundhf2"
22005   [(match_operand:HF 0 "register_operand")
22006    (match_operand:HF 1 "register_operand")]
22007   "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
22009   ix86_expand_round_sse4 (operands[0], operands[1]);
22010   DONE;
22013 (define_expand "round<mode>2"
22014   [(match_operand:X87MODEF 0 "register_operand")
22015    (match_operand:X87MODEF 1 "nonimmediate_operand")]
22016   "(TARGET_USE_FANCY_MATH_387
22017     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22018         || TARGET_MIX_SSE_I387)
22019     && flag_unsafe_math_optimizations
22020     && (flag_fp_int_builtin_inexact || !flag_trapping_math))
22021    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22022        && !flag_trapping_math && !flag_rounding_math)"
22024   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22025       && !flag_trapping_math && !flag_rounding_math)
22026     {
22027       if (TARGET_SSE4_1)
22028         {
22029           operands[1] = force_reg (<MODE>mode, operands[1]);
22030           ix86_expand_round_sse4 (operands[0], operands[1]);
22031         }
22032       else if (TARGET_64BIT || (<MODE>mode != DFmode))
22033         ix86_expand_round (operands[0], operands[1]);
22034       else
22035         ix86_expand_rounddf_32 (operands[0], operands[1]);
22036     }
22037   else
22038     {
22039       operands[1] = force_reg (<MODE>mode, operands[1]);
22040       ix86_emit_i387_round (operands[0], operands[1]);
22041     }
22042   DONE;
22045 (define_insn "lrintxfdi2"
22046   [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
22047         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
22048                    UNSPEC_FIST))
22049    (clobber (match_scratch:XF 2 "=&f"))]
22050   "TARGET_USE_FANCY_MATH_387"
22051   "* return output_fix_trunc (insn, operands, false);"
22052   [(set_attr "type" "fpspc")
22053    (set_attr "mode" "DI")])
22055 (define_insn "lrintxf<mode>2"
22056   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
22057         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
22058                       UNSPEC_FIST))]
22059   "TARGET_USE_FANCY_MATH_387"
22060   "* return output_fix_trunc (insn, operands, false);"
22061   [(set_attr "type" "fpspc")
22062    (set_attr "mode" "<MODE>")])
22064 (define_expand "lroundhf<mode>2"
22065   [(set (match_operand:SWI248 0 "register_operand")
22066      (unspec:SWI248 [(match_operand:HF 1 "nonimmediate_operand")]
22067                    UNSPEC_FIX_NOTRUNC))]
22068   "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
22070   ix86_expand_lround (operands[0], operands[1]);
22071   DONE;
22074 (define_expand "lrinthf<mode>2"
22075   [(set (match_operand:SWI48 0 "register_operand")
22076      (unspec:SWI48 [(match_operand:HF 1 "nonimmediate_operand")]
22077                    UNSPEC_FIX_NOTRUNC))]
22078   "TARGET_AVX512FP16")
22080 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
22081   [(set (match_operand:SWI48 0 "register_operand")
22082      (unspec:SWI48 [(match_operand:MODEF 1 "nonimmediate_operand")]
22083                    UNSPEC_FIX_NOTRUNC))]
22084   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
22086 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
22087   [(match_operand:SWI248x 0 "nonimmediate_operand")
22088    (match_operand:X87MODEF 1 "register_operand")]
22089   "(TARGET_USE_FANCY_MATH_387
22090     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
22091         || TARGET_MIX_SSE_I387)
22092     && flag_unsafe_math_optimizations)
22093    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
22094        && <SWI248x:MODE>mode != HImode 
22095        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
22096        && !flag_trapping_math && !flag_rounding_math)"
22098   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
22099       && <SWI248x:MODE>mode != HImode
22100       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
22101       && !flag_trapping_math && !flag_rounding_math)
22102     ix86_expand_lround (operands[0], operands[1]);
22103   else
22104     ix86_emit_i387_round (operands[0], operands[1]);
22105   DONE;
22108 (define_int_iterator FRNDINT_ROUNDING
22109         [UNSPEC_FRNDINT_ROUNDEVEN
22110          UNSPEC_FRNDINT_FLOOR
22111          UNSPEC_FRNDINT_CEIL
22112          UNSPEC_FRNDINT_TRUNC])
22114 (define_int_iterator FIST_ROUNDING
22115         [UNSPEC_FIST_FLOOR
22116          UNSPEC_FIST_CEIL])
22118 ;; Base name for define_insn
22119 (define_int_attr rounding_insn
22120         [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
22121          (UNSPEC_FRNDINT_FLOOR "floor")
22122          (UNSPEC_FRNDINT_CEIL "ceil")
22123          (UNSPEC_FRNDINT_TRUNC "btrunc")
22124          (UNSPEC_FIST_FLOOR "floor")
22125          (UNSPEC_FIST_CEIL "ceil")])
22127 (define_int_attr rounding
22128         [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
22129          (UNSPEC_FRNDINT_FLOOR "floor")
22130          (UNSPEC_FRNDINT_CEIL "ceil")
22131          (UNSPEC_FRNDINT_TRUNC "trunc")
22132          (UNSPEC_FIST_FLOOR "floor")
22133          (UNSPEC_FIST_CEIL "ceil")])
22135 (define_int_attr ROUNDING
22136         [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
22137          (UNSPEC_FRNDINT_FLOOR "FLOOR")
22138          (UNSPEC_FRNDINT_CEIL "CEIL")
22139          (UNSPEC_FRNDINT_TRUNC "TRUNC")
22140          (UNSPEC_FIST_FLOOR "FLOOR")
22141          (UNSPEC_FIST_CEIL "CEIL")])
22143 ;; Rounding mode control word calculation could clobber FLAGS_REG.
22144 (define_insn_and_split "frndintxf2_<rounding>"
22145   [(set (match_operand:XF 0 "register_operand")
22146         (unspec:XF [(match_operand:XF 1 "register_operand")]
22147                    FRNDINT_ROUNDING))
22148    (clobber (reg:CC FLAGS_REG))]
22149   "TARGET_USE_FANCY_MATH_387
22150    && (flag_fp_int_builtin_inexact || !flag_trapping_math)
22151    && ix86_pre_reload_split ()"
22152   "#"
22153   "&& 1"
22154   [(const_int 0)]
22156   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
22158   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
22159   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
22161   emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
22162                                              operands[2], operands[3]));
22163   DONE;
22165   [(set_attr "type" "frndint")
22166    (set_attr "i387_cw" "<rounding>")
22167    (set_attr "mode" "XF")])
22169 (define_insn "frndintxf2_<rounding>_i387"
22170   [(set (match_operand:XF 0 "register_operand" "=f")
22171         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
22172                    FRNDINT_ROUNDING))
22173    (use (match_operand:HI 2 "memory_operand" "m"))
22174    (use (match_operand:HI 3 "memory_operand" "m"))]
22175   "TARGET_USE_FANCY_MATH_387
22176    && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
22177   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
22178   [(set_attr "type" "frndint")
22179    (set_attr "i387_cw" "<rounding>")
22180    (set_attr "mode" "XF")])
22182 (define_expand "<rounding_insn>xf2"
22183   [(parallel [(set (match_operand:XF 0 "register_operand")
22184                    (unspec:XF [(match_operand:XF 1 "register_operand")]
22185                               FRNDINT_ROUNDING))
22186               (clobber (reg:CC FLAGS_REG))])]
22187   "TARGET_USE_FANCY_MATH_387
22188    && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
22190 (define_expand "<rounding_insn>hf2"
22191   [(parallel [(set (match_operand:HF 0 "register_operand")
22192                    (unspec:HF [(match_operand:HF 1 "register_operand")]
22193                      FRNDINT_ROUNDING))
22194               (clobber (reg:CC FLAGS_REG))])]
22195   "TARGET_AVX512FP16"
22197   emit_insn (gen_sse4_1_roundhf2 (operands[0], operands[1],
22198                                   GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22199   DONE;
22202 (define_expand "<rounding_insn><mode>2"
22203   [(parallel [(set (match_operand:MODEF 0 "register_operand")
22204                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
22205                                  FRNDINT_ROUNDING))
22206               (clobber (reg:CC FLAGS_REG))])]
22207   "(TARGET_USE_FANCY_MATH_387
22208     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22209         || TARGET_MIX_SSE_I387)
22210     && (flag_fp_int_builtin_inexact || !flag_trapping_math))
22211    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22212        && (TARGET_SSE4_1
22213            || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
22214                && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
22216   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22217       && (TARGET_SSE4_1
22218           || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
22219               && (flag_fp_int_builtin_inexact || !flag_trapping_math))))
22220     {
22221       if (TARGET_SSE4_1)
22222         emit_insn (gen_sse4_1_round<mode>2
22223                    (operands[0], operands[1],
22224                     GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22225       else if (TARGET_64BIT || (<MODE>mode != DFmode))
22226         {
22227           if (ROUND_<ROUNDING> == ROUND_FLOOR)
22228             ix86_expand_floorceil (operands[0], operands[1], true);
22229           else if (ROUND_<ROUNDING> == ROUND_CEIL)
22230             ix86_expand_floorceil (operands[0], operands[1], false);
22231           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
22232             ix86_expand_trunc (operands[0], operands[1]);
22233           else
22234             gcc_unreachable ();
22235         }
22236       else
22237         {
22238           if (ROUND_<ROUNDING> == ROUND_FLOOR)
22239             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
22240           else if (ROUND_<ROUNDING> == ROUND_CEIL)
22241             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
22242           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
22243             ix86_expand_truncdf_32 (operands[0], operands[1]);
22244           else
22245             gcc_unreachable ();
22246         }
22247     }
22248   else
22249     {
22250       rtx op0 = gen_reg_rtx (XFmode);
22251       rtx op1 = gen_reg_rtx (XFmode);
22253       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22254       emit_insn (gen_frndintxf2_<rounding> (op0, op1));
22255       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
22256     }
22257   DONE;
22260 ;; Rounding mode control word calculation could clobber FLAGS_REG.
22261 (define_insn_and_split "*fist<mode>2_<rounding>_1"
22262   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
22263         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
22264                         FIST_ROUNDING))
22265    (clobber (reg:CC FLAGS_REG))]
22266   "TARGET_USE_FANCY_MATH_387
22267    && flag_unsafe_math_optimizations
22268    && ix86_pre_reload_split ()"
22269   "#"
22270   "&& 1"
22271   [(const_int 0)]
22273   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
22275   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
22276   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
22278   emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
22279                                          operands[2], operands[3]));
22280   DONE;
22282   [(set_attr "type" "fistp")
22283    (set_attr "i387_cw" "<rounding>")
22284    (set_attr "mode" "<MODE>")])
22286 (define_insn "fistdi2_<rounding>"
22287   [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
22288         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
22289                    FIST_ROUNDING))
22290    (use (match_operand:HI 2 "memory_operand" "m"))
22291    (use (match_operand:HI 3 "memory_operand" "m"))
22292    (clobber (match_scratch:XF 4 "=&f"))]
22293   "TARGET_USE_FANCY_MATH_387
22294    && flag_unsafe_math_optimizations"
22295   "* return output_fix_trunc (insn, operands, false);"
22296   [(set_attr "type" "fistp")
22297    (set_attr "i387_cw" "<rounding>")
22298    (set_attr "mode" "DI")])
22300 (define_insn "fist<mode>2_<rounding>"
22301   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
22302         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
22303                       FIST_ROUNDING))
22304    (use (match_operand:HI 2 "memory_operand" "m"))
22305    (use (match_operand:HI 3 "memory_operand" "m"))]
22306   "TARGET_USE_FANCY_MATH_387
22307    && flag_unsafe_math_optimizations"
22308   "* return output_fix_trunc (insn, operands, false);"
22309   [(set_attr "type" "fistp")
22310    (set_attr "i387_cw" "<rounding>")
22311    (set_attr "mode" "<MODE>")])
22313 (define_expand "l<rounding_insn>xf<mode>2"
22314   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
22315                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
22316                                    FIST_ROUNDING))
22317               (clobber (reg:CC FLAGS_REG))])]
22318   "TARGET_USE_FANCY_MATH_387
22319    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
22320    && flag_unsafe_math_optimizations")
22322 (define_expand "l<rounding_insn>hf<mode>2"
22323   [(set (match_operand:SWI48 0 "nonimmediate_operand")
22324         (unspec:SWI48 [(match_operand:HF 1 "register_operand")]
22325                     FIST_ROUNDING))]
22326   "TARGET_AVX512FP16"
22328   rtx tmp = gen_reg_rtx (HFmode);
22329   emit_insn (gen_sse4_1_roundhf2 (tmp, operands[1],
22330                                  GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22331   emit_insn (gen_fix_trunchf<mode>2 (operands[0], tmp));
22332   DONE;
22335 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
22336   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
22337                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
22338                                  FIST_ROUNDING))
22339               (clobber (reg:CC FLAGS_REG))])]
22340   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
22341    && (TARGET_SSE4_1 || !flag_trapping_math)"
22343   if (TARGET_SSE4_1)
22344     {
22345       rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
22347       emit_insn (gen_sse4_1_round<MODEF:mode>2
22348                  (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
22349                                              | ROUND_NO_EXC)));
22350       emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
22351                  (operands[0], tmp));
22352     }
22353   else if (ROUND_<ROUNDING> == ROUND_FLOOR)
22354     ix86_expand_lfloorceil (operands[0], operands[1], true);
22355   else if (ROUND_<ROUNDING> == ROUND_CEIL)
22356     ix86_expand_lfloorceil (operands[0], operands[1], false);
22357   else
22358     gcc_unreachable ();
22360   DONE;
22363 (define_insn "fxam<mode>2_i387"
22364   [(set (match_operand:HI 0 "register_operand" "=a")
22365         (unspec:HI
22366           [(match_operand:X87MODEF 1 "register_operand" "f")]
22367           UNSPEC_FXAM))]
22368   "TARGET_USE_FANCY_MATH_387"
22369   "fxam\n\tfnstsw\t%0"
22370   [(set_attr "type" "multi")
22371    (set_attr "length" "4")
22372    (set_attr "unit" "i387")
22373    (set_attr "mode" "<MODE>")])
22375 (define_expand "signbittf2"
22376   [(use (match_operand:SI 0 "register_operand"))
22377    (use (match_operand:TF 1 "register_operand"))]
22378   "TARGET_SSE"
22380   if (TARGET_SSE4_1)
22381     {
22382       rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
22383       rtx scratch = gen_reg_rtx (QImode);
22385       emit_insn (gen_ptesttf2 (operands[1], mask));
22386         ix86_expand_setcc (scratch, NE,
22387                            gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
22389       emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
22390     }
22391   else
22392     {
22393       emit_insn (gen_sse_movmskps (operands[0],
22394                                    gen_lowpart (V4SFmode, operands[1])));
22395       emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
22396     }
22397   DONE;
22400 (define_expand "signbitxf2"
22401   [(use (match_operand:SI 0 "register_operand"))
22402    (use (match_operand:XF 1 "register_operand"))]
22403   "TARGET_USE_FANCY_MATH_387"
22405   rtx scratch = gen_reg_rtx (HImode);
22407   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
22408   emit_insn (gen_andsi3 (operands[0],
22409              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22410   DONE;
22413 (define_insn "movmsk_df"
22414   [(set (match_operand:SI 0 "register_operand" "=r,jr")
22415         (unspec:SI
22416           [(match_operand:DF 1 "register_operand" "x,x")]
22417           UNSPEC_MOVMSK))]
22418   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
22419   "%vmovmskpd\t{%1, %0|%0, %1}"
22420   [(set_attr "isa" "noavx,avx")
22421    (set_attr "type" "ssemov")
22422    (set_attr "prefix" "maybe_evex")
22423    (set_attr "mode" "DF")])
22425 ;; Use movmskpd in SSE mode to avoid store forwarding stall
22426 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
22427 (define_expand "signbitdf2"
22428   [(use (match_operand:SI 0 "register_operand"))
22429    (use (match_operand:DF 1 "register_operand"))]
22430   "TARGET_USE_FANCY_MATH_387
22431    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
22433   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
22434     {
22435       emit_insn (gen_movmsk_df (operands[0], operands[1]));
22436       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
22437     }
22438   else
22439     {
22440       rtx scratch = gen_reg_rtx (HImode);
22442       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
22443       emit_insn (gen_andsi3 (operands[0],
22444                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22445     }
22446   DONE;
22449 (define_expand "signbitsf2"
22450   [(use (match_operand:SI 0 "register_operand"))
22451    (use (match_operand:SF 1 "register_operand"))]
22452   "TARGET_USE_FANCY_MATH_387
22453    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
22455   rtx scratch = gen_reg_rtx (HImode);
22457   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
22458   emit_insn (gen_andsi3 (operands[0],
22459              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22460   DONE;
22463 ;; Block operation instructions
22465 (define_insn "cld"
22466   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
22467   ""
22468   "cld"
22469   [(set_attr "length" "1")
22470    (set_attr "length_immediate" "0")
22471    (set_attr "modrm" "0")])
22473 (define_expand "cpymem<mode>"
22474   [(use (match_operand:BLK 0 "memory_operand"))
22475    (use (match_operand:BLK 1 "memory_operand"))
22476    (use (match_operand:SWI48 2 "nonmemory_operand"))
22477    (use (match_operand:SWI48 3 "const_int_operand"))
22478    (use (match_operand:SI 4 "const_int_operand"))
22479    (use (match_operand:SI 5 "const_int_operand"))
22480    (use (match_operand:SI 6 ""))
22481    (use (match_operand:SI 7 ""))
22482    (use (match_operand:SI 8 ""))]
22483   ""
22485  if (ix86_expand_set_or_cpymem (operands[0], operands[1],
22486                                 operands[2], NULL, operands[3],
22487                                 operands[4], operands[5],
22488                                 operands[6], operands[7],
22489                                 operands[8], false))
22490    DONE;
22491  else
22492    FAIL;
22495 ;; Most CPUs don't like single string operations
22496 ;; Handle this case here to simplify previous expander.
22498 (define_expand "strmov"
22499   [(set (match_dup 4) (match_operand 3 "memory_operand"))
22500    (set (match_operand 1 "memory_operand") (match_dup 4))
22501    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
22502               (clobber (reg:CC FLAGS_REG))])
22503    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
22504               (clobber (reg:CC FLAGS_REG))])]
22505   ""
22507   /* Can't use this for non-default address spaces.  */
22508   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
22509     FAIL;
22511   int piece_size = GET_MODE_SIZE (GET_MODE (operands[1]));
22513   /* If .md ever supports :P for Pmode, these can be directly
22514      in the pattern above.  */
22515   operands[5] = plus_constant (Pmode, operands[0], piece_size);
22516   operands[6] = plus_constant (Pmode, operands[2], piece_size);
22518   /* Can't use this if the user has appropriated esi or edi.  */
22519   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22520       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
22521     {
22522       emit_insn (gen_strmov_singleop (operands[0], operands[1],
22523                                       operands[2], operands[3],
22524                                       operands[5], operands[6]));
22525       DONE;
22526     }
22528   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
22531 (define_expand "strmov_singleop"
22532   [(parallel [(set (match_operand 1 "memory_operand")
22533                    (match_operand 3 "memory_operand"))
22534               (set (match_operand 0 "register_operand")
22535                    (match_operand 4))
22536               (set (match_operand 2 "register_operand")
22537                    (match_operand 5))])]
22538   ""
22540   if (TARGET_CLD)
22541     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22544 (define_insn "*strmovdi_rex_1"
22545   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
22546         (mem:DI (match_operand:P 3 "register_operand" "1")))
22547    (set (match_operand:P 0 "register_operand" "=D")
22548         (plus:P (match_dup 2)
22549                 (const_int 8)))
22550    (set (match_operand:P 1 "register_operand" "=S")
22551         (plus:P (match_dup 3)
22552                 (const_int 8)))]
22553   "TARGET_64BIT
22554    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22555    && ix86_check_no_addr_space (insn)"
22556   "%^movsq"
22557   [(set_attr "type" "str")
22558    (set_attr "memory" "both")
22559    (set_attr "mode" "DI")])
22561 (define_insn "*strmovsi_1"
22562   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
22563         (mem:SI (match_operand:P 3 "register_operand" "1")))
22564    (set (match_operand:P 0 "register_operand" "=D")
22565         (plus:P (match_dup 2)
22566                 (const_int 4)))
22567    (set (match_operand:P 1 "register_operand" "=S")
22568         (plus:P (match_dup 3)
22569                 (const_int 4)))]
22570   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22571    && ix86_check_no_addr_space (insn)"
22572   "%^movs{l|d}"
22573   [(set_attr "type" "str")
22574    (set_attr "memory" "both")
22575    (set_attr "mode" "SI")])
22577 (define_insn "*strmovhi_1"
22578   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
22579         (mem:HI (match_operand:P 3 "register_operand" "1")))
22580    (set (match_operand:P 0 "register_operand" "=D")
22581         (plus:P (match_dup 2)
22582                 (const_int 2)))
22583    (set (match_operand:P 1 "register_operand" "=S")
22584         (plus:P (match_dup 3)
22585                 (const_int 2)))]
22586   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22587    && ix86_check_no_addr_space (insn)"
22588   "%^movsw"
22589   [(set_attr "type" "str")
22590    (set_attr "memory" "both")
22591    (set_attr "mode" "HI")])
22593 (define_insn "*strmovqi_1"
22594   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
22595         (mem:QI (match_operand:P 3 "register_operand" "1")))
22596    (set (match_operand:P 0 "register_operand" "=D")
22597         (plus:P (match_dup 2)
22598                 (const_int 1)))
22599    (set (match_operand:P 1 "register_operand" "=S")
22600         (plus:P (match_dup 3)
22601                 (const_int 1)))]
22602   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22603    && ix86_check_no_addr_space (insn)"
22604   "%^movsb"
22605   [(set_attr "type" "str")
22606    (set_attr "memory" "both")
22607    (set (attr "prefix_rex")
22608         (if_then_else
22609           (match_test "<P:MODE>mode == DImode")
22610           (const_string "0")
22611           (const_string "*")))
22612    (set_attr "mode" "QI")])
22614 (define_expand "rep_mov"
22615   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
22616               (set (match_operand 0 "register_operand")
22617                    (match_operand 5))
22618               (set (match_operand 2 "register_operand")
22619                    (match_operand 6))
22620               (set (match_operand 1 "memory_operand")
22621                    (match_operand 3 "memory_operand"))
22622               (use (match_dup 4))])]
22623   ""
22625   if (TARGET_CLD)
22626     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22629 (define_insn "*rep_movdi_rex64"
22630   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22631    (set (match_operand:P 0 "register_operand" "=D")
22632         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22633                           (const_int 3))
22634                 (match_operand:P 3 "register_operand" "0")))
22635    (set (match_operand:P 1 "register_operand" "=S")
22636         (plus:P (ashift:P (match_dup 5) (const_int 3))
22637                 (match_operand:P 4 "register_operand" "1")))
22638    (set (mem:BLK (match_dup 3))
22639         (mem:BLK (match_dup 4)))
22640    (use (match_dup 5))]
22641   "TARGET_64BIT
22642    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22643    && ix86_check_no_addr_space (insn)"
22644   "%^rep{%;} movsq"
22645   [(set_attr "type" "str")
22646    (set_attr "prefix_rep" "1")
22647    (set_attr "memory" "both")
22648    (set_attr "mode" "DI")])
22650 (define_insn "*rep_movsi"
22651   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22652    (set (match_operand:P 0 "register_operand" "=D")
22653         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22654                           (const_int 2))
22655                  (match_operand:P 3 "register_operand" "0")))
22656    (set (match_operand:P 1 "register_operand" "=S")
22657         (plus:P (ashift:P (match_dup 5) (const_int 2))
22658                 (match_operand:P 4 "register_operand" "1")))
22659    (set (mem:BLK (match_dup 3))
22660         (mem:BLK (match_dup 4)))
22661    (use (match_dup 5))]
22662   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22663    && ix86_check_no_addr_space (insn)"
22664   "%^rep{%;} movs{l|d}"
22665   [(set_attr "type" "str")
22666    (set_attr "prefix_rep" "1")
22667    (set_attr "memory" "both")
22668    (set_attr "mode" "SI")])
22670 (define_insn "*rep_movqi"
22671   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22672    (set (match_operand:P 0 "register_operand" "=D")
22673         (plus:P (match_operand:P 3 "register_operand" "0")
22674                 (match_operand:P 5 "register_operand" "2")))
22675    (set (match_operand:P 1 "register_operand" "=S")
22676         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
22677    (set (mem:BLK (match_dup 3))
22678         (mem:BLK (match_dup 4)))
22679    (use (match_dup 5))]
22680   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22681    && ix86_check_no_addr_space (insn)"
22682   "%^rep{%;} movsb"
22683   [(set_attr "type" "str")
22684    (set_attr "prefix_rep" "1")
22685    (set_attr "memory" "both")
22686    (set_attr "mode" "QI")])
22688 (define_expand "setmem<mode>"
22689    [(use (match_operand:BLK 0 "memory_operand"))
22690     (use (match_operand:SWI48 1 "nonmemory_operand"))
22691     (use (match_operand:QI 2 "nonmemory_operand"))
22692     (use (match_operand 3 "const_int_operand"))
22693     (use (match_operand:SI 4 "const_int_operand"))
22694     (use (match_operand:SI 5 "const_int_operand"))
22695     (use (match_operand:SI 6 ""))
22696     (use (match_operand:SI 7 ""))
22697     (use (match_operand:SI 8 ""))]
22698   ""
22700  if (ix86_expand_set_or_cpymem (operands[0], NULL,
22701                                 operands[1], operands[2],
22702                                 operands[3], operands[4],
22703                                 operands[5], operands[6],
22704                                 operands[7], operands[8], true))
22705    DONE;
22706  else
22707    FAIL;
22710 ;; Most CPUs don't like single string operations
22711 ;; Handle this case here to simplify previous expander.
22713 (define_expand "strset"
22714   [(set (match_operand 1 "memory_operand")
22715         (match_operand 2 "register_operand"))
22716    (parallel [(set (match_operand 0 "register_operand")
22717                    (match_dup 3))
22718               (clobber (reg:CC FLAGS_REG))])]
22719   ""
22721   /* Can't use this for non-default address spaces.  */
22722   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
22723     FAIL;
22725   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
22726     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
22728   /* If .md ever supports :P for Pmode, this can be directly
22729      in the pattern above.  */
22730   operands[3] = plus_constant (Pmode, operands[0],
22731                                GET_MODE_SIZE (GET_MODE (operands[2])));
22733   /* Can't use this if the user has appropriated eax or edi.  */
22734   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22735       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
22736     {
22737       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
22738                                       operands[3]));
22739       DONE;
22740     }
22743 (define_expand "strset_singleop"
22744   [(parallel [(set (match_operand 1 "memory_operand")
22745                    (match_operand 2 "register_operand"))
22746               (set (match_operand 0 "register_operand")
22747                    (match_operand 3))
22748               (unspec [(const_int 0)] UNSPEC_STOS)])]
22749   ""
22751   if (TARGET_CLD)
22752     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22755 (define_insn "*strsetdi_rex_1"
22756   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
22757         (match_operand:DI 2 "register_operand" "a"))
22758    (set (match_operand:P 0 "register_operand" "=D")
22759         (plus:P (match_dup 1)
22760                 (const_int 8)))
22761    (unspec [(const_int 0)] UNSPEC_STOS)]
22762   "TARGET_64BIT
22763    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22764    && ix86_check_no_addr_space (insn)"
22765   "%^stosq"
22766   [(set_attr "type" "str")
22767    (set_attr "memory" "store")
22768    (set_attr "mode" "DI")])
22770 (define_insn "*strsetsi_1"
22771   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
22772         (match_operand:SI 2 "register_operand" "a"))
22773    (set (match_operand:P 0 "register_operand" "=D")
22774         (plus:P (match_dup 1)
22775                 (const_int 4)))
22776    (unspec [(const_int 0)] UNSPEC_STOS)]
22777   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22778    && ix86_check_no_addr_space (insn)"
22779   "%^stos{l|d}"
22780   [(set_attr "type" "str")
22781    (set_attr "memory" "store")
22782    (set_attr "mode" "SI")])
22784 (define_insn "*strsethi_1"
22785   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
22786         (match_operand:HI 2 "register_operand" "a"))
22787    (set (match_operand:P 0 "register_operand" "=D")
22788         (plus:P (match_dup 1)
22789                 (const_int 2)))
22790    (unspec [(const_int 0)] UNSPEC_STOS)]
22791   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22792    && ix86_check_no_addr_space (insn)"
22793   "%^stosw"
22794   [(set_attr "type" "str")
22795    (set_attr "memory" "store")
22796    (set_attr "mode" "HI")])
22798 (define_insn "*strsetqi_1"
22799   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
22800         (match_operand:QI 2 "register_operand" "a"))
22801    (set (match_operand:P 0 "register_operand" "=D")
22802         (plus:P (match_dup 1)
22803                 (const_int 1)))
22804    (unspec [(const_int 0)] UNSPEC_STOS)]
22805   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22806    && ix86_check_no_addr_space (insn)"
22807   "%^stosb"
22808   [(set_attr "type" "str")
22809    (set_attr "memory" "store")
22810    (set (attr "prefix_rex")
22811         (if_then_else
22812           (match_test "<P:MODE>mode == DImode")
22813           (const_string "0")
22814           (const_string "*")))
22815    (set_attr "mode" "QI")])
22817 (define_expand "rep_stos"
22818   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
22819               (set (match_operand 0 "register_operand")
22820                    (match_operand 4))
22821               (set (match_operand 2 "memory_operand") (const_int 0))
22822               (use (match_operand 3 "register_operand"))
22823               (use (match_dup 1))])]
22824   ""
22826   if (TARGET_CLD)
22827     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22830 (define_insn "*rep_stosdi_rex64"
22831   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22832    (set (match_operand:P 0 "register_operand" "=D")
22833         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22834                           (const_int 3))
22835                  (match_operand:P 3 "register_operand" "0")))
22836    (set (mem:BLK (match_dup 3))
22837         (const_int 0))
22838    (use (match_operand:DI 2 "register_operand" "a"))
22839    (use (match_dup 4))]
22840   "TARGET_64BIT
22841    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22842    && ix86_check_no_addr_space (insn)"
22843   "%^rep{%;} stosq"
22844   [(set_attr "type" "str")
22845    (set_attr "prefix_rep" "1")
22846    (set_attr "memory" "store")
22847    (set_attr "mode" "DI")])
22849 (define_insn "*rep_stossi"
22850   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22851    (set (match_operand:P 0 "register_operand" "=D")
22852         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22853                           (const_int 2))
22854                  (match_operand:P 3 "register_operand" "0")))
22855    (set (mem:BLK (match_dup 3))
22856         (const_int 0))
22857    (use (match_operand:SI 2 "register_operand" "a"))
22858    (use (match_dup 4))]
22859   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22860    && ix86_check_no_addr_space (insn)"
22861   "%^rep{%;} stos{l|d}"
22862   [(set_attr "type" "str")
22863    (set_attr "prefix_rep" "1")
22864    (set_attr "memory" "store")
22865    (set_attr "mode" "SI")])
22867 (define_insn "*rep_stosqi"
22868   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22869    (set (match_operand:P 0 "register_operand" "=D")
22870         (plus:P (match_operand:P 3 "register_operand" "0")
22871                 (match_operand:P 4 "register_operand" "1")))
22872    (set (mem:BLK (match_dup 3))
22873         (const_int 0))
22874    (use (match_operand:QI 2 "register_operand" "a"))
22875    (use (match_dup 4))]
22876   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22877    && ix86_check_no_addr_space (insn)"
22878   "%^rep{%;} stosb"
22879   [(set_attr "type" "str")
22880    (set_attr "prefix_rep" "1")
22881    (set_attr "memory" "store")
22882    (set (attr "prefix_rex")
22883         (if_then_else
22884           (match_test "<P:MODE>mode == DImode")
22885           (const_string "0")
22886           (const_string "*")))
22887    (set_attr "mode" "QI")])
22889 (define_expand "cmpmemsi"
22890   [(set (match_operand:SI 0 "register_operand" "")
22891         (compare:SI (match_operand:BLK 1 "memory_operand" "")
22892                     (match_operand:BLK 2 "memory_operand" "") ) )
22893    (use (match_operand 3 "general_operand"))
22894    (use (match_operand 4 "immediate_operand"))]
22895   ""
22897   if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22898                                      operands[2], operands[3],
22899                                      operands[4], false))
22900     DONE;
22901   else
22902     FAIL;
22905 (define_expand "cmpstrnsi"
22906   [(set (match_operand:SI 0 "register_operand")
22907         (compare:SI (match_operand:BLK 1 "general_operand")
22908                     (match_operand:BLK 2 "general_operand")))
22909    (use (match_operand 3 "general_operand"))
22910    (use (match_operand 4 "immediate_operand"))]
22911   ""
22913   if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22914                                      operands[2], operands[3],
22915                                      operands[4], true))
22916     DONE;
22917   else
22918     FAIL;
22921 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
22923 (define_expand "cmpintqi"
22924   [(set (match_dup 1)
22925         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22926    (set (match_dup 2)
22927         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22928    (parallel [(set (match_operand:QI 0 "register_operand")
22929                    (minus:QI (match_dup 1)
22930                              (match_dup 2)))
22931               (clobber (reg:CC FLAGS_REG))])]
22932   ""
22934   operands[1] = gen_reg_rtx (QImode);
22935   operands[2] = gen_reg_rtx (QImode);
22938 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
22939 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
22941 (define_expand "cmpstrnqi_nz_1"
22942   [(parallel [(set (reg:CC FLAGS_REG)
22943                    (compare:CC (match_operand 4 "memory_operand")
22944                                (match_operand 5 "memory_operand")))
22945               (use (match_operand 2 "register_operand"))
22946               (use (match_operand:SI 3 "immediate_operand"))
22947               (clobber (match_operand 0 "register_operand"))
22948               (clobber (match_operand 1 "register_operand"))
22949               (clobber (match_dup 2))])]
22950   ""
22952   if (TARGET_CLD)
22953     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22956 (define_insn "*cmpstrnqi_nz_1"
22957   [(set (reg:CC FLAGS_REG)
22958         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
22959                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
22960    (use (match_operand:P 6 "register_operand" "2"))
22961    (use (match_operand:SI 3 "immediate_operand" "i"))
22962    (clobber (match_operand:P 0 "register_operand" "=S"))
22963    (clobber (match_operand:P 1 "register_operand" "=D"))
22964    (clobber (match_operand:P 2 "register_operand" "=c"))]
22965   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22966    && ix86_check_no_addr_space (insn)"
22967   "%^repz{%;} cmpsb"
22968   [(set_attr "type" "str")
22969    (set_attr "mode" "QI")
22970    (set (attr "prefix_rex")
22971         (if_then_else
22972           (match_test "<P:MODE>mode == DImode")
22973           (const_string "0")
22974           (const_string "*")))
22975    (set_attr "prefix_rep" "1")])
22977 ;; The same, but the count is not known to not be zero.
22979 (define_expand "cmpstrnqi_1"
22980   [(parallel [(set (reg:CC FLAGS_REG)
22981                 (if_then_else:CC (ne (match_operand 2 "register_operand")
22982                                      (const_int 0))
22983                   (compare:CC (match_operand 4 "memory_operand")
22984                               (match_operand 5 "memory_operand"))
22985                   (const_int 0)))
22986               (use (match_operand:SI 3 "immediate_operand"))
22987               (use (reg:CC FLAGS_REG))
22988               (clobber (match_operand 0 "register_operand"))
22989               (clobber (match_operand 1 "register_operand"))
22990               (clobber (match_dup 2))])]
22991   ""
22993   if (TARGET_CLD)
22994     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22997 (define_insn "*cmpstrnqi_1"
22998   [(set (reg:CC FLAGS_REG)
22999         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
23000                              (const_int 0))
23001           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
23002                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
23003           (const_int 0)))
23004    (use (match_operand:SI 3 "immediate_operand" "i"))
23005    (use (reg:CC FLAGS_REG))
23006    (clobber (match_operand:P 0 "register_operand" "=S"))
23007    (clobber (match_operand:P 1 "register_operand" "=D"))
23008    (clobber (match_operand:P 2 "register_operand" "=c"))]
23009   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
23010    && ix86_check_no_addr_space (insn)"
23011   "%^repz{%;} cmpsb"
23012   [(set_attr "type" "str")
23013    (set_attr "mode" "QI")
23014    (set (attr "prefix_rex")
23015         (if_then_else
23016           (match_test "<P:MODE>mode == DImode")
23017           (const_string "0")
23018           (const_string "*")))
23019    (set_attr "prefix_rep" "1")])
23021 (define_expand "strlen<mode>"
23022   [(set (match_operand:P 0 "register_operand")
23023         (unspec:P [(match_operand:BLK 1 "general_operand")
23024                    (match_operand:QI 2 "immediate_operand")
23025                    (match_operand 3 "immediate_operand")]
23026                   UNSPEC_SCAS))]
23027   ""
23029  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
23030    DONE;
23031  else
23032    FAIL;
23035 (define_expand "strlenqi_1"
23036   [(parallel [(set (match_operand 0 "register_operand")
23037                    (match_operand 2))
23038               (clobber (match_operand 1 "register_operand"))
23039               (clobber (reg:CC FLAGS_REG))])]
23040   ""
23042   if (TARGET_CLD)
23043     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
23046 (define_insn "*strlenqi_1"
23047   [(set (match_operand:P 0 "register_operand" "=&c")
23048         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
23049                    (match_operand:QI 2 "register_operand" "a")
23050                    (match_operand:P 3 "immediate_operand" "i")
23051                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
23052    (clobber (match_operand:P 1 "register_operand" "=D"))
23053    (clobber (reg:CC FLAGS_REG))]
23054   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
23055    && ix86_check_no_addr_space (insn)"
23056   "%^repnz{%;} scasb"
23057   [(set_attr "type" "str")
23058    (set_attr "mode" "QI")
23059    (set (attr "prefix_rex")
23060         (if_then_else
23061           (match_test "<P:MODE>mode == DImode")
23062           (const_string "0")
23063           (const_string "*")))
23064    (set_attr "prefix_rep" "1")])
23066 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
23067 ;; handled in combine, but it is not currently up to the task.
23068 ;; When used for their truth value, the cmpstrn* expanders generate
23069 ;; code like this:
23071 ;;   repz cmpsb
23072 ;;   seta       %al
23073 ;;   setb       %dl
23074 ;;   cmpb       %al, %dl
23075 ;;   jcc        label
23077 ;; The intermediate three instructions are unnecessary.
23079 ;; This one handles cmpstrn*_nz_1...
23080 (define_peephole2
23081   [(parallel[
23082      (set (reg:CC FLAGS_REG)
23083           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
23084                       (mem:BLK (match_operand 5 "register_operand"))))
23085      (use (match_operand 6 "register_operand"))
23086      (use (match_operand:SI 3 "immediate_operand"))
23087      (clobber (match_operand 0 "register_operand"))
23088      (clobber (match_operand 1 "register_operand"))
23089      (clobber (match_operand 2 "register_operand"))])
23090    (set (match_operand:QI 7 "register_operand")
23091         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
23092    (set (match_operand:QI 8 "register_operand")
23093         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
23094    (set (reg FLAGS_REG)
23095         (compare (match_dup 7) (match_dup 8)))
23096   ]
23097   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
23098   [(parallel[
23099      (set (reg:CC FLAGS_REG)
23100           (compare:CC (mem:BLK (match_dup 4))
23101                       (mem:BLK (match_dup 5))))
23102      (use (match_dup 6))
23103      (use (match_dup 3))
23104      (clobber (match_dup 0))
23105      (clobber (match_dup 1))
23106      (clobber (match_dup 2))])])
23108 ;; ...and this one handles cmpstrn*_1.
23109 (define_peephole2
23110   [(parallel[
23111      (set (reg:CC FLAGS_REG)
23112           (if_then_else:CC (ne (match_operand 6 "register_operand")
23113                                (const_int 0))
23114             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
23115                         (mem:BLK (match_operand 5 "register_operand")))
23116             (const_int 0)))
23117      (use (match_operand:SI 3 "immediate_operand"))
23118      (use (reg:CC FLAGS_REG))
23119      (clobber (match_operand 0 "register_operand"))
23120      (clobber (match_operand 1 "register_operand"))
23121      (clobber (match_operand 2 "register_operand"))])
23122    (set (match_operand:QI 7 "register_operand")
23123         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
23124    (set (match_operand:QI 8 "register_operand")
23125         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
23126    (set (reg FLAGS_REG)
23127         (compare (match_dup 7) (match_dup 8)))
23128   ]
23129   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
23130   [(parallel[
23131      (set (reg:CC FLAGS_REG)
23132           (if_then_else:CC (ne (match_dup 6)
23133                                (const_int 0))
23134             (compare:CC (mem:BLK (match_dup 4))
23135                         (mem:BLK (match_dup 5)))
23136             (const_int 0)))
23137      (use (match_dup 3))
23138      (use (reg:CC FLAGS_REG))
23139      (clobber (match_dup 0))
23140      (clobber (match_dup 1))
23141      (clobber (match_dup 2))])])
23143 ;; Conditional move instructions.
23145 (define_expand "mov<mode>cc"
23146   [(set (match_operand:SWIM 0 "register_operand")
23147         (if_then_else:SWIM (match_operand 1 "comparison_operator")
23148                            (match_operand:SWIM 2 "<general_operand>")
23149                            (match_operand:SWIM 3 "<general_operand>")))]
23150   ""
23151   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
23153 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
23154 ;; the register first winds up with `sbbl $0,reg', which is also weird.
23155 ;; So just document what we're doing explicitly.
23157 (define_expand "x86_mov<mode>cc_0_m1"
23158   [(parallel
23159     [(set (match_operand:SWI48 0 "register_operand")
23160           (if_then_else:SWI48
23161             (match_operator:SWI48 2 "ix86_carry_flag_operator"
23162              [(match_operand 1 "flags_reg_operand")
23163               (const_int 0)])
23164             (const_int -1)
23165             (const_int 0)))
23166      (clobber (reg:CC FLAGS_REG))])])
23168 (define_insn "*x86_mov<mode>cc_0_m1"
23169   [(set (match_operand:SWI48 0 "register_operand" "=r")
23170         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
23171                              [(reg FLAGS_REG) (const_int 0)])
23172           (const_int -1)
23173           (const_int 0)))
23174    (clobber (reg:CC FLAGS_REG))]
23175   ""
23176   "sbb{<imodesuffix>}\t%0, %0"
23177   [(set_attr "type" "alu1")
23178    (set_attr "use_carry" "1")
23179    (set_attr "pent_pair" "pu")
23180    (set_attr "mode" "<MODE>")
23181    (set_attr "length_immediate" "0")])
23183 (define_insn "*x86_mov<mode>cc_0_m1_se"
23184   [(set (match_operand:SWI48 0 "register_operand" "=r")
23185         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
23186                              [(reg FLAGS_REG) (const_int 0)])
23187                             (const_int 1)
23188                             (const_int 0)))
23189    (clobber (reg:CC FLAGS_REG))]
23190   ""
23191   "sbb{<imodesuffix>}\t%0, %0"
23192   [(set_attr "type" "alu1")
23193    (set_attr "use_carry" "1")
23194    (set_attr "pent_pair" "pu")
23195    (set_attr "mode" "<MODE>")
23196    (set_attr "length_immediate" "0")])
23198 (define_insn "*x86_mov<mode>cc_0_m1_neg"
23199   [(set (match_operand:SWI 0 "register_operand" "=<r>")
23200         (neg:SWI (match_operator 1 "ix86_carry_flag_operator"
23201                   [(reg FLAGS_REG) (const_int 0)])))
23202    (clobber (reg:CC FLAGS_REG))]
23203   ""
23204   "sbb{<imodesuffix>}\t%0, %0"
23205   [(set_attr "type" "alu1")
23206    (set_attr "use_carry" "1")
23207    (set_attr "pent_pair" "pu")
23208    (set_attr "mode" "<MODE>")
23209    (set_attr "length_immediate" "0")])
23211 (define_expand "x86_mov<mode>cc_0_m1_neg"
23212   [(parallel
23213     [(set (match_operand:SWI48 0 "register_operand")
23214           (neg:SWI48 (ltu:SWI48 (reg:CCC FLAGS_REG) (const_int 0))))
23215      (clobber (reg:CC FLAGS_REG))])])
23217 (define_split
23218   [(set (match_operand:SWI48 0 "register_operand")
23219         (neg:SWI48
23220           (leu:SWI48
23221             (match_operand 1 "int_nonimmediate_operand")
23222             (match_operand 2 "const_int_operand"))))]
23223   "x86_64_immediate_operand (operands[2], VOIDmode)
23224    && INTVAL (operands[2]) != -1
23225    && INTVAL (operands[2]) != 2147483647"
23226   [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
23227    (set (match_dup 0)
23228         (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))]
23229   "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
23231 (define_split
23232   [(set (match_operand:SWI 0 "register_operand")
23233         (neg:SWI
23234           (eq:SWI
23235             (match_operand 1 "int_nonimmediate_operand")
23236             (const_int 0))))]
23237   ""
23238   [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (const_int 1)))
23239    (set (match_dup 0)
23240         (neg:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))])
23242 (define_split
23243   [(set (match_operand:SWI 0 "register_operand")
23244         (neg:SWI
23245           (ne:SWI
23246             (match_operand 1 "int_nonimmediate_operand")
23247             (const_int 0))))]
23248   ""
23249   [(set (reg:CCC FLAGS_REG)
23250         (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
23251    (set (match_dup 0)
23252         (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))])
23254 (define_insn "*mov<mode>cc_noc"
23255   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
23256         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23257                                [(reg FLAGS_REG) (const_int 0)])
23258           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
23259           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
23260   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23261   "@
23262    cmov%O2%C1\t{%2, %0|%0, %2}
23263    cmov%O2%c1\t{%3, %0|%0, %3}"
23264   [(set_attr "type" "icmov")
23265    (set_attr "mode" "<MODE>")])
23267 (define_insn "*movsicc_noc_zext"
23268   [(set (match_operand:DI 0 "register_operand" "=r,r")
23269         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
23270                            [(reg FLAGS_REG) (const_int 0)])
23271           (zero_extend:DI
23272             (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
23273           (zero_extend:DI
23274             (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
23275   "TARGET_64BIT
23276    && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23277   "@
23278    cmov%O2%C1\t{%2, %k0|%k0, %2}
23279    cmov%O2%c1\t{%3, %k0|%k0, %3}"
23280   [(set_attr "type" "icmov")
23281    (set_attr "mode" "SI")])
23283 (define_insn "*movsicc_noc_zext_1"
23284   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r")
23285         (zero_extend:DI
23286           (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
23287                              [(reg FLAGS_REG) (const_int 0)])
23288              (match_operand:SI 2 "nonimmediate_operand" "rm,0")
23289              (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
23290   "TARGET_64BIT
23291    && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23292   "@
23293    cmov%O2%C1\t{%2, %k0|%k0, %2}
23294    cmov%O2%c1\t{%3, %k0|%k0, %3}"
23295   [(set_attr "type" "icmov")
23296    (set_attr "mode" "SI")])
23299 ;; Don't do conditional moves with memory inputs.  This splitter helps
23300 ;; register starved x86_32 by forcing inputs into registers before reload.
23301 (define_split
23302   [(set (match_operand:SWI248 0 "register_operand")
23303         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23304                                [(reg FLAGS_REG) (const_int 0)])
23305           (match_operand:SWI248 2 "nonimmediate_operand")
23306           (match_operand:SWI248 3 "nonimmediate_operand")))]
23307   "!TARGET_64BIT && TARGET_CMOVE
23308    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23309    && (MEM_P (operands[2]) || MEM_P (operands[3]))
23310    && can_create_pseudo_p ()
23311    && optimize_insn_for_speed_p ()"
23312   [(set (match_dup 0)
23313         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
23315   operands[2] = force_reg (<MODE>mode, operands[2]);
23316   operands[3] = force_reg (<MODE>mode, operands[3]);
23319 (define_insn "*movqicc_noc"
23320   [(set (match_operand:QI 0 "register_operand" "=r,r")
23321         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
23322                            [(reg FLAGS_REG) (const_int 0)])
23323                       (match_operand:QI 2 "register_operand" "r,0")
23324                       (match_operand:QI 3 "register_operand" "0,r")))]
23325   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
23326   "#"
23327   [(set_attr "type" "icmov")
23328    (set_attr "mode" "QI")])
23330 (define_split
23331   [(set (match_operand:SWI12 0 "register_operand")
23332         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
23333                               [(reg FLAGS_REG) (const_int 0)])
23334                       (match_operand:SWI12 2 "register_operand")
23335                       (match_operand:SWI12 3 "register_operand")))]
23336   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
23337    && reload_completed"
23338   [(set (match_dup 0)
23339         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
23341   operands[0] = gen_lowpart (SImode, operands[0]);
23342   operands[2] = gen_lowpart (SImode, operands[2]);
23343   operands[3] = gen_lowpart (SImode, operands[3]);
23346 ;; Don't do conditional moves with memory inputs
23347 (define_peephole2
23348   [(match_scratch:SWI248 4 "r")
23349    (set (match_operand:SWI248 0 "register_operand")
23350         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23351                                [(reg FLAGS_REG) (const_int 0)])
23352           (match_operand:SWI248 2 "nonimmediate_operand")
23353           (match_operand:SWI248 3 "nonimmediate_operand")))]
23354   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23355    && (MEM_P (operands[2]) || MEM_P (operands[3]))
23356    && optimize_insn_for_speed_p ()"
23357   [(set (match_dup 4) (match_dup 5))
23358    (set (match_dup 0)
23359         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
23361   if (MEM_P (operands[2]))
23362     {
23363       operands[5] = operands[2];
23364       operands[2] = operands[4];
23365     }
23366   else if (MEM_P (operands[3]))
23367     {
23368       operands[5] = operands[3];
23369       operands[3] = operands[4];
23370     }
23371   else
23372     gcc_unreachable ();
23375 (define_peephole2
23376   [(match_scratch:SI 4 "r")
23377    (set (match_operand:DI 0 "register_operand")
23378         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
23379                            [(reg FLAGS_REG) (const_int 0)])
23380           (zero_extend:DI
23381             (match_operand:SI 2 "nonimmediate_operand"))
23382           (zero_extend:DI
23383             (match_operand:SI 3 "nonimmediate_operand"))))]
23384   "TARGET_64BIT
23385    && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23386    && (MEM_P (operands[2]) || MEM_P (operands[3]))
23387    && optimize_insn_for_speed_p ()"
23388   [(set (match_dup 4) (match_dup 5))
23389    (set (match_dup 0)
23390         (if_then_else:DI (match_dup 1)
23391           (zero_extend:DI (match_dup 2))
23392           (zero_extend:DI (match_dup 3))))]
23394   if (MEM_P (operands[2]))
23395     {
23396       operands[5] = operands[2];
23397       operands[2] = operands[4];
23398     }
23399   else if (MEM_P (operands[3]))
23400     {
23401       operands[5] = operands[3];
23402       operands[3] = operands[4];
23403     }
23404   else
23405     gcc_unreachable ();
23408 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#1).
23409 ;; mov r0,r1; dec r0; mov r2,r3; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
23410 (define_peephole2
23411  [(set (match_operand:SWI248 0 "general_reg_operand")
23412        (match_operand:SWI248 1 "general_reg_operand"))
23413   (parallel [(set (reg FLAGS_REG) (match_operand 5))
23414              (set (match_dup 0) (match_operand:SWI248 6))])
23415   (set (match_operand:SWI248 2 "general_reg_operand")
23416        (match_operand:SWI248 3 "general_gr_operand"))
23417   (set (match_dup 0)
23418        (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
23419                              [(reg FLAGS_REG) (const_int 0)])
23420         (match_dup 0)
23421         (match_dup 2)))]
23422  "TARGET_CMOVE
23423   && REGNO (operands[2]) != REGNO (operands[0])
23424   && REGNO (operands[2]) != REGNO (operands[1])
23425   && peep2_reg_dead_p (1, operands[1])
23426   && peep2_reg_dead_p (4, operands[2])
23427   && !reg_overlap_mentioned_p (operands[0], operands[3])"
23428  [(parallel [(set (match_dup 7) (match_dup 8))
23429              (set (match_dup 1) (match_dup 9))])
23430   (set (match_dup 0) (match_dup 3))
23431   (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23432                                           (match_dup 1)
23433                                           (match_dup 0)))]
23435   operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
23436   operands[8]
23437     = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23438   operands[9]
23439     = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23442 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#2).
23443 ;; mov r2,r3; mov r0,r1; dec r0; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
23444 (define_peephole2
23445  [(set (match_operand:SWI248 2 "general_reg_operand")
23446        (match_operand:SWI248 3 "general_gr_operand"))
23447   (set (match_operand:SWI248 0 "general_reg_operand")
23448        (match_operand:SWI248 1 "general_reg_operand"))
23449   (parallel [(set (reg FLAGS_REG) (match_operand 5))
23450              (set (match_dup 0) (match_operand:SWI248 6))])
23451   (set (match_dup 0)
23452        (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
23453                              [(reg FLAGS_REG) (const_int 0)])
23454         (match_dup 0)
23455         (match_dup 2)))]
23456  "TARGET_CMOVE
23457   && REGNO (operands[2]) != REGNO (operands[0])
23458   && REGNO (operands[2]) != REGNO (operands[1])
23459   && peep2_reg_dead_p (2, operands[1])
23460   && peep2_reg_dead_p (4, operands[2])
23461   && !reg_overlap_mentioned_p (operands[0], operands[3])
23462   && !reg_mentioned_p (operands[2], operands[6])"
23463  [(parallel [(set (match_dup 7) (match_dup 8))
23464              (set (match_dup 1) (match_dup 9))])
23465   (set (match_dup 0) (match_dup 3))
23466   (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23467                                           (match_dup 1)
23468                                           (match_dup 0)))]
23470   operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (2)), 0, 0));
23471   operands[8]
23472     = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23473   operands[9]
23474     = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23477 (define_insn "movhf_mask"
23478   [(set (match_operand:HF 0 "nonimmediate_operand" "=v,m,v")
23479         (unspec:HF
23480           [(match_operand:HF 1 "nonimmediate_operand" "m,v,v")
23481            (match_operand:HF 2 "nonimm_or_0_operand" "0C,0C,0C")
23482            (match_operand:QI 3 "register_operand" "Yk,Yk,Yk")]
23483           UNSPEC_MOVCC_MASK))]
23484   "TARGET_AVX512FP16"
23485   "@
23486    vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23487    vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23488    vmovsh\t{%d1, %0%{%3%}%N2|%0%{%3%}%N2, %d1}"
23489   [(set_attr "type" "ssemov")
23490    (set_attr "prefix" "evex")
23491    (set_attr "mode" "HF")])
23493 (define_expand "movhfcc"
23494   [(set (match_operand:HF 0 "register_operand")
23495         (if_then_else:HF
23496           (match_operand 1 "comparison_operator")
23497           (match_operand:HF 2 "register_operand")
23498           (match_operand:HF 3 "register_operand")))]
23499   "TARGET_AVX512FP16"
23500   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23502 (define_expand "mov<mode>cc"
23503   [(set (match_operand:X87MODEF 0 "register_operand")
23504         (if_then_else:X87MODEF
23505           (match_operand 1 "comparison_operator")
23506           (match_operand:X87MODEF 2 "register_operand")
23507           (match_operand:X87MODEF 3 "register_operand")))]
23508   "(TARGET_80387 && TARGET_CMOVE)
23509    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
23510   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23512 (define_insn "*movxfcc_1"
23513   [(set (match_operand:XF 0 "register_operand" "=f,f")
23514         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
23515                                 [(reg FLAGS_REG) (const_int 0)])
23516                       (match_operand:XF 2 "register_operand" "f,0")
23517                       (match_operand:XF 3 "register_operand" "0,f")))]
23518   "TARGET_80387 && TARGET_CMOVE"
23519   "@
23520    fcmov%F1\t{%2, %0|%0, %2}
23521    fcmov%f1\t{%3, %0|%0, %3}"
23522   [(set_attr "type" "fcmov")
23523    (set_attr "mode" "XF")])
23525 (define_insn "*movdfcc_1"
23526   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
23527         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23528                                 [(reg FLAGS_REG) (const_int 0)])
23529                       (match_operand:DF 2 "nonimmediate_operand"
23530                                                "f ,0,rm,0 ,rm,0")
23531                       (match_operand:DF 3 "nonimmediate_operand"
23532                                                "0 ,f,0 ,rm,0, rm")))]
23533   "TARGET_80387 && TARGET_CMOVE
23534    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23535   "@
23536    fcmov%F1\t{%2, %0|%0, %2}
23537    fcmov%f1\t{%3, %0|%0, %3}
23538    #
23539    #
23540    cmov%O2%C1\t{%2, %0|%0, %2}
23541    cmov%O2%c1\t{%3, %0|%0, %3}"
23542   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
23543    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
23544    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
23546 (define_split
23547   [(set (match_operand:DF 0 "general_reg_operand")
23548         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23549                                 [(reg FLAGS_REG) (const_int 0)])
23550                       (match_operand:DF 2 "nonimmediate_operand")
23551                       (match_operand:DF 3 "nonimmediate_operand")))]
23552   "!TARGET_64BIT && reload_completed"
23553   [(set (match_dup 2)
23554         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
23555    (set (match_dup 3)
23556         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
23558   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
23559   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
23562 (define_insn "*movsfcc_1_387"
23563   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
23564         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
23565                                 [(reg FLAGS_REG) (const_int 0)])
23566                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
23567                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
23568   "TARGET_80387 && TARGET_CMOVE
23569    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23570   "@
23571    fcmov%F1\t{%2, %0|%0, %2}
23572    fcmov%f1\t{%3, %0|%0, %3}
23573    cmov%O2%C1\t{%2, %0|%0, %2}
23574    cmov%O2%c1\t{%3, %0|%0, %3}"
23575   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
23576    (set_attr "mode" "SF,SF,SI,SI")])
23578 ;; Don't do conditional moves with memory inputs.  This splitter helps
23579 ;; register starved x86_32 by forcing inputs into registers before reload.
23580 (define_split
23581   [(set (match_operand:MODEF 0 "register_operand")
23582         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
23583                               [(reg FLAGS_REG) (const_int 0)])
23584           (match_operand:MODEF 2 "nonimmediate_operand")
23585           (match_operand:MODEF 3 "nonimmediate_operand")))]
23586   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
23587    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23588    && (MEM_P (operands[2]) || MEM_P (operands[3]))
23589    && can_create_pseudo_p ()
23590    && optimize_insn_for_speed_p ()"
23591   [(set (match_dup 0)
23592         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23594   operands[2] = force_reg (<MODE>mode, operands[2]);
23595   operands[3] = force_reg (<MODE>mode, operands[3]);
23598 ;; Don't do conditional moves with memory inputs
23599 (define_peephole2
23600   [(match_scratch:MODEF 4 "r")
23601    (set (match_operand:MODEF 0 "general_reg_operand")
23602         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
23603                               [(reg FLAGS_REG) (const_int 0)])
23604           (match_operand:MODEF 2 "nonimmediate_operand")
23605           (match_operand:MODEF 3 "nonimmediate_operand")))]
23606   "(<MODE>mode != DFmode || TARGET_64BIT)
23607    && TARGET_80387 && TARGET_CMOVE
23608    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23609    && (MEM_P (operands[2]) || MEM_P (operands[3]))
23610    && optimize_insn_for_speed_p ()"
23611   [(set (match_dup 4) (match_dup 5))
23612    (set (match_dup 0)
23613         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23615   if (MEM_P (operands[2]))
23616     {
23617       operands[5] = operands[2];
23618       operands[2] = operands[4];
23619     }
23620   else if (MEM_P (operands[3]))
23621     {
23622       operands[5] = operands[3];
23623       operands[3] = operands[4];
23624     }
23625   else
23626     gcc_unreachable ();
23629 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
23630 ;; the scalar versions to have only XMM registers as operands.
23632 ;; XOP conditional move
23633 (define_insn "*xop_pcmov_<mode>"
23634   [(set (match_operand:MODEF 0 "register_operand" "=x")
23635         (if_then_else:MODEF
23636           (match_operand:MODEF 1 "register_operand" "x")
23637           (match_operand:MODEF 2 "register_operand" "x")
23638           (match_operand:MODEF 3 "register_operand" "x")))]
23639   "TARGET_XOP"
23640   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
23641   [(set_attr "type" "sse4arg")
23642    (set_attr "mode" "TI")])
23644 ;; These versions of the min/max patterns are intentionally ignorant of
23645 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
23646 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
23647 ;; are undefined in this condition, we're certain this is correct.
23649 (define_insn "<code><mode>3"
23650   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23651         (smaxmin:MODEF
23652           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
23653           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
23654   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23655   "@
23656    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
23657    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23658   [(set_attr "isa" "noavx,avx")
23659    (set_attr "prefix" "orig,vex")
23660    (set_attr "type" "sseadd")
23661    (set_attr "mode" "<MODE>")])
23663 (define_insn "<code>hf3"
23664   [(set (match_operand:HF 0 "register_operand" "=v")
23665         (smaxmin:HF
23666           (match_operand:HF 1 "nonimmediate_operand" "%v")
23667           (match_operand:HF 2 "nonimmediate_operand" "vm")))]
23668   "TARGET_AVX512FP16"
23669   "v<maxmin_float>sh\t{%2, %1, %0|%0, %1, %2}"
23670   [(set_attr "prefix" "evex")
23671    (set_attr "type" "sseadd")
23672    (set_attr "mode" "HF")])
23674 ;; These versions of the min/max patterns implement exactly the operations
23675 ;;   min = (op1 < op2 ? op1 : op2)
23676 ;;   max = (!(op1 < op2) ? op1 : op2)
23677 ;; Their operands are not commutative, and thus they may be used in the
23678 ;; presence of -0.0 and NaN.
23680 (define_insn "*ieee_s<ieee_maxmin>hf3"
23681   [(set (match_operand:HF 0 "register_operand" "=v")
23682         (unspec:HF
23683           [(match_operand:HF 1 "register_operand" "v")
23684            (match_operand:HF 2 "nonimmediate_operand" "vm")]
23685           IEEE_MAXMIN))]
23686   "TARGET_AVX512FP16"
23687   "v<ieee_maxmin>sh\t{%2, %1, %0|%0, %1, %2}"
23688   [(set_attr "prefix" "evex")
23689    (set_attr "type" "sseadd")
23690    (set_attr "mode" "HF")])
23692 (define_insn "*ieee_s<ieee_maxmin><mode>3"
23693   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23694         (unspec:MODEF
23695           [(match_operand:MODEF 1 "register_operand" "0,v")
23696            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
23697           IEEE_MAXMIN))]
23698   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23699   "@
23700    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
23701    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23702   [(set_attr "isa" "noavx,avx")
23703    (set_attr "prefix" "orig,maybe_evex")
23704    (set_attr "type" "sseadd")
23705    (set_attr "mode" "<MODE>")])
23707 ;; Operands order in min/max instruction matters for signed zero and NANs.
23708 (define_insn_and_split "*ieee_max<mode>3_1"
23709   [(set (match_operand:MODEF 0 "register_operand")
23710         (unspec:MODEF
23711           [(match_operand:MODEF 1 "register_operand")
23712            (match_operand:MODEF 2 "register_operand")
23713            (lt:MODEF
23714              (match_operand:MODEF 3 "register_operand")
23715              (match_operand:MODEF 4 "register_operand"))]
23716           UNSPEC_BLENDV))]
23717   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23718   && (rtx_equal_p (operands[1], operands[3])
23719       && rtx_equal_p (operands[2], operands[4]))
23720   && ix86_pre_reload_split ()"
23721   "#"
23722   "&& 1"
23723   [(set (match_dup 0)
23724         (unspec:MODEF
23725           [(match_dup 2)
23726            (match_dup 1)]
23727          UNSPEC_IEEE_MAX))])
23729 (define_insn_and_split "*ieee_min<mode>3_1"
23730   [(set (match_operand:MODEF 0 "register_operand")
23731         (unspec:MODEF
23732           [(match_operand:MODEF 1 "register_operand")
23733            (match_operand:MODEF 2 "register_operand")
23734            (lt:MODEF
23735              (match_operand:MODEF 3 "register_operand")
23736              (match_operand:MODEF 4 "register_operand"))]
23737           UNSPEC_BLENDV))]
23738   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23739   && (rtx_equal_p (operands[1], operands[4])
23740       && rtx_equal_p (operands[2], operands[3]))
23741   && ix86_pre_reload_split ()"
23742   "#"
23743   "&& 1"
23744   [(set (match_dup 0)
23745         (unspec:MODEF
23746           [(match_dup 2)
23747            (match_dup 1)]
23748          UNSPEC_IEEE_MIN))])
23750 ;; Make two stack loads independent:
23751 ;;   fld aa              fld aa
23752 ;;   fld %st(0)     ->   fld bb
23753 ;;   fmul bb             fmul %st(1), %st
23755 ;; Actually we only match the last two instructions for simplicity.
23757 (define_peephole2
23758   [(set (match_operand 0 "fp_register_operand")
23759         (match_operand 1 "fp_register_operand"))
23760    (set (match_dup 0)
23761         (match_operator 2 "binary_fp_operator"
23762            [(match_dup 0)
23763             (match_operand 3 "memory_operand")]))]
23764   "REGNO (operands[0]) != REGNO (operands[1])"
23765   [(set (match_dup 0) (match_dup 3))
23766    (set (match_dup 0)
23767         (match_op_dup 2
23768           [(match_dup 5) (match_dup 4)]))]
23770   operands[4] = operands[0];
23771   operands[5] = operands[1];
23773   /* The % modifier is not operational anymore in peephole2's, so we have to
23774      swap the operands manually in the case of addition and multiplication. */
23775   if (COMMUTATIVE_ARITH_P (operands[2]))
23776     std::swap (operands[4], operands[5]);
23779 (define_peephole2
23780   [(set (match_operand 0 "fp_register_operand")
23781         (match_operand 1 "fp_register_operand"))
23782    (set (match_dup 0)
23783         (match_operator 2 "binary_fp_operator"
23784            [(match_operand 3 "memory_operand")
23785             (match_dup 0)]))]
23786   "REGNO (operands[0]) != REGNO (operands[1])"
23787   [(set (match_dup 0) (match_dup 3))
23788    (set (match_dup 0)
23789         (match_op_dup 2
23790           [(match_dup 4) (match_dup 5)]))]
23792   operands[4] = operands[0];
23793   operands[5] = operands[1];
23795   /* The % modifier is not operational anymore in peephole2's, so we have to
23796      swap the operands manually in the case of addition and multiplication. */
23797   if (COMMUTATIVE_ARITH_P (operands[2]))
23798     std::swap (operands[4], operands[5]);
23801 ;; Conditional addition patterns
23802 (define_expand "add<mode>cc"
23803   [(match_operand:SWI 0 "register_operand")
23804    (match_operand 1 "ordered_comparison_operator")
23805    (match_operand:SWI 2 "register_operand")
23806    (match_operand:SWI 3 "const_int_operand")]
23807   ""
23808   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
23810 ;; min/max patterns
23812 (define_code_attr maxmin_rel
23813   [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
23815 (define_expand "<code><mode>3"
23816   [(parallel
23817     [(set (match_operand:SDWIM 0 "register_operand")
23818           (maxmin:SDWIM
23819             (match_operand:SDWIM 1 "register_operand")
23820             (match_operand:SDWIM 2 "general_operand")))
23821      (clobber (reg:CC FLAGS_REG))])]
23822   "TARGET_CMOVE
23823    && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)")
23825 (define_insn_and_split "*<code><dwi>3_doubleword"
23826   [(set (match_operand:<DWI> 0 "register_operand")
23827         (maxmin:<DWI>
23828           (match_operand:<DWI> 1 "register_operand")
23829           (match_operand:<DWI> 2 "general_operand")))
23830    (clobber (reg:CC FLAGS_REG))]
23831   "TARGET_CMOVE
23832    && ix86_pre_reload_split ()"
23833   "#"
23834   "&& 1"
23835   [(set (match_dup 0)
23836         (if_then_else:DWIH (match_dup 6)
23837           (match_dup 1)
23838           (match_dup 2)))
23839    (set (match_dup 3)
23840         (if_then_else:DWIH (match_dup 6)
23841           (match_dup 4)
23842           (match_dup 5)))]
23844   operands[2] = force_reg (<DWI>mode, operands[2]);
23846   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
23848   rtx cmplo[2] = { operands[1], operands[2] };
23849   rtx cmphi[2] = { operands[4], operands[5] };
23851   enum rtx_code code = <maxmin_rel>;
23853   switch (code)
23854     {
23855     case LE: case LEU:
23856       std::swap (cmplo[0], cmplo[1]);
23857       std::swap (cmphi[0], cmphi[1]);
23858       code = swap_condition (code);
23859       /* FALLTHRU */
23861     case GE: case GEU:
23862       {
23863         bool uns = (code == GEU);
23864         rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
23865           = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
23867         emit_insn (gen_cmp_1 (<MODE>mode, cmplo[0], cmplo[1]));
23869         rtx tmp = gen_rtx_SCRATCH (<MODE>mode);
23870         emit_insn (sbb_insn (<MODE>mode, tmp, cmphi[0], cmphi[1]));
23872         rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
23873         operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23875         break;
23876       }
23878     default:
23879       gcc_unreachable ();
23880     }
23883 (define_insn_and_split "*<code><mode>3_1"
23884   [(set (match_operand:SWI 0 "register_operand")
23885         (maxmin:SWI
23886           (match_operand:SWI 1 "register_operand")
23887           (match_operand:SWI 2 "general_operand")))
23888    (clobber (reg:CC FLAGS_REG))]
23889   "TARGET_CMOVE
23890    && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
23891    && ix86_pre_reload_split ()"
23892   "#"
23893   "&& 1"
23894   [(set (match_dup 0)
23895         (if_then_else:SWI (match_dup 3)
23896           (match_dup 1)
23897           (match_dup 2)))]
23899   machine_mode mode = <MODE>mode;
23900   rtx cmp_op = operands[2];
23902   operands[2] = force_reg (mode, cmp_op);
23904   enum rtx_code code = <maxmin_rel>;
23906   if (cmp_op == const1_rtx)
23907     {
23908       /* Convert smax (x, 1) into (x > 0 ? x : 1).
23909          Convert umax (x, 1) into (x != 0 ? x : 1).
23910          Convert ?min (x, 1) into (x <= 0 ? x : 1).  */
23911       cmp_op = const0_rtx;
23912       if (code == GE)
23913         code = GT;
23914       else if (code == GEU)
23915         code = NE;
23916     }
23917   /* Convert smin (x, -1) into (x < 0 ? x : -1).  */
23918   else if (cmp_op == constm1_rtx && code == LE)
23919     {
23920       cmp_op = const0_rtx;
23921       code = LT;
23922     }
23923   /* Convert smax (x, -1) into (x >= 0 ? x : -1).  */
23924   else if (cmp_op == constm1_rtx && code == GE)
23925     cmp_op = const0_rtx;
23926   else if (cmp_op != const0_rtx)
23927     cmp_op = operands[2];
23929   machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], cmp_op);
23930   rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
23932   rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], cmp_op);
23933   emit_insn (gen_rtx_SET (flags, tmp));
23935   operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23938 ;; Avoid clearing a register between a flags setting comparison and its use,
23939 ;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
23940 (define_peephole2
23941   [(set (reg FLAGS_REG) (match_operand 0))
23942    (set (match_operand:SWI 1 "general_reg_operand") (const_int 0))]
23943   "peep2_regno_dead_p (0, FLAGS_REG)
23944    && !reg_overlap_mentioned_p (operands[1], operands[0])"
23945    [(set (match_dup 2) (match_dup 0))]
23947   operands[2] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
23948   ix86_expand_clear (operands[1]);
23951 ;; When optimizing for size, zeroing memory should use a register.
23952 (define_peephole2
23953   [(match_scratch:SWI48 0 "r")
23954    (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23955    (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
23956    (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
23957    (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
23958   "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23959   [(const_int 0)]
23961   ix86_expand_clear (operands[0]);
23962   emit_move_insn (operands[1], operands[0]);
23963   emit_move_insn (operands[2], operands[0]);
23964   emit_move_insn (operands[3], operands[0]);
23965   ix86_last_zero_store_uid
23966     = INSN_UID (emit_move_insn (operands[4], operands[0]));
23967   DONE;
23970 (define_peephole2
23971   [(match_scratch:SWI48 0 "r")
23972    (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23973    (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
23974   "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23975   [(const_int 0)]
23977   ix86_expand_clear (operands[0]);
23978   emit_move_insn (operands[1], operands[0]);
23979   ix86_last_zero_store_uid
23980     = INSN_UID (emit_move_insn (operands[2], operands[0]));
23981   DONE;
23984 (define_peephole2
23985   [(match_scratch:SWI48 0 "r")
23986    (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
23987   "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23988   [(const_int 0)]
23990   ix86_expand_clear (operands[0]);
23991   ix86_last_zero_store_uid
23992     = INSN_UID (emit_move_insn (operands[1], operands[0]));
23993   DONE;
23996 (define_peephole2
23997   [(set (match_operand:SWI48 5 "memory_operand")
23998         (match_operand:SWI48 0 "general_reg_operand"))
23999    (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
24000    (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
24001    (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
24002    (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
24003   "optimize_insn_for_size_p ()
24004    && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
24005   [(const_int 0)]
24007   emit_move_insn (operands[5], operands[0]);
24008   emit_move_insn (operands[1], operands[0]);
24009   emit_move_insn (operands[2], operands[0]);
24010   emit_move_insn (operands[3], operands[0]);
24011   ix86_last_zero_store_uid
24012     = INSN_UID (emit_move_insn (operands[4], operands[0]));
24013   DONE;
24016 (define_peephole2
24017   [(set (match_operand:SWI48 3 "memory_operand")
24018         (match_operand:SWI48 0 "general_reg_operand"))
24019    (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
24020    (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
24021   "optimize_insn_for_size_p ()
24022    && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
24023   [(const_int 0)]
24025   emit_move_insn (operands[3], operands[0]);
24026   emit_move_insn (operands[1], operands[0]);
24027   ix86_last_zero_store_uid
24028     = INSN_UID (emit_move_insn (operands[2], operands[0]));
24029   DONE;
24032 (define_peephole2
24033   [(set (match_operand:SWI48 2 "memory_operand")
24034         (match_operand:SWI48 0 "general_reg_operand"))
24035    (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
24036   "optimize_insn_for_size_p ()
24037    && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
24038   [(const_int 0)]
24040   emit_move_insn (operands[2], operands[0]);
24041   ix86_last_zero_store_uid
24042     = INSN_UID (emit_move_insn (operands[1], operands[0]));
24043   DONE;
24046 ;; Reload dislikes loading constants directly into class_likely_spilled
24047 ;; hard registers.  Try to tidy things up here.
24048 (define_peephole2
24049   [(set (match_operand:SWI 0 "general_reg_operand")
24050         (match_operand:SWI 1 "x86_64_general_operand"))
24051    (set (match_operand:SWI 2 "general_reg_operand")
24052         (match_dup 0))]
24053   "peep2_reg_dead_p (2, operands[0])"
24054   [(set (match_dup 2) (match_dup 1))])
24056 ;; Misc patterns (?)
24058 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
24059 ;; Otherwise there will be nothing to keep
24061 ;; [(set (reg ebp) (reg esp))]
24062 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
24063 ;;  (clobber (eflags)]
24064 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
24066 ;; in proper program order.
24068 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
24069   [(set (match_operand:P 0 "register_operand" "=r,r")
24070         (plus:P (match_operand:P 1 "register_operand" "0,r")
24071                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
24072    (clobber (reg:CC FLAGS_REG))
24073    (clobber (mem:BLK (scratch)))]
24074   ""
24076   switch (get_attr_type (insn))
24077     {
24078     case TYPE_IMOV:
24079       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
24081     case TYPE_ALU:
24082       gcc_assert (rtx_equal_p (operands[0], operands[1]));
24083       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
24084         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
24086       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
24088     default:
24089       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
24090       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
24091     }
24093   [(set (attr "type")
24094         (cond [(and (eq_attr "alternative" "0")
24095                     (not (match_test "TARGET_OPT_AGU")))
24096                  (const_string "alu")
24097                (match_operand:<MODE> 2 "const0_operand")
24098                  (const_string "imov")
24099               ]
24100               (const_string "lea")))
24101    (set (attr "length_immediate")
24102         (cond [(eq_attr "type" "imov")
24103                  (const_string "0")
24104                (and (eq_attr "type" "alu")
24105                     (match_operand 2 "const128_operand"))
24106                  (const_string "1")
24107               ]
24108               (const_string "*")))
24109    (set_attr "mode" "<MODE>")])
24111 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
24112   [(set (match_operand:P 0 "register_operand" "=r")
24113         (minus:P (match_operand:P 1 "register_operand" "0")
24114                  (match_operand:P 2 "register_operand" "r")))
24115    (clobber (reg:CC FLAGS_REG))
24116    (clobber (mem:BLK (scratch)))]
24117   ""
24118   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
24119   [(set_attr "type" "alu")
24120    (set_attr "mode" "<MODE>")])
24122 (define_insn "@allocate_stack_worker_probe_<mode>"
24123   [(set (match_operand:P 0 "register_operand" "=a")
24124         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
24125                             UNSPECV_STACK_PROBE))
24126    (clobber (reg:CC FLAGS_REG))]
24127   "ix86_target_stack_probe ()"
24128   "call\t___chkstk_ms"
24129   [(set_attr "type" "multi")
24130    (set_attr "length" "5")])
24132 (define_expand "allocate_stack"
24133   [(match_operand 0 "register_operand")
24134    (match_operand 1 "general_operand")]
24135   "ix86_target_stack_probe ()"
24137   rtx x;
24139 #ifndef CHECK_STACK_LIMIT
24140 #define CHECK_STACK_LIMIT 0
24141 #endif
24143   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
24144       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
24145     x = operands[1];
24146   else
24147     {
24148       x = copy_to_mode_reg (Pmode, operands[1]);
24150       emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
24151     }
24153   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
24154                            stack_pointer_rtx, 0, OPTAB_DIRECT);
24156   if (x != stack_pointer_rtx)
24157     emit_move_insn (stack_pointer_rtx, x);
24159   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
24160   DONE;
24163 (define_expand "probe_stack"
24164   [(match_operand 0 "memory_operand")]
24165   ""
24167   emit_insn (gen_probe_stack_1
24168              (word_mode, operands[0], const0_rtx));
24169   DONE;
24172 ;; Use OR for stack probes, this is shorter.
24173 (define_insn "@probe_stack_1_<mode>"
24174   [(set (match_operand:W 0 "memory_operand" "=m")
24175         (unspec:W [(match_operand:W 1 "const0_operand")]
24176                   UNSPEC_PROBE_STACK))
24177    (clobber (reg:CC FLAGS_REG))]
24178   ""
24179   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
24180   [(set_attr "type" "alu1")
24181    (set_attr "mode" "<MODE>")
24182    (set_attr "length_immediate" "1")])
24183   
24184 (define_insn "@adjust_stack_and_probe_<mode>"
24185   [(set (match_operand:P 0 "register_operand" "=r")
24186         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
24187                             UNSPECV_PROBE_STACK_RANGE))
24188    (set (reg:P SP_REG)
24189         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand")))
24190    (clobber (reg:CC FLAGS_REG))
24191    (clobber (mem:BLK (scratch)))]
24192   ""
24193   "* return output_adjust_stack_and_probe (operands[0]);"
24194   [(set_attr "type" "multi")])
24196 (define_insn "@probe_stack_range_<mode>"
24197   [(set (match_operand:P 0 "register_operand" "=r")
24198         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
24199                             (match_operand:P 2 "const_int_operand")]
24200                             UNSPECV_PROBE_STACK_RANGE))
24201    (clobber (reg:CC FLAGS_REG))]
24202   ""
24203   "* return output_probe_stack_range (operands[0], operands[2]);"
24204   [(set_attr "type" "multi")])
24206 (define_expand "builtin_setjmp_receiver"
24207   [(label_ref (match_operand 0))]
24208   "!TARGET_64BIT && flag_pic"
24210 #if TARGET_MACHO
24211   if (TARGET_MACHO)
24212     {
24213       rtx xops[3];
24214       rtx_code_label *label_rtx = gen_label_rtx ();
24215       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
24216       xops[0] = xops[1] = pic_offset_table_rtx;
24217       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
24218       ix86_expand_binary_operator (MINUS, SImode, xops);
24219     }
24220   else
24221 #endif
24222     emit_insn (gen_set_got (pic_offset_table_rtx));
24223   DONE;
24226 (define_expand "save_stack_nonlocal"
24227   [(set (match_operand 0 "memory_operand")
24228         (match_operand 1 "register_operand"))]
24229   ""
24231   rtx stack_slot;
24233   if (flag_cf_protection & CF_RETURN)
24234     {
24235       /* Copy shadow stack pointer to the first slot
24236          and stack pointer to the second slot.  */
24237       rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
24238       stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
24240       rtx reg_ssp = force_reg (word_mode, const0_rtx);
24241       emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
24242       emit_move_insn (ssp_slot, reg_ssp);
24243     }
24244   else
24245     stack_slot = adjust_address (operands[0], Pmode, 0);
24246   emit_move_insn (stack_slot, operands[1]);
24247   DONE;
24250 (define_expand "restore_stack_nonlocal"
24251   [(set (match_operand 0 "register_operand" "")
24252         (match_operand 1 "memory_operand" ""))]
24253   ""
24255   rtx stack_slot;
24257   if (flag_cf_protection & CF_RETURN)
24258     {
24259       /* Restore shadow stack pointer from the first slot
24260          and stack pointer from the second slot.  */
24261       rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
24262       stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
24264       /* Get the current shadow stack pointer.  The code below will check if
24265          SHSTK feature is enabled.  If it is not enabled the RDSSP instruction
24266          is a NOP.  */
24267       rtx reg_ssp = force_reg (word_mode, const0_rtx);
24268       emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
24270       /* Compare through subtraction the saved and the current ssp
24271          to decide if ssp has to be adjusted.  */
24272       reg_ssp = expand_simple_binop (word_mode, MINUS,
24273                                      reg_ssp, ssp_slot,
24274                                      reg_ssp, 1, OPTAB_DIRECT);
24276       /* Compare and jump over adjustment code.  */
24277       rtx noadj_label = gen_label_rtx ();
24278       emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
24279                                word_mode, 1, noadj_label);
24281       /* Compute the number of frames to adjust.  */
24282       rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
24283       rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
24284                                             NULL_RTX, 1);
24286       reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
24287                                      GEN_INT (exact_log2 (UNITS_PER_WORD)),
24288                                      reg_adj, 1, OPTAB_DIRECT);
24290       /* Check if number of frames <= 255 so no loop is needed.  */
24291       rtx inc_label = gen_label_rtx ();
24292       emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
24293                                ptr_mode, 1, inc_label);
24295       /* Adjust the ssp in a loop.  */
24296       rtx loop_label = gen_label_rtx ();
24297       emit_label (loop_label);
24298       LABEL_NUSES (loop_label) = 1;
24300       rtx reg_255 = force_reg (word_mode, GEN_INT (255));
24301       emit_insn (gen_incssp (word_mode, reg_255));
24303       reg_adj = expand_simple_binop (ptr_mode, MINUS,
24304                                      reg_adj, GEN_INT (255),
24305                                      reg_adj, 1, OPTAB_DIRECT);
24307       /* Compare and jump to the loop label.  */
24308       emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
24309                                ptr_mode, 1, loop_label);
24311       emit_label (inc_label);
24312       LABEL_NUSES (inc_label) = 1;
24314       emit_insn (gen_incssp (word_mode, reg_ssp));
24316       emit_label (noadj_label);
24317       LABEL_NUSES (noadj_label) = 1;
24318     }
24319   else
24320     stack_slot = adjust_address (operands[1], Pmode, 0);
24321   emit_move_insn (operands[0], stack_slot);
24322   DONE;
24325 (define_expand "stack_protect_set"
24326   [(match_operand 0 "memory_operand")
24327    (match_operand 1 "memory_operand")]
24328   ""
24330   rtx scratch = gen_reg_rtx (word_mode);
24332   emit_insn (gen_stack_protect_set_1
24333              (ptr_mode, word_mode, operands[0], operands[1], scratch));
24334   DONE;
24337 (define_insn "@stack_protect_set_1_<PTR:mode>_<W:mode>"
24338   [(set (match_operand:PTR 0 "memory_operand" "=m")
24339         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
24340                     UNSPEC_SP_SET))
24341    (set (match_operand:W 2 "register_operand" "=&r") (const_int 0))
24342    (clobber (reg:CC FLAGS_REG))]
24343   ""
24345   output_asm_insn ("mov{<PTR:imodesuffix>}\t{%1, %<PTR:k>2|%<PTR:k>2, %1}",
24346                    operands);
24347   output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>2, %0|%0, %<PTR:k>2}",
24348                    operands);
24349   if (!TARGET_USE_MOV0 || optimize_insn_for_size_p ())
24350     return "xor{l}\t%k2, %k2";
24351   else
24352     return "mov{l}\t{$0, %k2|%k2, 0}";
24354   [(set_attr "type" "multi")])
24356 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
24357 ;; immediately followed by *mov{s,d}i_internal, where we can avoid
24358 ;; the xor{l} above.  We don't split this, so that scheduling or
24359 ;; anything else doesn't separate the *stack_protect_set* pattern from
24360 ;; the set of the register that overwrites the register with a new value.
24362 (define_peephole2
24363   [(parallel [(set (match_operand:PTR 0 "memory_operand")
24364                    (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24365                                UNSPEC_SP_SET))
24366               (set (match_operand 2 "general_reg_operand") (const_int 0))
24367               (clobber (reg:CC FLAGS_REG))])
24368    (set (match_operand 3 "general_reg_operand")
24369         (match_operand 4 "const0_operand"))]
24370   "GET_MODE (operands[2]) == word_mode
24371    && GET_MODE_SIZE (GET_MODE (operands[3])) <= UNITS_PER_WORD
24372    && peep2_reg_dead_p (0, operands[3])
24373    && peep2_reg_dead_p (1, operands[2])"
24374   [(parallel [(set (match_dup 0)
24375                    (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24376               (set (match_dup 3) (const_int 0))
24377               (clobber (reg:CC FLAGS_REG))])]
24378   "operands[3] = gen_lowpart (word_mode, operands[3]);")
24380 (define_insn "*stack_protect_set_2_<mode>_si"
24381   [(set (match_operand:PTR 0 "memory_operand" "=m")
24382         (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24383                     UNSPEC_SP_SET))
24384    (set (match_operand:SI 1 "register_operand" "=&r")
24385         (match_operand:SI 2 "general_operand" "g"))]
24386   "reload_completed"
24388   output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24389   output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24390   if (pic_32bit_operand (operands[2], SImode)
24391       || ix86_use_lea_for_mov (insn, operands + 1))
24392     return "lea{l}\t{%E2, %1|%1, %E2}";
24393   else
24394     return "mov{l}\t{%2, %1|%1, %2}";
24396   [(set_attr "type" "multi")
24397    (set_attr "length" "24")])
24399 (define_insn "*stack_protect_set_2_<mode>_di"
24400   [(set (match_operand:PTR 0 "memory_operand" "=m,m,m")
24401         (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m,m,m")]
24402                     UNSPEC_SP_SET))
24403    (set (match_operand:DI 1 "register_operand" "=&r,&r,&r")
24404         (match_operand:DI 2 "general_operand" "Z,rem,i"))]
24405   "TARGET_64BIT && reload_completed"
24407   output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24408   output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24409   if (pic_32bit_operand (operands[2], DImode))
24410     return "lea{q}\t{%E2, %1|%1, %E2}";
24411   else if (which_alternative == 0)
24412     return "mov{l}\t{%k2, %k1|%k1, %k2}";
24413   else if (which_alternative == 2)
24414     return "movabs{q}\t{%2, %1|%1, %2}";
24415   else if (ix86_use_lea_for_mov (insn, operands + 1))
24416     return "lea{q}\t{%E2, %1|%1, %E2}";
24417   else
24418     return "mov{q}\t{%2, %1|%1, %2}";
24420   [(set_attr "type" "multi")
24421    (set_attr "length" "24")])
24423 (define_peephole2
24424   [(parallel [(set (match_operand:PTR 0 "memory_operand")
24425                    (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24426                                UNSPEC_SP_SET))
24427               (set (match_operand 2 "general_reg_operand") (const_int 0))
24428               (clobber (reg:CC FLAGS_REG))])
24429    (set (match_operand:SWI48 3 "general_reg_operand")
24430         (match_operand:SWI48 4 "general_gr_operand"))]
24431   "GET_MODE (operands[2]) == word_mode
24432    && peep2_reg_dead_p (0, operands[3])
24433    && peep2_reg_dead_p (1, operands[2])"
24434   [(parallel [(set (match_dup 0)
24435                    (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24436               (set (match_dup 3) (match_dup 4))])])
24438 (define_peephole2
24439   [(set (match_operand:SWI48 3 "general_reg_operand")
24440         (match_operand:SWI48 4 "general_gr_operand"))
24441    (parallel [(set (match_operand:PTR 0 "memory_operand")
24442                    (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24443                                UNSPEC_SP_SET))
24444               (set (match_operand 2 "general_reg_operand") (const_int 0))
24445               (clobber (reg:CC FLAGS_REG))])]
24446   "GET_MODE (operands[2]) == word_mode
24447    && peep2_reg_dead_p (0, operands[3])
24448    && peep2_reg_dead_p (2, operands[2])
24449    && !reg_mentioned_p (operands[3], operands[0])
24450    && !reg_mentioned_p (operands[3], operands[1])"
24451   [(parallel [(set (match_dup 0)
24452                    (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24453               (set (match_dup 3) (match_dup 4))])])
24455 (define_insn "*stack_protect_set_3_<PTR:mode>_<SWI48:mode>"
24456   [(set (match_operand:PTR 0 "memory_operand" "=m")
24457         (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24458                     UNSPEC_SP_SET))
24459    (set (match_operand:SWI48 1 "register_operand" "=&r")
24460         (match_operand:SWI48 2 "address_no_seg_operand" "Ts"))]
24461   ""
24463   output_asm_insn ("mov{<PTR:imodesuffix>}\t{%3, %<PTR:k>1|%<PTR:k>1, %3}",
24464                    operands);
24465   output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>1, %0|%0, %<PTR:k>1}",
24466                    operands);
24467   if (SImode_address_operand (operands[2], VOIDmode))
24468     {
24469       gcc_assert (TARGET_64BIT);
24470       return "lea{l}\t{%E2, %k1|%k1, %E2}";
24471     }
24472   else
24473     return "lea{<SWI48:imodesuffix>}\t{%E2, %1|%1, %E2}";
24475   [(set_attr "type" "multi")
24476    (set_attr "length" "24")])
24478 (define_peephole2
24479   [(parallel [(set (match_operand:PTR 0 "memory_operand")
24480                    (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24481                                UNSPEC_SP_SET))
24482               (set (match_operand 2 "general_reg_operand") (const_int 0))
24483               (clobber (reg:CC FLAGS_REG))])
24484    (set (match_operand:SWI48 3 "general_reg_operand")
24485         (match_operand:SWI48 4 "address_no_seg_operand"))]
24486   "GET_MODE (operands[2]) == word_mode
24487    && peep2_reg_dead_p (0, operands[3])
24488    && peep2_reg_dead_p (1, operands[2])"
24489   [(parallel [(set (match_dup 0)
24490                    (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24491               (set (match_dup 3) (match_dup 4))])])
24493 (define_insn "*stack_protect_set_4z_<mode>_di"
24494   [(set (match_operand:PTR 0 "memory_operand" "=m")
24495         (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24496                     UNSPEC_SP_SET))
24497    (set (match_operand:DI 1 "register_operand" "=&r")
24498         (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))]
24499   "TARGET_64BIT && reload_completed"
24501   output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24502   output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24503   if (ix86_use_lea_for_mov (insn, operands + 1))
24504     return "lea{l}\t{%E2, %k1|%k1, %E2}";
24505   else
24506     return "mov{l}\t{%2, %k1|%k1, %2}";
24508   [(set_attr "type" "multi")
24509    (set_attr "length" "24")])
24511 (define_insn "*stack_protect_set_4s_<mode>_di"
24512   [(set (match_operand:PTR 0 "memory_operand" "=m")
24513         (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24514                     UNSPEC_SP_SET))
24515    (set (match_operand:DI 1 "register_operand" "=&r")
24516         (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))]
24517   "TARGET_64BIT && reload_completed"
24519   output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24520   output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24521   return "movs{lq|x}\t{%2, %1|%1, %2}";
24523   [(set_attr "type" "multi")
24524    (set_attr "length" "24")])
24526 (define_peephole2
24527   [(parallel [(set (match_operand:PTR 0 "memory_operand")
24528                    (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24529                                UNSPEC_SP_SET))
24530               (set (match_operand 2 "general_reg_operand") (const_int 0))
24531               (clobber (reg:CC FLAGS_REG))])
24532    (set (match_operand:DI 3 "general_reg_operand")
24533         (any_extend:DI
24534           (match_operand:SI 4 "nonimmediate_gr_operand")))]
24535   "TARGET_64BIT
24536    && GET_MODE (operands[2]) == word_mode
24537    && peep2_reg_dead_p (0, operands[3])
24538    && peep2_reg_dead_p (1, operands[2])"
24539   [(parallel [(set (match_dup 0)
24540                    (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24541               (set (match_dup 3)
24542                    (any_extend:DI (match_dup 4)))])])
24544 (define_expand "stack_protect_test"
24545   [(match_operand 0 "memory_operand")
24546    (match_operand 1 "memory_operand")
24547    (match_operand 2)]
24548   ""
24550   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
24552   emit_insn (gen_stack_protect_test_1
24553              (ptr_mode, flags, operands[0], operands[1]));
24555   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
24556                                   flags, const0_rtx, operands[2]));
24557   DONE;
24560 (define_insn "@stack_protect_test_1_<mode>"
24561   [(set (match_operand:CCZ 0 "flags_reg_operand")
24562         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
24563                      (match_operand:PTR 2 "memory_operand" "m")]
24564                     UNSPEC_SP_TEST))
24565    (clobber (match_scratch:PTR 3 "=&r"))]
24566   ""
24568   output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
24569   return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
24571   [(set_attr "type" "multi")])
24573 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
24574 ;; Do not split instructions with mask registers.
24575 (define_split
24576   [(set (match_operand 0 "general_reg_operand")
24577         (match_operator 3 "promotable_binary_operator"
24578            [(match_operand 1 "general_reg_operand")
24579             (match_operand 2 "aligned_operand")]))
24580    (clobber (reg:CC FLAGS_REG))]
24581   "! TARGET_PARTIAL_REG_STALL && reload_completed
24582    && ((GET_MODE (operands[0]) == HImode
24583         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
24584             /* ??? next two lines just !satisfies_constraint_K (...) */
24585             || !CONST_INT_P (operands[2])
24586             || satisfies_constraint_K (operands[2])))
24587        || (GET_MODE (operands[0]) == QImode
24588            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
24589   [(parallel [(set (match_dup 0)
24590                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
24591               (clobber (reg:CC FLAGS_REG))])]
24593   operands[0] = gen_lowpart (SImode, operands[0]);
24594   operands[1] = gen_lowpart (SImode, operands[1]);
24595   if (GET_CODE (operands[3]) != ASHIFT)
24596     operands[2] = gen_lowpart (SImode, operands[2]);
24597   operands[3] = shallow_copy_rtx (operands[3]);
24598   PUT_MODE (operands[3], SImode);
24601 ; Promote the QImode tests, as i386 has encoding of the AND
24602 ; instruction with 32-bit sign-extended immediate and thus the
24603 ; instruction size is unchanged, except in the %eax case for
24604 ; which it is increased by one byte, hence the ! optimize_size.
24605 (define_split
24606   [(set (match_operand 0 "flags_reg_operand")
24607         (match_operator 2 "compare_operator"
24608           [(and (match_operand 3 "aligned_operand")
24609                 (match_operand 4 "const_int_operand"))
24610            (const_int 0)]))
24611    (set (match_operand 1 "register_operand")
24612         (and (match_dup 3) (match_dup 4)))]
24613   "! TARGET_PARTIAL_REG_STALL && reload_completed
24614    && optimize_insn_for_speed_p ()
24615    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
24616        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
24617    /* Ensure that the operand will remain sign-extended immediate.  */
24618    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
24619   [(parallel [(set (match_dup 0)
24620                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
24621                                     (const_int 0)]))
24622               (set (match_dup 1)
24623                    (and:SI (match_dup 3) (match_dup 4)))])]
24625   operands[4]
24626     = gen_int_mode (INTVAL (operands[4])
24627                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
24628   operands[1] = gen_lowpart (SImode, operands[1]);
24629   operands[3] = gen_lowpart (SImode, operands[3]);
24632 ; Don't promote the QImode tests, as i386 doesn't have encoding of
24633 ; the TEST instruction with 32-bit sign-extended immediate and thus
24634 ; the instruction size would at least double, which is not what we
24635 ; want even with ! optimize_size.
24636 (define_split
24637   [(set (match_operand 0 "flags_reg_operand")
24638         (match_operator 1 "compare_operator"
24639           [(and (match_operand:HI 2 "aligned_operand")
24640                 (match_operand:HI 3 "const_int_operand"))
24641            (const_int 0)]))]
24642   "! TARGET_PARTIAL_REG_STALL && reload_completed
24643    && ! TARGET_FAST_PREFIX
24644    && optimize_insn_for_speed_p ()
24645    /* Ensure that the operand will remain sign-extended immediate.  */
24646    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
24647   [(set (match_dup 0)
24648         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24649                          (const_int 0)]))]
24651   operands[3]
24652     = gen_int_mode (INTVAL (operands[3])
24653                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
24654   operands[2] = gen_lowpart (SImode, operands[2]);
24657 (define_split
24658   [(set (match_operand 0 "register_operand")
24659         (neg (match_operand 1 "register_operand")))
24660    (clobber (reg:CC FLAGS_REG))]
24661   "! TARGET_PARTIAL_REG_STALL && reload_completed
24662    && (GET_MODE (operands[0]) == HImode
24663        || (GET_MODE (operands[0]) == QImode
24664            && (TARGET_PROMOTE_QImode
24665                || optimize_insn_for_size_p ())))"
24666   [(parallel [(set (match_dup 0)
24667                    (neg:SI (match_dup 1)))
24668               (clobber (reg:CC FLAGS_REG))])]
24670   operands[0] = gen_lowpart (SImode, operands[0]);
24671   operands[1] = gen_lowpart (SImode, operands[1]);
24674 ;; Do not split instructions with mask regs.
24675 (define_split
24676   [(set (match_operand 0 "general_reg_operand")
24677         (not (match_operand 1 "general_reg_operand")))]
24678   "! TARGET_PARTIAL_REG_STALL && reload_completed
24679    && (GET_MODE (operands[0]) == HImode
24680        || (GET_MODE (operands[0]) == QImode
24681            && (TARGET_PROMOTE_QImode
24682                || optimize_insn_for_size_p ())))"
24683   [(set (match_dup 0)
24684         (not:SI (match_dup 1)))]
24686   operands[0] = gen_lowpart (SImode, operands[0]);
24687   operands[1] = gen_lowpart (SImode, operands[1]);
24690 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
24691 ;; transform a complex memory operation into two memory to register operations.
24693 ;; Don't push memory operands
24694 (define_peephole2
24695   [(set (match_operand:SWI 0 "push_operand")
24696         (match_operand:SWI 1 "memory_operand"))
24697    (match_scratch:SWI 2 "<r>")]
24698   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
24699    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
24700   [(set (match_dup 2) (match_dup 1))
24701    (set (match_dup 0) (match_dup 2))])
24703 ;; We need to handle SFmode only, because DFmode and XFmode are split to
24704 ;; SImode pushes.
24705 (define_peephole2
24706   [(set (match_operand:SF 0 "push_operand")
24707         (match_operand:SF 1 "memory_operand"))
24708    (match_scratch:SF 2 "r")]
24709   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
24710    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
24711   [(set (match_dup 2) (match_dup 1))
24712    (set (match_dup 0) (match_dup 2))])
24714 ;; Don't move an immediate directly to memory when the instruction
24715 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
24716 (define_peephole2
24717   [(match_scratch:SWI124 1 "<r>")
24718    (set (match_operand:SWI124 0 "memory_operand")
24719         (const_int 0))]
24720   "optimize_insn_for_speed_p ()
24721    && ((<MODE>mode == HImode
24722        && TARGET_LCP_STALL)
24723        || (!TARGET_USE_MOV0
24724           && TARGET_SPLIT_LONG_MOVES
24725           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
24726    && peep2_regno_dead_p (0, FLAGS_REG)"
24727   [(parallel [(set (match_dup 2) (const_int 0))
24728               (clobber (reg:CC FLAGS_REG))])
24729    (set (match_dup 0) (match_dup 1))]
24730   "operands[2] = gen_lowpart (SImode, operands[1]);")
24732 (define_peephole2
24733   [(match_scratch:SWI124 2 "<r>")
24734    (set (match_operand:SWI124 0 "memory_operand")
24735         (match_operand:SWI124 1 "immediate_operand"))]
24736   "optimize_insn_for_speed_p ()
24737    && ((<MODE>mode == HImode
24738        && TARGET_LCP_STALL)
24739        || (TARGET_SPLIT_LONG_MOVES
24740           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
24741   [(set (match_dup 2) (match_dup 1))
24742    (set (match_dup 0) (match_dup 2))])
24744 ;; Don't compare memory with zero, load and use a test instead.
24745 (define_peephole2
24746   [(set (match_operand 0 "flags_reg_operand")
24747         (match_operator 1 "compare_operator"
24748           [(match_operand:SI 2 "memory_operand")
24749            (const_int 0)]))
24750    (match_scratch:SI 3 "r")]
24751   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
24752   [(set (match_dup 3) (match_dup 2))
24753    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
24755 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
24756 ;; Don't split NOTs with a displacement operand, because resulting XOR
24757 ;; will not be pairable anyway.
24759 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
24760 ;; represented using a modRM byte.  The XOR replacement is long decoded,
24761 ;; so this split helps here as well.
24763 ;; Note: Can't do this as a regular split because we can't get proper
24764 ;; lifetime information then.
24766 (define_peephole2
24767   [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
24768         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
24769   "optimize_insn_for_speed_p ()
24770    && ((TARGET_NOT_UNPAIRABLE
24771         && (!MEM_P (operands[0])
24772             || !memory_displacement_operand (operands[0], <MODE>mode)))
24773        || (TARGET_NOT_VECTORMODE
24774            && long_memory_operand (operands[0], <MODE>mode)))
24775    && peep2_regno_dead_p (0, FLAGS_REG)"
24776   [(parallel [(set (match_dup 0)
24777                    (xor:SWI124 (match_dup 1) (const_int -1)))
24778               (clobber (reg:CC FLAGS_REG))])])
24780 ;; Non pairable "test imm, reg" instructions can be translated to
24781 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
24782 ;; byte opcode instead of two, have a short form for byte operands),
24783 ;; so do it for other CPUs as well.  Given that the value was dead,
24784 ;; this should not create any new dependencies.  Pass on the sub-word
24785 ;; versions if we're concerned about partial register stalls.
24787 (define_peephole2
24788   [(set (match_operand 0 "flags_reg_operand")
24789         (match_operator 1 "compare_operator"
24790           [(and:SI (match_operand:SI 2 "register_operand")
24791                    (match_operand:SI 3 "immediate_operand"))
24792            (const_int 0)]))]
24793   "ix86_match_ccmode (insn, CCNOmode)
24794    && (REGNO (operands[2]) != AX_REG
24795        || satisfies_constraint_K (operands[3]))
24796    && peep2_reg_dead_p (1, operands[2])"
24797   [(parallel
24798      [(set (match_dup 0)
24799            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24800                             (const_int 0)]))
24801       (set (match_dup 2)
24802            (and:SI (match_dup 2) (match_dup 3)))])])
24804 ;; We don't need to handle HImode case, because it will be promoted to SImode
24805 ;; on ! TARGET_PARTIAL_REG_STALL
24807 (define_peephole2
24808   [(set (match_operand 0 "flags_reg_operand")
24809         (match_operator 1 "compare_operator"
24810           [(and:QI (match_operand:QI 2 "register_operand")
24811                    (match_operand:QI 3 "immediate_operand"))
24812            (const_int 0)]))]
24813   "! TARGET_PARTIAL_REG_STALL
24814    && ix86_match_ccmode (insn, CCNOmode)
24815    && REGNO (operands[2]) != AX_REG
24816    && peep2_reg_dead_p (1, operands[2])"
24817   [(parallel
24818      [(set (match_dup 0)
24819            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
24820                             (const_int 0)]))
24821       (set (match_dup 2)
24822            (and:QI (match_dup 2) (match_dup 3)))])])
24824 (define_peephole2
24825   [(set (match_operand 0 "flags_reg_operand")
24826         (match_operator 1 "compare_operator"
24827           [(and:QI
24828              (subreg:QI
24829                (match_operator:SWI248 4 "extract_operator"
24830                  [(match_operand 2 "int248_register_operand")
24831                   (const_int 8)
24832                   (const_int 8)]) 0)
24833              (match_operand 3 "const_int_operand"))
24834            (const_int 0)]))]
24835   "! TARGET_PARTIAL_REG_STALL
24836    && ix86_match_ccmode (insn, CCNOmode)
24837    && REGNO (operands[2]) != AX_REG
24838    && peep2_reg_dead_p (1, operands[2])"
24839   [(parallel
24840      [(set (match_dup 0)
24841            (match_op_dup 1
24842              [(and:QI
24843                 (subreg:QI
24844                   (match_op_dup 4 [(match_dup 2)
24845                                    (const_int 8)
24846                                    (const_int 8)]) 0)
24847                 (match_dup 3))
24848               (const_int 0)]))
24849       (set (zero_extract:SWI248 (match_dup 2)
24850                                 (const_int 8)
24851                                 (const_int 8))
24852            (subreg:SWI248
24853              (and:QI
24854                (subreg:QI
24855                  (match_op_dup 4 [(match_dup 2)
24856                                   (const_int 8)
24857                                   (const_int 8)]) 0)
24858                (match_dup 3)) 0))])])
24860 ;; Don't do logical operations with memory inputs.
24861 (define_peephole2
24862   [(match_scratch:SWI 2 "<r>")
24863    (parallel [(set (match_operand:SWI 0 "register_operand")
24864                    (match_operator:SWI 3 "arith_or_logical_operator"
24865                      [(match_dup 0)
24866                       (match_operand:SWI 1 "memory_operand")]))
24867               (clobber (reg:CC FLAGS_REG))])]
24868   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24869   [(set (match_dup 2) (match_dup 1))
24870    (parallel [(set (match_dup 0)
24871                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
24872               (clobber (reg:CC FLAGS_REG))])])
24874 (define_peephole2
24875   [(match_scratch:SWI 2 "<r>")
24876    (parallel [(set (match_operand:SWI 0 "register_operand")
24877                    (match_operator:SWI 3 "arith_or_logical_operator"
24878                      [(match_operand:SWI 1 "memory_operand")
24879                       (match_dup 0)]))
24880               (clobber (reg:CC FLAGS_REG))])]
24881   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24882   [(set (match_dup 2) (match_dup 1))
24883    (parallel [(set (match_dup 0)
24884                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
24885               (clobber (reg:CC FLAGS_REG))])])
24887 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when
24888 ;; the memory address refers to the destination of the load!
24890 (define_peephole2
24891   [(set (match_operand:SWI 0 "general_reg_operand")
24892         (match_operand:SWI 1 "general_reg_operand"))
24893    (parallel [(set (match_dup 0)
24894                    (match_operator:SWI 3 "commutative_operator"
24895                      [(match_dup 0)
24896                       (match_operand:SWI 2 "memory_operand")]))
24897               (clobber (reg:CC FLAGS_REG))])]
24898   "REGNO (operands[0]) != REGNO (operands[1])
24899    && (<MODE>mode != QImode
24900        || any_QIreg_operand (operands[1], QImode))"
24901   [(set (match_dup 0) (match_dup 4))
24902    (parallel [(set (match_dup 0)
24903                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
24904               (clobber (reg:CC FLAGS_REG))])]
24906   operands[4]
24907     = ix86_replace_reg_with_reg (operands[2], operands[0], operands[1]);
24910 (define_peephole2
24911   [(set (match_operand 0 "mmx_reg_operand")
24912         (match_operand 1 "mmx_reg_operand"))
24913    (set (match_dup 0)
24914         (match_operator 3 "commutative_operator"
24915           [(match_dup 0)
24916            (match_operand 2 "memory_operand")]))]
24917   "REGNO (operands[0]) != REGNO (operands[1])"
24918   [(set (match_dup 0) (match_dup 2))
24919    (set (match_dup 0)
24920         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
24922 (define_peephole2
24923   [(set (match_operand 0 "sse_reg_operand")
24924         (match_operand 1 "sse_reg_operand"))
24925    (set (match_dup 0)
24926         (match_operator 3 "commutative_operator"
24927           [(match_dup 0)
24928            (match_operand 2 "memory_operand")]))]
24929   "REGNO (operands[0]) != REGNO (operands[1])
24930    /* Punt if operands[1] is %[xy]mm16+ and AVX512BW is not enabled,
24931       as EVEX encoded vpadd[bw], vpmullw, vpmin[su][bw] and vpmax[su][bw]
24932       instructions require AVX512BW and AVX512VL, but with the original
24933       instructions it might require just AVX512VL.
24934       AVX512VL is implied from TARGET_HARD_REGNO_MODE_OK.  */
24935    && (!EXT_REX_SSE_REGNO_P (REGNO (operands[1]))
24936        || TARGET_AVX512BW
24937        || GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (operands[0]))) > 2
24938        || logic_operator (operands[3], VOIDmode))"
24939   [(set (match_dup 0) (match_dup 2))
24940    (set (match_dup 0)
24941         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
24943 ; Don't do logical operations with memory outputs
24945 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
24946 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
24947 ; the same decoder scheduling characteristics as the original.
24949 (define_peephole2
24950   [(match_scratch:SWI 2 "<r>")
24951    (parallel [(set (match_operand:SWI 0 "memory_operand")
24952                    (match_operator:SWI 3 "arith_or_logical_operator"
24953                      [(match_dup 0)
24954                       (match_operand:SWI 1 "<nonmemory_operand>")]))
24955               (clobber (reg:CC FLAGS_REG))])]
24956   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
24957   [(set (match_dup 2) (match_dup 0))
24958    (parallel [(set (match_dup 2)
24959                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
24960               (clobber (reg:CC FLAGS_REG))])
24961    (set (match_dup 0) (match_dup 2))])
24963 (define_peephole2
24964   [(match_scratch:SWI 2 "<r>")
24965    (parallel [(set (match_operand:SWI 0 "memory_operand")
24966                    (match_operator:SWI 3 "arith_or_logical_operator"
24967                      [(match_operand:SWI 1 "<nonmemory_operand>")
24968                       (match_dup 0)]))
24969               (clobber (reg:CC FLAGS_REG))])]
24970   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
24971   [(set (match_dup 2) (match_dup 0))
24972    (parallel [(set (match_dup 2)
24973                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
24974               (clobber (reg:CC FLAGS_REG))])
24975    (set (match_dup 0) (match_dup 2))])
24977 ;; Attempt to use arith or logical operations with memory outputs with
24978 ;; setting of flags.
24979 (define_peephole2
24980   [(set (match_operand:SWI 0 "register_operand")
24981         (match_operand:SWI 1 "memory_operand"))
24982    (parallel [(set (match_dup 0)
24983                    (match_operator:SWI 3 "plusminuslogic_operator"
24984                      [(match_dup 0)
24985                       (match_operand:SWI 2 "<nonmemory_operand>")]))
24986               (clobber (reg:CC FLAGS_REG))])
24987    (set (match_dup 1) (match_dup 0))
24988    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24989   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24990    && peep2_reg_dead_p (4, operands[0])
24991    && !reg_overlap_mentioned_p (operands[0], operands[1])
24992    && !reg_overlap_mentioned_p (operands[0], operands[2])
24993    && (<MODE>mode != QImode
24994        || immediate_operand (operands[2], QImode)
24995        || any_QIreg_operand (operands[2], QImode))
24996    && ix86_match_ccmode (peep2_next_insn (3),
24997                          (GET_CODE (operands[3]) == PLUS
24998                           || GET_CODE (operands[3]) == MINUS)
24999                          ? CCGOCmode : CCNOmode)"
25000   [(parallel [(set (match_dup 4) (match_dup 6))
25001               (set (match_dup 1) (match_dup 5))])]
25003   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
25004   operands[5]
25005     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25006                       copy_rtx (operands[1]),
25007                       operands[2]);
25008   operands[6]
25009     = gen_rtx_COMPARE (GET_MODE (operands[4]),
25010                        copy_rtx (operands[5]),
25011                        const0_rtx);
25014 ;; Likewise for cmpelim optimized pattern.
25015 (define_peephole2
25016   [(set (match_operand:SWI 0 "register_operand")
25017         (match_operand:SWI 1 "memory_operand"))
25018    (parallel [(set (reg FLAGS_REG)
25019                    (compare (match_operator:SWI 3 "plusminuslogic_operator"
25020                               [(match_dup 0)
25021                                (match_operand:SWI 2 "<nonmemory_operand>")])
25022                             (const_int 0)))
25023               (set (match_dup 0) (match_dup 3))])
25024    (set (match_dup 1) (match_dup 0))]
25025   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25026    && peep2_reg_dead_p (3, operands[0])
25027    && !reg_overlap_mentioned_p (operands[0], operands[1])
25028    && !reg_overlap_mentioned_p (operands[0], operands[2])
25029    && ix86_match_ccmode (peep2_next_insn (1),
25030                          (GET_CODE (operands[3]) == PLUS
25031                           || GET_CODE (operands[3]) == MINUS)
25032                          ? CCGOCmode : CCNOmode)"
25033   [(parallel [(set (match_dup 4) (match_dup 6))
25034               (set (match_dup 1) (match_dup 5))])]
25036   operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
25037   operands[5]
25038     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25039                       copy_rtx (operands[1]), operands[2]);
25040   operands[6]
25041     = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
25042                        const0_rtx);
25045 ;; Likewise for instances where we have a lea pattern.
25046 (define_peephole2
25047   [(set (match_operand:SWI 0 "register_operand")
25048         (match_operand:SWI 1 "memory_operand"))
25049    (set (match_operand:<LEAMODE> 3 "register_operand")
25050         (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
25051                         (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
25052    (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
25053    (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
25054   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25055    && REGNO (operands[4]) == REGNO (operands[0])
25056    && REGNO (operands[5]) == REGNO (operands[3])
25057    && peep2_reg_dead_p (4, operands[3])
25058    && ((REGNO (operands[0]) == REGNO (operands[3]))
25059        || peep2_reg_dead_p (2, operands[0]))
25060    && !reg_overlap_mentioned_p (operands[0], operands[1])
25061    && !reg_overlap_mentioned_p (operands[3], operands[1])
25062    && !reg_overlap_mentioned_p (operands[0], operands[2])
25063    && (<MODE>mode != QImode
25064        || immediate_operand (operands[2], QImode)
25065        || any_QIreg_operand (operands[2], QImode))
25066    && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
25067   [(parallel [(set (match_dup 6) (match_dup 8))
25068               (set (match_dup 1) (match_dup 7))])]
25070   operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
25071   operands[7]
25072     = gen_rtx_PLUS (<MODE>mode,
25073                     copy_rtx (operands[1]),
25074                     gen_lowpart (<MODE>mode, operands[2]));
25075   operands[8]
25076     = gen_rtx_COMPARE (GET_MODE (operands[6]),
25077                        copy_rtx (operands[7]),
25078                        const0_rtx);
25081 (define_peephole2
25082   [(parallel [(set (match_operand:SWI 0 "register_operand")
25083                    (match_operator:SWI 2 "plusminuslogic_operator"
25084                      [(match_dup 0)
25085                       (match_operand:SWI 1 "memory_operand")]))
25086               (clobber (reg:CC FLAGS_REG))])
25087    (set (match_dup 1) (match_dup 0))
25088    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
25089   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25090    && COMMUTATIVE_ARITH_P (operands[2])
25091    && peep2_reg_dead_p (3, operands[0])
25092    && !reg_overlap_mentioned_p (operands[0], operands[1])
25093    && ix86_match_ccmode (peep2_next_insn (2),
25094                          GET_CODE (operands[2]) == PLUS
25095                          ? CCGOCmode : CCNOmode)"
25096   [(parallel [(set (match_dup 3) (match_dup 5))
25097               (set (match_dup 1) (match_dup 4))])]
25099   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
25100   operands[4]
25101     = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
25102                       copy_rtx (operands[1]),
25103                       operands[0]);
25104   operands[5]
25105     = gen_rtx_COMPARE (GET_MODE (operands[3]),
25106                        copy_rtx (operands[4]),
25107                        const0_rtx);
25110 ;; Likewise for cmpelim optimized pattern.
25111 (define_peephole2
25112   [(parallel [(set (reg FLAGS_REG)
25113                    (compare (match_operator:SWI 2 "plusminuslogic_operator"
25114                               [(match_operand:SWI 0 "register_operand")
25115                                (match_operand:SWI 1 "memory_operand")])
25116                             (const_int 0)))
25117               (set (match_dup 0) (match_dup 2))])
25118    (set (match_dup 1) (match_dup 0))]
25119   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25120    && COMMUTATIVE_ARITH_P (operands[2])
25121    && peep2_reg_dead_p (2, operands[0])
25122    && !reg_overlap_mentioned_p (operands[0], operands[1])
25123    && ix86_match_ccmode (peep2_next_insn (0),
25124                          GET_CODE (operands[2]) == PLUS
25125                          ? CCGOCmode : CCNOmode)"
25126   [(parallel [(set (match_dup 3) (match_dup 5))
25127               (set (match_dup 1) (match_dup 4))])]
25129   operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
25130   operands[4]
25131     = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
25132                       copy_rtx (operands[1]), operands[0]);
25133   operands[5]
25134     = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
25135                        const0_rtx);
25138 (define_peephole2
25139   [(set (match_operand:SWI12 0 "register_operand")
25140         (match_operand:SWI12 1 "memory_operand"))
25141    (parallel [(set (match_operand:SI 4 "register_operand")
25142                    (match_operator:SI 3 "plusminuslogic_operator"
25143                      [(match_dup 4)
25144                       (match_operand:SI 2 "nonmemory_operand")]))
25145               (clobber (reg:CC FLAGS_REG))])
25146    (set (match_dup 1) (match_dup 0))
25147    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
25148   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25149    && REGNO (operands[0]) == REGNO (operands[4])
25150    && peep2_reg_dead_p (4, operands[0])
25151    && (<MODE>mode != QImode
25152        || immediate_operand (operands[2], SImode)
25153        || any_QIreg_operand (operands[2], SImode))
25154    && !reg_overlap_mentioned_p (operands[0], operands[1])
25155    && !reg_overlap_mentioned_p (operands[0], operands[2])
25156    && ix86_match_ccmode (peep2_next_insn (3),
25157                          (GET_CODE (operands[3]) == PLUS
25158                           || GET_CODE (operands[3]) == MINUS)
25159                          ? CCGOCmode : CCNOmode)"
25160   [(parallel [(set (match_dup 5) (match_dup 7))
25161               (set (match_dup 1) (match_dup 6))])]
25163   operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
25164   operands[6]
25165     = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
25166                       copy_rtx (operands[1]),
25167                       gen_lowpart (<MODE>mode, operands[2]));
25168   operands[7]
25169     = gen_rtx_COMPARE (GET_MODE (operands[5]),
25170                        copy_rtx (operands[6]),
25171                        const0_rtx);
25174 ;; peephole2 comes before regcprop, so deal also with a case that
25175 ;; would be cleaned up by regcprop.
25176 (define_peephole2
25177   [(set (match_operand:SWI 0 "register_operand")
25178         (match_operand:SWI 1 "memory_operand"))
25179    (parallel [(set (match_dup 0)
25180                    (match_operator:SWI 3 "plusminuslogic_operator"
25181                      [(match_dup 0)
25182                       (match_operand:SWI 2 "<nonmemory_operand>")]))
25183               (clobber (reg:CC FLAGS_REG))])
25184    (set (match_operand:SWI 4 "register_operand") (match_dup 0))
25185    (set (match_dup 1) (match_dup 4))
25186    (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
25187   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25188    && peep2_reg_dead_p (3, operands[0])
25189    && peep2_reg_dead_p (5, operands[4])
25190    && !reg_overlap_mentioned_p (operands[0], operands[1])
25191    && !reg_overlap_mentioned_p (operands[0], operands[2])
25192    && !reg_overlap_mentioned_p (operands[4], operands[1])
25193    && (<MODE>mode != QImode
25194        || immediate_operand (operands[2], QImode)
25195        || any_QIreg_operand (operands[2], QImode))
25196    && ix86_match_ccmode (peep2_next_insn (4),
25197                          (GET_CODE (operands[3]) == PLUS
25198                           || GET_CODE (operands[3]) == MINUS)
25199                          ? CCGOCmode : CCNOmode)"
25200   [(parallel [(set (match_dup 5) (match_dup 7))
25201               (set (match_dup 1) (match_dup 6))])]
25203   operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
25204   operands[6]
25205     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25206                       copy_rtx (operands[1]),
25207                       operands[2]);
25208   operands[7]
25209     = gen_rtx_COMPARE (GET_MODE (operands[5]),
25210                        copy_rtx (operands[6]),
25211                        const0_rtx);
25214 (define_peephole2
25215   [(set (match_operand:SWI12 0 "register_operand")
25216         (match_operand:SWI12 1 "memory_operand"))
25217    (parallel [(set (match_operand:SI 4 "register_operand")
25218                    (match_operator:SI 3 "plusminuslogic_operator"
25219                      [(match_dup 4)
25220                       (match_operand:SI 2 "nonmemory_operand")]))
25221               (clobber (reg:CC FLAGS_REG))])
25222    (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
25223    (set (match_dup 1) (match_dup 5))
25224    (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
25225   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25226    && REGNO (operands[0]) == REGNO (operands[4])
25227    && peep2_reg_dead_p (3, operands[0])
25228    && peep2_reg_dead_p (5, operands[5])
25229    && (<MODE>mode != QImode
25230        || immediate_operand (operands[2], SImode)
25231        || any_QIreg_operand (operands[2], SImode))
25232    && !reg_overlap_mentioned_p (operands[0], operands[1])
25233    && !reg_overlap_mentioned_p (operands[0], operands[2])
25234    && !reg_overlap_mentioned_p (operands[5], operands[1])
25235    && ix86_match_ccmode (peep2_next_insn (4),
25236                          (GET_CODE (operands[3]) == PLUS
25237                           || GET_CODE (operands[3]) == MINUS)
25238                          ? CCGOCmode : CCNOmode)"
25239   [(parallel [(set (match_dup 6) (match_dup 8))
25240               (set (match_dup 1) (match_dup 7))])]
25242   operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
25243   operands[7]
25244     = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
25245                       copy_rtx (operands[1]),
25246                       gen_lowpart (<MODE>mode, operands[2]));
25247   operands[8]
25248     = gen_rtx_COMPARE (GET_MODE (operands[6]),
25249                        copy_rtx (operands[7]),
25250                        const0_rtx);
25253 ;; Likewise for cmpelim optimized pattern.
25254 (define_peephole2
25255   [(set (match_operand:SWI 0 "register_operand")
25256         (match_operand:SWI 1 "memory_operand"))
25257    (parallel [(set (reg FLAGS_REG)
25258                    (compare (match_operator:SWI 3 "plusminuslogic_operator"
25259                               [(match_dup 0)
25260                                (match_operand:SWI 2 "<nonmemory_operand>")])
25261                             (const_int 0)))
25262               (set (match_dup 0) (match_dup 3))])
25263    (set (match_operand:SWI 4 "register_operand") (match_dup 0))
25264    (set (match_dup 1) (match_dup 4))]
25265   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25266    && peep2_reg_dead_p (3, operands[0])
25267    && peep2_reg_dead_p (4, operands[4])
25268    && !reg_overlap_mentioned_p (operands[0], operands[1])
25269    && !reg_overlap_mentioned_p (operands[0], operands[2])
25270    && !reg_overlap_mentioned_p (operands[4], operands[1])
25271    && ix86_match_ccmode (peep2_next_insn (1),
25272                          (GET_CODE (operands[3]) == PLUS
25273                           || GET_CODE (operands[3]) == MINUS)
25274                          ? CCGOCmode : CCNOmode)"
25275   [(parallel [(set (match_dup 5) (match_dup 7))
25276               (set (match_dup 1) (match_dup 6))])]
25278   operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
25279   operands[6]
25280     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25281                       copy_rtx (operands[1]), operands[2]);
25282   operands[7]
25283     = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
25284                        const0_rtx);
25287 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
25288 ;; into x = z; x ^= y; x != z
25289 (define_peephole2
25290   [(set (match_operand:SWI 0 "register_operand")
25291         (match_operand:SWI 1 "memory_operand"))
25292    (set (match_operand:SWI 3 "register_operand") (match_dup 0))
25293    (parallel [(set (match_operand:SWI 4 "register_operand")
25294                    (xor:SWI (match_dup 4)
25295                             (match_operand:SWI 2 "<nonmemory_operand>")))
25296               (clobber (reg:CC FLAGS_REG))])
25297    (set (match_dup 1) (match_dup 4))
25298    (set (reg:CCZ FLAGS_REG)
25299         (compare:CCZ (match_operand:SWI 5 "register_operand")
25300                      (match_operand:SWI 6 "<nonmemory_operand>")))]
25301   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25302    && (REGNO (operands[4]) == REGNO (operands[0])
25303        || REGNO (operands[4]) == REGNO (operands[3]))
25304    && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
25305                              ? 3 : 0], operands[5])
25306        ? rtx_equal_p (operands[2], operands[6])
25307        : rtx_equal_p (operands[2], operands[5])
25308          && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
25309                                   ? 3 : 0], operands[6]))
25310    && peep2_reg_dead_p (4, operands[4])
25311    && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
25312                                     ? 3 : 0])
25313    && !reg_overlap_mentioned_p (operands[0], operands[1])
25314    && !reg_overlap_mentioned_p (operands[0], operands[2])
25315    && !reg_overlap_mentioned_p (operands[3], operands[0])
25316    && !reg_overlap_mentioned_p (operands[3], operands[1])
25317    && !reg_overlap_mentioned_p (operands[3], operands[2])
25318    && (<MODE>mode != QImode
25319        || immediate_operand (operands[2], QImode)
25320        || any_QIreg_operand (operands[2], QImode))"
25321   [(parallel [(set (match_dup 7) (match_dup 9))
25322               (set (match_dup 1) (match_dup 8))])]
25324   operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
25325   operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
25326                              operands[2]);
25327   operands[9]
25328     = gen_rtx_COMPARE (GET_MODE (operands[7]),
25329                        copy_rtx (operands[8]),
25330                        const0_rtx);
25333 (define_peephole2
25334   [(set (match_operand:SWI12 0 "register_operand")
25335         (match_operand:SWI12 1 "memory_operand"))
25336    (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
25337    (parallel [(set (match_operand:SI 4 "register_operand")
25338                    (xor:SI (match_dup 4)
25339                            (match_operand:SI 2 "<nonmemory_operand>")))
25340               (clobber (reg:CC FLAGS_REG))])
25341    (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
25342    (set (reg:CCZ FLAGS_REG)
25343         (compare:CCZ (match_operand:SWI12 6 "register_operand")
25344                      (match_operand:SWI12 7 "<nonmemory_operand>")))]
25345   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25346    && (REGNO (operands[5]) == REGNO (operands[0])
25347        || REGNO (operands[5]) == REGNO (operands[3]))
25348    && REGNO (operands[5]) == REGNO (operands[4])
25349    && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
25350                              ? 3 : 0], operands[6])
25351        ? (REG_P (operands[2])
25352           ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
25353           : rtx_equal_p (operands[2], operands[7]))
25354        : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
25355                                 ? 3 : 0], operands[7])
25356           && REG_P (operands[2])
25357           && REGNO (operands[2]) == REGNO (operands[6])))
25358    && peep2_reg_dead_p (4, operands[5])
25359    && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
25360                                     ? 3 : 0])
25361    && !reg_overlap_mentioned_p (operands[0], operands[1])
25362    && !reg_overlap_mentioned_p (operands[0], operands[2])
25363    && !reg_overlap_mentioned_p (operands[3], operands[0])
25364    && !reg_overlap_mentioned_p (operands[3], operands[1])
25365    && !reg_overlap_mentioned_p (operands[3], operands[2])
25366    && (<MODE>mode != QImode
25367        || immediate_operand (operands[2], SImode)
25368        || any_QIreg_operand (operands[2], SImode))"
25369   [(parallel [(set (match_dup 8) (match_dup 10))
25370               (set (match_dup 1) (match_dup 9))])]
25372   operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
25373   operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
25374                              gen_lowpart (<MODE>mode, operands[2]));
25375   operands[10]
25376     = gen_rtx_COMPARE (GET_MODE (operands[8]),
25377                        copy_rtx (operands[9]),
25378                        const0_rtx);
25381 ;; Attempt to optimize away memory stores of values the memory already
25382 ;; has.  See PR79593.
25383 (define_peephole2
25384   [(set (match_operand 0 "register_operand")
25385         (match_operand 1 "memory_operand"))
25386    (set (match_operand 2 "memory_operand") (match_dup 0))]
25387   "!MEM_VOLATILE_P (operands[1])
25388    && !MEM_VOLATILE_P (operands[2])
25389    && rtx_equal_p (operands[1], operands[2])
25390    && !reg_overlap_mentioned_p (operands[0], operands[2])"
25391   [(set (match_dup 0) (match_dup 1))])
25393 ;; Attempt to always use XOR for zeroing registers (including FP modes).
25394 (define_peephole2
25395   [(set (match_operand 0 "general_reg_operand")
25396         (match_operand 1 "const0_operand"))]
25397   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
25398    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
25399    && peep2_regno_dead_p (0, FLAGS_REG)"
25400   [(parallel [(set (match_dup 0) (const_int 0))
25401               (clobber (reg:CC FLAGS_REG))])]
25402   "operands[0] = gen_lowpart (word_mode, operands[0]);")
25404 (define_peephole2
25405   [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
25406         (const_int 0))]
25407   "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
25408    && peep2_regno_dead_p (0, FLAGS_REG)"
25409   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
25410               (clobber (reg:CC FLAGS_REG))])])
25412 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
25413 (define_peephole2
25414   [(set (match_operand:SWI248 0 "general_reg_operand")
25415         (const_int -1))]
25416   "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
25417    && peep2_regno_dead_p (0, FLAGS_REG)"
25418   [(parallel [(set (match_dup 0) (const_int -1))
25419               (clobber (reg:CC FLAGS_REG))])]
25421   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
25422     operands[0] = gen_lowpart (SImode, operands[0]);
25425 ;; Attempt to convert simple lea to add/shift.
25426 ;; These can be created by move expanders.
25427 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
25428 ;; relevant lea instructions were already split.
25430 (define_peephole2
25431   [(set (match_operand:SWI48 0 "register_operand")
25432         (plus:SWI48 (match_dup 0)
25433                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
25434   "!TARGET_OPT_AGU
25435    && peep2_regno_dead_p (0, FLAGS_REG)"
25436   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
25437               (clobber (reg:CC FLAGS_REG))])])
25439 (define_peephole2
25440   [(set (match_operand:SWI48 0 "register_operand")
25441         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
25442                     (match_dup 0)))]
25443   "!TARGET_OPT_AGU
25444    && peep2_regno_dead_p (0, FLAGS_REG)"
25445   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
25446               (clobber (reg:CC FLAGS_REG))])])
25448 (define_peephole2
25449   [(set (match_operand:DI 0 "register_operand")
25450         (zero_extend:DI
25451           (plus:SI (match_operand:SI 1 "register_operand")
25452                    (match_operand:SI 2 "nonmemory_operand"))))]
25453   "TARGET_64BIT && !TARGET_OPT_AGU
25454    && REGNO (operands[0]) == REGNO (operands[1])
25455    && peep2_regno_dead_p (0, FLAGS_REG)"
25456   [(parallel [(set (match_dup 0)
25457                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
25458               (clobber (reg:CC FLAGS_REG))])])
25460 (define_peephole2
25461   [(set (match_operand:DI 0 "register_operand")
25462         (zero_extend:DI
25463           (plus:SI (match_operand:SI 1 "nonmemory_operand")
25464                    (match_operand:SI 2 "register_operand"))))]
25465   "TARGET_64BIT && !TARGET_OPT_AGU
25466    && REGNO (operands[0]) == REGNO (operands[2])
25467    && peep2_regno_dead_p (0, FLAGS_REG)"
25468   [(parallel [(set (match_dup 0)
25469                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
25470               (clobber (reg:CC FLAGS_REG))])])
25472 (define_peephole2
25473   [(set (match_operand:SWI48 0 "register_operand")
25474         (mult:SWI48 (match_dup 0)
25475                     (match_operand:SWI48 1 "const_int_operand")))]
25476   "pow2p_hwi (INTVAL (operands[1]))
25477    && peep2_regno_dead_p (0, FLAGS_REG)"
25478   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
25479               (clobber (reg:CC FLAGS_REG))])]
25480   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
25482 (define_peephole2
25483   [(set (match_operand:DI 0 "register_operand")
25484         (zero_extend:DI
25485           (mult:SI (match_operand:SI 1 "register_operand")
25486                    (match_operand:SI 2 "const_int_operand"))))]
25487   "TARGET_64BIT
25488    && pow2p_hwi (INTVAL (operands[2]))
25489    && REGNO (operands[0]) == REGNO (operands[1])
25490    && peep2_regno_dead_p (0, FLAGS_REG)"
25491   [(parallel [(set (match_dup 0)
25492                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
25493               (clobber (reg:CC FLAGS_REG))])]
25494   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
25496 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
25497 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
25498 ;; On many CPUs it is also faster, since special hardware to avoid esp
25499 ;; dependencies is present.
25501 ;; While some of these conversions may be done using splitters, we use
25502 ;; peepholes in order to allow combine_stack_adjustments pass to see
25503 ;; nonobfuscated RTL.
25505 ;; Convert prologue esp subtractions to push.
25506 ;; We need register to push.  In order to keep verify_flow_info happy we have
25507 ;; two choices
25508 ;; - use scratch and clobber it in order to avoid dependencies
25509 ;; - use already live register
25510 ;; We can't use the second way right now, since there is no reliable way how to
25511 ;; verify that given register is live.  First choice will also most likely in
25512 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
25513 ;; call clobbered registers are dead.  We may want to use base pointer as an
25514 ;; alternative when no register is available later.
25516 (define_peephole2
25517   [(match_scratch:W 1 "r")
25518    (parallel [(set (reg:P SP_REG)
25519                    (plus:P (reg:P SP_REG)
25520                            (match_operand:P 0 "const_int_operand")))
25521               (clobber (reg:CC FLAGS_REG))
25522               (clobber (mem:BLK (scratch)))])]
25523   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
25524    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
25525    && !ix86_red_zone_used"
25526   [(clobber (match_dup 1))
25527    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25528               (clobber (mem:BLK (scratch)))])])
25530 (define_peephole2
25531   [(match_scratch:W 1 "r")
25532    (parallel [(set (reg:P SP_REG)
25533                    (plus:P (reg:P SP_REG)
25534                            (match_operand:P 0 "const_int_operand")))
25535               (clobber (reg:CC FLAGS_REG))
25536               (clobber (mem:BLK (scratch)))])]
25537   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
25538    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
25539    && !ix86_red_zone_used"
25540   [(clobber (match_dup 1))
25541    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25542    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25543               (clobber (mem:BLK (scratch)))])])
25545 ;; Convert esp subtractions to push.
25546 (define_peephole2
25547   [(match_scratch:W 1 "r")
25548    (parallel [(set (reg:P SP_REG)
25549                    (plus:P (reg:P SP_REG)
25550                            (match_operand:P 0 "const_int_operand")))
25551               (clobber (reg:CC FLAGS_REG))])]
25552   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
25553    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
25554    && !ix86_red_zone_used"
25555   [(clobber (match_dup 1))
25556    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
25558 (define_peephole2
25559   [(match_scratch:W 1 "r")
25560    (parallel [(set (reg:P SP_REG)
25561                    (plus:P (reg:P SP_REG)
25562                            (match_operand:P 0 "const_int_operand")))
25563               (clobber (reg:CC FLAGS_REG))])]
25564   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
25565    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
25566    && !ix86_red_zone_used"
25567   [(clobber (match_dup 1))
25568    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25569    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
25571 ;; Convert epilogue deallocator to pop.
25572 (define_peephole2
25573   [(match_scratch:W 1 "r")
25574    (parallel [(set (reg:P SP_REG)
25575                    (plus:P (reg:P SP_REG)
25576                            (match_operand:P 0 "const_int_operand")))
25577               (clobber (reg:CC FLAGS_REG))
25578               (clobber (mem:BLK (scratch)))])]
25579   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
25580    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
25581   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25582               (clobber (mem:BLK (scratch)))])])
25584 ;; Two pops case is tricky, since pop causes dependency
25585 ;; on destination register.  We use two registers if available.
25586 (define_peephole2
25587   [(match_scratch:W 1 "r")
25588    (match_scratch:W 2 "r")
25589    (parallel [(set (reg:P SP_REG)
25590                    (plus:P (reg:P SP_REG)
25591                            (match_operand:P 0 "const_int_operand")))
25592               (clobber (reg:CC FLAGS_REG))
25593               (clobber (mem:BLK (scratch)))])]
25594   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
25595    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25596   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25597               (clobber (mem:BLK (scratch)))])
25598    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
25600 (define_peephole2
25601   [(match_scratch:W 1 "r")
25602    (parallel [(set (reg:P SP_REG)
25603                    (plus:P (reg:P SP_REG)
25604                            (match_operand:P 0 "const_int_operand")))
25605               (clobber (reg:CC FLAGS_REG))
25606               (clobber (mem:BLK (scratch)))])]
25607   "optimize_insn_for_size_p ()
25608    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25609   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25610               (clobber (mem:BLK (scratch)))])
25611    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25613 ;; Convert esp additions to pop.
25614 (define_peephole2
25615   [(match_scratch:W 1 "r")
25616    (parallel [(set (reg:P SP_REG)
25617                    (plus:P (reg:P SP_REG)
25618                            (match_operand:P 0 "const_int_operand")))
25619               (clobber (reg:CC FLAGS_REG))])]
25620   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
25621   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25623 ;; Two pops case is tricky, since pop causes dependency
25624 ;; on destination register.  We use two registers if available.
25625 (define_peephole2
25626   [(match_scratch:W 1 "r")
25627    (match_scratch:W 2 "r")
25628    (parallel [(set (reg:P SP_REG)
25629                    (plus:P (reg:P SP_REG)
25630                            (match_operand:P 0 "const_int_operand")))
25631               (clobber (reg:CC FLAGS_REG))])]
25632   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25633   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25634    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
25636 (define_peephole2
25637   [(match_scratch:W 1 "r")
25638    (parallel [(set (reg:P SP_REG)
25639                    (plus:P (reg:P SP_REG)
25640                            (match_operand:P 0 "const_int_operand")))
25641               (clobber (reg:CC FLAGS_REG))])]
25642   "optimize_insn_for_size_p ()
25643    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25644   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25645    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25647 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
25648 ;; required and register dies.  Similarly for 128 to -128.
25649 (define_peephole2
25650   [(set (match_operand 0 "flags_reg_operand")
25651         (match_operator 1 "compare_operator"
25652           [(match_operand 2 "register_operand")
25653            (match_operand 3 "const_int_operand")]))]
25654   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
25655      && incdec_operand (operands[3], GET_MODE (operands[3])))
25656     || (!TARGET_FUSE_CMP_AND_BRANCH
25657         && INTVAL (operands[3]) == 128))
25658    && ix86_match_ccmode (insn, CCGCmode)
25659    && peep2_reg_dead_p (1, operands[2])"
25660   [(parallel [(set (match_dup 0)
25661                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
25662               (clobber (match_dup 2))])])
25664 ;; Convert imul by three, five and nine into lea
25665 (define_peephole2
25666   [(parallel
25667     [(set (match_operand:SWI48 0 "register_operand")
25668           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
25669                       (match_operand:SWI48 2 "const359_operand")))
25670      (clobber (reg:CC FLAGS_REG))])]
25671   "!TARGET_PARTIAL_REG_STALL
25672    || <MODE>mode == SImode
25673    || optimize_function_for_size_p (cfun)"
25674   [(set (match_dup 0)
25675         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
25676                     (match_dup 1)))]
25677   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
25679 (define_peephole2
25680   [(parallel
25681     [(set (match_operand:SWI48 0 "register_operand")
25682           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
25683                       (match_operand:SWI48 2 "const359_operand")))
25684      (clobber (reg:CC FLAGS_REG))])]
25685   "optimize_insn_for_speed_p ()
25686    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
25687   [(set (match_dup 0) (match_dup 1))
25688    (set (match_dup 0)
25689         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
25690                     (match_dup 0)))]
25691   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
25693 ;; imul $32bit_imm, mem, reg is vector decoded, while
25694 ;; imul $32bit_imm, reg, reg is direct decoded.
25695 (define_peephole2
25696   [(match_scratch:SWI48 3 "r")
25697    (parallel [(set (match_operand:SWI48 0 "register_operand")
25698                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
25699                                (match_operand:SWI48 2 "immediate_operand")))
25700               (clobber (reg:CC FLAGS_REG))])]
25701   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25702    && !satisfies_constraint_K (operands[2])"
25703   [(set (match_dup 3) (match_dup 1))
25704    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
25705               (clobber (reg:CC FLAGS_REG))])])
25707 (define_peephole2
25708   [(match_scratch:SI 3 "r")
25709    (parallel [(set (match_operand:DI 0 "register_operand")
25710                    (zero_extend:DI
25711                      (mult:SI (match_operand:SI 1 "memory_operand")
25712                               (match_operand:SI 2 "immediate_operand"))))
25713               (clobber (reg:CC FLAGS_REG))])]
25714   "TARGET_64BIT
25715    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25716    && !satisfies_constraint_K (operands[2])"
25717   [(set (match_dup 3) (match_dup 1))
25718    (parallel [(set (match_dup 0)
25719                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
25720               (clobber (reg:CC FLAGS_REG))])])
25722 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
25723 ;; Convert it into imul reg, reg
25724 ;; It would be better to force assembler to encode instruction using long
25725 ;; immediate, but there is apparently no way to do so.
25726 (define_peephole2
25727   [(parallel [(set (match_operand:SWI248 0 "register_operand")
25728                    (mult:SWI248
25729                     (match_operand:SWI248 1 "nonimmediate_operand")
25730                     (match_operand:SWI248 2 "const_int_operand")))
25731               (clobber (reg:CC FLAGS_REG))])
25732    (match_scratch:SWI248 3 "r")]
25733   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
25734    && satisfies_constraint_K (operands[2])"
25735   [(set (match_dup 3) (match_dup 2))
25736    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
25737               (clobber (reg:CC FLAGS_REG))])]
25739   if (!rtx_equal_p (operands[0], operands[1]))
25740     emit_move_insn (operands[0], operands[1]);
25743 ;; After splitting up read-modify operations, array accesses with memory
25744 ;; operands might end up in form:
25745 ;;  sall    $2, %eax
25746 ;;  movl    4(%esp), %edx
25747 ;;  addl    %edx, %eax
25748 ;; instead of pre-splitting:
25749 ;;  sall    $2, %eax
25750 ;;  addl    4(%esp), %eax
25751 ;; Turn it into:
25752 ;;  movl    4(%esp), %edx
25753 ;;  leal    (%edx,%eax,4), %eax
25755 (define_peephole2
25756   [(match_scratch:W 5 "r")
25757    (parallel [(set (match_operand 0 "register_operand")
25758                    (ashift (match_operand 1 "register_operand")
25759                            (match_operand 2 "const_int_operand")))
25760                (clobber (reg:CC FLAGS_REG))])
25761    (parallel [(set (match_operand 3 "register_operand")
25762                    (plus (match_dup 0)
25763                          (match_operand 4 "x86_64_general_operand")))
25764                    (clobber (reg:CC FLAGS_REG))])]
25765   "IN_RANGE (INTVAL (operands[2]), 1, 3)
25766    /* Validate MODE for lea.  */
25767    && ((!TARGET_PARTIAL_REG_STALL
25768         && (GET_MODE (operands[0]) == QImode
25769             || GET_MODE (operands[0]) == HImode))
25770        || GET_MODE (operands[0]) == SImode
25771        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
25772    && (rtx_equal_p (operands[0], operands[3])
25773        || peep2_reg_dead_p (2, operands[0]))
25774    /* We reorder load and the shift.  */
25775    && !reg_overlap_mentioned_p (operands[0], operands[4])"
25776   [(set (match_dup 5) (match_dup 4))
25777    (set (match_dup 0) (match_dup 1))]
25779   machine_mode op1mode = GET_MODE (operands[1]);
25780   machine_mode mode = op1mode == DImode ? DImode : SImode;
25781   int scale = 1 << INTVAL (operands[2]);
25782   rtx index = gen_lowpart (word_mode, operands[1]);
25783   rtx base = gen_lowpart (word_mode, operands[5]);
25784   rtx dest = gen_lowpart (mode, operands[3]);
25786   operands[1] = gen_rtx_PLUS (word_mode, base,
25787                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
25788   if (mode != word_mode)
25789     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
25791   operands[5] = base;
25792   if (op1mode != word_mode)
25793     operands[5] = gen_lowpart (op1mode, operands[5]);
25795   operands[0] = dest;
25798 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
25799 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
25800 ;; caught for use by garbage collectors and the like.  Using an insn that
25801 ;; maps to SIGILL makes it more likely the program will rightfully die.
25802 ;; Keeping with tradition, "6" is in honor of #UD.
25803 (define_insn "trap"
25804   [(trap_if (const_int 1) (const_int 6))]
25805   ""
25807 #ifdef HAVE_AS_IX86_UD2
25808   return "ud2";
25809 #else
25810   return ASM_SHORT "0x0b0f";
25811 #endif
25813   [(set_attr "length" "2")])
25815 (define_insn "ud2"
25816   [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
25817   ""
25819 #ifdef HAVE_AS_IX86_UD2
25820   return "ud2";
25821 #else
25822   return ASM_SHORT "0x0b0f";
25823 #endif
25825   [(set_attr "length" "2")])
25827 (define_expand "prefetch"
25828   [(prefetch (match_operand 0 "address_operand")
25829              (match_operand:SI 1 "const_int_operand")
25830              (match_operand:SI 2 "const_int_operand"))]
25831   "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25833   bool write = operands[1] != const0_rtx;
25834   int locality = INTVAL (operands[2]);
25836   gcc_assert (IN_RANGE (locality, 0, 3));
25838   /* Use 3dNOW prefetch in case we are asking for write prefetch not
25839      supported by SSE counterpart (non-SSE2 athlon machines) or the
25840      SSE prefetch is not available (K6 machines).  Otherwise use SSE
25841      prefetch as it allows specifying of locality.  */
25843   if (write)
25844     {
25845       if (TARGET_PREFETCHWT1)
25846         operands[2] = GEN_INT (MAX (locality, 2)); 
25847       else if (TARGET_PRFCHW)
25848         operands[2] = GEN_INT (3);
25849       else if (TARGET_3DNOW && !TARGET_SSE2)
25850         operands[2] = GEN_INT (3);
25851       else if (TARGET_PREFETCH_SSE)
25852         operands[1] = const0_rtx;
25853       else
25854         {
25855           gcc_assert (TARGET_3DNOW);
25856           operands[2] = GEN_INT (3);
25857         }
25858     }
25859   else
25860     {
25861       if (TARGET_PREFETCH_SSE)
25862         ;
25863       else
25864         {
25865           gcc_assert (TARGET_3DNOW);
25866           operands[2] = GEN_INT (3);
25867         }
25868     }
25871 (define_insn "*prefetch_sse"
25872   [(prefetch (match_operand 0 "address_operand" "p")
25873              (const_int 0)
25874              (match_operand:SI 1 "const_int_operand"))]
25875   "TARGET_PREFETCH_SSE"
25877   static const char * const patterns[4] = {
25878    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
25879   };
25881   int locality = INTVAL (operands[1]);
25882   gcc_assert (IN_RANGE (locality, 0, 3));
25884   return patterns[locality];
25886   [(set_attr "type" "sse")
25887    (set_attr "atom_sse_attr" "prefetch")
25888    (set (attr "length_address")
25889         (symbol_ref "memory_address_length (operands[0], false)"))
25890    (set_attr "memory" "none")])
25892 (define_insn "*prefetch_3dnow"
25893   [(prefetch (match_operand 0 "address_operand" "p")
25894              (match_operand:SI 1 "const_int_operand")
25895              (const_int 3))]
25896   "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25898   if (operands[1] == const0_rtx)
25899     return "prefetch\t%a0";
25900   else
25901     return "prefetchw\t%a0";
25903   [(set_attr "type" "mmx")
25904    (set (attr "length_address")
25905         (symbol_ref "memory_address_length (operands[0], false)"))
25906    (set_attr "memory" "none")])
25908 (define_insn "*prefetch_prefetchwt1"
25909   [(prefetch (match_operand 0 "address_operand" "p")
25910              (const_int 1)
25911              (const_int 2))]
25912   "TARGET_PREFETCHWT1"
25913   "prefetchwt1\t%a0";
25914   [(set_attr "type" "sse")
25915    (set (attr "length_address")
25916         (symbol_ref "memory_address_length (operands[0], false)"))
25917    (set_attr "memory" "none")])
25919 (define_insn "prefetchi"
25920   [(unspec_volatile [(match_operand 0 "local_func_symbolic_operand" "p")
25921                      (match_operand:SI 1 "const_int_operand")]
25922                     UNSPECV_PREFETCHI)]
25923   "TARGET_PREFETCHI && TARGET_64BIT"
25925   static const char * const patterns[2] = {
25926     "prefetchit1\t%0", "prefetchit0\t%0"
25927   };
25929   int locality = INTVAL (operands[1]);
25930   gcc_assert (IN_RANGE (locality, 2, 3));
25932   return patterns[locality - 2];
25934   [(set_attr "type" "sse")
25935    (set (attr "length_address")
25936         (symbol_ref "memory_address_length (operands[0], false)"))
25937    (set_attr "memory" "none")])
25939 (define_insn "sse4_2_crc32<mode>"
25940   [(set (match_operand:SI 0 "register_operand" "=r")
25941         (unspec:SI
25942           [(match_operand:SI 1 "register_operand" "0")
25943            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
25944           UNSPEC_CRC32))]
25945   "TARGET_CRC32"
25946   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
25947   [(set_attr "type" "sselog1")
25948    (set_attr "prefix_rep" "1")
25949    (set_attr "prefix_extra" "1")
25950    (set (attr "prefix_data16")
25951      (if_then_else (match_operand:HI 2)
25952        (const_string "1")
25953        (const_string "*")))
25954    (set (attr "prefix_rex")
25955      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
25956        (const_string "1")
25957        (const_string "*")))
25958    (set_attr "mode" "SI")])
25960 (define_insn "sse4_2_crc32di"
25961   [(set (match_operand:DI 0 "register_operand" "=r")
25962         (zero_extend:DI
25963           (unspec:SI
25964             [(match_operand:SI 1 "register_operand" "0")
25965              (match_operand:DI 2 "nonimmediate_operand" "rm")]
25966           UNSPEC_CRC32)))]
25967   "TARGET_64BIT && TARGET_CRC32"
25968   "crc32{q}\t{%2, %0|%0, %2}"
25969   [(set_attr "type" "sselog1")
25970    (set_attr "prefix_rep" "1")
25971    (set_attr "prefix_extra" "1")
25972    (set_attr "mode" "DI")])
25974 (define_insn "rdpmc"
25975   [(set (match_operand:DI 0 "register_operand" "=A")
25976         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
25977                             UNSPECV_RDPMC))]
25978   "!TARGET_64BIT"
25979   "rdpmc"
25980   [(set_attr "type" "other")
25981    (set_attr "length" "2")])
25983 (define_insn "rdpmc_rex64"
25984   [(set (match_operand:DI 0 "register_operand" "=a")
25985         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
25986                             UNSPECV_RDPMC))
25987    (set (match_operand:DI 1 "register_operand" "=d")
25988         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
25989   "TARGET_64BIT"
25990   "rdpmc"
25991   [(set_attr "type" "other")
25992    (set_attr "length" "2")])
25994 (define_insn "rdtsc"
25995   [(set (match_operand:DI 0 "register_operand" "=A")
25996         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
25997   "!TARGET_64BIT"
25998   "rdtsc"
25999   [(set_attr "type" "other")
26000    (set_attr "length" "2")])
26002 (define_insn "rdtsc_rex64"
26003   [(set (match_operand:DI 0 "register_operand" "=a")
26004         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
26005    (set (match_operand:DI 1 "register_operand" "=d")
26006         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
26007   "TARGET_64BIT"
26008   "rdtsc"
26009   [(set_attr "type" "other")
26010    (set_attr "length" "2")])
26012 (define_insn "rdtscp"
26013   [(set (match_operand:DI 0 "register_operand" "=A")
26014         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
26015    (set (match_operand:SI 1 "register_operand" "=c")
26016         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
26017   "!TARGET_64BIT"
26018   "rdtscp"
26019   [(set_attr "type" "other")
26020    (set_attr "length" "3")])
26022 (define_insn "rdtscp_rex64"
26023   [(set (match_operand:DI 0 "register_operand" "=a")
26024         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
26025    (set (match_operand:DI 1 "register_operand" "=d")
26026         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
26027    (set (match_operand:SI 2 "register_operand" "=c")
26028         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
26029   "TARGET_64BIT"
26030   "rdtscp"
26031   [(set_attr "type" "other")
26032    (set_attr "length" "3")])
26034 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26036 ;; FXSR, XSAVE and XSAVEOPT instructions
26038 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26040 (define_insn "fxsave"
26041   [(set (match_operand:BLK 0 "memory_operand" "=m")
26042         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
26043   "TARGET_FXSR"
26044   "fxsave\t%0"
26045   [(set_attr "type" "other")
26046    (set_attr "memory" "store")
26047    (set (attr "length")
26048         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26050 (define_insn "fxsave64"
26051   [(set (match_operand:BLK 0 "memory_operand" "=jm")
26052         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
26053   "TARGET_64BIT && TARGET_FXSR"
26054   "fxsave64\t%0"
26055   [(set_attr "type" "other")
26056    (set_attr "addr" "gpr16")
26057    (set_attr "memory" "store")
26058    (set (attr "length")
26059         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26061 (define_insn "fxrstor"
26062   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
26063                     UNSPECV_FXRSTOR)]
26064   "TARGET_FXSR"
26065   "fxrstor\t%0"
26066   [(set_attr "type" "other")
26067    (set_attr "memory" "load")
26068    (set (attr "length")
26069         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26071 (define_insn "fxrstor64"
26072   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "jm")]
26073                     UNSPECV_FXRSTOR64)]
26074   "TARGET_64BIT && TARGET_FXSR"
26075   "fxrstor64\t%0"
26076   [(set_attr "type" "other")
26077    (set_attr "addr" "gpr16")
26078    (set_attr "memory" "load")
26079    (set (attr "length")
26080         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26082 (define_int_iterator ANY_XSAVE
26083         [UNSPECV_XSAVE
26084          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
26085          (UNSPECV_XSAVEC "TARGET_XSAVEC")
26086          (UNSPECV_XSAVES "TARGET_XSAVES")])
26088 (define_int_iterator ANY_XSAVE64
26089         [UNSPECV_XSAVE64
26090          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
26091          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
26092          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
26094 (define_int_attr xsave
26095         [(UNSPECV_XSAVE "xsave")
26096          (UNSPECV_XSAVE64 "xsave64")
26097          (UNSPECV_XSAVEOPT "xsaveopt")
26098          (UNSPECV_XSAVEOPT64 "xsaveopt64")
26099          (UNSPECV_XSAVEC "xsavec")
26100          (UNSPECV_XSAVEC64 "xsavec64")
26101          (UNSPECV_XSAVES "xsaves")
26102          (UNSPECV_XSAVES64 "xsaves64")])
26104 (define_int_iterator ANY_XRSTOR
26105         [UNSPECV_XRSTOR
26106          (UNSPECV_XRSTORS "TARGET_XSAVES")])
26108 (define_int_iterator ANY_XRSTOR64
26109         [UNSPECV_XRSTOR64
26110          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
26112 (define_int_attr xrstor
26113         [(UNSPECV_XRSTOR "xrstor")
26114          (UNSPECV_XRSTOR64 "xrstor")
26115          (UNSPECV_XRSTORS "xrstors")
26116          (UNSPECV_XRSTORS64 "xrstors")])
26118 (define_insn "<xsave>"
26119   [(set (match_operand:BLK 0 "memory_operand" "=m")
26120         (unspec_volatile:BLK
26121          [(match_operand:DI 1 "register_operand" "A")]
26122          ANY_XSAVE))]
26123   "!TARGET_64BIT && TARGET_XSAVE"
26124   "<xsave>\t%0"
26125   [(set_attr "type" "other")
26126    (set_attr "memory" "store")
26127    (set (attr "length")
26128         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26130 (define_insn "<xsave>_rex64"
26131   [(set (match_operand:BLK 0 "memory_operand" "=jm")
26132         (unspec_volatile:BLK
26133          [(match_operand:SI 1 "register_operand" "a")
26134           (match_operand:SI 2 "register_operand" "d")]
26135          ANY_XSAVE))]
26136   "TARGET_64BIT && TARGET_XSAVE"
26137   "<xsave>\t%0"
26138   [(set_attr "type" "other")
26139    (set_attr "memory" "store")
26140    (set_attr "addr" "gpr16")
26141    (set (attr "length")
26142         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26144 (define_insn "<xsave>"
26145   [(set (match_operand:BLK 0 "memory_operand" "=jm")
26146         (unspec_volatile:BLK
26147          [(match_operand:SI 1 "register_operand" "a")
26148           (match_operand:SI 2 "register_operand" "d")]
26149          ANY_XSAVE64))]
26150   "TARGET_64BIT && TARGET_XSAVE"
26151   "<xsave>\t%0"
26152   [(set_attr "type" "other")
26153    (set_attr "memory" "store")
26154    (set_attr "addr" "gpr16")
26155    (set (attr "length")
26156         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26158 (define_insn "<xrstor>"
26159    [(unspec_volatile:BLK
26160      [(match_operand:BLK 0 "memory_operand" "m")
26161       (match_operand:DI 1 "register_operand" "A")]
26162      ANY_XRSTOR)]
26163   "!TARGET_64BIT && TARGET_XSAVE"
26164   "<xrstor>\t%0"
26165   [(set_attr "type" "other")
26166    (set_attr "memory" "load")
26167    (set (attr "length")
26168         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26170 (define_insn "<xrstor>_rex64"
26171    [(unspec_volatile:BLK
26172      [(match_operand:BLK 0 "memory_operand" "jm")
26173       (match_operand:SI 1 "register_operand" "a")
26174       (match_operand:SI 2 "register_operand" "d")]
26175      ANY_XRSTOR)]
26176   "TARGET_64BIT && TARGET_XSAVE"
26177   "<xrstor>\t%0"
26178   [(set_attr "type" "other")
26179    (set_attr "memory" "load")
26180    (set_attr "addr" "gpr16")
26181    (set (attr "length")
26182         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26184 (define_insn "<xrstor>64"
26185    [(unspec_volatile:BLK
26186      [(match_operand:BLK 0 "memory_operand" "jm")
26187       (match_operand:SI 1 "register_operand" "a")
26188       (match_operand:SI 2 "register_operand" "d")]
26189      ANY_XRSTOR64)]
26190   "TARGET_64BIT && TARGET_XSAVE"
26191   "<xrstor>64\t%0"
26192   [(set_attr "type" "other")
26193    (set_attr "memory" "load")
26194    (set_attr "addr" "gpr16")
26195    (set (attr "length")
26196         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26198 (define_insn "xsetbv"
26199   [(unspec_volatile:SI
26200          [(match_operand:SI 0 "register_operand" "c")
26201           (match_operand:DI 1 "register_operand" "A")]
26202          UNSPECV_XSETBV)]
26203   "!TARGET_64BIT && TARGET_XSAVE"
26204   "xsetbv"
26205   [(set_attr "type" "other")])
26207 (define_insn "xsetbv_rex64"
26208   [(unspec_volatile:SI
26209          [(match_operand:SI 0 "register_operand" "c")
26210           (match_operand:SI 1 "register_operand" "a")
26211           (match_operand:SI 2 "register_operand" "d")]
26212          UNSPECV_XSETBV)]
26213   "TARGET_64BIT && TARGET_XSAVE"
26214   "xsetbv"
26215   [(set_attr "type" "other")])
26217 (define_insn "xgetbv"
26218   [(set (match_operand:DI 0 "register_operand" "=A")
26219         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
26220                             UNSPECV_XGETBV))]
26221   "!TARGET_64BIT && TARGET_XSAVE"
26222   "xgetbv"
26223   [(set_attr "type" "other")])
26225 (define_insn "xgetbv_rex64"
26226   [(set (match_operand:DI 0 "register_operand" "=a")
26227         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
26228                             UNSPECV_XGETBV))
26229    (set (match_operand:DI 1 "register_operand" "=d")
26230         (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
26231   "TARGET_64BIT && TARGET_XSAVE"
26232   "xgetbv"
26233   [(set_attr "type" "other")])
26235 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26237 ;; Floating-point instructions for atomic compound assignments
26239 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26241 ; Clobber all floating-point registers on environment save and restore
26242 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
26243 (define_insn "fnstenv"
26244   [(set (match_operand:BLK 0 "memory_operand" "=m")
26245         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
26246    (clobber (reg:XF ST0_REG))
26247    (clobber (reg:XF ST1_REG))
26248    (clobber (reg:XF ST2_REG))
26249    (clobber (reg:XF ST3_REG))
26250    (clobber (reg:XF ST4_REG))
26251    (clobber (reg:XF ST5_REG))
26252    (clobber (reg:XF ST6_REG))
26253    (clobber (reg:XF ST7_REG))]
26254   "TARGET_80387"
26255   "fnstenv\t%0"
26256   [(set_attr "type" "other")
26257    (set_attr "memory" "store")
26258    (set (attr "length")
26259         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26261 (define_insn "fldenv"
26262   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
26263                     UNSPECV_FLDENV)
26264    (clobber (reg:XF ST0_REG))
26265    (clobber (reg:XF ST1_REG))
26266    (clobber (reg:XF ST2_REG))
26267    (clobber (reg:XF ST3_REG))
26268    (clobber (reg:XF ST4_REG))
26269    (clobber (reg:XF ST5_REG))
26270    (clobber (reg:XF ST6_REG))
26271    (clobber (reg:XF ST7_REG))]
26272   "TARGET_80387"
26273   "fldenv\t%0"
26274   [(set_attr "type" "other")
26275    (set_attr "memory" "load")
26276    (set (attr "length")
26277         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26279 (define_insn "fnstsw"
26280   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
26281         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
26282   "TARGET_80387"
26283   "fnstsw\t%0"
26284   [(set_attr "type" "other,other")
26285    (set_attr "memory" "none,store")
26286    (set (attr "length")
26287         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26289 (define_insn "fnclex"
26290   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
26291   "TARGET_80387"
26292   "fnclex"
26293   [(set_attr "type" "other")
26294    (set_attr "memory" "none")
26295    (set_attr "length" "2")])
26297 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26299 ;; LWP instructions
26301 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26303 (define_insn "@lwp_llwpcb<mode>"
26304   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26305                     UNSPECV_LLWP_INTRINSIC)]
26306   "TARGET_LWP"
26307   "llwpcb\t%0"
26308   [(set_attr "type" "lwp")
26309    (set_attr "mode" "<MODE>")
26310    (set_attr "length" "5")])
26312 (define_insn "@lwp_slwpcb<mode>"
26313   [(set (match_operand:P 0 "register_operand" "=r")
26314         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
26315   "TARGET_LWP"
26316   "slwpcb\t%0"
26317   [(set_attr "type" "lwp")
26318    (set_attr "mode" "<MODE>")
26319    (set_attr "length" "5")])
26321 (define_insn "@lwp_lwpval<mode>"
26322   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26323                      (match_operand:SI 1 "nonimmediate_operand" "rm")
26324                      (match_operand:SI 2 "const_int_operand")]
26325                     UNSPECV_LWPVAL_INTRINSIC)]
26326   "TARGET_LWP"
26327   "lwpval\t{%2, %1, %0|%0, %1, %2}"
26328   [(set_attr "type" "lwp")
26329    (set_attr "mode" "<MODE>")
26330    (set (attr "length")
26331         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
26333 (define_insn "@lwp_lwpins<mode>"
26334   [(set (reg:CCC FLAGS_REG)
26335         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
26336                               (match_operand:SI 1 "nonimmediate_operand" "rm")
26337                               (match_operand:SI 2 "const_int_operand")]
26338                              UNSPECV_LWPINS_INTRINSIC))]
26339   "TARGET_LWP"
26340   "lwpins\t{%2, %1, %0|%0, %1, %2}"
26341   [(set_attr "type" "lwp")
26342    (set_attr "mode" "<MODE>")
26343    (set (attr "length")
26344         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
26346 (define_int_iterator RDFSGSBASE
26347         [UNSPECV_RDFSBASE
26348          UNSPECV_RDGSBASE])
26350 (define_int_iterator WRFSGSBASE
26351         [UNSPECV_WRFSBASE
26352          UNSPECV_WRGSBASE])
26354 (define_int_attr fsgs
26355         [(UNSPECV_RDFSBASE "fs")
26356          (UNSPECV_RDGSBASE "gs")
26357          (UNSPECV_WRFSBASE "fs")
26358          (UNSPECV_WRGSBASE "gs")])
26360 (define_insn "rd<fsgs>base<mode>"
26361   [(set (match_operand:SWI48 0 "register_operand" "=r")
26362         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
26363   "TARGET_64BIT && TARGET_FSGSBASE"
26364   "rd<fsgs>base\t%0"
26365   [(set_attr "type" "other")
26366    (set_attr "prefix_0f" "1")
26367    (set_attr "prefix_rep" "1")])
26369 (define_insn "wr<fsgs>base<mode>"
26370   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
26371                     WRFSGSBASE)]
26372   "TARGET_64BIT && TARGET_FSGSBASE"
26373   "wr<fsgs>base\t%0"
26374   [(set_attr "type" "other")
26375    (set_attr "prefix_0f" "1")
26376    (set_attr "prefix_rep" "1")])
26378 (define_insn "ptwrite<mode>"
26379   [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
26380                     UNSPECV_PTWRITE)]
26381   "TARGET_PTWRITE"
26382   "ptwrite\t%0"
26383   [(set_attr "type" "other")
26384    (set_attr "prefix_0f" "1")
26385    (set_attr "prefix_rep" "1")])
26387 (define_insn "@rdrand<mode>"
26388   [(set (match_operand:SWI248 0 "register_operand" "=r")
26389         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
26390    (set (reg:CCC FLAGS_REG)
26391         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
26392   "TARGET_RDRND"
26393   "rdrand\t%0"
26394   [(set_attr "type" "other")
26395    (set_attr "prefix_0f" "1")])
26397 (define_insn "@rdseed<mode>"
26398   [(set (match_operand:SWI248 0 "register_operand" "=r")
26399         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
26400    (set (reg:CCC FLAGS_REG)
26401         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
26402   "TARGET_RDSEED"
26403   "rdseed\t%0"
26404   [(set_attr "type" "other")
26405    (set_attr "prefix_0f" "1")])
26407 (define_expand "pause"
26408   [(set (match_dup 0)
26409         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
26410   ""
26412   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
26413   MEM_VOLATILE_P (operands[0]) = 1;
26416 ;; Use "rep; nop", instead of "pause", to support older assemblers.
26417 ;; They have the same encoding.
26418 (define_insn "*pause"
26419   [(set (match_operand:BLK 0)
26420         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
26421   ""
26422   "rep%; nop"
26423   [(set_attr "length" "2")
26424    (set_attr "memory" "unknown")])
26426 ;; CET instructions
26427 (define_insn "@rdssp<mode>"
26428   [(set (match_operand:SWI48 0 "register_operand" "=r")
26429         (unspec_volatile:SWI48 [(match_operand:SWI48 1 "register_operand" "0")]
26430                                UNSPECV_NOP_RDSSP))]
26431   "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
26432   "rdssp<mskmodesuffix>\t%0"
26433   [(set_attr "length" "6")
26434    (set_attr "type" "other")])
26436 (define_insn "@incssp<mode>"
26437   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
26438                     UNSPECV_INCSSP)]
26439   "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
26440   "incssp<mskmodesuffix>\t%0"
26441   [(set_attr "length" "4")
26442    (set_attr "type" "other")])
26444 (define_insn "saveprevssp"
26445   [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
26446   "TARGET_SHSTK"
26447   "saveprevssp"
26448   [(set_attr "length" "5")
26449    (set_attr "type" "other")])
26451 (define_insn "rstorssp"
26452   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
26453                     UNSPECV_RSTORSSP)]
26454   "TARGET_SHSTK"
26455   "rstorssp\t%0"
26456   [(set_attr "length" "5")
26457    (set_attr "type" "other")])
26459 (define_insn "@wrss<mode>"
26460   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26461                      (match_operand:SWI48 1 "memory_operand" "m")]
26462                     UNSPECV_WRSS)]
26463   "TARGET_SHSTK"
26464   "wrss<mskmodesuffix>\t%0, %1"
26465   [(set_attr "length" "3")
26466    (set_attr "type" "other")])
26468 (define_insn "@wruss<mode>"
26469   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26470                      (match_operand:SWI48 1 "memory_operand" "m")]
26471                     UNSPECV_WRUSS)]
26472   "TARGET_SHSTK"
26473   "wruss<mskmodesuffix>\t%0, %1"
26474   [(set_attr "length" "4")
26475    (set_attr "type" "other")])
26477 (define_insn "setssbsy"
26478   [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
26479   "TARGET_SHSTK"
26480   "setssbsy"
26481   [(set_attr "length" "4")
26482    (set_attr "type" "other")])
26484 (define_insn "clrssbsy"
26485   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
26486                     UNSPECV_CLRSSBSY)]
26487   "TARGET_SHSTK"
26488   "clrssbsy\t%0"
26489   [(set_attr "length" "4")
26490    (set_attr "type" "other")])
26492 (define_insn "nop_endbr"
26493   [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
26494   "(flag_cf_protection & CF_BRANCH)"
26496   return TARGET_64BIT ? "endbr64" : "endbr32";
26498   [(set_attr "length" "4")
26499    (set_attr "length_immediate" "0")
26500    (set_attr "modrm" "0")])
26502 ;; For RTM support
26503 (define_expand "xbegin"
26504   [(set (match_operand:SI 0 "register_operand")
26505         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
26506   "TARGET_RTM"
26508   rtx_code_label *label = gen_label_rtx ();
26510   /* xbegin is emitted as jump_insn, so reload won't be able
26511      to reload its operand.  Force the value into AX hard register.  */
26512   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
26513   emit_move_insn (ax_reg, constm1_rtx);
26515   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
26517   emit_label (label);
26518   LABEL_NUSES (label) = 1;
26520   emit_move_insn (operands[0], ax_reg);
26522   DONE;
26525 (define_insn "xbegin_1"
26526   [(set (pc)
26527         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
26528                           (const_int 0))
26529                       (label_ref (match_operand 1))
26530                       (pc)))
26531    (set (match_operand:SI 0 "register_operand" "+a")
26532         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
26533   "TARGET_RTM"
26534   "xbegin\t%l1"
26535   [(set_attr "type" "other")
26536    (set_attr "length" "6")])
26538 (define_insn "xend"
26539   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
26540   "TARGET_RTM"
26541   "xend"
26542   [(set_attr "type" "other")
26543    (set_attr "length" "3")])
26545 (define_insn "xabort"
26546   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand")]
26547                     UNSPECV_XABORT)]
26548   "TARGET_RTM"
26549   "xabort\t%0"
26550   [(set_attr "type" "other")
26551    (set_attr "length" "3")])
26553 (define_expand "xtest"
26554   [(set (match_operand:QI 0 "register_operand")
26555         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
26556   "TARGET_RTM"
26558   emit_insn (gen_xtest_1 ());
26560   ix86_expand_setcc (operands[0], NE,
26561                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
26562   DONE;
26565 (define_insn "xtest_1"
26566   [(set (reg:CCZ FLAGS_REG)
26567         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
26568   "TARGET_RTM"
26569   "xtest"
26570   [(set_attr "type" "other")
26571    (set_attr "length" "3")])
26573 (define_insn "clwb"
26574   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26575                    UNSPECV_CLWB)]
26576   "TARGET_CLWB"
26577   "clwb\t%a0"
26578   [(set_attr "type" "sse")
26579    (set_attr "atom_sse_attr" "fence")
26580    (set_attr "memory" "unknown")])
26582 (define_insn "clflushopt"
26583   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26584                    UNSPECV_CLFLUSHOPT)]
26585   "TARGET_CLFLUSHOPT"
26586   "clflushopt\t%a0"
26587   [(set_attr "type" "sse")
26588    (set_attr "atom_sse_attr" "fence")
26589    (set_attr "memory" "unknown")])
26591 ;; MONITORX and MWAITX
26592 (define_insn "mwaitx"
26593   [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
26594                      (match_operand:SI 1 "register_operand" "a")
26595                      (match_operand:SI 2 "register_operand" "b")]
26596                    UNSPECV_MWAITX)]
26597   "TARGET_MWAITX"
26598 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
26599 ;; Since 32bit register operands are implicitly zero extended to 64bit,
26600 ;; we only need to set up 32bit registers.
26601   "mwaitx"
26602   [(set_attr "length" "3")])
26604 (define_insn "@monitorx_<mode>"
26605   [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
26606                      (match_operand:SI 1 "register_operand" "c")
26607                      (match_operand:SI 2 "register_operand" "d")]
26608                    UNSPECV_MONITORX)]
26609   "TARGET_MWAITX"
26610 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
26611 ;; RCX and RDX are used.  Since 32bit register operands are implicitly
26612 ;; zero extended to 64bit, we only need to set up 32bit registers.
26613   "%^monitorx"
26614   [(set (attr "length")
26615      (symbol_ref ("(Pmode != word_mode) + 3")))])
26617 ;; CLZERO
26618 (define_insn "@clzero_<mode>"
26619   [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
26620                    UNSPECV_CLZERO)]
26621   "TARGET_CLZERO"
26622   "clzero"
26623   [(set_attr "length" "3")
26624   (set_attr "memory" "unknown")])
26626 ;; RDPKRU and WRPKRU
26628 (define_expand "rdpkru"
26629   [(parallel
26630      [(set (match_operand:SI 0 "register_operand")
26631            (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
26632       (set (match_dup 2) (const_int 0))])]
26633   "TARGET_PKU"
26635   operands[1] = force_reg (SImode, const0_rtx);
26636   operands[2] = gen_reg_rtx (SImode);
26639 (define_insn "*rdpkru"
26640   [(set (match_operand:SI 0 "register_operand" "=a")
26641         (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
26642                             UNSPECV_PKU))
26643    (set (match_operand:SI 1 "register_operand" "=d")
26644         (const_int 0))]
26645   "TARGET_PKU"
26646   "rdpkru"
26647   [(set_attr "type" "other")])
26649 (define_expand "wrpkru"
26650   [(unspec_volatile:SI
26651      [(match_operand:SI 0 "register_operand")
26652       (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
26653   "TARGET_PKU"
26655   operands[1] = force_reg (SImode, const0_rtx);
26656   operands[2] = force_reg (SImode, const0_rtx);
26659 (define_insn "*wrpkru"
26660   [(unspec_volatile:SI
26661      [(match_operand:SI 0 "register_operand" "a")
26662       (match_operand:SI 1 "register_operand" "d")
26663       (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
26664   "TARGET_PKU"
26665   "wrpkru"
26666   [(set_attr "type" "other")])
26668 (define_insn "rdpid"
26669   [(set (match_operand:SI 0 "register_operand" "=r")
26670         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
26671   "!TARGET_64BIT && TARGET_RDPID"
26672   "rdpid\t%0"
26673   [(set_attr "type" "other")])
26675 (define_insn "rdpid_rex64"
26676   [(set (match_operand:DI 0 "register_operand" "=r")
26677         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
26678   "TARGET_64BIT && TARGET_RDPID"
26679   "rdpid\t%0"
26680   [(set_attr "type" "other")])
26682 ;; Intirinsics for > i486
26684 (define_insn "wbinvd"
26685   [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
26686   ""
26687   "wbinvd"
26688   [(set_attr "type" "other")])
26690 (define_insn "wbnoinvd"
26691   [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
26692   "TARGET_WBNOINVD"
26693   "wbnoinvd"
26694   [(set_attr "type" "other")])
26696 ;; MOVDIRI and MOVDIR64B
26698 (define_insn "movdiri<mode>"
26699   [(set (match_operand:SWI48 0 "memory_operand" "=m")
26700         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
26701                       UNSPEC_MOVDIRI))]
26702   "TARGET_MOVDIRI"
26703   "movdiri\t{%1, %0|%0, %1}"
26704   [(set_attr "type" "other")])
26706 (define_insn "@movdir64b_<mode>"
26707   [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
26708         (unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
26709                    UNSPEC_MOVDIR64B))]
26710   "TARGET_MOVDIR64B"
26711   "movdir64b\t{%1, %0|%0, %1}"
26712   [(set_attr "type" "other")])
26714 ;; TSXLDTRK
26715 (define_int_iterator TSXLDTRK [UNSPECV_XSUSLDTRK UNSPECV_XRESLDTRK])
26716 (define_int_attr tsxldtrk [(UNSPECV_XSUSLDTRK "xsusldtrk")
26717                  (UNSPECV_XRESLDTRK "xresldtrk")])
26718 (define_insn "<tsxldtrk>"
26719   [(unspec_volatile [(const_int 0)] TSXLDTRK)]
26720   "TARGET_TSXLDTRK"
26721   "<tsxldtrk>"
26722   [(set_attr "type" "other")
26723    (set_attr "length" "4")])
26725 ;; ENQCMD and ENQCMDS
26727 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
26728 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
26730 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
26731   [(set (reg:CCZ FLAGS_REG)
26732         (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
26733                               (match_operand:XI 1 "memory_operand" "m")]
26734                              ENQCMD))]
26735   "TARGET_ENQCMD"
26736   "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
26737   [(set_attr "type" "other")])
26739 ;; UINTR
26740 (define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI])
26741 (define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")])
26743 (define_insn "<uintr>"
26744   [(unspec_volatile [(const_int 0)] UINTR)]
26745   "TARGET_UINTR && TARGET_64BIT"
26746   "<uintr>"
26747   [(set_attr "type" "other")
26748    (set_attr "length" "4")])
26750 (define_insn "testui"
26751   [(set (reg:CCC FLAGS_REG)
26752         (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))]
26753   "TARGET_UINTR && TARGET_64BIT"
26754   "testui"
26755   [(set_attr "type" "other")
26756    (set_attr "length" "4")])
26758 (define_insn "senduipi"
26759   [(unspec_volatile
26760     [(match_operand:DI 0 "register_operand" "r")]
26761     UNSPECV_SENDUIPI)]
26762   "TARGET_UINTR && TARGET_64BIT"
26763   "senduipi\t%0"
26764   [(set_attr "type" "other")
26765    (set_attr "length" "4")])
26767 ;; WAITPKG
26769 (define_insn "umwait"
26770   [(set (reg:CCC FLAGS_REG)
26771         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26772                               (match_operand:DI 1 "register_operand" "A")]
26773                              UNSPECV_UMWAIT))]
26774   "!TARGET_64BIT && TARGET_WAITPKG"
26775   "umwait\t%0"
26776   [(set_attr "length" "3")])
26778 (define_insn "umwait_rex64"
26779   [(set (reg:CCC FLAGS_REG)
26780         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26781                               (match_operand:SI 1 "register_operand" "a")
26782                               (match_operand:SI 2 "register_operand" "d")]
26783                              UNSPECV_UMWAIT))]
26784   "TARGET_64BIT && TARGET_WAITPKG"
26785   "umwait\t%0"
26786   [(set_attr "length" "3")])
26788 (define_insn "@umonitor_<mode>"
26789   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26790                     UNSPECV_UMONITOR)]
26791   "TARGET_WAITPKG"
26792   "umonitor\t%0"
26793   [(set (attr "length")
26794      (symbol_ref ("(Pmode != word_mode) + 3")))])
26796 (define_insn "tpause"
26797   [(set (reg:CCC FLAGS_REG)
26798         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26799                               (match_operand:DI 1 "register_operand" "A")]
26800                              UNSPECV_TPAUSE))]
26801   "!TARGET_64BIT && TARGET_WAITPKG"
26802   "tpause\t%0"
26803   [(set_attr "length" "3")])
26805 (define_insn "tpause_rex64"
26806   [(set (reg:CCC FLAGS_REG)
26807         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26808                               (match_operand:SI 1 "register_operand" "a")
26809                               (match_operand:SI 2 "register_operand" "d")]
26810                              UNSPECV_TPAUSE))]
26811   "TARGET_64BIT && TARGET_WAITPKG"
26812   "tpause\t%0"
26813   [(set_attr "length" "3")])
26815 (define_insn "cldemote"
26816   [(unspec_volatile[(match_operand 0 "address_operand" "p")]
26817                  UNSPECV_CLDEMOTE)]
26818   "TARGET_CLDEMOTE"
26819   "cldemote\t%a0"
26820   [(set_attr "type" "other")
26821    (set_attr "memory" "unknown")])
26823 (define_insn "speculation_barrier"
26824   [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
26825   ""
26826   "lfence"
26827   [(set_attr "type" "other")
26828    (set_attr "length" "3")])
26830 (define_insn "serialize"
26831   [(unspec_volatile [(const_int 0)] UNSPECV_SERIALIZE)]
26832   "TARGET_SERIALIZE"
26833   "serialize"
26834   [(set_attr "type" "other")
26835    (set_attr "length" "3")])
26837 (define_insn "patchable_area"
26838   [(unspec_volatile [(match_operand 0 "const_int_operand")
26839                      (match_operand 1 "const_int_operand")]
26840                     UNSPECV_PATCHABLE_AREA)]
26841   ""
26843   ix86_output_patchable_area (INTVAL (operands[0]),
26844                               INTVAL (operands[1]) != 0);
26845   return "";
26847   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
26848    (set_attr "length_immediate" "0")
26849    (set_attr "modrm" "0")])
26851 (define_insn "hreset"
26852   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")]
26853                      UNSPECV_HRESET)]
26854   "TARGET_HRESET"
26855   "hreset\t{$0|0}"
26856   [(set_attr "type" "other")
26857    (set_attr "length" "4")])
26859 ;; Spaceship optimization
26860 (define_expand "spaceship<mode>3"
26861   [(match_operand:SI 0 "register_operand")
26862    (match_operand:MODEF 1 "cmp_fp_expander_operand")
26863    (match_operand:MODEF 2 "cmp_fp_expander_operand")]
26864   "(TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
26865    && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26867   ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26868   DONE;
26871 (define_expand "spaceshipxf3"
26872   [(match_operand:SI 0 "register_operand")
26873    (match_operand:XF 1 "nonmemory_operand")
26874    (match_operand:XF 2 "nonmemory_operand")]
26875   "TARGET_80387 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26877   ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26878   DONE;
26881 ;; Defined because the generic expand_builtin_issignaling for XFmode
26882 ;; only tests for sNaNs, but i387 treats also pseudo numbers as always
26883 ;; signaling.
26884 (define_expand "issignalingxf2"
26885   [(match_operand:SI 0 "register_operand")
26886    (match_operand:XF 1 "general_operand")]
26887   ""
26889   rtx temp = operands[1];
26890   if (!MEM_P (temp))
26891     {
26892       rtx mem = assign_stack_temp (XFmode, GET_MODE_SIZE (XFmode));
26893       emit_move_insn (mem, temp);
26894       temp = mem;
26895     }
26896   rtx ex = adjust_address (temp, HImode, 8);
26897   rtx hi = adjust_address (temp, SImode, 4);
26898   rtx lo = adjust_address (temp, SImode, 0);
26899   rtx val = GEN_INT (HOST_WIDE_INT_M1U << 30);
26900   rtx mask = GEN_INT (0x7fff);
26901   rtx bit = GEN_INT (HOST_WIDE_INT_1U << 30);
26902   /* Expand to:
26903      ((ex & mask) && (int) hi >= 0)
26904      || ((ex & mask) == mask && ((hi ^ bit) | ((lo | -lo) >> 31)) > val).  */
26905   rtx nlo = expand_unop (SImode, neg_optab, lo, NULL_RTX, 0);
26906   lo = expand_binop (SImode, ior_optab, lo, nlo,
26907                      NULL_RTX, 1, OPTAB_LIB_WIDEN);
26908   lo = expand_shift (RSHIFT_EXPR, SImode, lo, 31, NULL_RTX, 1);
26909   temp = expand_binop (SImode, xor_optab, hi, bit,
26910                        NULL_RTX, 1, OPTAB_LIB_WIDEN);
26911   temp = expand_binop (SImode, ior_optab, temp, lo,
26912                        NULL_RTX, 1, OPTAB_LIB_WIDEN);
26913   temp = emit_store_flag_force (gen_reg_rtx (SImode), GTU, temp, val,
26914                                 SImode, 1, 1);
26915   ex = expand_binop (HImode, and_optab, ex, mask,
26916                      NULL_RTX, 1, OPTAB_LIB_WIDEN);
26917   rtx temp2 = emit_store_flag_force (gen_reg_rtx (SImode), NE,
26918                                      ex, const0_rtx, SImode, 1, 1);
26919   ex = emit_store_flag_force (gen_reg_rtx (SImode), EQ,
26920                               ex, mask, HImode, 1, 1);
26921   temp = expand_binop (SImode, and_optab, temp, ex,
26922                        NULL_RTX, 1, OPTAB_LIB_WIDEN);
26923   rtx temp3 = emit_store_flag_force (gen_reg_rtx (SImode), GE,
26924                                      hi, const0_rtx, SImode, 0, 1);
26925   temp2 = expand_binop (SImode, and_optab, temp2, temp3,
26926                         NULL_RTX, 1, OPTAB_LIB_WIDEN);
26927   temp = expand_binop (SImode, ior_optab, temp, temp2,
26928                        NULL_RTX, 1, OPTAB_LIB_WIDEN);
26929   emit_move_insn (operands[0], temp);
26930   DONE;
26933 (define_insn "urdmsr"
26934   [(set (match_operand:DI 0 "register_operand" "=r")
26935     (unspec_volatile:DI
26936       [(match_operand:DI 1 "x86_64_szext_nonmemory_operand" "reZ")]
26937       UNSPECV_URDMSR))]
26938   "TARGET_USER_MSR && TARGET_64BIT"
26939   "urdmsr\t{%1, %0|%0, %1}"
26940   [(set_attr "prefix" "vex")
26941    (set_attr "type" "other")])
26943 (define_insn "uwrmsr"
26944   [(unspec_volatile
26945     [(match_operand:DI 0 "x86_64_szext_nonmemory_operand" "reZ")
26946       (match_operand:DI 1 "register_operand" "r")]
26947       UNSPECV_UWRMSR)]
26948   "TARGET_USER_MSR && TARGET_64BIT"
26949   "uwrmsr\t{%1, %0|%0, %1}"
26950   [(set_attr "prefix" "vex")
26951    (set_attr "type" "other")])
26953 (include "mmx.md")
26954 (include "sse.md")
26955 (include "sync.md")