i386: Use "addr" attribute to limit address regclass to non-REX regs
[official-gcc.git] / gcc / config / i386 / i386.md
blob97ab69342a50a0cf96b8b4729ea7b02016548d19
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
119   ;; For SSE/MMX support:
120   UNSPEC_FIX_NOTRUNC
121   UNSPEC_MASKMOV
122   UNSPEC_MOVCC_MASK
123   UNSPEC_MOVMSK
124   UNSPEC_INSERTPS
125   UNSPEC_BLENDV
126   UNSPEC_PSHUFB
127   UNSPEC_XOP_PERMUTE
128   UNSPEC_RCP
129   UNSPEC_RSQRT
130   UNSPEC_PSADBW
132   ;; Different from generic us_truncate RTX
133   ;; as it does unsigned saturation of signed source.
134   UNSPEC_US_TRUNCATE
136   ;; For AVX/AVX512F support
137   UNSPEC_SCALEF
138   UNSPEC_PCMP
139   UNSPEC_CVTBFSF
141   ;; Generic math support
142   UNSPEC_IEEE_MIN       ; not commutative
143   UNSPEC_IEEE_MAX       ; not commutative
145   ;; x87 Floating point
146   UNSPEC_SIN
147   UNSPEC_COS
148   UNSPEC_FPATAN
149   UNSPEC_FYL2X
150   UNSPEC_FYL2XP1
151   UNSPEC_FRNDINT
152   UNSPEC_FIST
153   UNSPEC_F2XM1
154   UNSPEC_TAN
155   UNSPEC_FXAM
157   ;; x87 Rounding
158   UNSPEC_FRNDINT_ROUNDEVEN
159   UNSPEC_FRNDINT_FLOOR
160   UNSPEC_FRNDINT_CEIL
161   UNSPEC_FRNDINT_TRUNC
162   UNSPEC_FIST_FLOOR
163   UNSPEC_FIST_CEIL
165   ;; x87 Double output FP
166   UNSPEC_SINCOS_COS
167   UNSPEC_SINCOS_SIN
168   UNSPEC_XTRACT_FRACT
169   UNSPEC_XTRACT_EXP
170   UNSPEC_FSCALE_FRACT
171   UNSPEC_FSCALE_EXP
172   UNSPEC_FPREM_F
173   UNSPEC_FPREM_U
174   UNSPEC_FPREM1_F
175   UNSPEC_FPREM1_U
177   UNSPEC_C2_FLAG
178   UNSPEC_FXAM_MEM
180   ;; SSP patterns
181   UNSPEC_SP_SET
182   UNSPEC_SP_TEST
184   ;; For ROUND support
185   UNSPEC_ROUND
187   ;; For CRC32 support
188   UNSPEC_CRC32
190   ;; For LZCNT suppoprt
191   UNSPEC_LZCNT
193   ;; For BMI support
194   UNSPEC_TZCNT
195   UNSPEC_BEXTR
197   ;; For BMI2 support
198   UNSPEC_PDEP
199   UNSPEC_PEXT
201   ;; IRET support
202   UNSPEC_INTERRUPT_RETURN
204   ;; For MOVDIRI and MOVDIR64B support
205   UNSPEC_MOVDIRI
206   UNSPEC_MOVDIR64B
208   ;; For insn_callee_abi:
209   UNSPEC_CALLEE_ABI
211   ;; For PUSH2/POP2 support
212   UNSPEC_APXPUSH2
213   UNSPEC_APXPOP2_LOW
214   UNSPEC_APXPOP2_HIGH
217 (define_c_enum "unspecv" [
218   UNSPECV_UD2
219   UNSPECV_BLOCKAGE
220   UNSPECV_STACK_PROBE
221   UNSPECV_PROBE_STACK_RANGE
222   UNSPECV_ALIGN
223   UNSPECV_PROLOGUE_USE
224   UNSPECV_SPLIT_STACK_RETURN
225   UNSPECV_CLD
226   UNSPECV_NOPS
227   UNSPECV_RDTSC
228   UNSPECV_RDTSCP
229   UNSPECV_RDPMC
230   UNSPECV_LLWP_INTRINSIC
231   UNSPECV_SLWP_INTRINSIC
232   UNSPECV_LWPVAL_INTRINSIC
233   UNSPECV_LWPINS_INTRINSIC
234   UNSPECV_RDFSBASE
235   UNSPECV_RDGSBASE
236   UNSPECV_WRFSBASE
237   UNSPECV_WRGSBASE
238   UNSPECV_FXSAVE
239   UNSPECV_FXRSTOR
240   UNSPECV_FXSAVE64
241   UNSPECV_FXRSTOR64
242   UNSPECV_XSAVE
243   UNSPECV_XRSTOR
244   UNSPECV_XSAVE64
245   UNSPECV_XRSTOR64
246   UNSPECV_XSAVEOPT
247   UNSPECV_XSAVEOPT64
248   UNSPECV_XSAVES
249   UNSPECV_XRSTORS
250   UNSPECV_XSAVES64
251   UNSPECV_XRSTORS64
252   UNSPECV_XSAVEC
253   UNSPECV_XSAVEC64
254   UNSPECV_XGETBV
255   UNSPECV_XSETBV
256   UNSPECV_WBINVD
257   UNSPECV_WBNOINVD
259   ;; For atomic compound assignments.
260   UNSPECV_FNSTENV
261   UNSPECV_FLDENV
262   UNSPECV_FNSTSW
263   UNSPECV_FNCLEX
265   ;; For RDRAND support
266   UNSPECV_RDRAND
268   ;; For RDSEED support
269   UNSPECV_RDSEED
271   ;; For RTM support
272   UNSPECV_XBEGIN
273   UNSPECV_XEND
274   UNSPECV_XABORT
275   UNSPECV_XTEST
277   UNSPECV_NLGR
279   ;; For CLWB support
280   UNSPECV_CLWB
282   ;; For CLFLUSHOPT support
283   UNSPECV_CLFLUSHOPT
285   ;; For MONITORX and MWAITX support 
286   UNSPECV_MONITORX
287   UNSPECV_MWAITX
289   ;; For CLZERO support
290   UNSPECV_CLZERO
292   ;; For RDPKRU and WRPKRU support
293   UNSPECV_PKU
295   ;; For RDPID support
296   UNSPECV_RDPID
298   ;; For CET support
299   UNSPECV_NOP_ENDBR
300   UNSPECV_NOP_RDSSP
301   UNSPECV_INCSSP
302   UNSPECV_SAVEPREVSSP
303   UNSPECV_RSTORSSP
304   UNSPECV_WRSS
305   UNSPECV_WRUSS
306   UNSPECV_SETSSBSY
307   UNSPECV_CLRSSBSY
309   ;; For TSXLDTRK support
310   UNSPECV_XSUSLDTRK
311   UNSPECV_XRESLDTRK
313   ;; For WAITPKG support
314   UNSPECV_UMWAIT
315   UNSPECV_UMONITOR
316   UNSPECV_TPAUSE
318   ;; For UINTR support
319   UNSPECV_CLUI
320   UNSPECV_STUI
321   UNSPECV_TESTUI
322   UNSPECV_SENDUIPI
324   ;; For CLDEMOTE support
325   UNSPECV_CLDEMOTE
327   ;; For Speculation Barrier support
328   UNSPECV_SPECULATION_BARRIER
330   UNSPECV_PTWRITE
332   ;; For ENQCMD and ENQCMDS support
333   UNSPECV_ENQCMD
334   UNSPECV_ENQCMDS
336   ;; For SERIALIZE support
337   UNSPECV_SERIALIZE
339   ;; For patchable area support
340   UNSPECV_PATCHABLE_AREA
342   ;; For HRESET support
343   UNSPECV_HRESET
345   ;; For PREFETCHI support
346   UNSPECV_PREFETCHI
348   ;; For USER_MSR support
349   UNSPECV_URDMSR
350   UNSPECV_UWRMSR
353 ;; Constants to represent rounding modes in the ROUND instruction
354 (define_constants
355   [(ROUND_ROUNDEVEN             0x0)
356    (ROUND_FLOOR                 0x1)
357    (ROUND_CEIL                  0x2)
358    (ROUND_TRUNC                 0x3)
359    (ROUND_MXCSR                 0x4)
360    (ROUND_NO_EXC                0x8)
361   ])
363 ;; Constants to represent AVX512F embeded rounding
364 (define_constants
365   [(ROUND_NEAREST_INT                   0)
366    (ROUND_NEG_INF                       1)
367    (ROUND_POS_INF                       2)
368    (ROUND_ZERO                          3)
369    (NO_ROUND                            4)
370    (ROUND_SAE                           8)
371   ])
373 ;; Constants to represent pcomtrue/pcomfalse variants
374 (define_constants
375   [(PCOM_FALSE                  0)
376    (PCOM_TRUE                   1)
377    (COM_FALSE_S                 2)
378    (COM_FALSE_P                 3)
379    (COM_TRUE_S                  4)
380    (COM_TRUE_P                  5)
381   ])
383 ;; Constants used in the XOP pperm instruction
384 (define_constants
385   [(PPERM_SRC                   0x00)   /* copy source */
386    (PPERM_INVERT                0x20)   /* invert source */
387    (PPERM_REVERSE               0x40)   /* bit reverse source */
388    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
389    (PPERM_ZERO                  0x80)   /* all 0's */
390    (PPERM_ONES                  0xa0)   /* all 1's */
391    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
392    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
393    (PPERM_SRC1                  0x00)   /* use first source byte */
394    (PPERM_SRC2                  0x10)   /* use second source byte */
395    ])
397 ;; Registers by name.
398 (define_constants
399   [(AX_REG                       0)
400    (DX_REG                       1)
401    (CX_REG                       2)
402    (BX_REG                       3)
403    (SI_REG                       4)
404    (DI_REG                       5)
405    (BP_REG                       6)
406    (SP_REG                       7)
407    (ST0_REG                      8)
408    (ST1_REG                      9)
409    (ST2_REG                     10)
410    (ST3_REG                     11)
411    (ST4_REG                     12)
412    (ST5_REG                     13)
413    (ST6_REG                     14)
414    (ST7_REG                     15)
415    (ARGP_REG                    16)
416    (FLAGS_REG                   17)
417    (FPSR_REG                    18)
418    (FRAME_REG                   19)
419    (XMM0_REG                    20)
420    (XMM1_REG                    21)
421    (XMM2_REG                    22)
422    (XMM3_REG                    23)
423    (XMM4_REG                    24)
424    (XMM5_REG                    25)
425    (XMM6_REG                    26)
426    (XMM7_REG                    27)
427    (MM0_REG                     28)
428    (MM1_REG                     29)
429    (MM2_REG                     30)
430    (MM3_REG                     31)
431    (MM4_REG                     32)
432    (MM5_REG                     33)
433    (MM6_REG                     34)
434    (MM7_REG                     35)
435    (R8_REG                      36)
436    (R9_REG                      37)
437    (R10_REG                     38)
438    (R11_REG                     39)
439    (R12_REG                     40)
440    (R13_REG                     41)
441    (R14_REG                     42)
442    (R15_REG                     43)
443    (XMM8_REG                    44)
444    (XMM9_REG                    45)
445    (XMM10_REG                   46)
446    (XMM11_REG                   47)
447    (XMM12_REG                   48)
448    (XMM13_REG                   49)
449    (XMM14_REG                   50)
450    (XMM15_REG                   51)
451    (XMM16_REG                   52)
452    (XMM17_REG                   53)
453    (XMM18_REG                   54)
454    (XMM19_REG                   55)
455    (XMM20_REG                   56)
456    (XMM21_REG                   57)
457    (XMM22_REG                   58)
458    (XMM23_REG                   59)
459    (XMM24_REG                   60)
460    (XMM25_REG                   61)
461    (XMM26_REG                   62)
462    (XMM27_REG                   63)
463    (XMM28_REG                   64)
464    (XMM29_REG                   65)
465    (XMM30_REG                   66)
466    (XMM31_REG                   67)
467    (MASK0_REG                   68)
468    (MASK1_REG                   69)
469    (MASK2_REG                   70)
470    (MASK3_REG                   71)
471    (MASK4_REG                   72)
472    (MASK5_REG                   73)
473    (MASK6_REG                   74)
474    (MASK7_REG                   75)
475    (R16_REG                     76)
476    (R17_REG                     77)
477    (R18_REG                     78)
478    (R19_REG                     79)
479    (R20_REG                     80)
480    (R21_REG                     81)
481    (R22_REG                     82)
482    (R23_REG                     83)
483    (R24_REG                     84)
484    (R25_REG                     85)
485    (R26_REG                     86)
486    (R27_REG                     87)
487    (R28_REG                     88)
488    (R29_REG                     89)
489    (R30_REG                     90)
490    (R31_REG                     91)
491    (FIRST_PSEUDO_REG            92)
492   ])
494 ;; Insn callee abi index.
495 (define_constants
496   [(ABI_DEFAULT         0)
497    (ABI_VZEROUPPER      1)
498    (ABI_UNKNOWN         2)])
500 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
501 ;; from i386.cc.
503 ;; In C guard expressions, put expressions which may be compile-time
504 ;; constants first.  This allows for better optimization.  For
505 ;; example, write "TARGET_64BIT && reload_completed", not
506 ;; "reload_completed && TARGET_64BIT".
509 ;; Processor type.
510 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
511                     atom,slm,glm,haswell,generic,lujiazui,yongfeng,amdfam10,bdver1,
512                     bdver2,bdver3,bdver4,btver2,znver1,znver2,znver3,znver4"
513   (const (symbol_ref "ix86_schedule")))
515 ;; A basic instruction type.  Refinements due to arguments to be
516 ;; provided in other attributes.
517 (define_attr "type"
518   "other,multi,
519    alu,alu1,negnot,imov,imovx,lea,
520    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
521    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
522    push,pop,call,callv,leave,
523    str,bitmanip,
524    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
525    fxch,fistp,fisttp,frndint,
526    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
527    ssemul,sseimul,ssediv,sselog,sselog1,
528    sseishft,sseishft1,ssecmp,ssecomi,
529    ssecvt,ssecvt1,sseicvt,sseins,
530    sseshuf,sseshuf1,ssemuladd,sse4arg,
531    lwp,mskmov,msklog,
532    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
533   (const_string "other"))
535 ;; Main data type used by the insn
536 (define_attr "mode"
537   "unknown,none,QI,HI,SI,DI,TI,OI,XI,HF,BF,SF,DF,XF,TF,V32HF,V16HF,V8HF,
538    V16SF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,V8DF,V4HF,V4BF,V2HF,V2BF"
539   (const_string "unknown"))
541 ;; The CPU unit operations uses.
542 (define_attr "unit" "integer,i387,sse,mmx,unknown"
543   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
544                           fxch,fistp,fisttp,frndint")
545            (const_string "i387")
546          (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
547                           ssemul,sseimul,ssediv,sselog,sselog1,
548                           sseishft,sseishft1,ssecmp,ssecomi,
549                           ssecvt,ssecvt1,sseicvt,sseins,
550                           sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
551            (const_string "sse")
552          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
553            (const_string "mmx")
554          (eq_attr "type" "other")
555            (const_string "unknown")]
556          (const_string "integer")))
558 ;; Used to control the "enabled" attribute on a per-instruction basis.
559 (define_attr "isa" "base,x64,nox64,x64_sse2,x64_sse4,x64_sse4_noavx,
560                     x64_avx,x64_avx512bw,x64_avx512dq,aes,
561                     sse_noavx,sse2,sse2_noavx,sse3,sse3_noavx,sse4,sse4_noavx,
562                     avx,noavx,avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,avx512f_512,
563                     noavx512f,avx512bw,avx512bw_512,noavx512bw,avx512dq,
564                     noavx512dq,fma_or_avx512vl,avx512vl,noavx512vl,avxvnni,
565                     avx512vnnivl,avx512fp16,avxifma,avx512ifmavl,avxneconvert,
566                     avx512bf16vl,vpclmulqdqvl,avx_noavx512f,avx_noavx512vl"
567   (const_string "base"))
569 ;; The (bounding maximum) length of an instruction immediate.
570 (define_attr "length_immediate" ""
571   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
572                           bitmanip,imulx,msklog,mskmov")
573            (const_int 0)
574          (ior (eq_attr "type" "sse4arg")
575               (eq_attr "isa" "fma4"))
576            (const_int 1)
577          (eq_attr "unit" "i387,sse,mmx")
578            (const_int 0)
579          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
580                           rotate,rotatex,rotate1,imul,icmp,push,pop")
581            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
582          (eq_attr "type" "imov,test")
583            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
584          (eq_attr "type" "call")
585            (if_then_else (match_operand 0 "constant_call_address_operand")
586              (const_int 4)
587              (const_int 0))
588          (eq_attr "type" "callv")
589            (if_then_else (match_operand 1 "constant_call_address_operand")
590              (const_int 4)
591              (const_int 0))
592          ;; We don't know the size before shorten_branches.  Expect
593          ;; the instruction to fit for better scheduling.
594          (eq_attr "type" "ibr")
595            (const_int 1)
596          ]
597          (symbol_ref "/* Update immediate_length and other attributes! */
598                       gcc_unreachable (),1")))
600 ;; The (bounding maximum) length of an instruction address.
601 (define_attr "length_address" ""
602   (cond [(eq_attr "type" "str,other,multi,fxch")
603            (const_int 0)
604          (and (eq_attr "type" "call")
605               (match_operand 0 "constant_call_address_operand"))
606              (const_int 0)
607          (and (eq_attr "type" "callv")
608               (match_operand 1 "constant_call_address_operand"))
609              (const_int 0)
610          ]
611          (symbol_ref "ix86_attr_length_address_default (insn)")))
613 ;; Set when length prefix is used.
614 (define_attr "prefix_data16" ""
615   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
616            (const_int 0)
617          (eq_attr "mode" "HI")
618            (const_int 1)
619          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
620            (const_int 1)
621         ]
622         (const_int 0)))
624 ;; Set when string REP prefix is used.
625 (define_attr "prefix_rep" ""
626   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
627            (const_int 0)
628          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
629            (const_int 1)
630         ]
631         (const_int 0)))
633 ;; Set when 0f opcode prefix is used.
634 (define_attr "prefix_0f" ""
635   (if_then_else
636     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
637          (eq_attr "unit" "sse,mmx"))
638     (const_int 1)
639     (const_int 0)))
641 ;; Set when REX opcode prefix is used.
642 (define_attr "prefix_rex" ""
643   (cond [(not (match_test "TARGET_64BIT"))
644            (const_int 0)
645          (and (eq_attr "mode" "DI")
646               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
647                    (eq_attr "unit" "!mmx")))
648            (const_int 1)
649          (and (eq_attr "mode" "QI")
650               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
651            (const_int 1)
652          (match_test "x86_extended_reg_mentioned_p (insn)")
653            (const_int 1)
654          (and (eq_attr "type" "imovx")
655               (match_operand:QI 1 "ext_QIreg_operand"))
656            (const_int 1)
657         ]
658         (const_int 0)))
660 ;; There are also additional prefixes in 3DNOW, SSSE3.
661 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
662 ;; While generally inapplicable to VEX/XOP/EVEX encodings, "length_vex" uses
663 ;; the attribute evaluating to zero to know that VEX2 encoding may be usable.
664 (define_attr "prefix_extra" ""
665   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
666            (const_int 1)
667         ]
668         (const_int 0)))
670 ;; Prefix used: original, VEX or maybe VEX.
671 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
672   (cond [(eq_attr "mode" "OI,V8SF,V4DF")
673            (const_string "vex")
674          (eq_attr "mode" "XI,V16SF,V8DF")
675            (const_string "evex")
676          (eq_attr "type" "ssemuladd")
677            (if_then_else (eq_attr "isa" "fma4")
678              (const_string "vex")
679              (const_string "maybe_evex"))
680          (eq_attr "type" "sse4arg")
681            (const_string "vex")
682         ]
683         (const_string "orig")))
685 ;; VEX W bit is used.
686 (define_attr "prefix_vex_w" "" (const_int 0))
688 ;; The length of VEX prefix
689 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
690 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
691 ;; still prefix_0f 1, with prefix_extra 1.
692 (define_attr "length_vex" ""
693   (if_then_else (and (eq_attr "prefix_0f" "1")
694                      (eq_attr "prefix_extra" "0"))
695     (if_then_else (eq_attr "prefix_vex_w" "1")
696       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
697       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
698     (if_then_else (eq_attr "prefix_vex_w" "1")
699       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
700       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
702 ;; 4-bytes evex prefix and 1 byte opcode.
703 (define_attr "length_evex" "" (const_int 5))
705 ;; Set when modrm byte is used.
706 (define_attr "modrm" ""
707   (cond [(eq_attr "type" "str,leave")
708            (const_int 0)
709          (eq_attr "unit" "i387")
710            (const_int 0)
711          (and (eq_attr "type" "incdec")
712               (and (not (match_test "TARGET_64BIT"))
713                    (ior (match_operand:SI 1 "register_operand")
714                         (match_operand:HI 1 "register_operand"))))
715            (const_int 0)
716          (and (eq_attr "type" "push")
717               (not (match_operand 1 "memory_operand")))
718            (const_int 0)
719          (and (eq_attr "type" "pop")
720               (not (match_operand 0 "memory_operand")))
721            (const_int 0)
722          (and (eq_attr "type" "imov")
723               (and (not (eq_attr "mode" "DI"))
724                    (ior (and (match_operand 0 "register_operand")
725                              (match_operand 1 "immediate_operand"))
726                         (ior (and (match_operand 0 "ax_reg_operand")
727                                   (match_operand 1 "memory_displacement_only_operand"))
728                              (and (match_operand 0 "memory_displacement_only_operand")
729                                   (match_operand 1 "ax_reg_operand"))))))
730            (const_int 0)
731          (and (eq_attr "type" "call")
732               (match_operand 0 "constant_call_address_operand"))
733              (const_int 0)
734          (and (eq_attr "type" "callv")
735               (match_operand 1 "constant_call_address_operand"))
736              (const_int 0)
737          (and (eq_attr "type" "alu,alu1,icmp,test")
738               (match_operand 0 "ax_reg_operand"))
739              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
740          ]
741          (const_int 1)))
743 ;; The (bounding maximum) length of an instruction in bytes.
744 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
745 ;; Later we may want to split them and compute proper length as for
746 ;; other insns.
747 (define_attr "length" ""
748   (cond [(eq_attr "type" "other,multi,fistp,frndint")
749            (const_int 16)
750          (eq_attr "type" "fcmp")
751            (const_int 4)
752          (eq_attr "unit" "i387")
753            (plus (const_int 2)
754                  (plus (attr "prefix_data16")
755                        (attr "length_address")))
756          (ior (eq_attr "prefix" "evex")
757               (and (ior (eq_attr "prefix" "maybe_evex")
758                         (eq_attr "prefix" "maybe_vex"))
759                    (match_test "TARGET_AVX512F")))
760            (plus (attr "length_evex")
761                  (plus (attr "length_immediate")
762                        (plus (attr "modrm")
763                              (attr "length_address"))))
764          (ior (eq_attr "prefix" "vex")
765               (and (ior (eq_attr "prefix" "maybe_vex")
766                         (eq_attr "prefix" "maybe_evex"))
767                    (match_test "TARGET_AVX")))
768            (plus (attr "length_vex")
769                  (plus (attr "length_immediate")
770                        (plus (attr "modrm")
771                              (attr "length_address"))))]
772          (plus (plus (attr "modrm")
773                      (plus (attr "prefix_0f")
774                            (plus (attr "prefix_rex")
775                                  (plus (attr "prefix_extra")
776                                        (const_int 1)))))
777                (plus (attr "prefix_rep")
778                      (plus (attr "prefix_data16")
779                            (plus (attr "length_immediate")
780                                  (attr "length_address")))))))
782 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
783 ;; `store' if there is a simple memory reference therein, or `unknown'
784 ;; if the instruction is complex.
786 (define_attr "memory" "none,load,store,both,unknown"
787   (cond [(eq_attr "type" "other,multi,str,lwp")
788            (const_string "unknown")
789          (eq_attr "type" "lea,fcmov,fpspc")
790            (const_string "none")
791          (eq_attr "type" "fistp,leave")
792            (const_string "both")
793          (eq_attr "type" "frndint")
794            (const_string "load")
795          (eq_attr "type" "push")
796            (if_then_else (match_operand 1 "memory_operand")
797              (const_string "both")
798              (const_string "store"))
799          (eq_attr "type" "pop")
800            (if_then_else (match_operand 0 "memory_operand")
801              (const_string "both")
802              (const_string "load"))
803          (eq_attr "type" "setcc")
804            (if_then_else (match_operand 0 "memory_operand")
805              (const_string "store")
806              (const_string "none"))
807          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
808            (if_then_else (ior (match_operand 0 "memory_operand")
809                               (match_operand 1 "memory_operand"))
810              (const_string "load")
811              (const_string "none"))
812          (eq_attr "type" "ibr")
813            (if_then_else (match_operand 0 "memory_operand")
814              (const_string "load")
815              (const_string "none"))
816          (eq_attr "type" "call")
817            (if_then_else (match_operand 0 "constant_call_address_operand")
818              (const_string "none")
819              (const_string "load"))
820          (eq_attr "type" "callv")
821            (if_then_else (match_operand 1 "constant_call_address_operand")
822              (const_string "none")
823              (const_string "load"))
824          (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
825               (match_operand 1 "memory_operand"))
826            (const_string "both")
827          (and (match_operand 0 "memory_operand")
828               (match_operand 1 "memory_operand"))
829            (const_string "both")
830          (match_operand 0 "memory_operand")
831            (const_string "store")
832          (match_operand 1 "memory_operand")
833            (const_string "load")
834          (and (eq_attr "type"
835                  "!alu1,negnot,ishift1,rotate1,
836                    imov,imovx,icmp,test,bitmanip,
837                    fmov,fcmp,fsgn,
838                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
839                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
840                    mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
841               (match_operand 2 "memory_operand"))
842            (const_string "load")
843          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
844               (match_operand 3 "memory_operand"))
845            (const_string "load")
846         ]
847         (const_string "none")))
849 ;; Indicates if an instruction has both an immediate and a displacement.
851 (define_attr "imm_disp" "false,true,unknown"
852   (cond [(eq_attr "type" "other,multi")
853            (const_string "unknown")
854          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
855               (and (match_operand 0 "memory_displacement_operand")
856                    (match_operand 1 "immediate_operand")))
857            (const_string "true")
858          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
859               (and (match_operand 0 "memory_displacement_operand")
860                    (match_operand 2 "immediate_operand")))
861            (const_string "true")
862         ]
863         (const_string "false")))
865 ;; Indicates if an FP operation has an integer source.
867 (define_attr "fp_int_src" "false,true"
868   (const_string "false"))
870 ;; Defines rounding mode of an FP operation.
872 (define_attr "i387_cw" "roundeven,floor,ceil,trunc,uninitialized,any"
873   (const_string "any"))
875 ;; Define attribute to indicate AVX insns with partial XMM register update.
876 (define_attr "avx_partial_xmm_update" "false,true"
877   (const_string "false"))
879 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
880 (define_attr "use_carry" "0,1" (const_string "0"))
882 ;; Define attribute to indicate unaligned ssemov insns
883 (define_attr "movu" "0,1" (const_string "0"))
885 ;; Define attribute to limit memory address register set.
886 (define_attr "addr" "gpr8,gpr16,gpr32" (const_string "gpr32"))
888 ;; Define instruction set of MMX instructions
889 (define_attr "mmx_isa" "base,native,sse,sse_noavx,avx"
890   (const_string "base"))
892 (define_attr "enabled" ""
893   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
894          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
895          (eq_attr "isa" "x64_sse2")
896            (symbol_ref "TARGET_64BIT && TARGET_SSE2")
897          (eq_attr "isa" "x64_sse4")
898            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
899          (eq_attr "isa" "x64_sse4_noavx")
900            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
901          (eq_attr "isa" "x64_avx")
902            (symbol_ref "TARGET_64BIT && TARGET_AVX")
903          (eq_attr "isa" "x64_avx512bw")
904            (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
905          (eq_attr "isa" "x64_avx512dq")
906            (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
907          (eq_attr "isa" "aes") (symbol_ref "TARGET_AES")
908          (eq_attr "isa" "sse_noavx")
909            (symbol_ref "TARGET_SSE && !TARGET_AVX")
910          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
911          (eq_attr "isa" "sse2_noavx")
912            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
913          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
914          (eq_attr "isa" "sse3_noavx")
915            (symbol_ref "TARGET_SSE3 && !TARGET_AVX")
916          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
917          (eq_attr "isa" "sse4_noavx")
918            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
919          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
920          (eq_attr "isa" "avx_noavx512f")
921            (symbol_ref "TARGET_AVX && !TARGET_AVX512F")
922          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
923          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
924          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
925          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
926          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
927          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
928          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
929          (eq_attr "isa" "fma_or_avx512vl")
930            (symbol_ref "TARGET_FMA || TARGET_AVX512VL")
931          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
932          (eq_attr "isa" "avx512f_512")
933            (symbol_ref "TARGET_AVX512F && TARGET_EVEX512")
934          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
935          (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
936          (eq_attr "isa" "avx512bw_512")
937            (symbol_ref "TARGET_AVX512BW && TARGET_EVEX512")
938          (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
939          (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
940          (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
941          (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
942          (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
943          (eq_attr "isa" "avxvnni") (symbol_ref "TARGET_AVXVNNI")
944          (eq_attr "isa" "avx512vnnivl")
945            (symbol_ref "TARGET_AVX512VNNI && TARGET_AVX512VL")
946          (eq_attr "isa" "avx512fp16")
947            (symbol_ref "TARGET_AVX512FP16")
948          (eq_attr "isa" "avxifma") (symbol_ref "TARGET_AVXIFMA")
949          (eq_attr "isa" "avx512ifmavl")
950            (symbol_ref "TARGET_AVX512IFMA && TARGET_AVX512VL")
951          (eq_attr "isa" "avxneconvert") (symbol_ref "TARGET_AVXNECONVERT")
952          (eq_attr "isa" "avx512bf16vl")
953            (symbol_ref "TARGET_AVX512BF16 && TARGET_AVX512VL")
954          (eq_attr "isa" "vpclmulqdqvl")
955            (symbol_ref "TARGET_VPCLMULQDQ && TARGET_AVX512VL")
957          (eq_attr "mmx_isa" "native")
958            (symbol_ref "!TARGET_MMX_WITH_SSE")
959          (eq_attr "mmx_isa" "sse")
960            (symbol_ref "TARGET_MMX_WITH_SSE")
961          (eq_attr "mmx_isa" "sse_noavx")
962            (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
963          (eq_attr "mmx_isa" "avx")
964            (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
965         ]
966         (const_int 1)))
968 (define_attr "preferred_for_size" "" (const_int 1))
969 (define_attr "preferred_for_speed" "" (const_int 1))
971 ;; Describe a user's asm statement.
972 (define_asm_attributes
973   [(set_attr "length" "128")
974    (set_attr "type" "multi")])
976 (define_code_iterator plusminus [plus minus])
977 (define_code_iterator plusminusmult [plus minus mult])
978 (define_code_iterator plusminusmultdiv [plus minus mult div])
980 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
982 ;; Base name for insn mnemonic.
983 (define_code_attr plusminus_mnemonic
984   [(plus "add") (ss_plus "adds") (us_plus "addus")
985    (minus "sub") (ss_minus "subs") (us_minus "subus")])
987 (define_code_iterator multdiv [mult div])
989 (define_code_attr multdiv_mnemonic
990   [(mult "mul") (div "div")])
992 ;; Mark commutative operators as such in constraints.
993 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
994                         (minus "") (ss_minus "") (us_minus "")
995                         (mult "%") (div "")])
997 ;; Mapping of max and min
998 (define_code_iterator maxmin [smax smin umax umin])
1000 ;; Mapping of signed max and min
1001 (define_code_iterator smaxmin [smax smin])
1003 ;; Mapping of unsigned max and min
1004 (define_code_iterator umaxmin [umax umin])
1006 ;; Base name for integer and FP insn mnemonic
1007 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
1008                               (umax "maxu") (umin "minu")])
1009 (define_code_attr maxmin_float [(smax "max") (smin "min")])
1011 (define_int_iterator IEEE_MAXMIN
1012         [UNSPEC_IEEE_MAX
1013          UNSPEC_IEEE_MIN])
1015 (define_int_attr ieee_maxmin
1016         [(UNSPEC_IEEE_MAX "max")
1017          (UNSPEC_IEEE_MIN "min")])
1019 ;; Mapping of logic operators
1020 (define_code_iterator any_logic [and ior xor])
1021 (define_code_iterator any_or [ior xor])
1022 (define_code_iterator fpint_logic [and xor])
1024 ;; Base name for insn mnemonic.
1025 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
1027 ;; Mapping of logic-shift operators
1028 (define_code_iterator any_lshift [ashift lshiftrt])
1030 ;; Mapping of shift-right operators
1031 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
1033 ;; Mapping of all shift operators
1034 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
1036 ;; Base name for insn mnemonic.
1037 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
1038 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
1040 ;; Mapping of rotate operators
1041 (define_code_iterator any_rotate [rotate rotatert])
1043 ;; Base name for insn mnemonic.
1044 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
1046 ;; Mapping of abs neg operators
1047 (define_code_iterator absneg [abs neg])
1049 ;; Mapping of abs neg operators to logic operation
1050 (define_code_attr absneg_op [(abs "and") (neg "xor")])
1052 ;; Base name for x87 insn mnemonic.
1053 (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
1055 ;; Mapping of extend operators
1056 (define_code_iterator any_extend [sign_extend zero_extend])
1058 ;; Mapping of highpart multiply operators
1059 (define_code_iterator any_mul_highpart [smul_highpart umul_highpart])
1061 ;; Prefix for insn menmonic.
1062 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
1063                              (smul_highpart "i") (umul_highpart "")
1064                              (div "i") (udiv "")])
1065 ;; Prefix for define_insn
1066 (define_code_attr s [(sign_extend "s") (zero_extend "u")
1067                      (smul_highpart "s") (umul_highpart "u")])
1068 (define_code_attr u [(sign_extend "") (zero_extend "u")
1069                      (div "") (udiv "u")])
1070 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")
1071                           (div "false") (udiv "true")])
1073 ;; Used in signed and unsigned truncations.
1074 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
1075 ;; Instruction suffix for truncations.
1076 (define_code_attr trunsuffix
1077   [(ss_truncate "s") (truncate "") (us_truncate "us")])
1079 ;; Instruction suffix for SSE sign and zero extensions.
1080 (define_code_attr extsuffix [(sign_extend "sx") (zero_extend "zx")])
1082 ;; Used in signed and unsigned fix.
1083 (define_code_iterator any_fix [fix unsigned_fix])
1084 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
1085 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
1086 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
1088 ;; Used in signed and unsigned float.
1089 (define_code_iterator any_float [float unsigned_float])
1090 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
1091 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
1092 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
1094 ;; Base name for expression
1095 (define_code_attr insn
1096   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
1097    (minus "sub") (ss_minus "sssub") (us_minus "ussub")
1098    (sign_extend "extend") (zero_extend "zero_extend")
1099    (ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")
1100    (rotate "rotl") (rotatert "rotr")
1101    (mult "mul") (div "div")])
1103 ;; All integer modes.
1104 (define_mode_iterator SWI1248x [QI HI SI DI])
1106 ;; All integer modes without QImode.
1107 (define_mode_iterator SWI248x [HI SI DI])
1109 ;; All integer modes without QImode and HImode.
1110 (define_mode_iterator SWI48x [SI DI])
1112 ;; All integer modes without SImode and DImode.
1113 (define_mode_iterator SWI12 [QI HI])
1115 ;; All integer modes without DImode.
1116 (define_mode_iterator SWI124 [QI HI SI])
1118 ;; All integer modes without QImode and DImode.
1119 (define_mode_iterator SWI24 [HI SI])
1121 ;; Single word integer modes.
1122 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1124 ;; Single word integer modes without QImode.
1125 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1127 ;; Single word integer modes without QImode and HImode.
1128 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1130 ;; All math-dependant single and double word integer modes.
1131 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1132                              (HI "TARGET_HIMODE_MATH")
1133                              SI DI (TI "TARGET_64BIT")])
1135 ;; Math-dependant single word integer modes.
1136 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1137                             (HI "TARGET_HIMODE_MATH")
1138                             SI (DI "TARGET_64BIT")])
1140 ;; Math-dependant integer modes without DImode.
1141 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1142                                (HI "TARGET_HIMODE_MATH")
1143                                SI])
1145 ;; Math-dependant integer modes with DImode.
1146 (define_mode_iterator SWIM1248x
1147         [(QI "TARGET_QIMODE_MATH")
1148          (HI "TARGET_HIMODE_MATH")
1149          SI DI])
1151 ;; Math-dependant single word integer modes without QImode.
1152 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1153                                SI (DI "TARGET_64BIT")])
1155 ;; Double word integer modes.
1156 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1157                            (TI "TARGET_64BIT")])
1159 ;; SWI and DWI together.
1160 (define_mode_iterator SWIDWI [QI HI SI DI (TI "TARGET_64BIT")])
1162 ;; SWI48 and DWI together.
1163 (define_mode_iterator SWI48DWI [SI DI (TI "TARGET_64BIT")])
1165 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
1166 ;; compile time constant, it is faster to use <MODE_SIZE> than
1167 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
1168 ;; command line options just use GET_MODE_SIZE macro.
1169 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8")
1170                              (TI "16") (HF "2") (BF "2") (SF "4") (DF "8")
1171                              (XF "GET_MODE_SIZE (XFmode)")
1172                              (V16QI "16") (V32QI "32") (V64QI "64")
1173                              (V8HI "16") (V16HI "32") (V32HI "64")
1174                              (V4SI "16") (V8SI "32") (V16SI "64")
1175                              (V2DI "16") (V4DI "32") (V8DI "64")
1176                              (V1TI "16") (V2TI "32") (V4TI "64")
1177                              (V2DF "16") (V4DF "32") (V8DF "64")
1178                              (V4SF "16") (V8SF "32") (V16SF "64")
1179                              (V8HF "16") (V16HF "32") (V32HF "64")
1180                              (V4HF "8") (V2HF "4")
1181                              (V8BF "16") (V16BF "32") (V32BF "64")
1182                              (V4BF "8") (V2BF "4")])
1184 ;; Double word integer modes as mode attribute.
1185 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "OI")])
1186 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti") (TI "oi")])
1188 ;; Half sized integer modes.
1189 (define_mode_attr HALF [(TI "DI") (DI "SI")])
1190 (define_mode_attr half [(TI "di") (DI "si")])
1192 ;; LEA mode corresponding to an integer mode
1193 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1195 ;; Half mode for double word integer modes.
1196 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1197                             (DI "TARGET_64BIT")])
1199 ;; Instruction suffix for integer modes.
1200 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1202 ;; Instruction suffix for masks.
1203 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1205 ;; Pointer size prefix for integer modes (Intel asm dialect)
1206 (define_mode_attr iptrsize [(QI "BYTE")
1207                             (HI "WORD")
1208                             (SI "DWORD")
1209                             (DI "QWORD")])
1211 ;; Register class for integer modes.
1212 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1214 ;; Immediate operand constraint for integer modes.
1215 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1217 ;; General operand constraint for word modes.
1218 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1220 ;; Memory operand constraint for word modes.
1221 (define_mode_attr m [(QI "m") (HI "m") (SI "BM") (DI "BM")])
1223 ;; Immediate operand constraint for double integer modes.
1224 (define_mode_attr di [(SI "nF") (DI "Wd")])
1226 ;; Immediate operand constraint for shifts.
1227 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1228 (define_mode_attr KS [(QI "Wb") (HI "Ww") (SI "I") (DI "J")])
1230 ;; Print register name in the specified mode.
1231 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1233 ;; General operand predicate for integer modes.
1234 (define_mode_attr general_operand
1235         [(QI "general_operand")
1236          (HI "general_operand")
1237          (SI "x86_64_general_operand")
1238          (DI "x86_64_general_operand")
1239          (TI "x86_64_general_operand")])
1241 ;; General operand predicate for integer modes, where for TImode
1242 ;; we need both words of the operand to be general operands.
1243 (define_mode_attr general_hilo_operand
1244         [(QI "general_operand")
1245          (HI "general_operand")
1246          (SI "x86_64_general_operand")
1247          (DI "x86_64_general_operand")
1248          (TI "x86_64_hilo_general_operand")])
1250 ;; General sign extend operand predicate for integer modes,
1251 ;; which disallows VOIDmode operands and thus it is suitable
1252 ;; for use inside sign_extend.
1253 (define_mode_attr general_sext_operand
1254         [(QI "sext_operand")
1255          (HI "sext_operand")
1256          (SI "x86_64_sext_operand")
1257          (DI "x86_64_sext_operand")])
1259 ;; General sign/zero extend operand predicate for integer modes.
1260 (define_mode_attr general_szext_operand
1261         [(QI "general_operand")
1262          (HI "general_operand")
1263          (SI "x86_64_szext_general_operand")
1264          (DI "x86_64_szext_general_operand")
1265          (TI "x86_64_hilo_general_operand")])
1267 (define_mode_attr nonmemory_szext_operand
1268         [(QI "nonmemory_operand")
1269          (HI "nonmemory_operand")
1270          (SI "x86_64_szext_nonmemory_operand")
1271          (DI "x86_64_szext_nonmemory_operand")])
1273 ;; Immediate operand predicate for integer modes.
1274 (define_mode_attr immediate_operand
1275         [(QI "immediate_operand")
1276          (HI "immediate_operand")
1277          (SI "x86_64_immediate_operand")
1278          (DI "x86_64_immediate_operand")])
1280 ;; Nonmemory operand predicate for integer modes.
1281 (define_mode_attr nonmemory_operand
1282         [(QI "nonmemory_operand")
1283          (HI "nonmemory_operand")
1284          (SI "x86_64_nonmemory_operand")
1285          (DI "x86_64_nonmemory_operand")])
1287 ;; Operand predicate for shifts.
1288 (define_mode_attr shift_operand
1289         [(QI "nonimmediate_operand")
1290          (HI "nonimmediate_operand")
1291          (SI "nonimmediate_operand")
1292          (DI "shiftdi_operand")
1293          (TI "register_operand")])
1295 ;; Operand predicate for shift argument.
1296 (define_mode_attr shift_immediate_operand
1297         [(QI "const_1_to_31_operand")
1298          (HI "const_1_to_31_operand")
1299          (SI "const_1_to_31_operand")
1300          (DI "const_1_to_63_operand")])
1302 ;; Input operand predicate for arithmetic left shifts.
1303 (define_mode_attr ashl_input_operand
1304         [(QI "nonimmediate_operand")
1305          (HI "nonimmediate_operand")
1306          (SI "nonimmediate_operand")
1307          (DI "ashldi_input_operand")
1308          (TI "reg_or_pm1_operand")])
1310 ;; SSE and x87 SFmode and DFmode floating point modes
1311 (define_mode_iterator MODEF [SF DF])
1313 ;; SSE floating point modes
1314 (define_mode_iterator MODEFH [(HF "TARGET_AVX512FP16") SF DF])
1316 ;; All x87 floating point modes
1317 (define_mode_iterator X87MODEF [SF DF XF])
1319 ;; All x87 floating point modes plus HFmode
1320 (define_mode_iterator X87MODEFH [HF SF DF XF BF])
1322 ;; All SSE floating point modes
1323 (define_mode_iterator SSEMODEF [HF SF DF TF])
1324 (define_mode_attr ssevecmodef [(HF "V8HF") (SF "V4SF") (DF "V2DF") (TF "TF")])
1326 ;; SSE instruction suffix for various modes
1327 (define_mode_attr ssemodesuffix
1328   [(HF "sh") (SF "ss") (DF "sd")
1329    (V32HF "ph") (V16SF "ps") (V8DF "pd")
1330    (V16HF "ph") (V16BF "bf") (V8SF "ps") (V4DF "pd")
1331    (V8HF "ph")  (V8BF "bf") (V4SF "ps") (V2DF "pd")
1332    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1333    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1334    (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1336 ;; SSE vector suffix for floating point modes
1337 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1339 ;; SSE vector mode corresponding to a scalar mode
1340 (define_mode_attr ssevecmode
1341   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (HF "V8HF") (BF "V8BF") (SF "V4SF") (DF "V2DF")])
1342 (define_mode_attr ssevecmodelower
1343   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1345 ;; AVX512F vector mode corresponding to a scalar mode
1346 (define_mode_attr avx512fvecmode
1347   [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1349 ;; Instruction suffix for REX 64bit operators.
1350 (define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")])
1351 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1353 ;; This mode iterator allows :P to be used for patterns that operate on
1354 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1355 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1357 ;; This mode iterator allows :W to be used for patterns that operate on
1358 ;; word_mode sized quantities.
1359 (define_mode_iterator W
1360   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1362 ;; This mode iterator allows :PTR to be used for patterns that operate on
1363 ;; ptr_mode sized quantities.
1364 (define_mode_iterator PTR
1365   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1367 ;; Scheduling descriptions
1369 (include "pentium.md")
1370 (include "ppro.md")
1371 (include "k6.md")
1372 (include "athlon.md")
1373 (include "bdver1.md")
1374 (include "bdver3.md")
1375 (include "btver2.md")
1376 (include "znver.md")
1377 (include "znver4.md")
1378 (include "geode.md")
1379 (include "atom.md")
1380 (include "slm.md")
1381 (include "glm.md")
1382 (include "core2.md")
1383 (include "haswell.md")
1384 (include "lujiazui.md")
1385 (include "yongfeng.md")
1388 ;; Operand and operator predicates and constraints
1390 (include "predicates.md")
1391 (include "constraints.md")
1394 ;; Compare and branch/compare and store instructions.
1396 (define_expand "cbranch<mode>4"
1397   [(set (reg:CC FLAGS_REG)
1398         (compare:CC (match_operand:SWIM1248x 1 "nonimmediate_operand")
1399                     (match_operand:SWIM1248x 2 "<general_operand>")))
1400    (set (pc) (if_then_else
1401                (match_operator 0 "ordered_comparison_operator"
1402                 [(reg:CC FLAGS_REG) (const_int 0)])
1403                (label_ref (match_operand 3))
1404                (pc)))]
1405   ""
1407   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1408     operands[1] = force_reg (<MODE>mode, operands[1]);
1409   ix86_expand_branch (GET_CODE (operands[0]),
1410                       operands[1], operands[2], operands[3]);
1411   DONE;
1414 (define_expand "cbranchti4"
1415   [(set (reg:CC FLAGS_REG)
1416         (compare:CC (match_operand:TI 1 "nonimmediate_operand")
1417                     (match_operand:TI 2 "ix86_timode_comparison_operand")))
1418    (set (pc) (if_then_else
1419                (match_operator 0 "ix86_timode_comparison_operator"
1420                 [(reg:CC FLAGS_REG) (const_int 0)])
1421                (label_ref (match_operand 3))
1422                (pc)))]
1423   "TARGET_64BIT || TARGET_SSE4_1"
1425   ix86_expand_branch (GET_CODE (operands[0]),
1426                       operands[1], operands[2], operands[3]);
1427   DONE;
1430 (define_expand "cbranchoi4"
1431   [(set (reg:CC FLAGS_REG)
1432         (compare:CC (match_operand:OI 1 "nonimmediate_operand")
1433                     (match_operand:OI 2 "nonimmediate_operand")))
1434    (set (pc) (if_then_else
1435                (match_operator 0 "bt_comparison_operator"
1436                 [(reg:CC FLAGS_REG) (const_int 0)])
1437                (label_ref (match_operand 3))
1438                (pc)))]
1439   "TARGET_AVX"
1441   ix86_expand_branch (GET_CODE (operands[0]),
1442                       operands[1], operands[2], operands[3]);
1443   DONE;
1446 (define_expand "cbranchxi4"
1447   [(set (reg:CC FLAGS_REG)
1448         (compare:CC (match_operand:XI 1 "nonimmediate_operand")
1449                     (match_operand:XI 2 "nonimmediate_operand")))
1450    (set (pc) (if_then_else
1451                (match_operator 0 "bt_comparison_operator"
1452                 [(reg:CC FLAGS_REG) (const_int 0)])
1453                (label_ref (match_operand 3))
1454                (pc)))]
1455   "TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256"
1457   ix86_expand_branch (GET_CODE (operands[0]),
1458                       operands[1], operands[2], operands[3]);
1459   DONE;
1462 (define_expand "cstore<mode>4"
1463   [(set (reg:CC FLAGS_REG)
1464         (compare:CC (match_operand:SDWIM 2 "nonimmediate_operand")
1465                     (match_operand:SDWIM 3 "<general_operand>")))
1466    (set (match_operand:QI 0 "register_operand")
1467         (match_operator 1 "ordered_comparison_operator"
1468           [(reg:CC FLAGS_REG) (const_int 0)]))]
1469   ""
1471   if (<MODE>mode == (TARGET_64BIT ? TImode : DImode))
1472     {
1473       if (GET_CODE (operands[1]) != EQ
1474           && GET_CODE (operands[1]) != NE)
1475         FAIL;
1476     }
1477   else if (MEM_P (operands[2]) && MEM_P (operands[3]))
1478     operands[2] = force_reg (<MODE>mode, operands[2]);
1479   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1480                      operands[2], operands[3]);
1481   DONE;
1484 (define_expand "@cmp<mode>_1"
1485   [(set (reg:CC FLAGS_REG)
1486         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1487                     (match_operand:SWI48 1 "<general_operand>")))])
1489 (define_mode_iterator SWI1248_AVX512BWDQ_64
1490   [(QI "TARGET_AVX512DQ") HI
1491    (SI "TARGET_AVX512BW")
1492    (DI "TARGET_AVX512BW && TARGET_EVEX512 && TARGET_64BIT")])
1494 (define_insn "*cmp<mode>_ccz_1"
1495   [(set (reg FLAGS_REG)
1496         (compare (match_operand:SWI1248_AVX512BWDQ_64 0
1497                         "nonimmediate_operand" "<r>,?m<r>,$k")
1498                  (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))]
1499   "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
1500   "@
1501    test{<imodesuffix>}\t%0, %0
1502    cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1503    kortest<mskmodesuffix>\t%0, %0"
1504   [(set_attr "type" "test,icmp,msklog")
1505    (set_attr "length_immediate" "0,1,*")
1506    (set_attr "prefix" "*,*,vex")
1507    (set_attr "mode" "<MODE>")])
1509 (define_insn "*cmp<mode>_ccno_1"
1510   [(set (reg FLAGS_REG)
1511         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1512                  (match_operand:SWI 1 "const0_operand")))]
1513   "ix86_match_ccmode (insn, CCNOmode)"
1514   "@
1515    test{<imodesuffix>}\t%0, %0
1516    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1517   [(set_attr "type" "test,icmp")
1518    (set_attr "length_immediate" "0,1")
1519    (set_attr "mode" "<MODE>")])
1521 (define_insn "*cmp<mode>_1"
1522   [(set (reg FLAGS_REG)
1523         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1524                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>")))]
1525   "ix86_match_ccmode (insn, CCmode)"
1526   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1527   [(set_attr "type" "icmp")
1528    (set_attr "mode" "<MODE>")])
1530 (define_insn "*cmp<mode>_minus_1"
1531   [(set (reg FLAGS_REG)
1532         (compare
1533           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1534                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>"))
1535           (const_int 0)))]
1536   "ix86_match_ccmode (insn, CCGOCmode)"
1537   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1538   [(set_attr "type" "icmp")
1539    (set_attr "mode" "<MODE>")])
1541 (define_insn "*cmpqi_ext<mode>_1"
1542   [(set (reg FLAGS_REG)
1543         (compare
1544           (match_operand:QI 0 "nonimmediate_operand" "QBn")
1545           (subreg:QI
1546             (match_operator:SWI248 2 "extract_operator"
1547               [(match_operand 1 "int248_register_operand" "Q")
1548                (const_int 8)
1549                (const_int 8)]) 0)))]
1550   "ix86_match_ccmode (insn, CCmode)"
1551   "cmp{b}\t{%h1, %0|%0, %h1}"
1552   [(set_attr "addr" "gpr8")
1553    (set_attr "type" "icmp")
1554    (set_attr "mode" "QI")])
1556 (define_insn "*cmpqi_ext<mode>_2"
1557   [(set (reg FLAGS_REG)
1558         (compare
1559           (subreg:QI
1560             (match_operator:SWI248 2 "extract_operator"
1561               [(match_operand 0 "int248_register_operand" "Q")
1562                (const_int 8)
1563                (const_int 8)]) 0)
1564           (match_operand:QI 1 "const0_operand")))]
1565   "ix86_match_ccmode (insn, CCNOmode)"
1566   "test{b}\t%h0, %h0"
1567   [(set_attr "type" "test")
1568    (set_attr "length_immediate" "0")
1569    (set_attr "mode" "QI")])
1571 (define_expand "cmpqi_ext_3"
1572   [(set (reg:CC FLAGS_REG)
1573         (compare:CC
1574           (subreg:QI
1575             (zero_extract:HI
1576               (match_operand:HI 0 "register_operand")
1577               (const_int 8)
1578               (const_int 8)) 0)
1579           (match_operand:QI 1 "const_int_operand")))])
1581 (define_insn "*cmpqi_ext<mode>_3"
1582   [(set (reg FLAGS_REG)
1583         (compare
1584           (subreg:QI
1585             (match_operator:SWI248 2 "extract_operator"
1586               [(match_operand 0 "int248_register_operand" "Q")
1587                (const_int 8)
1588                (const_int 8)]) 0)
1589           (match_operand:QI 1 "general_operand" "QnBn")))]
1590   "ix86_match_ccmode (insn, CCmode)"
1591   "cmp{b}\t{%1, %h0|%h0, %1}"
1592   [(set_attr "addr" "gpr8")
1593    (set_attr "type" "icmp")
1594    (set_attr "mode" "QI")])
1596 (define_insn "*cmpqi_ext<mode>_4"
1597   [(set (reg FLAGS_REG)
1598         (compare
1599           (subreg:QI
1600             (match_operator:SWI248 2 "extract_operator"
1601               [(match_operand 0 "int248_register_operand" "Q")
1602                (const_int 8)
1603                (const_int 8)]) 0)
1604           (subreg:QI
1605             (match_operator:SWI248 3 "extract_operator"
1606               [(match_operand 1 "int248_register_operand" "Q")
1607                (const_int 8)
1608                (const_int 8)]) 0)))]
1609   "ix86_match_ccmode (insn, CCmode)"
1610   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1611   [(set_attr "type" "icmp")
1612    (set_attr "mode" "QI")])
1614 (define_insn_and_split "*cmp<dwi>_doubleword"
1615   [(set (reg:CCZ FLAGS_REG)
1616         (compare:CCZ (match_operand:<DWI> 0 "nonimmediate_operand")
1617                      (match_operand:<DWI> 1 "general_operand")))]
1618   "ix86_pre_reload_split ()"
1619   "#"
1620   "&& 1"
1621   [(parallel [(set (reg:CCZ FLAGS_REG)
1622                    (compare:CCZ (ior:DWIH (match_dup 4) (match_dup 5))
1623                                 (const_int 0)))
1624               (set (match_dup 4) (ior:DWIH (match_dup 4) (match_dup 5)))])]
1626   split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);
1627   /* Placing the SUBREG pieces in pseudos helps reload.  */
1628   for (int i = 0; i < 4; i++)
1629     if (SUBREG_P (operands[i]))
1630       operands[i] = force_reg (<MODE>mode, operands[i]);
1632   operands[4] = gen_reg_rtx (<MODE>mode);
1634   /* Special case comparisons against -1.  */
1635   if (operands[1] == constm1_rtx && operands[3] == constm1_rtx)
1636     {
1637       emit_insn (gen_and<mode>3 (operands[4], operands[0], operands[2]));
1638       emit_insn (gen_cmp_1 (<MODE>mode, operands[4], constm1_rtx));
1639       DONE;
1640     }
1642   if (operands[1] == const0_rtx)
1643     emit_move_insn (operands[4], operands[0]);
1644   else if (operands[0] == const0_rtx)
1645     emit_move_insn (operands[4], operands[1]);
1646   else if (operands[1] == constm1_rtx)
1647     emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[0]));
1648   else if (operands[0] == constm1_rtx)
1649     emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[1]));
1650   else
1651     {
1652       if (CONST_SCALAR_INT_P (operands[1])
1653           && !x86_64_immediate_operand (operands[1], <MODE>mode))
1654         operands[1] = force_reg (<MODE>mode, operands[1]);
1655       emit_insn (gen_xor<mode>3 (operands[4], operands[0], operands[1]));
1656     }
1658   if (operands[3] == const0_rtx)
1659     operands[5] = operands[2];
1660   else if (operands[2] == const0_rtx)
1661     operands[5] = operands[3];
1662   else
1663     {
1664       operands[5] = gen_reg_rtx (<MODE>mode);
1665       if (operands[3] == constm1_rtx)
1666         emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[2]));
1667       else if (operands[2] == constm1_rtx)
1668         emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[3]));
1669       else
1670         {
1671           if (CONST_SCALAR_INT_P (operands[3])
1672               && !x86_64_immediate_operand (operands[3], <MODE>mode))
1673             operands[3] = force_reg (<MODE>mode, operands[3]);
1674           emit_insn (gen_xor<mode>3 (operands[5], operands[2], operands[3]));
1675         }
1676     }
1679 ;; These implement float point compares.
1680 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1681 ;; which would allow mix and match FP modes on the compares.  Which is what
1682 ;; the old patterns did, but with many more of them.
1684 (define_expand "cbranchxf4"
1685   [(set (reg:CC FLAGS_REG)
1686         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1687                     (match_operand:XF 2 "nonmemory_operand")))
1688    (set (pc) (if_then_else
1689               (match_operator 0 "ix86_fp_comparison_operator"
1690                [(reg:CC FLAGS_REG)
1691                 (const_int 0)])
1692               (label_ref (match_operand 3))
1693               (pc)))]
1694   "TARGET_80387"
1696   ix86_expand_branch (GET_CODE (operands[0]),
1697                       operands[1], operands[2], operands[3]);
1698   DONE;
1701 (define_expand "cstorexf4"
1702   [(set (reg:CC FLAGS_REG)
1703         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1704                     (match_operand:XF 3 "nonmemory_operand")))
1705    (set (match_operand:QI 0 "register_operand")
1706               (match_operator 1 "ix86_fp_comparison_operator"
1707                [(reg:CC FLAGS_REG)
1708                 (const_int 0)]))]
1709   "TARGET_80387"
1711   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1712                      operands[2], operands[3]);
1713   DONE;
1716 (define_expand "cbranchhf4"
1717   [(set (reg:CC FLAGS_REG)
1718         (compare:CC (match_operand:HF 1 "cmp_fp_expander_operand")
1719                     (match_operand:HF 2 "cmp_fp_expander_operand")))
1720    (set (pc) (if_then_else
1721               (match_operator 0 "ix86_fp_comparison_operator"
1722                [(reg:CC FLAGS_REG)
1723                 (const_int 0)])
1724               (label_ref (match_operand 3))
1725               (pc)))]
1726   "TARGET_AVX512FP16"
1728   ix86_expand_branch (GET_CODE (operands[0]),
1729                       operands[1], operands[2], operands[3]);
1730   DONE;
1733 (define_expand "cbranch<mode>4"
1734   [(set (reg:CC FLAGS_REG)
1735         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1736                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1737    (set (pc) (if_then_else
1738               (match_operator 0 "ix86_fp_comparison_operator"
1739                [(reg:CC FLAGS_REG)
1740                 (const_int 0)])
1741               (label_ref (match_operand 3))
1742               (pc)))]
1743   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1745   ix86_expand_branch (GET_CODE (operands[0]),
1746                       operands[1], operands[2], operands[3]);
1747   DONE;
1750 (define_expand "cbranchbf4"
1751   [(set (reg:CC FLAGS_REG)
1752         (compare:CC (match_operand:BF 1 "cmp_fp_expander_operand")
1753                     (match_operand:BF 2 "cmp_fp_expander_operand")))
1754    (set (pc) (if_then_else
1755               (match_operator 0 "comparison_operator"
1756                [(reg:CC FLAGS_REG)
1757                 (const_int 0)])
1758               (label_ref (match_operand 3))
1759               (pc)))]
1760   "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1762   rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[1]);
1763   rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1764   do_compare_rtx_and_jump (op1, op2, GET_CODE (operands[0]), 0,
1765                            SFmode, NULL_RTX, NULL,
1766                            as_a <rtx_code_label *> (operands[3]),
1767                            /* Unfortunately this isn't propagated.  */
1768                            profile_probability::even ());
1769   DONE;
1772 (define_expand "cstorehf4"
1773   [(set (reg:CC FLAGS_REG)
1774         (compare:CC (match_operand:HF 2 "cmp_fp_expander_operand")
1775                     (match_operand:HF 3 "cmp_fp_expander_operand")))
1776    (set (match_operand:QI 0 "register_operand")
1777         (match_operator 1 "ix86_fp_comparison_operator"
1778           [(reg:CC FLAGS_REG)
1779            (const_int 0)]))]
1780   "TARGET_AVX512FP16"
1782   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1783                      operands[2], operands[3]);
1784   DONE;
1787 (define_expand "cstorebf4"
1788   [(set (reg:CC FLAGS_REG)
1789         (compare:CC (match_operand:BF 2 "cmp_fp_expander_operand")
1790                     (match_operand:BF 3 "cmp_fp_expander_operand")))
1791    (set (match_operand:QI 0 "register_operand")
1792         (match_operator 1 "comparison_operator"
1793           [(reg:CC FLAGS_REG)
1794            (const_int 0)]))]
1795   "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1797   rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1798   rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[3]);
1799   rtx res = emit_store_flag_force (operands[0], GET_CODE (operands[1]),
1800                                    op1, op2, SFmode, 0, 1);
1801   if (!rtx_equal_p (res, operands[0]))
1802     emit_move_insn (operands[0], res);
1803   DONE;
1806 (define_expand "cstore<mode>4"
1807   [(set (reg:CC FLAGS_REG)
1808         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1809                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1810    (set (match_operand:QI 0 "register_operand")
1811               (match_operator 1 "ix86_fp_comparison_operator"
1812                [(reg:CC FLAGS_REG)
1813                 (const_int 0)]))]
1814   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1816   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1817                      operands[2], operands[3]);
1818   DONE;
1821 (define_expand "cbranchcc4"
1822   [(set (pc) (if_then_else
1823               (match_operator 0 "comparison_operator"
1824                [(match_operand 1 "flags_reg_operand")
1825                 (match_operand 2 "const0_operand")])
1826               (label_ref (match_operand 3))
1827               (pc)))]
1828   ""
1830   ix86_expand_branch (GET_CODE (operands[0]),
1831                       operands[1], operands[2], operands[3]);
1832   DONE;
1835 (define_expand "cstorecc4"
1836   [(set (match_operand:QI 0 "register_operand")
1837               (match_operator 1 "comparison_operator"
1838                [(match_operand 2 "flags_reg_operand")
1839                 (match_operand 3 "const0_operand")]))]
1840   ""
1842   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1843                      operands[2], operands[3]);
1844   DONE;
1847 ;; FP compares, step 1:
1848 ;; Set the FP condition codes and move fpsr to ax.
1850 ;; We may not use "#" to split and emit these
1851 ;; due to reg-stack pops killing fpsr.
1853 (define_insn "*cmpxf_i387"
1854   [(set (match_operand:HI 0 "register_operand" "=a")
1855         (unspec:HI
1856           [(compare:CCFP
1857              (match_operand:XF 1 "register_operand" "f")
1858              (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1859           UNSPEC_FNSTSW))]
1860   "TARGET_80387"
1861   "* return output_fp_compare (insn, operands, false, false);"
1862   [(set_attr "type" "multi")
1863    (set_attr "unit" "i387")
1864    (set_attr "mode" "XF")])
1866 (define_insn "*cmp<mode>_i387"
1867   [(set (match_operand:HI 0 "register_operand" "=a")
1868         (unspec:HI
1869           [(compare:CCFP
1870              (match_operand:MODEF 1 "register_operand" "f")
1871              (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1872           UNSPEC_FNSTSW))]
1873   "TARGET_80387"
1874   "* return output_fp_compare (insn, operands, false, false);"
1875   [(set_attr "type" "multi")
1876    (set_attr "unit" "i387")
1877    (set_attr "mode" "<MODE>")])
1879 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1880   [(set (match_operand:HI 0 "register_operand" "=a")
1881         (unspec:HI
1882           [(compare:CCFP
1883              (match_operand:X87MODEF 1 "register_operand" "f")
1884              (float:X87MODEF
1885                (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1886           UNSPEC_FNSTSW))]
1887   "TARGET_80387
1888    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1889        || optimize_function_for_size_p (cfun))"
1890   "* return output_fp_compare (insn, operands, false, false);"
1891   [(set_attr "type" "multi")
1892    (set_attr "unit" "i387")
1893    (set_attr "fp_int_src" "true")
1894    (set_attr "mode" "<SWI24:MODE>")])
1896 (define_insn "*cmpu<mode>_i387"
1897   [(set (match_operand:HI 0 "register_operand" "=a")
1898         (unspec:HI
1899           [(unspec:CCFP
1900              [(compare:CCFP
1901                 (match_operand:X87MODEF 1 "register_operand" "f")
1902                 (match_operand:X87MODEF 2 "register_operand" "f"))]
1903              UNSPEC_NOTRAP)]
1904           UNSPEC_FNSTSW))]
1905   "TARGET_80387"
1906   "* return output_fp_compare (insn, operands, false, true);"
1907   [(set_attr "type" "multi")
1908    (set_attr "unit" "i387")
1909    (set_attr "mode" "<MODE>")])
1911 ;; FP compares, step 2:
1912 ;; Get ax into flags, general case.
1914 (define_insn "x86_sahf_1"
1915   [(set (reg:CC FLAGS_REG)
1916         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1917                    UNSPEC_SAHF))]
1918   "TARGET_SAHF"
1920 #ifndef HAVE_AS_IX86_SAHF
1921   if (TARGET_64BIT)
1922     return ASM_BYTE "0x9e";
1923   else
1924 #endif
1925   return "sahf";
1927   [(set_attr "length" "1")
1928    (set_attr "athlon_decode" "vector")
1929    (set_attr "amdfam10_decode" "direct")
1930    (set_attr "bdver1_decode" "direct")
1931    (set_attr "mode" "SI")])
1933 ;; Pentium Pro can do both steps in one go.
1934 ;; (these instructions set flags directly)
1936 (define_subst_attr "unord" "unord_subst" "" "u")
1937 (define_subst_attr "unordered" "unord_subst" "false" "true")
1939 (define_subst "unord_subst"
1940   [(set (match_operand:CCFP 0)
1941         (match_operand:CCFP 1))]
1942   ""
1943   [(set (match_dup 0)
1944         (unspec:CCFP
1945           [(match_dup 1)]
1946           UNSPEC_NOTRAP))])
1948 (define_insn "*cmpi<unord>xf_i387"
1949   [(set (reg:CCFP FLAGS_REG)
1950         (compare:CCFP
1951           (match_operand:XF 0 "register_operand" "f")
1952           (match_operand:XF 1 "register_operand" "f")))]
1953   "TARGET_80387 && TARGET_CMOVE"
1954   "* return output_fp_compare (insn, operands, true, <unordered>);"
1955   [(set_attr "type" "fcmp")
1956    (set_attr "mode" "XF")
1957    (set_attr "athlon_decode" "vector")
1958    (set_attr "amdfam10_decode" "direct")
1959    (set_attr "bdver1_decode" "double")
1960    (set_attr "znver1_decode" "double")])
1962 (define_insn "*cmpi<unord><MODEF:mode>"
1963   [(set (reg:CCFP FLAGS_REG)
1964         (compare:CCFP
1965           (match_operand:MODEF 0 "register_operand" "f,v")
1966           (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1967   "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1968    || (TARGET_80387 && TARGET_CMOVE)"
1969   "@
1970    * return output_fp_compare (insn, operands, true, <unordered>);
1971    %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1972   [(set_attr "type" "fcmp,ssecomi")
1973    (set_attr "prefix" "orig,maybe_vex")
1974    (set_attr "mode" "<MODEF:MODE>")
1975    (set_attr "prefix_rep" "*,0")
1976    (set (attr "prefix_data16")
1977         (cond [(eq_attr "alternative" "0")
1978                  (const_string "*")
1979                (eq_attr "mode" "DF")
1980                  (const_string "1")
1981               ]
1982               (const_string "0")))
1983    (set_attr "athlon_decode" "vector")
1984    (set_attr "amdfam10_decode" "direct")
1985    (set_attr "bdver1_decode" "double")
1986    (set_attr "znver1_decode" "double")
1987    (set (attr "enabled")
1988      (if_then_else
1989        (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1990        (if_then_else
1991          (eq_attr "alternative" "0")
1992          (symbol_ref "TARGET_MIX_SSE_I387")
1993          (symbol_ref "true"))
1994        (if_then_else
1995          (eq_attr "alternative" "0")
1996          (symbol_ref "true")
1997          (symbol_ref "false"))))])
1999 (define_insn "*cmpi<unord>hf"
2000   [(set (reg:CCFP FLAGS_REG)
2001         (compare:CCFP
2002           (match_operand:HF 0 "register_operand" "v")
2003           (match_operand:HF 1 "nonimmediate_operand" "vm")))]
2004   "TARGET_AVX512FP16"
2005   "v<unord>comish\t{%1, %0|%0, %1}"
2006   [(set_attr "type" "ssecomi")
2007    (set_attr "prefix" "evex")
2008    (set_attr "mode" "HF")])
2010 ;; Set carry flag.
2011 (define_insn "x86_stc"
2012   [(set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2013   ""
2014   "stc"
2015   [(set_attr "length" "1")
2016    (set_attr "length_immediate" "0")
2017    (set_attr "modrm" "0")])
2019 ;; On Pentium 4, set the carry flag using mov $1,%al;addb $-1,%al.
2020 (define_peephole2
2021   [(match_scratch:QI 0 "r")
2022    (set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2023   "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2024   [(set (match_dup 0) (const_int 1))
2025    (parallel
2026      [(set (reg:CCC FLAGS_REG)
2027            (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2028                         (match_dup 0)))
2029       (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2031 ;; Complement carry flag.
2032 (define_insn "*x86_cmc"
2033   [(set (reg:CCC FLAGS_REG)
2034         (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2035                      (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2036   ""
2037   "cmc"
2038   [(set_attr "length" "1")
2039    (set_attr "length_immediate" "0")
2040    (set_attr "use_carry" "1")
2041    (set_attr "modrm" "0")])
2043 ;; On Pentium 4, cmc is replaced with setnc %al;addb $-1,%al.
2044 (define_peephole2
2045   [(match_scratch:QI 0 "r")
2046    (set (reg:CCC FLAGS_REG)
2047         (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2048                      (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2049   "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2050   [(set (match_dup 0) (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
2051    (parallel
2052      [(set (reg:CCC FLAGS_REG)
2053            (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2054                         (match_dup 0)))
2055       (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2057 ;; Push/pop instructions.
2059 (define_insn_and_split "*pushv1ti2"
2060   [(set (match_operand:V1TI 0 "push_operand" "=<")
2061         (match_operand:V1TI 1 "register_operand" "v"))]
2062   "TARGET_64BIT && TARGET_STV"
2063   "#"
2064   "&& reload_completed"
2065   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2066    (set (match_dup 0) (match_dup 1))]
2068   operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (V1TImode)));
2069   /* Preserve memory attributes. */
2070   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2072   [(set_attr "type" "multi")
2073    (set_attr "mode" "TI")])
2075 (define_insn "*push<mode>2"
2076   [(set (match_operand:DWI 0 "push_operand" "=<,<")
2077         (match_operand:DWI 1 "general_no_elim_operand" "riF*o,*v"))]
2078   ""
2079   "#"
2080   [(set_attr "type" "multi")
2081    (set_attr "mode" "<MODE>")])
2083 (define_split
2084   [(set (match_operand:DWI 0 "push_operand")
2085         (match_operand:DWI 1 "general_gr_operand"))]
2086   "reload_completed"
2087   [(const_int 0)]
2088   "ix86_split_long_move (operands); DONE;")
2090 (define_insn "*pushdi2_rex64"
2091   [(set (match_operand:DI 0 "push_operand" "=<,<,!<")
2092         (match_operand:DI 1 "general_no_elim_operand" "re*m,*v,n"))]
2093   "TARGET_64BIT"
2094   "@
2095    push{q}\t%1
2096    #
2097    #"
2098   [(set_attr "type" "push,multi,multi")
2099    (set_attr "mode" "DI")])
2101 ;; Convert impossible pushes of immediate to existing instructions.
2102 ;; First try to get scratch register and go through it.  In case this
2103 ;; fails, push sign extended lower part first and then overwrite
2104 ;; upper part by 32bit move.
2106 (define_peephole2
2107   [(match_scratch:DI 2 "r")
2108    (set (match_operand:DI 0 "push_operand")
2109         (match_operand:DI 1 "immediate_operand"))]
2110   "TARGET_64BIT
2111    && !symbolic_operand (operands[1], DImode)
2112    && !x86_64_immediate_operand (operands[1], DImode)"
2113   [(set (match_dup 2) (match_dup 1))
2114    (set (match_dup 0) (match_dup 2))])
2116 (define_split
2117   [(set (match_operand:DI 0 "push_operand")
2118         (match_operand:DI 1 "immediate_operand"))]
2119   "TARGET_64BIT && epilogue_completed
2120    && !symbolic_operand (operands[1], DImode)
2121    && !x86_64_immediate_operand (operands[1], DImode)"
2122   [(set (match_dup 0) (match_dup 1))
2123    (set (match_dup 2) (match_dup 3))]
2125   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
2127   operands[1] = gen_lowpart (DImode, operands[2]);
2128   operands[2] = gen_rtx_MEM (SImode,
2129                              plus_constant (Pmode, stack_pointer_rtx, 4));
2132 ;; For TARGET_64BIT we always round up to 8 bytes.
2133 (define_insn "*pushsi2_rex64"
2134   [(set (match_operand:SI 0 "push_operand" "=X,X")
2135         (match_operand:SI 1 "nonmemory_no_elim_operand" "re,*v"))]
2136   "TARGET_64BIT"
2137   "@
2138    push{q}\t%q1
2139    #"
2140   [(set_attr "type" "push,multi")
2141    (set_attr "mode" "DI")])
2143 (define_insn "*pushsi2"
2144   [(set (match_operand:SI 0 "push_operand" "=<,<")
2145         (match_operand:SI 1 "general_no_elim_operand" "ri*m,*v"))]
2146   "!TARGET_64BIT"
2147   "@
2148    push{l}\t%1
2149    #"
2150   [(set_attr "type" "push,multi")
2151    (set_attr "mode" "SI")])
2153 (define_split
2154   [(set (match_operand:SWI48DWI 0 "push_operand")
2155         (match_operand:SWI48DWI 1 "sse_reg_operand"))]
2156   "TARGET_SSE && reload_completed"
2157   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2158     (set (match_dup 0) (match_dup 1))]
2160   operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (<SWI48DWI:MODE>mode)));
2161   /* Preserve memory attributes. */
2162   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2165 ;; emit_push_insn when it calls move_by_pieces requires an insn to
2166 ;; "push a byte/word".  But actually we use push{l,q}, which has
2167 ;; the effect of rounding the amount pushed up to a word.
2169 (define_insn "*push<mode>2"
2170   [(set (match_operand:SWI12 0 "push_operand" "=X")
2171         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
2172   ""
2173   "* return TARGET_64BIT ? \"push{q}\t%q1\" : \"push{l}\t%k1\";"
2174   [(set_attr "type" "push")
2175    (set (attr "mode")
2176         (if_then_else (match_test "TARGET_64BIT")
2177           (const_string "DI")
2178           (const_string "SI")))])
2180 (define_insn "*push<mode>2_prologue"
2181   [(set (match_operand:W 0 "push_operand" "=<")
2182         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
2183    (clobber (mem:BLK (scratch)))]
2184   ""
2185   "push{<imodesuffix>}\t%1"
2186   [(set_attr "type" "push")
2187    (set_attr "mode" "<MODE>")])
2189 (define_insn "*pop<mode>1"
2190   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2191         (match_operand:W 1 "pop_operand" ">"))]
2192   ""
2193   "pop{<imodesuffix>}\t%0"
2194   [(set_attr "type" "pop")
2195    (set_attr "mode" "<MODE>")])
2197 (define_insn "*pop<mode>1_epilogue"
2198   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2199         (match_operand:W 1 "pop_operand" ">"))
2200    (clobber (mem:BLK (scratch)))]
2201   ""
2202   "pop{<imodesuffix>}\t%0"
2203   [(set_attr "type" "pop")
2204    (set_attr "mode" "<MODE>")])
2206 (define_insn "*pushfl<mode>2"
2207   [(set (match_operand:W 0 "push_operand" "=<")
2208         (match_operand:W 1 "flags_reg_operand"))]
2209   ""
2210   "pushf{<imodesuffix>}"
2211   [(set_attr "type" "push")
2212    (set_attr "mode" "<MODE>")])
2214 (define_insn "*popfl<mode>1"
2215   [(set (match_operand:W 0 "flags_reg_operand")
2216         (match_operand:W 1 "pop_operand" ">"))]
2217   ""
2218   "popf{<imodesuffix>}"
2219   [(set_attr "type" "pop")
2220    (set_attr "mode" "<MODE>")])
2223 ;; Reload patterns to support multi-word load/store
2224 ;; with non-offsetable address.
2225 (define_expand "reload_noff_store"
2226   [(parallel [(match_operand 0 "memory_operand" "=m")
2227               (match_operand 1 "register_operand" "r")
2228               (match_operand:DI 2 "register_operand" "=&r")])]
2229   "TARGET_64BIT"
2231   rtx mem = operands[0];
2232   rtx addr = XEXP (mem, 0);
2234   emit_move_insn (operands[2], addr);
2235   mem = replace_equiv_address_nv (mem, operands[2]);
2237   emit_insn (gen_rtx_SET (mem, operands[1]));
2238   DONE;
2241 (define_expand "reload_noff_load"
2242   [(parallel [(match_operand 0 "register_operand" "=r")
2243               (match_operand 1 "memory_operand" "m")
2244               (match_operand:DI 2 "register_operand" "=r")])]
2245   "TARGET_64BIT"
2247   rtx mem = operands[1];
2248   rtx addr = XEXP (mem, 0);
2250   emit_move_insn (operands[2], addr);
2251   mem = replace_equiv_address_nv (mem, operands[2]);
2253   emit_insn (gen_rtx_SET (operands[0], mem));
2254   DONE;
2257 ;; Move instructions.
2259 (define_expand "movxi"
2260   [(set (match_operand:XI 0 "nonimmediate_operand")
2261         (match_operand:XI 1 "general_operand"))]
2262   "TARGET_AVX512F && TARGET_EVEX512"
2263   "ix86_expand_vector_move (XImode, operands); DONE;")
2265 (define_expand "movoi"
2266   [(set (match_operand:OI 0 "nonimmediate_operand")
2267         (match_operand:OI 1 "general_operand"))]
2268   "TARGET_AVX"
2269   "ix86_expand_vector_move (OImode, operands); DONE;")
2271 (define_expand "movti"
2272   [(set (match_operand:TI 0 "nonimmediate_operand")
2273         (match_operand:TI 1 "general_operand"))]
2274   "TARGET_64BIT || TARGET_SSE"
2276   if (TARGET_64BIT)
2277     ix86_expand_move (TImode, operands);
2278   else
2279     ix86_expand_vector_move (TImode, operands);
2280   DONE;
2283 ;; This expands to what emit_move_complex would generate if we didn't
2284 ;; have a movti pattern.  Having this avoids problems with reload on
2285 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2286 ;; to have around all the time.
2287 (define_expand "movcdi"
2288   [(set (match_operand:CDI 0 "nonimmediate_operand")
2289         (match_operand:CDI 1 "general_operand"))]
2290   ""
2292   if (push_operand (operands[0], CDImode))
2293     emit_move_complex_push (CDImode, operands[0], operands[1]);
2294   else
2295     emit_move_complex_parts (operands[0], operands[1]);
2296   DONE;
2299 (define_expand "mov<mode>"
2300   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2301         (match_operand:SWI1248x 1 "general_operand"))]
2302   ""
2303   "ix86_expand_move (<MODE>mode, operands); DONE;")
2305 (define_insn "*mov<mode>_xor"
2306   [(set (match_operand:SWI48 0 "register_operand" "=r")
2307         (match_operand:SWI48 1 "const0_operand"))
2308    (clobber (reg:CC FLAGS_REG))]
2309   "reload_completed"
2310   "xor{l}\t%k0, %k0"
2311   [(set_attr "type" "alu1")
2312    (set_attr "mode" "SI")
2313    (set_attr "length_immediate" "0")])
2315 (define_insn "*mov<mode>_and"
2316   [(set (match_operand:SWI248 0 "memory_operand" "=m")
2317         (match_operand:SWI248 1 "const0_operand"))
2318    (clobber (reg:CC FLAGS_REG))]
2319   "reload_completed"
2320   "and{<imodesuffix>}\t{%1, %0|%0, %1}"
2321   [(set_attr "type" "alu1")
2322    (set_attr "mode" "<MODE>")
2323    (set_attr "length_immediate" "1")])
2325 (define_insn "*mov<mode>_or"
2326   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
2327         (match_operand:SWI248 1 "constm1_operand"))
2328    (clobber (reg:CC FLAGS_REG))]
2329   "reload_completed"
2330   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2331   [(set_attr "type" "alu1")
2332    (set_attr "mode" "<MODE>")
2333    (set_attr "length_immediate" "1")])
2335 (define_insn "*movxi_internal_avx512f"
2336   [(set (match_operand:XI 0 "nonimmediate_operand"              "=v,v ,v ,m")
2337         (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2338   "TARGET_AVX512F && TARGET_EVEX512
2339    && (register_operand (operands[0], XImode)
2340        || register_operand (operands[1], XImode))"
2342   switch (get_attr_type (insn))
2343     {
2344     case TYPE_SSELOG1:
2345       return standard_sse_constant_opcode (insn, operands);
2347     case TYPE_SSEMOV:
2348       return ix86_output_ssemov (insn, operands);
2350     default:
2351       gcc_unreachable ();
2352     }
2354   [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2355    (set_attr "prefix" "evex")
2356    (set_attr "mode" "XI")])
2358 (define_insn "*movoi_internal_avx"
2359   [(set (match_operand:OI 0 "nonimmediate_operand"              "=v,v ,v ,m")
2360         (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2361   "TARGET_AVX
2362    && (register_operand (operands[0], OImode)
2363        || register_operand (operands[1], OImode))"
2365   switch (get_attr_type (insn))
2366     {
2367     case TYPE_SSELOG1:
2368       return standard_sse_constant_opcode (insn, operands);
2370     case TYPE_SSEMOV:
2371       return ix86_output_ssemov (insn, operands);
2373     default:
2374       gcc_unreachable ();
2375     }
2377   [(set_attr "isa" "*,avx2,*,*")
2378    (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2379    (set_attr "prefix" "vex")
2380    (set_attr "mode" "OI")])
2382 (define_insn "*movti_internal"
2383   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
2384         (match_operand:TI 1 "general_operand"      "riFo,re,C,BC,vm,v,Yd,r"))]
2385   "(TARGET_64BIT
2386     && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2387    || (TARGET_SSE
2388        && nonimmediate_or_sse_const_operand (operands[1], TImode)
2389        && (register_operand (operands[0], TImode)
2390            || register_operand (operands[1], TImode)))"
2392   switch (get_attr_type (insn))
2393     {
2394     case TYPE_MULTI:
2395       return "#";
2397     case TYPE_SSELOG1:
2398       return standard_sse_constant_opcode (insn, operands);
2400     case TYPE_SSEMOV:
2401       return ix86_output_ssemov (insn, operands);
2403     default:
2404       gcc_unreachable ();
2405     }
2407   [(set (attr "isa")
2408      (cond [(eq_attr "alternative" "0,1,6,7")
2409               (const_string "x64")
2410             (eq_attr "alternative" "3")
2411               (const_string "sse2")
2412            ]
2413            (const_string "*")))
2414    (set (attr "type")
2415      (cond [(eq_attr "alternative" "0,1,6,7")
2416               (const_string "multi")
2417             (eq_attr "alternative" "2,3")
2418               (const_string "sselog1")
2419            ]
2420            (const_string "ssemov")))
2421    (set (attr "prefix")
2422      (if_then_else (eq_attr "type" "sselog1,ssemov")
2423        (const_string "maybe_vex")
2424        (const_string "orig")))
2425    (set (attr "mode")
2426         (cond [(eq_attr "alternative" "0,1")
2427                  (const_string "DI")
2428                (match_test "TARGET_AVX")
2429                  (const_string "TI")
2430                (ior (not (match_test "TARGET_SSE2"))
2431                     (match_test "optimize_function_for_size_p (cfun)"))
2432                  (const_string "V4SF")
2433                (and (eq_attr "alternative" "5")
2434                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2435                  (const_string "V4SF")
2436                ]
2437                (const_string "TI")))
2438    (set (attr "preferred_for_speed")
2439      (cond [(eq_attr "alternative" "6")
2440               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2441             (eq_attr "alternative" "7")
2442               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2443            ]
2444            (symbol_ref "true")))])
2446 (define_split
2447   [(set (match_operand:TI 0 "sse_reg_operand")
2448         (match_operand:TI 1 "general_reg_operand"))]
2449   "TARGET_64BIT && TARGET_SSE4_1
2450    && reload_completed"
2451   [(set (match_dup 2)
2452         (vec_merge:V2DI
2453           (vec_duplicate:V2DI (match_dup 3))
2454           (match_dup 2)
2455           (const_int 2)))]
2457   operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2458   operands[3] = gen_highpart (DImode, operands[1]);
2460   emit_move_insn (gen_lowpart (DImode, operands[0]),
2461                   gen_lowpart (DImode, operands[1]));
2464 (define_insn "*movdi_internal"
2465   [(set (match_operand:DI 0 "nonimmediate_operand"
2466     "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r,?*y,?Yv,?v,?v,m ,m,?r ,?*Yd,?r,?v,?*y,?*x,*k,*k  ,*r,*m,*k")
2467         (match_operand:DI 1 "general_operand"
2468     "riFo,riF,Z,rem,i,re,C ,*y,Bk ,*y,*y,r  ,C  ,?v,Bk,?v,v,*Yd,r   ,?v,r  ,*x ,*y ,*r,*kBk,*k,*k,CBC"))]
2469   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2470    && ix86_hardreg_mov_ok (operands[0], operands[1])"
2472   switch (get_attr_type (insn))
2473     {
2474     case TYPE_MSKMOV:
2475       return "kmovq\t{%1, %0|%0, %1}";
2477     case TYPE_MSKLOG:
2478       if (operands[1] == const0_rtx)
2479         return "kxorq\t%0, %0, %0";
2480       else if (operands[1] == constm1_rtx)
2481         return "kxnorq\t%0, %0, %0";
2482       gcc_unreachable ();
2484     case TYPE_MULTI:
2485       return "#";
2487     case TYPE_MMX:
2488       return "pxor\t%0, %0";
2490     case TYPE_MMXMOV:
2491       /* Handle broken assemblers that require movd instead of movq.  */
2492       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2493           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2494         return "movd\t{%1, %0|%0, %1}";
2495       return "movq\t{%1, %0|%0, %1}";
2497     case TYPE_SSELOG1:
2498       return standard_sse_constant_opcode (insn, operands);
2500     case TYPE_SSEMOV:
2501       return ix86_output_ssemov (insn, operands);
2503     case TYPE_SSECVT:
2504       if (SSE_REG_P (operands[0]))
2505         return "movq2dq\t{%1, %0|%0, %1}";
2506       else
2507         return "movdq2q\t{%1, %0|%0, %1}";
2509     case TYPE_LEA:
2510       return "lea{q}\t{%E1, %0|%0, %E1}";
2512     case TYPE_IMOV:
2513       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2514       if (get_attr_mode (insn) == MODE_SI)
2515         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2516       else if (which_alternative == 4)
2517         return "movabs{q}\t{%1, %0|%0, %1}";
2518       else if (ix86_use_lea_for_mov (insn, operands))
2519         return "lea{q}\t{%E1, %0|%0, %E1}";
2520       else
2521         return "mov{q}\t{%1, %0|%0, %1}";
2523     default:
2524       gcc_unreachable ();
2525     }
2527   [(set (attr "isa")
2528      (cond [(eq_attr "alternative" "0,1,17,18")
2529               (const_string "nox64")
2530             (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2531               (const_string "x64")
2532             (eq_attr "alternative" "19,20")
2533               (const_string "x64_sse2")
2534             (eq_attr "alternative" "21,22")
2535               (const_string "sse2")
2536            ]
2537            (const_string "*")))
2538    (set (attr "type")
2539      (cond [(eq_attr "alternative" "0,1,17,18")
2540               (const_string "multi")
2541             (eq_attr "alternative" "6")
2542               (const_string "mmx")
2543             (eq_attr "alternative" "7,8,9,10,11")
2544               (const_string "mmxmov")
2545             (eq_attr "alternative" "12")
2546               (const_string "sselog1")
2547             (eq_attr "alternative" "13,14,15,16,19,20")
2548               (const_string "ssemov")
2549             (eq_attr "alternative" "21,22")
2550               (const_string "ssecvt")
2551             (eq_attr "alternative" "23,24,25,26")
2552               (const_string "mskmov")
2553             (eq_attr "alternative" "27")
2554               (const_string "msklog")
2555             (and (match_operand 0 "register_operand")
2556                  (match_operand 1 "pic_32bit_operand"))
2557               (const_string "lea")
2558            ]
2559            (const_string "imov")))
2560    (set (attr "modrm")
2561      (if_then_else
2562        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2563        (const_string "0")
2564        (const_string "*")))
2565    (set (attr "length_immediate")
2566      (if_then_else
2567        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2568        (const_string "8")
2569        (const_string "*")))
2570    (set (attr "prefix_rex")
2571      (if_then_else
2572        (eq_attr "alternative" "10,11,19,20")
2573        (const_string "1")
2574        (const_string "*")))
2575    (set (attr "prefix")
2576      (if_then_else (eq_attr "type" "sselog1,ssemov")
2577        (const_string "maybe_vex")
2578        (const_string "orig")))
2579    (set (attr "prefix_data16")
2580      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2581        (const_string "1")
2582        (const_string "*")))
2583    (set (attr "mode")
2584      (cond [(eq_attr "alternative" "2")
2585               (const_string "SI")
2586             (eq_attr "alternative" "12")
2587               (cond [(match_test "TARGET_AVX")
2588                        (const_string "TI")
2589                      (ior (not (match_test "TARGET_SSE2"))
2590                           (match_test "optimize_function_for_size_p (cfun)"))
2591                        (const_string "V4SF")
2592                     ]
2593                     (const_string "TI"))
2594             (eq_attr "alternative" "13")
2595               (cond [(match_test "TARGET_AVX512VL")
2596                        (const_string "TI")
2597                      (match_test "TARGET_AVX512F")
2598                        (const_string "DF")
2599                      (match_test "TARGET_AVX")
2600                        (const_string "TI")
2601                      (ior (not (match_test "TARGET_SSE2"))
2602                           (match_test "optimize_function_for_size_p (cfun)"))
2603                        (const_string "V4SF")
2604                     ]
2605                     (const_string "TI"))
2607             (and (eq_attr "alternative" "14,15,16")
2608                  (not (match_test "TARGET_SSE2")))
2609               (const_string "V2SF")
2610            ]
2611            (const_string "DI")))
2612    (set (attr "preferred_for_speed")
2613      (cond [(eq_attr "alternative" "10,17,19")
2614               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2615             (eq_attr "alternative" "11,18,20")
2616               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2617            ]
2618            (symbol_ref "true")))
2619    (set (attr "enabled")
2620      (cond [(eq_attr "alternative" "15")
2621               (if_then_else
2622                 (match_test "TARGET_STV && TARGET_SSE2")
2623                 (symbol_ref "false")
2624                 (const_string "*"))
2625             (eq_attr "alternative" "16")
2626               (if_then_else
2627                 (match_test "TARGET_STV && TARGET_SSE2")
2628                 (symbol_ref "true")
2629                 (symbol_ref "false"))
2630            ]
2631            (const_string "*")))])
2633 (define_split
2634   [(set (match_operand:<DWI> 0 "general_reg_operand")
2635         (match_operand:<DWI> 1 "sse_reg_operand"))]
2636   "TARGET_SSE4_1
2637    && reload_completed"
2638   [(set (match_dup 2)
2639         (vec_select:DWIH
2640           (match_dup 3)
2641           (parallel [(const_int 1)])))]
2643   operands[2] = gen_highpart (<MODE>mode, operands[0]);
2644   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2646   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2647                   gen_lowpart (<MODE>mode, operands[1]));
2650 (define_split
2651   [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2652         (match_operand:DWI 1 "general_gr_operand"))]
2653   "reload_completed"
2654   [(const_int 0)]
2655   "ix86_split_long_move (operands); DONE;")
2657 (define_split
2658   [(set (match_operand:DI 0 "sse_reg_operand")
2659         (match_operand:DI 1 "general_reg_operand"))]
2660   "!TARGET_64BIT && TARGET_SSE4_1
2661    && reload_completed"
2662   [(set (match_dup 2)
2663         (vec_merge:V4SI
2664           (vec_duplicate:V4SI (match_dup 3))
2665           (match_dup 2)
2666           (const_int 2)))]
2668   operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2669   operands[3] = gen_highpart (SImode, operands[1]);
2671   emit_move_insn (gen_lowpart (SImode, operands[0]),
2672                   gen_lowpart (SImode, operands[1]));
2675 ;; movabsq $0x0012345678000000, %rax is longer
2676 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2677 (define_peephole2
2678   [(set (match_operand:DI 0 "register_operand")
2679         (match_operand:DI 1 "const_int_operand"))]
2680   "TARGET_64BIT
2681    && optimize_insn_for_size_p ()
2682    && LEGACY_INT_REG_P (operands[0])
2683    && !x86_64_immediate_operand (operands[1], DImode)
2684    && !x86_64_zext_immediate_operand (operands[1], DImode)
2685    && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2686         & ~(HOST_WIDE_INT) 0xffffffff)
2687    && peep2_regno_dead_p (0, FLAGS_REG)"
2688   [(set (match_dup 0) (match_dup 1))
2689    (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2690               (clobber (reg:CC FLAGS_REG))])]
2692   int shift = ctz_hwi (UINTVAL (operands[1]));
2693   operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2694   operands[2] = gen_int_mode (shift, QImode);
2697 (define_insn "*movsi_internal"
2698   [(set (match_operand:SI 0 "nonimmediate_operand"
2699     "=r,m ,*y,*y,?*y,?m,?r,?*y,?Yv,?v,?v,m ,?r,?v,*k,*k  ,*rm,*k")
2700         (match_operand:SI 1 "general_operand"
2701     "g ,re,C ,*y,Bk ,*y,*y,r  ,C  ,?v,Bk,?v,?v,r  ,*r,*kBk,*k ,CBC"))]
2702   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2703    && ix86_hardreg_mov_ok (operands[0], operands[1])"
2705   switch (get_attr_type (insn))
2706     {
2707     case TYPE_SSELOG1:
2708       return standard_sse_constant_opcode (insn, operands);
2710     case TYPE_MSKMOV:
2711       return "kmovd\t{%1, %0|%0, %1}";
2713     case TYPE_MSKLOG:
2714       if (operands[1] == const0_rtx)
2715         return "kxord\t%0, %0, %0";
2716       else if (operands[1] == constm1_rtx)
2717         return "kxnord\t%0, %0, %0";
2718       gcc_unreachable ();
2720     case TYPE_SSEMOV:
2721       return ix86_output_ssemov (insn, operands);
2723     case TYPE_MMX:
2724       return "pxor\t%0, %0";
2726     case TYPE_MMXMOV:
2727       switch (get_attr_mode (insn))
2728         {
2729         case MODE_DI:
2730           return "movq\t{%1, %0|%0, %1}";
2731         case MODE_SI:
2732           return "movd\t{%1, %0|%0, %1}";
2734         default:
2735           gcc_unreachable ();
2736         }
2738     case TYPE_LEA:
2739       return "lea{l}\t{%E1, %0|%0, %E1}";
2741     case TYPE_IMOV:
2742       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2743       if (ix86_use_lea_for_mov (insn, operands))
2744         return "lea{l}\t{%E1, %0|%0, %E1}";
2745       else
2746         return "mov{l}\t{%1, %0|%0, %1}";
2748     default:
2749       gcc_unreachable ();
2750     }
2752   [(set (attr "isa")
2753      (cond [(eq_attr "alternative" "12,13")
2754               (const_string "sse2")
2755            ]
2756            (const_string "*")))
2757    (set (attr "type")
2758      (cond [(eq_attr "alternative" "2")
2759               (const_string "mmx")
2760             (eq_attr "alternative" "3,4,5,6,7")
2761               (const_string "mmxmov")
2762             (eq_attr "alternative" "8")
2763               (const_string "sselog1")
2764             (eq_attr "alternative" "9,10,11,12,13")
2765               (const_string "ssemov")
2766             (eq_attr "alternative" "14,15,16")
2767               (const_string "mskmov")
2768             (eq_attr "alternative" "17")
2769               (const_string "msklog")
2770             (and (match_operand 0 "register_operand")
2771                  (match_operand 1 "pic_32bit_operand"))
2772               (const_string "lea")
2773            ]
2774            (const_string "imov")))
2775    (set (attr "prefix")
2776      (if_then_else (eq_attr "type" "sselog1,ssemov")
2777        (const_string "maybe_vex")
2778        (const_string "orig")))
2779    (set (attr "prefix_data16")
2780      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2781        (const_string "1")
2782        (const_string "*")))
2783    (set (attr "mode")
2784      (cond [(eq_attr "alternative" "2,3")
2785               (const_string "DI")
2786             (eq_attr "alternative" "8")
2787               (cond [(match_test "TARGET_AVX")
2788                        (const_string "TI")
2789                      (ior (not (match_test "TARGET_SSE2"))
2790                           (match_test "optimize_function_for_size_p (cfun)"))
2791                        (const_string "V4SF")
2792                     ]
2793                     (const_string "TI"))
2794             (eq_attr "alternative" "9")
2795               (cond [(match_test "TARGET_AVX512VL")
2796                        (const_string "TI")
2797                      (match_test "TARGET_AVX512F")
2798                        (const_string "SF")
2799                      (match_test "TARGET_AVX")
2800                        (const_string "TI")
2801                      (ior (not (match_test "TARGET_SSE2"))
2802                           (match_test "optimize_function_for_size_p (cfun)"))
2803                        (const_string "V4SF")
2804                     ]
2805                     (const_string "TI"))
2807             (and (eq_attr "alternative" "10,11")
2808                  (not (match_test "TARGET_SSE2")))
2809               (const_string "SF")
2810            ]
2811            (const_string "SI")))
2812    (set (attr "preferred_for_speed")
2813      (cond [(eq_attr "alternative" "6,12")
2814               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2815             (eq_attr "alternative" "7,13")
2816               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2817            ]
2818            (symbol_ref "true")))])
2820 ;; With -Oz, transform mov $imm,reg to the shorter push $imm; pop reg.
2821 (define_peephole2
2822   [(set (match_operand:SWI248 0 "general_reg_operand")
2823         (match_operand:SWI248 1 "const_int_operand"))]
2824   "optimize_insn_for_size_p () && optimize_size > 1
2825    && operands[1] != const0_rtx
2826    && IN_RANGE (INTVAL (operands[1]), -128, 127)
2827    && !ix86_red_zone_used
2828    && REGNO (operands[0]) != SP_REG"
2829   [(set (match_dup 2) (match_dup 1))
2830    (set (match_dup 0) (match_dup 3))]
2832   if (GET_MODE (operands[0]) != word_mode)
2833     operands[0] = gen_rtx_REG (word_mode, REGNO (operands[0]));
2835   operands[2] = gen_rtx_MEM (word_mode,
2836                              gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
2837   operands[3] = gen_rtx_MEM (word_mode,
2838                              gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2841 ;; With -Oz, transform mov $0,mem to the shorter and $0,mem.
2842 ;; Likewise, transform mov $-1,mem to the shorter or $-1,mem.
2843 (define_peephole2
2844   [(set (match_operand:SWI248 0 "memory_operand")
2845         (match_operand:SWI248 1 "const_int_operand"))]
2846   "(operands[1] == const0_rtx || operands[1] == constm1_rtx)
2847    && optimize_insn_for_size_p () && optimize_size > 1
2848    && peep2_regno_dead_p (0, FLAGS_REG)"
2849   [(parallel [(set (match_dup 0) (match_dup 1))
2850               (clobber (reg:CC FLAGS_REG))])])
2852 (define_insn "*movhi_internal"
2853   [(set (match_operand:HI 0 "nonimmediate_operand"
2854     "=r,r,r,m ,*k,*k ,r ,m ,*k ,?r,?*v,*Yv,*v,*v,jm,m")
2855         (match_operand:HI 1 "general_operand"
2856     "r ,n,m,rn,r ,*km,*k,*k,CBC,*v,r  ,C  ,*v,m ,*x,*v"))]
2857   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2858    && ix86_hardreg_mov_ok (operands[0], operands[1])"
2860   switch (get_attr_type (insn))
2861     {
2862     case TYPE_IMOVX:
2863       /* movzwl is faster than movw on p2 due to partial word stalls,
2864          though not as fast as an aligned movl.  */
2865       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2867     case TYPE_MSKMOV:
2868       switch (which_alternative)
2869         {
2870         case 4:
2871           return "kmovw\t{%k1, %0|%0, %k1}";
2872         case 6:
2873           return "kmovw\t{%1, %k0|%k0, %1}";
2874         case 5:
2875         case 7:
2876           return "kmovw\t{%1, %0|%0, %1}";
2877         default:
2878           gcc_unreachable ();
2879         }
2881     case TYPE_SSEMOV:
2882       return ix86_output_ssemov (insn, operands);
2884     case TYPE_SSELOG1:
2885       if (satisfies_constraint_C (operands[1]))
2886         return standard_sse_constant_opcode (insn, operands);
2888       if (SSE_REG_P (operands[0]))
2889         return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
2890       else
2891         return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
2893     case TYPE_MSKLOG:
2894       if (operands[1] == const0_rtx)
2895         return "kxorw\t%0, %0, %0";
2896       else if (operands[1] == constm1_rtx)
2897         return "kxnorw\t%0, %0, %0";
2898       gcc_unreachable ();
2900     default:
2901       if (get_attr_mode (insn) == MODE_SI)
2902         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2903       else
2904         return "mov{w}\t{%1, %0|%0, %1}";
2905     }
2907   [(set (attr "isa")
2908         (cond [(eq_attr "alternative" "9,10,11,12,13")
2909                   (const_string "sse2")
2910                (eq_attr "alternative" "14")
2911                   (const_string "sse4_noavx")
2912                (eq_attr "alternative" "15")
2913                   (const_string "avx")
2914                ]
2915                (const_string "*")))
2916    (set (attr "addr")
2917         (if_then_else (eq_attr "alternative" "14")
2918                       (const_string "gpr16")
2919                       (const_string "*")))
2920    (set (attr "type")
2921      (cond [(eq_attr "alternative" "4,5,6,7")
2922               (const_string "mskmov")
2923             (eq_attr "alternative" "8")
2924               (const_string "msklog")
2925             (eq_attr "alternative" "13,14,15")
2926               (if_then_else (match_test "TARGET_AVX512FP16")
2927                 (const_string "ssemov")
2928                 (const_string "sselog1"))
2929             (eq_attr "alternative" "11")
2930               (const_string "sselog1")
2931             (eq_attr "alternative" "9,10,12")
2932               (const_string "ssemov")
2933             (match_test "optimize_function_for_size_p (cfun)")
2934               (const_string "imov")
2935             (and (eq_attr "alternative" "0")
2936                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2937                       (not (match_test "TARGET_HIMODE_MATH"))))
2938               (const_string "imov")
2939             (and (eq_attr "alternative" "1,2")
2940                  (match_operand:HI 1 "aligned_operand"))
2941               (const_string "imov")
2942             (and (match_test "TARGET_MOVX")
2943                  (eq_attr "alternative" "0,2"))
2944               (const_string "imovx")
2945            ]
2946            (const_string "imov")))
2947    (set (attr "prefix")
2948         (cond [(eq_attr "alternative" "4,5,6,7,8")
2949                  (const_string "vex")
2950                (eq_attr "alternative" "9,10,11,12,13,14,15")
2951                  (const_string "maybe_evex")
2952               ]
2953               (const_string "orig")))
2954    (set (attr "mode")
2955      (cond [(eq_attr "alternative" "9,10")
2956               (if_then_else (match_test "TARGET_AVX512FP16")
2957                 (const_string "HI")
2958                 (const_string "SI"))
2959             (eq_attr "alternative" "13,14,15")
2960               (if_then_else (match_test "TARGET_AVX512FP16")
2961                 (const_string "HI")
2962                 (const_string "TI"))
2963             (eq_attr "alternative" "11")
2964               (cond [(match_test "TARGET_AVX")
2965                        (const_string "TI")
2966                      (ior (not (match_test "TARGET_SSE2"))
2967                           (match_test "optimize_function_for_size_p (cfun)"))
2968                        (const_string "V4SF")
2969                     ]
2970                     (const_string "TI"))
2971             (eq_attr "alternative" "12")
2972               (cond [(match_test "TARGET_AVX512VL")
2973                        (const_string "TI")
2974                      (match_test "TARGET_AVX512FP16")
2975                        (const_string "HF")
2976                      (match_test "TARGET_AVX512F")
2977                        (const_string "SF")
2978                      (match_test "TARGET_AVX")
2979                        (const_string "TI")
2980                      (ior (not (match_test "TARGET_SSE2"))
2981                           (match_test "optimize_function_for_size_p (cfun)"))
2982                        (const_string "V4SF")
2983                     ]
2984                     (const_string "TI"))
2985             (eq_attr "type" "imovx")
2986               (const_string "SI")
2987             (and (eq_attr "alternative" "1,2")
2988                  (match_operand:HI 1 "aligned_operand"))
2989               (const_string "SI")
2990             (and (eq_attr "alternative" "0")
2991                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2992                       (not (match_test "TARGET_HIMODE_MATH"))))
2993               (const_string "SI")
2994             ]
2995             (const_string "HI")))
2996    (set (attr "preferred_for_speed")
2997      (cond [(eq_attr "alternative" "9")
2998               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2999             (eq_attr "alternative" "10")
3000               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3001            ]
3002            (symbol_ref "true")))])
3004 ;; Situation is quite tricky about when to choose full sized (SImode) move
3005 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
3006 ;; partial register dependency machines (such as AMD Athlon), where QImode
3007 ;; moves issue extra dependency and for partial register stalls machines
3008 ;; that don't use QImode patterns (and QImode move cause stall on the next
3009 ;; instruction).
3011 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
3012 ;; register stall machines with, where we use QImode instructions, since
3013 ;; partial register stall can be caused there.  Then we use movzx.
3015 (define_insn "*movqi_internal"
3016   [(set (match_operand:QI 0 "nonimmediate_operand"
3017                         "=Q,R,r,q,q,r,r ,?r,m ,*k,*k,*r,*m,*k,*k,*k")
3018         (match_operand:QI 1 "general_operand"
3019                         "Q ,R,r,n,m,q,rn, m,qn,*r,*k,*k,*k,*m,C,BC"))]
3020   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3021    && ix86_hardreg_mov_ok (operands[0], operands[1])"
3024   char buf[128];
3025   const char *ops;
3026   const char *suffix;
3028   switch (get_attr_type (insn))
3029     {
3030     case TYPE_IMOVX:
3031       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
3032       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
3034     case TYPE_MSKMOV:
3035       switch (which_alternative)
3036         {
3037         case 9:
3038           ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
3039           break;
3040         case 11:
3041           ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
3042           break;
3043         case 12:
3044         case 13:
3045           gcc_assert (TARGET_AVX512DQ);
3046           /* FALLTHRU */
3047         case 10:
3048           ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
3049           break;
3050         default:
3051           gcc_unreachable ();
3052         }
3054       suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
3056       snprintf (buf, sizeof (buf), ops, suffix);
3057       output_asm_insn (buf, operands);
3058       return "";
3060     case TYPE_MSKLOG:
3061       if (operands[1] == const0_rtx)
3062         {
3063           if (get_attr_mode (insn) == MODE_HI)
3064             return "kxorw\t%0, %0, %0";
3065           else
3066             return "kxorb\t%0, %0, %0";
3067         }
3068       else if (operands[1] == constm1_rtx)
3069         {
3070           gcc_assert (TARGET_AVX512DQ);
3071           return "kxnorb\t%0, %0, %0";
3072         }
3073       gcc_unreachable ();
3075     default:
3076       if (get_attr_mode (insn) == MODE_SI)
3077         return "mov{l}\t{%k1, %k0|%k0, %k1}";
3078       else
3079         return "mov{b}\t{%1, %0|%0, %1}";
3080     }
3082   [(set (attr "isa")
3083      (cond [(eq_attr "alternative" "1,2")
3084               (const_string "x64")
3085             (eq_attr "alternative" "12,13,15")
3086               (const_string "avx512dq")
3087            ]
3088            (const_string "*")))
3089    (set (attr "type")
3090      (cond [(eq_attr "alternative" "9,10,11,12,13")
3091               (const_string "mskmov")
3092             (eq_attr "alternative" "14,15")
3093               (const_string "msklog")
3094             (and (eq_attr "alternative" "7")
3095                  (not (match_operand:QI 1 "aligned_operand")))
3096               (const_string "imovx")
3097             (match_test "optimize_function_for_size_p (cfun)")
3098               (const_string "imov")
3099             (and (eq_attr "alternative" "5")
3100                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
3101                       (not (match_test "TARGET_QIMODE_MATH"))))
3102               (const_string "imov")
3103             (eq_attr "alternative" "5,7")
3104               (const_string "imovx")
3105             (and (match_test "TARGET_MOVX")
3106                  (eq_attr "alternative" "4"))
3107               (const_string "imovx")
3108            ]
3109            (const_string "imov")))
3110    (set (attr "prefix")
3111      (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15")
3112        (const_string "vex")
3113        (const_string "orig")))
3114    (set (attr "mode")
3115       (cond [(eq_attr "alternative" "5,6,7")
3116                (const_string "SI")
3117              (eq_attr "alternative" "8")
3118                (const_string "QI")
3119              (and (eq_attr "alternative" "9,10,11,14")
3120                   (not (match_test "TARGET_AVX512DQ")))
3121                (const_string "HI")
3122              (eq_attr "type" "imovx")
3123                (const_string "SI")
3124              ;; For -Os, 8-bit immediates are always shorter than 32-bit
3125              ;; ones.
3126              (and (eq_attr "type" "imov")
3127                   (and (eq_attr "alternative" "3")
3128                        (match_test "optimize_function_for_size_p (cfun)")))
3129                (const_string "QI")
3130              ;; For -Os, movl where one or both operands are NON_Q_REGS
3131              ;; and both are LEGACY_REGS is shorter than movb.
3132              ;; Otherwise movb and movl sizes are the same, so decide purely
3133              ;; based on speed factors.
3134              (and (eq_attr "type" "imov")
3135                   (and (eq_attr "alternative" "1")
3136                        (match_test "optimize_function_for_size_p (cfun)")))
3137                (const_string "SI")
3138              (and (eq_attr "type" "imov")
3139                   (and (eq_attr "alternative" "0,1,2,3")
3140                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
3141                             (not (match_test "TARGET_PARTIAL_REG_STALL")))))
3142                (const_string "SI")
3143              ;; Avoid partial register stalls when not using QImode arithmetic
3144              (and (eq_attr "type" "imov")
3145                   (and (eq_attr "alternative" "0,1,2,3")
3146                        (and (match_test "TARGET_PARTIAL_REG_STALL")
3147                             (not (match_test "TARGET_QIMODE_MATH")))))
3148                (const_string "SI")
3149            ]
3150            (const_string "QI")))])
3152 /* Reload dislikes loading 0/-1 directly into mask registers.
3153    Try to tidy things up here.  */
3154 (define_peephole2
3155   [(set (match_operand:SWI 0 "general_reg_operand")
3156         (match_operand:SWI 1 "immediate_operand"))
3157    (set (match_operand:SWI 2 "mask_reg_operand")
3158         (match_dup 0))]
3159   "peep2_reg_dead_p (2, operands[0])
3160    && (const0_operand (operands[1], <MODE>mode)
3161        || (constm1_operand (operands[1], <MODE>mode)
3162            && (<MODE_SIZE> > 1 || TARGET_AVX512DQ)))"
3163   [(set (match_dup 2) (match_dup 1))])
3165 ;; Stores and loads of ax to arbitrary constant address.
3166 ;; We fake an second form of instruction to force reload to load address
3167 ;; into register when rax is not available
3168 (define_insn "*movabs<mode>_1"
3169   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
3170         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
3171   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
3173   /* Recover the full memory rtx.  */
3174   operands[0] = SET_DEST (PATTERN (insn));
3175   switch (which_alternative)
3176     {
3177     case 0:
3178       return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
3179     case 1:
3180       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3181     default:
3182       gcc_unreachable ();
3183     }
3185   [(set_attr "type" "imov")
3186    (set_attr "modrm" "0,*")
3187    (set_attr "length_address" "8,0")
3188    (set_attr "length_immediate" "0,*")
3189    (set_attr "memory" "store")
3190    (set_attr "mode" "<MODE>")])
3192 (define_insn "*movabs<mode>_2"
3193   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
3194         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
3195   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
3197   /* Recover the full memory rtx.  */
3198   operands[1] = SET_SRC (PATTERN (insn));
3199   switch (which_alternative)
3200     {
3201     case 0:
3202       return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
3203     case 1:
3204       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3205     default:
3206       gcc_unreachable ();
3207     }
3209   [(set_attr "type" "imov")
3210    (set_attr "modrm" "0,*")
3211    (set_attr "length_address" "8,0")
3212    (set_attr "length_immediate" "0")
3213    (set_attr "memory" "load")
3214    (set_attr "mode" "<MODE>")])
3216 (define_insn "swap<mode>"
3217   [(set (match_operand:SWI48 0 "register_operand" "+r")
3218         (match_operand:SWI48 1 "register_operand" "+r"))
3219    (set (match_dup 1)
3220         (match_dup 0))]
3221   ""
3222   "xchg{<imodesuffix>}\t%1, %0"
3223   [(set_attr "type" "imov")
3224    (set_attr "mode" "<MODE>")
3225    (set_attr "pent_pair" "np")
3226    (set_attr "athlon_decode" "vector")
3227    (set_attr "amdfam10_decode" "double")
3228    (set_attr "bdver1_decode" "double")])
3230 (define_insn "*swap<mode>"
3231   [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
3232         (match_operand:SWI12 1 "register_operand" "+<r>,r"))
3233    (set (match_dup 1)
3234         (match_dup 0))]
3235   ""
3236   "@
3237    xchg{<imodesuffix>}\t%1, %0
3238    xchg{l}\t%k1, %k0"
3239   [(set_attr "type" "imov")
3240    (set_attr "mode" "<MODE>,SI")
3241    (set (attr "preferred_for_size")
3242      (cond [(eq_attr "alternative" "0")
3243               (symbol_ref "false")]
3244            (symbol_ref "true")))
3245    ;; Potential partial reg stall on alternative 1.
3246    (set (attr "preferred_for_speed")
3247      (cond [(eq_attr "alternative" "1")
3248               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
3249            (symbol_ref "true")))
3250    (set_attr "pent_pair" "np")
3251    (set_attr "athlon_decode" "vector")
3252    (set_attr "amdfam10_decode" "double")
3253    (set_attr "bdver1_decode" "double")])
3255 (define_peephole2
3256   [(set (match_operand:SWI 0 "general_reg_operand")
3257         (match_operand:SWI 1 "general_reg_operand"))
3258    (set (match_dup 1)
3259         (match_operand:SWI 2 "general_reg_operand"))
3260    (set (match_dup 2) (match_dup 0))]
3261   "peep2_reg_dead_p (3, operands[0])
3262    && optimize_insn_for_size_p ()"
3263   [(parallel [(set (match_dup 1) (match_dup 2))
3264               (set (match_dup 2) (match_dup 1))])])
3266 ;; Convert xchg with a REG_UNUSED note to a mov (variant #1).
3267 (define_peephole2
3268   [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3269                    (match_operand:SWI 1 "general_reg_operand"))
3270               (set (match_dup 1) (match_dup 0))])]
3271   "((REGNO (operands[0]) != AX_REG
3272      && REGNO (operands[1]) != AX_REG)
3273     || optimize_size < 2
3274     || !optimize_insn_for_size_p ())
3275    && peep2_reg_dead_p (1, operands[0])"
3276   [(set (match_dup 1) (match_dup 0))])
3278 ;; Convert xchg with a REG_UNUSED note to a mov (variant #2).
3279 (define_peephole2
3280   [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3281                    (match_operand:SWI 1 "general_reg_operand"))
3282               (set (match_dup 1) (match_dup 0))])]
3283   "((REGNO (operands[0]) != AX_REG
3284      && REGNO (operands[1]) != AX_REG)
3285     || optimize_size < 2
3286     || !optimize_insn_for_size_p ())
3287    && peep2_reg_dead_p (1, operands[1])"
3288   [(set (match_dup 0) (match_dup 1))])
3290 ;; Convert moves to/from AX_REG into xchg with -Oz.
3291 (define_peephole2
3292   [(set (match_operand:SWI48 0 "general_reg_operand")
3293         (match_operand:SWI48 1 "general_reg_operand"))]
3294  "optimize_size > 1
3295   && ((REGNO (operands[0]) == AX_REG)
3296       != (REGNO (operands[1]) == AX_REG))
3297   && optimize_insn_for_size_p ()
3298   && peep2_reg_dead_p (1, operands[1])"
3299   [(parallel [(set (match_dup 0) (match_dup 1))
3300               (set (match_dup 1) (match_dup 0))])])
3302 (define_expand "movstrict<mode>"
3303   [(set (strict_low_part (match_operand:SWI12 0 "register_operand"))
3304         (match_operand:SWI12 1 "general_operand"))]
3305   ""
3307   gcc_assert (SUBREG_P (operands[0]));
3308   if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
3309       || !VALID_INT_MODE_P (GET_MODE (SUBREG_REG (operands[0]))))
3310     FAIL;
3313 (define_insn "*movstrict<mode>_1"
3314   [(set (strict_low_part
3315           (match_operand:SWI12 0 "register_operand" "+<r>"))
3316         (match_operand:SWI12 1 "general_operand" "<r>mn"))]
3317   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
3318   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
3319   [(set_attr "type" "imov")
3320    (set_attr "mode" "<MODE>")])
3322 (define_insn "*movstrict<mode>_xor"
3323   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
3324         (match_operand:SWI12 1 "const0_operand"))
3325    (clobber (reg:CC FLAGS_REG))]
3326   "reload_completed"
3327   "xor{<imodesuffix>}\t%0, %0"
3328   [(set_attr "type" "alu1")
3329    (set_attr "mode" "<MODE>")
3330    (set_attr "length_immediate" "0")])
3332 (define_expand "extv<mode>"
3333   [(set (match_operand:SWI24 0 "register_operand")
3334         (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
3335                             (match_operand:QI 2 "const_int_operand")
3336                             (match_operand:QI 3 "const_int_operand")))]
3337   ""
3339   /* Handle extractions from %ah et al.  */
3340   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3341     FAIL;
3343   unsigned int regno = reg_or_subregno (operands[1]);
3345   /* Be careful to expand only with registers having upper parts.  */
3346   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3347     operands[1] = copy_to_reg (operands[1]);
3350 (define_insn "*extv<mode>"
3351   [(set (match_operand:SWI24 0 "register_operand" "=R")
3352         (sign_extract:SWI24 (match_operand 1 "int248_register_operand" "Q")
3353                             (const_int 8)
3354                             (const_int 8)))]
3355   ""
3356   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
3357   [(set_attr "type" "imovx")
3358    (set_attr "mode" "SI")])
3360 ;; Split sign-extension of single least significant bit as and x,$1;neg x
3361 (define_insn_and_split "*extv<mode>_1_0"
3362   [(set (match_operand:SWI48 0 "register_operand" "=r")
3363         (sign_extract:SWI48 (match_operand:SWI48 1 "register_operand" "0")
3364                             (const_int 1)
3365                             (const_int 0)))
3366    (clobber (reg:CC FLAGS_REG))]
3367   ""
3368   "#"
3369   ""
3370   [(parallel [(set (match_dup 0) (and:SWI48 (match_dup 1) (const_int 1)))
3371               (clobber (reg:CC FLAGS_REG))])
3372    (parallel [(set (match_dup 0) (neg:SWI48 (match_dup 0)))
3373               (clobber (reg:CC FLAGS_REG))])])
3375 (define_expand "extzv<mode>"
3376   [(set (match_operand:SWI248 0 "register_operand")
3377         (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
3378                              (match_operand:QI 2 "const_int_operand")
3379                              (match_operand:QI 3 "const_int_operand")))]
3380   ""
3382   if (ix86_expand_pextr (operands))
3383     DONE;
3385   /* Handle extractions from %ah et al.  */
3386   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3387     FAIL;
3389   unsigned int regno = reg_or_subregno (operands[1]);
3391   /* Be careful to expand only with registers having upper parts.  */
3392   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3393     operands[1] = copy_to_reg (operands[1]);
3396 (define_insn "*extzv<mode>"
3397   [(set (match_operand:SWI248 0 "register_operand" "=R")
3398         (zero_extract:SWI248 (match_operand 1 "int248_register_operand" "Q")
3399                              (const_int 8)
3400                              (const_int 8)))]
3401   ""
3402   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
3403   [(set_attr "type" "imovx")
3404    (set_attr "mode" "SI")])
3406 (define_insn "*extzvqi"
3407   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn,?R")
3408         (subreg:QI
3409           (match_operator:SWI248 2 "extract_operator"
3410             [(match_operand 1 "int248_register_operand" "Q,Q")
3411              (const_int 8)
3412              (const_int 8)]) 0))]
3413   ""
3415   switch (get_attr_type (insn))
3416     {
3417     case TYPE_IMOVX:
3418       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
3419     default:
3420       return "mov{b}\t{%h1, %0|%0, %h1}";
3421     }
3423   [(set_attr "addr" "gpr8,*")
3424    (set (attr "type")
3425      (if_then_else (and (match_operand:QI 0 "register_operand")
3426                         (ior (not (match_operand:QI 0 "QIreg_operand"))
3427                              (match_test "TARGET_MOVX")))
3428         (const_string "imovx")
3429         (const_string "imov")))
3430    (set (attr "mode")
3431      (if_then_else (eq_attr "type" "imovx")
3432         (const_string "SI")
3433         (const_string "QI")))])
3435 (define_expand "insv<mode>"
3436   [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3437                              (match_operand:QI 1 "const_int_operand")
3438                              (match_operand:QI 2 "const_int_operand"))
3439         (match_operand:SWI248 3 "register_operand"))]
3440   ""
3442   rtx dst;
3444   if (ix86_expand_pinsr (operands))
3445     DONE;
3447   /* Handle insertions to %ah et al.  */
3448   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3449     FAIL;
3451   unsigned int regno = reg_or_subregno (operands[0]);
3453   /* Be careful to expand only with registers having upper parts.  */
3454   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3455     dst = copy_to_reg (operands[0]);
3456   else
3457     dst = operands[0];
3459   emit_insn (gen_insv_1 (<MODE>mode, dst, operands[3]));
3461   /* Fix up the destination if needed.  */
3462   if (dst != operands[0])
3463     emit_move_insn (operands[0], dst);
3465   DONE;
3468 (define_insn "@insv<mode>_1"
3469   [(set (zero_extract:SWI248
3470           (match_operand 0 "int248_register_operand" "+Q")
3471           (const_int 8)
3472           (const_int 8))
3473         (match_operand:SWI248 1 "general_operand" "QnBn"))]
3474   ""
3476   if (CONST_INT_P (operands[1]))
3477     operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3478   return "mov{b}\t{%b1, %h0|%h0, %b1}";
3480   [(set_attr "addr" "gpr8")
3481    (set_attr "type" "imov")
3482    (set_attr "mode" "QI")])
3484 (define_insn "*insvqi_1"
3485   [(set (zero_extract:SWI248
3486           (match_operand 0 "int248_register_operand" "+Q")
3487           (const_int 8)
3488           (const_int 8))
3489         (subreg:SWI248
3490           (match_operand:QI 1 "general_operand" "QnBn") 0))]
3491   ""
3492   "mov{b}\t{%1, %h0|%h0, %1}"
3493   [(set_attr "addr" "gpr8")
3494    (set_attr "type" "imov")
3495    (set_attr "mode" "QI")])
3497 ;; Eliminate redundant insv, e.g. xorl %eax,%eax; movb $0, %ah
3498 (define_peephole2
3499   [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3500                    (const_int 0))
3501               (clobber (reg:CC FLAGS_REG))])
3502    (set (zero_extract:SWI248 (match_operand 1 "int248_register_operand")
3503                              (const_int 8)
3504                              (const_int 8))
3505         (const_int 0))]
3506   "REGNO (operands[0]) == REGNO (operands[1])"
3507   [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3508                    (const_int 0))
3509               (clobber (reg:CC FLAGS_REG))])])
3511 ;; Combine movl followed by movb.
3512 (define_peephole2
3513   [(set (match_operand:SWI48 0 "general_reg_operand")
3514         (match_operand:SWI48 1 "const_int_operand"))
3515    (set (zero_extract:SWI248 (match_operand 2 "int248_register_operand")
3516                              (const_int 8)
3517                              (const_int 8))
3518         (match_operand:SWI248 3 "const_int_operand"))]
3519   "REGNO (operands[0]) == REGNO (operands[2])"
3520   [(set (match_operand:SWI48 0 "general_reg_operand")
3521         (match_dup 4))]
3523   HOST_WIDE_INT tmp = INTVAL (operands[1]) & ~(HOST_WIDE_INT)0xff00;
3524   tmp |= (INTVAL (operands[3]) & 0xff) << 8;
3525   operands[4] = gen_int_mode (tmp, <SWI48:MODE>mode);
3528 (define_insn "*insvqi_2"
3529   [(set (zero_extract:SWI248
3530           (match_operand 0 "int248_register_operand" "+Q")
3531           (const_int 8)
3532           (const_int 8))
3533         (match_operator:SWI248 2 "extract_operator"
3534           [(match_operand 1 "int248_register_operand" "Q")
3535            (const_int 8)
3536            (const_int 8)]))]
3537   ""
3538   "mov{b}\t{%h1, %h0|%h0, %h1}"
3539   [(set_attr "type" "imov")
3540    (set_attr "mode" "QI")])
3542 (define_insn "*insvqi_3"
3543   [(set (zero_extract:SWI248
3544           (match_operand 0 "int248_register_operand" "+Q")
3545           (const_int 8)
3546           (const_int 8))
3547         (any_shiftrt:SWI248
3548           (match_operand:SWI248 1 "register_operand" "Q")
3549           (const_int 8)))]
3550   ""
3551   "mov{b}\t{%h1, %h0|%h0, %h1}"
3552   [(set_attr "type" "imov")
3553    (set_attr "mode" "QI")])
3555 (define_code_iterator any_or_plus [plus ior xor])
3557 (define_insn_and_split "*insvti_highpart_1"
3558   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3559         (any_or_plus:TI
3560           (and:TI
3561             (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3562             (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3563           (ashift:TI
3564             (zero_extend:TI
3565               (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))
3566             (const_int 64))))]
3567   "TARGET_64BIT
3568    && CONST_WIDE_INT_P (operands[3])
3569    && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3570    && CONST_WIDE_INT_ELT (operands[3], 0) == -1
3571    && CONST_WIDE_INT_ELT (operands[3], 1) == 0"
3572   "#"
3573   "&& reload_completed"
3574   [(const_int 0)]
3576   operands[4] = gen_lowpart (DImode, operands[1]);
3577   split_double_concat (TImode, operands[0], operands[4], operands[2]);
3578   DONE;
3581 (define_insn_and_split "*insvti_lowpart_1"
3582   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3583         (any_or_plus:TI
3584           (and:TI
3585             (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3586             (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3587           (zero_extend:TI
3588             (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))))]
3589   "TARGET_64BIT
3590    && CONST_WIDE_INT_P (operands[3])
3591    && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3592    && CONST_WIDE_INT_ELT (operands[3], 0) == 0
3593    && CONST_WIDE_INT_ELT (operands[3], 1) == -1"
3594   "#"
3595   "&& reload_completed"
3596   [(const_int 0)]
3598   operands[4] = gen_highpart (DImode, operands[1]);
3599   split_double_concat (TImode, operands[0], operands[2], operands[4]);
3600   DONE;
3603 (define_insn_and_split "*insvdi_lowpart_1"
3604   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,r,r,&r")
3605         (any_or_plus:DI
3606           (and:DI
3607             (match_operand:DI 1 "nonimmediate_operand" "r,m,r,m")
3608             (match_operand:DI 3 "const_int_operand" "n,n,n,n"))
3609           (zero_extend:DI
3610             (match_operand:SI 2 "nonimmediate_operand" "r,r,m,m"))))]
3611   "!TARGET_64BIT
3612    && CONST_INT_P (operands[3])
3613    && UINTVAL (operands[3]) == 0xffffffff00000000ll"
3614   "#"
3615   "&& reload_completed"
3616   [(const_int 0)]
3618   operands[4] = gen_highpart (SImode, operands[1]);
3619   split_double_concat (DImode, operands[0], operands[2], operands[4]);
3620   DONE;
3623 ;; Floating point push instructions.
3625 (define_insn "*pushtf"
3626   [(set (match_operand:TF 0 "push_operand" "=<,<")
3627         (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3628   "TARGET_64BIT || TARGET_SSE"
3630   /* This insn should be already split before reg-stack.  */
3631   return "#";
3633   [(set_attr "isa" "*,x64")
3634    (set_attr "type" "multi")
3635    (set_attr "unit" "sse,*")
3636    (set_attr "mode" "TF,DI")])
3638 ;; %%% Kill this when call knows how to work this out.
3639 (define_split
3640   [(set (match_operand:TF 0 "push_operand")
3641         (match_operand:TF 1 "sse_reg_operand"))]
3642   "TARGET_SSE && reload_completed"
3643   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3644    (set (match_dup 0) (match_dup 1))]
3646   /* Preserve memory attributes. */
3647   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3650 (define_insn "*pushxf"
3651   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3652         (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3653   ""
3655   /* This insn should be already split before reg-stack.  */
3656   return "#";
3658   [(set_attr "isa" "*,*,*,nox64,x64")
3659    (set_attr "type" "multi")
3660    (set_attr "unit" "i387,*,*,*,*")
3661    (set (attr "mode")
3662         (cond [(eq_attr "alternative" "1,2,3,4")
3663                  (if_then_else (match_test "TARGET_64BIT")
3664                    (const_string "DI")
3665                    (const_string "SI"))
3666               ]
3667               (const_string "XF")))
3668    (set (attr "preferred_for_size")
3669      (cond [(eq_attr "alternative" "1")
3670               (symbol_ref "false")]
3671            (symbol_ref "true")))])
3673 ;; %%% Kill this when call knows how to work this out.
3674 (define_split
3675   [(set (match_operand:XF 0 "push_operand")
3676         (match_operand:XF 1 "fp_register_operand"))]
3677   "reload_completed"
3678   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3679    (set (match_dup 0) (match_dup 1))]
3681   operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3682   /* Preserve memory attributes. */
3683   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3686 (define_insn "*pushdf"
3687   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3688         (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,v"))]
3689   ""
3691   /* This insn should be already split before reg-stack.  */
3692   return "#";
3694   [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3695    (set_attr "type" "multi")
3696    (set_attr "unit" "i387,*,*,*,*,sse")
3697    (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3698    (set (attr "preferred_for_size")
3699      (cond [(eq_attr "alternative" "1")
3700               (symbol_ref "false")]
3701            (symbol_ref "true")))
3702    (set (attr "preferred_for_speed")
3703      (cond [(eq_attr "alternative" "1")
3704               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3705            (symbol_ref "true")))])
3706    
3707 ;; %%% Kill this when call knows how to work this out.
3708 (define_split
3709   [(set (match_operand:DF 0 "push_operand")
3710         (match_operand:DF 1 "any_fp_register_operand"))]
3711   "reload_completed"
3712   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3713    (set (match_dup 0) (match_dup 1))]
3715   /* Preserve memory attributes. */
3716   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3719 (define_mode_iterator HFBF [HF BF])
3721 (define_insn "*push<mode>_rex64"
3722   [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3723         (match_operand:HFBF 1 "nonmemory_no_elim_operand" "r,x"))]
3724   "TARGET_64BIT"
3726   /* Anything else should be already split before reg-stack.  */
3727   gcc_assert (which_alternative == 0);
3728   return "push{q}\t%q1";
3730   [(set_attr "isa"  "*,sse4")
3731    (set_attr "type" "push,multi")
3732    (set_attr "mode" "DI,TI")])
3734 (define_insn "*push<mode>"
3735   [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3736         (match_operand:HFBF 1 "general_no_elim_operand" "rmF,x"))]
3737   "!TARGET_64BIT"
3739   /* Anything else should be already split before reg-stack.  */
3740   gcc_assert (which_alternative == 0);
3741   return "push{l}\t%k1";
3743   [(set_attr "isa"  "*,sse4")
3744    (set_attr "type" "push,multi")
3745    (set_attr "mode" "SI,TI")])
3747 (define_insn "push2_di"
3748   [(set (match_operand:TI 0 "push_operand" "=<")
3749         (unspec:TI [(match_operand:DI 1 "register_operand" "r")
3750                     (match_operand:DI 2 "register_operand" "r")]
3751                     UNSPEC_APXPUSH2))]
3752   "TARGET_APX_PUSH2POP2"
3753   "push2\t%1, %2"
3754   [(set_attr "mode" "TI")
3755    (set_attr "type" "multi")
3756    (set_attr "prefix" "evex")])
3758 (define_insn "pop2_di"
3759   [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3760                    (unspec:DI [(match_operand:TI 1 "pop_operand" ">")]
3761                               UNSPEC_APXPOP2_LOW))
3762               (set (match_operand:DI 2 "register_operand" "=r")
3763                    (unspec:DI [(const_int 0)] UNSPEC_APXPOP2_HIGH))])]
3764   "TARGET_APX_PUSH2POP2"
3765   "pop2\t%0, %2"
3766   [(set_attr "mode" "TI")
3767    (set_attr "prefix" "evex")])
3769 (define_insn "*pushsf_rex64"
3770   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3771         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,v"))]
3772   "TARGET_64BIT"
3774   /* Anything else should be already split before reg-stack.  */
3775   if (which_alternative != 1)
3776     return "#";
3777   return "push{q}\t%q1";
3779   [(set_attr "type" "multi,push,multi")
3780    (set_attr "unit" "i387,*,*")
3781    (set_attr "mode" "SF,DI,SF")])
3783 (define_insn "*pushsf"
3784   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3785         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,v"))]
3786   "!TARGET_64BIT"
3788   /* Anything else should be already split before reg-stack.  */
3789   if (which_alternative != 1)
3790     return "#";
3791   return "push{l}\t%1";
3793   [(set_attr "type" "multi,push,multi")
3794    (set_attr "unit" "i387,*,*")
3795    (set_attr "mode" "SF,SI,SF")])
3797 (define_mode_iterator MODESH [SF HF BF])
3798 ;; %%% Kill this when call knows how to work this out.
3799 (define_split
3800   [(set (match_operand:MODESH 0 "push_operand")
3801         (match_operand:MODESH 1 "any_fp_register_operand"))]
3802   "reload_completed"
3803   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3804    (set (match_dup 0) (match_dup 1))]
3806   rtx op = XEXP (operands[0], 0);
3807   if (GET_CODE (op) == PRE_DEC)
3808     {
3809       gcc_assert (!TARGET_64BIT);
3810       op = GEN_INT (-4);
3811     }
3812   else
3813     {
3814       op = XEXP (XEXP (op, 1), 1);
3815       gcc_assert (CONST_INT_P (op));
3816     }
3817   operands[2] = op;
3818   /* Preserve memory attributes. */
3819   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3822 (define_split
3823   [(set (match_operand:SF 0 "push_operand")
3824         (match_operand:SF 1 "memory_operand"))]
3825   "reload_completed
3826    && find_constant_src (insn)"
3827   [(set (match_dup 0) (match_dup 2))]
3828   "operands[2] = find_constant_src (curr_insn);")
3830 (define_split
3831   [(set (match_operand 0 "push_operand")
3832         (match_operand 1 "general_gr_operand"))]
3833   "reload_completed
3834    && (GET_MODE (operands[0]) == TFmode
3835        || GET_MODE (operands[0]) == XFmode
3836        || GET_MODE (operands[0]) == DFmode)"
3837   [(const_int 0)]
3838   "ix86_split_long_move (operands); DONE;")
3840 ;; Floating point move instructions.
3842 (define_expand "movtf"
3843   [(set (match_operand:TF 0 "nonimmediate_operand")
3844         (match_operand:TF 1 "nonimmediate_operand"))]
3845   "TARGET_64BIT || TARGET_SSE"
3846   "ix86_expand_move (TFmode, operands); DONE;")
3848 (define_expand "mov<mode>"
3849   [(set (match_operand:X87MODEFH 0 "nonimmediate_operand")
3850         (match_operand:X87MODEFH 1 "general_operand"))]
3851   ""
3852   "ix86_expand_move (<MODE>mode, operands); DONE;")
3854 (define_insn "*movtf_internal"
3855   [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3856         (match_operand:TF 1 "general_operand"      "C ,vm,v,*roF,*rC"))]
3857   "(TARGET_64BIT || TARGET_SSE)
3858    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3859    && (lra_in_progress || reload_completed
3860        || !CONST_DOUBLE_P (operands[1])
3861        || (standard_sse_constant_p (operands[1], TFmode) == 1
3862            && !memory_operand (operands[0], TFmode))
3863        || (!TARGET_MEMORY_MISMATCH_STALL
3864            && memory_operand (operands[0], TFmode)))"
3866   switch (get_attr_type (insn))
3867     {
3868     case TYPE_SSELOG1:
3869       return standard_sse_constant_opcode (insn, operands);
3871     case TYPE_SSEMOV:
3872       return ix86_output_ssemov (insn, operands);
3874     case TYPE_MULTI:
3875         return "#";
3877     default:
3878       gcc_unreachable ();
3879     }
3881   [(set_attr "isa" "*,*,*,x64,x64")
3882    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3883    (set (attr "prefix")
3884      (if_then_else (eq_attr "type" "sselog1,ssemov")
3885        (const_string "maybe_vex")
3886        (const_string "orig")))
3887    (set (attr "mode")
3888         (cond [(eq_attr "alternative" "3,4")
3889                  (const_string "DI")
3890                (match_test "TARGET_AVX")
3891                  (const_string "TI")
3892                (ior (not (match_test "TARGET_SSE2"))
3893                     (match_test "optimize_function_for_size_p (cfun)"))
3894                  (const_string "V4SF")
3895                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3896                  (const_string "V4SF")
3897                (and (eq_attr "alternative" "2")
3898                     (match_test "TARGET_SSE_TYPELESS_STORES"))
3899                  (const_string "V4SF")
3900                ]
3901                (const_string "TI")))])
3903 (define_split
3904   [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3905         (match_operand:TF 1 "general_gr_operand"))]
3906   "reload_completed"
3907   [(const_int 0)]
3908   "ix86_split_long_move (operands); DONE;")
3910 ;; Possible store forwarding (partial memory) stall
3911 ;; in alternatives 4, 6, 7 and 8.
3912 (define_insn "*movxf_internal"
3913   [(set (match_operand:XF 0 "nonimmediate_operand"
3914          "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r  ,o ,o")
3915         (match_operand:XF 1 "general_operand"
3916          "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3917   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3918    && (lra_in_progress || reload_completed
3919        || !CONST_DOUBLE_P (operands[1])
3920        || ((optimize_function_for_size_p (cfun)
3921             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3922            && standard_80387_constant_p (operands[1]) > 0
3923            && !memory_operand (operands[0], XFmode))
3924        || (!TARGET_MEMORY_MISMATCH_STALL
3925            && memory_operand (operands[0], XFmode))
3926        || !TARGET_HARD_XF_REGS)"
3928   switch (get_attr_type (insn))
3929     {
3930     case TYPE_FMOV:
3931       if (which_alternative == 2)
3932         return standard_80387_constant_opcode (operands[1]);
3933       return output_387_reg_move (insn, operands);
3935     case TYPE_MULTI:
3936       return "#";
3938     default:
3939       gcc_unreachable ();
3940     }
3942   [(set (attr "isa")
3943         (cond [(eq_attr "alternative" "7,10")
3944                  (const_string "nox64")
3945                (eq_attr "alternative" "8,11")
3946                  (const_string "x64")
3947               ]
3948               (const_string "*")))
3949    (set (attr "type")
3950         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3951                  (const_string "multi")
3952               ]
3953               (const_string "fmov")))
3954    (set (attr "mode")
3955         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3956                  (if_then_else (match_test "TARGET_64BIT")
3957                    (const_string "DI")
3958                    (const_string "SI"))
3959               ]
3960               (const_string "XF")))
3961    (set (attr "preferred_for_size")
3962      (cond [(eq_attr "alternative" "3,4")
3963               (symbol_ref "false")]
3964            (symbol_ref "true")))
3965    (set (attr "enabled")
3966      (cond [(eq_attr "alternative" "9,10,11")
3967               (if_then_else
3968                 (match_test "TARGET_HARD_XF_REGS")
3969                 (symbol_ref "false")
3970                 (const_string "*"))
3971             (not (match_test "TARGET_HARD_XF_REGS"))
3972               (symbol_ref "false")
3973            ]
3974            (const_string "*")))])
3975    
3976 (define_split
3977   [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3978         (match_operand:XF 1 "general_gr_operand"))]
3979   "reload_completed"
3980   [(const_int 0)]
3981   "ix86_split_long_move (operands); DONE;")
3983 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3984 (define_insn "*movdf_internal"
3985   [(set (match_operand:DF 0 "nonimmediate_operand"
3986     "=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")
3987         (match_operand:DF 1 "general_operand"
3988     "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"))]
3989   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3990    && (lra_in_progress || reload_completed
3991        || !CONST_DOUBLE_P (operands[1])
3992        || ((optimize_function_for_size_p (cfun)
3993             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3994            && IS_STACK_MODE (DFmode)
3995            && standard_80387_constant_p (operands[1]) > 0
3996            && !memory_operand (operands[0], DFmode))
3997        || (TARGET_SSE2 && TARGET_SSE_MATH
3998            && standard_sse_constant_p (operands[1], DFmode) == 1
3999            && !memory_operand (operands[0], DFmode))
4000        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
4001            && memory_operand (operands[0], DFmode))
4002        || !TARGET_HARD_DF_REGS)"
4004   switch (get_attr_type (insn))
4005     {
4006     case TYPE_FMOV:
4007       if (which_alternative == 2)
4008         return standard_80387_constant_opcode (operands[1]);
4009       return output_387_reg_move (insn, operands);
4011     case TYPE_MULTI:
4012       return "#";
4014     case TYPE_IMOV:
4015       if (get_attr_mode (insn) == MODE_SI)
4016         return "mov{l}\t{%1, %k0|%k0, %1}";
4017       else if (which_alternative == 11)
4018         return "movabs{q}\t{%1, %0|%0, %1}";
4019       else
4020         return "mov{q}\t{%1, %0|%0, %1}";
4022     case TYPE_SSELOG1:
4023       return standard_sse_constant_opcode (insn, operands);
4025     case TYPE_SSEMOV:
4026       return ix86_output_ssemov (insn, operands);
4028     default:
4029       gcc_unreachable ();
4030     }
4032   [(set (attr "isa")
4033         (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
4034                  (const_string "nox64")
4035                (eq_attr "alternative" "8,9,10,11,24,25")
4036                  (const_string "x64")
4037                (eq_attr "alternative" "12,13,14,15")
4038                  (const_string "sse2")
4039                (eq_attr "alternative" "20,21")
4040                  (const_string "x64_sse2")
4041               ]
4042               (const_string "*")))
4043    (set (attr "type")
4044         (cond [(eq_attr "alternative" "0,1,2")
4045                  (const_string "fmov")
4046                (eq_attr "alternative" "3,4,5,6,7,22,23")
4047                  (const_string "multi")
4048                (eq_attr "alternative" "8,9,10,11,24,25")
4049                  (const_string "imov")
4050                (eq_attr "alternative" "12,16")
4051                  (const_string "sselog1")
4052               ]
4053               (const_string "ssemov")))
4054    (set (attr "modrm")
4055      (if_then_else (eq_attr "alternative" "11")
4056        (const_string "0")
4057        (const_string "*")))
4058    (set (attr "length_immediate")
4059      (if_then_else (eq_attr "alternative" "11")
4060        (const_string "8")
4061        (const_string "*")))
4062    (set (attr "prefix")
4063      (if_then_else (eq_attr "type" "sselog1,ssemov")
4064        (const_string "maybe_vex")
4065        (const_string "orig")))
4066    (set (attr "prefix_data16")
4067      (if_then_else
4068        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
4069             (eq_attr "mode" "V1DF"))
4070        (const_string "1")
4071        (const_string "*")))
4072    (set (attr "mode")
4073         (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
4074                  (const_string "SI")
4075                (eq_attr "alternative" "8,9,11,20,21,24,25")
4076                  (const_string "DI")
4078                /* xorps is one byte shorter for non-AVX targets.  */
4079                (eq_attr "alternative" "12,16")
4080                  (cond [(match_test "TARGET_AVX")
4081                           (const_string "V2DF")
4082                         (ior (not (match_test "TARGET_SSE2"))
4083                              (match_test "optimize_function_for_size_p (cfun)"))
4084                           (const_string "V4SF")
4085                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4086                           (const_string "TI")
4087                        ]
4088                        (const_string "V2DF"))
4090                /* For architectures resolving dependencies on
4091                   whole SSE registers use movapd to break dependency
4092                   chains, otherwise use short move to avoid extra work.  */
4094                /* movaps is one byte shorter for non-AVX targets.  */
4095                (eq_attr "alternative" "13,17")
4096                  (cond [(match_test "TARGET_AVX512VL")
4097                           (const_string "V2DF")
4098                         (match_test "TARGET_AVX512F")
4099                           (const_string "DF")
4100                         (match_test "TARGET_AVX")
4101                           (const_string "V2DF")
4102                         (ior (not (match_test "TARGET_SSE2"))
4103                              (match_test "optimize_function_for_size_p (cfun)"))
4104                           (const_string "V4SF")
4105                         (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
4106                           (const_string "V4SF")
4107                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4108                           (const_string "V2DF")
4109                        ]
4110                        (const_string "DF"))
4112                /* For architectures resolving dependencies on register
4113                   parts we may avoid extra work to zero out upper part
4114                   of register.  */
4115                (eq_attr "alternative" "14,18")
4116                  (cond [(not (match_test "TARGET_SSE2"))
4117                           (const_string "V2SF")
4118                         (match_test "TARGET_AVX")
4119                           (const_string "DF")
4120                         (match_test "TARGET_SSE_SPLIT_REGS")
4121                           (const_string "V1DF")
4122                        ]
4123                        (const_string "DF"))
4125                (and (eq_attr "alternative" "15,19")
4126                     (not (match_test "TARGET_SSE2")))
4127                  (const_string "V2SF")
4128               ]
4129               (const_string "DF")))
4130    (set (attr "preferred_for_size")
4131      (cond [(eq_attr "alternative" "3,4")
4132               (symbol_ref "false")]
4133            (symbol_ref "true")))
4134    (set (attr "preferred_for_speed")
4135      (cond [(eq_attr "alternative" "3,4")
4136               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
4137             (eq_attr "alternative" "20")
4138               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4139             (eq_attr "alternative" "21")
4140               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4141            ]
4142            (symbol_ref "true")))
4143    (set (attr "enabled")
4144      (cond [(eq_attr "alternative" "22,23,24,25")
4145               (if_then_else
4146                 (match_test "TARGET_HARD_DF_REGS")
4147                 (symbol_ref "false")
4148                 (const_string "*"))
4149             (not (match_test "TARGET_HARD_DF_REGS"))
4150               (symbol_ref "false")
4151            ]
4152            (const_string "*")))])
4154 (define_split
4155   [(set (match_operand:DF 0 "nonimmediate_gr_operand")
4156         (match_operand:DF 1 "general_gr_operand"))]
4157   "!TARGET_64BIT && reload_completed"
4158   [(const_int 0)]
4159   "ix86_split_long_move (operands); DONE;")
4161 (define_insn "*movsf_internal"
4162   [(set (match_operand:SF 0 "nonimmediate_operand"
4163           "=Yf*f,m   ,Yf*f,?r ,?m,Yv,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r  ,m")
4164         (match_operand:SF 1 "general_operand"
4165           "Yf*fm,Yf*f,G   ,rmF,rF,C ,v,m,v,v ,r ,*y ,m  ,*y,*y,r  ,rmF,rF"))]
4166   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4167    && (lra_in_progress || reload_completed
4168        || !CONST_DOUBLE_P (operands[1])
4169        || ((optimize_function_for_size_p (cfun)
4170             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4171            && IS_STACK_MODE (SFmode)
4172            && standard_80387_constant_p (operands[1]) > 0)
4173        || (TARGET_SSE && TARGET_SSE_MATH
4174            && standard_sse_constant_p (operands[1], SFmode) == 1)
4175        || memory_operand (operands[0], SFmode)
4176        || !TARGET_HARD_SF_REGS)"
4178   switch (get_attr_type (insn))
4179     {
4180     case TYPE_FMOV:
4181       if (which_alternative == 2)
4182         return standard_80387_constant_opcode (operands[1]);
4183       return output_387_reg_move (insn, operands);
4185     case TYPE_IMOV:
4186       return "mov{l}\t{%1, %0|%0, %1}";
4188     case TYPE_SSELOG1:
4189       return standard_sse_constant_opcode (insn, operands);
4191     case TYPE_SSEMOV:
4192       return ix86_output_ssemov (insn, operands);
4194     case TYPE_MMXMOV:
4195       switch (get_attr_mode (insn))
4196         {
4197         case MODE_DI:
4198           return "movq\t{%1, %0|%0, %1}";
4199         case MODE_SI:
4200           return "movd\t{%1, %0|%0, %1}";
4202         default:
4203           gcc_unreachable ();
4204         }
4206     default:
4207       gcc_unreachable ();
4208     }
4210   [(set (attr "isa")
4211      (cond [(eq_attr "alternative" "9,10")
4212               (const_string "sse2")
4213            ]
4214            (const_string "*")))
4215    (set (attr "type")
4216         (cond [(eq_attr "alternative" "0,1,2")
4217                  (const_string "fmov")
4218                (eq_attr "alternative" "3,4,16,17")
4219                  (const_string "imov")
4220                (eq_attr "alternative" "5")
4221                  (const_string "sselog1")
4222                (eq_attr "alternative" "11,12,13,14,15")
4223                  (const_string "mmxmov")
4224               ]
4225               (const_string "ssemov")))
4226    (set (attr "prefix")
4227      (if_then_else (eq_attr "type" "sselog1,ssemov")
4228        (const_string "maybe_vex")
4229        (const_string "orig")))
4230    (set (attr "prefix_data16")
4231      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
4232        (const_string "1")
4233        (const_string "*")))
4234    (set (attr "mode")
4235         (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
4236                  (const_string "SI")
4237                (eq_attr "alternative" "11")
4238                  (const_string "DI")
4239                (eq_attr "alternative" "5")
4240                  (cond [(and (match_test "TARGET_AVX512F && TARGET_EVEX512")
4241                              (not (match_test "TARGET_PREFER_AVX256")))
4242                           (const_string "V16SF")
4243                         (match_test "TARGET_AVX")
4244                           (const_string "V4SF")
4245                         (ior (not (match_test "TARGET_SSE2"))
4246                              (match_test "optimize_function_for_size_p (cfun)"))
4247                           (const_string "V4SF")
4248                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4249                           (const_string "TI")
4250                        ]
4251                        (const_string "V4SF"))
4253                /* For architectures resolving dependencies on
4254                   whole SSE registers use APS move to break dependency
4255                   chains, otherwise use short move to avoid extra work.
4257                   Do the same for architectures resolving dependencies on
4258                   the parts.  While in DF mode it is better to always handle
4259                   just register parts, the SF mode is different due to lack
4260                   of instructions to load just part of the register.  It is
4261                   better to maintain the whole registers in single format
4262                   to avoid problems on using packed logical operations.  */
4263                (eq_attr "alternative" "6")
4264                  (cond [(match_test "TARGET_AVX512VL")
4265                           (const_string "V4SF")
4266                         (match_test "TARGET_AVX512F")
4267                           (const_string "SF")
4268                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4269                              (match_test "TARGET_SSE_SPLIT_REGS"))
4270                           (const_string "V4SF")
4271                        ]
4272                        (const_string "SF"))
4273               ]
4274               (const_string "SF")))
4275    (set (attr "preferred_for_speed")
4276      (cond [(eq_attr "alternative" "9,14")
4277               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4278             (eq_attr "alternative" "10,15")
4279               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4280            ]
4281            (symbol_ref "true")))
4282    (set (attr "enabled")
4283      (cond [(eq_attr "alternative" "16,17")
4284               (if_then_else
4285                 (match_test "TARGET_HARD_SF_REGS")
4286                 (symbol_ref "false")
4287                 (const_string "*"))
4288             (not (match_test "TARGET_HARD_SF_REGS"))
4289               (symbol_ref "false")
4290            ]
4291            (const_string "*")))])
4293 (define_mode_attr hfbfconstf
4294  [(HF "F") (BF "")])
4296 (define_insn "*mov<mode>_internal"
4297  [(set (match_operand:HFBF 0 "nonimmediate_operand"
4298          "=?r,?r,?r,?m           ,Yv,v,?r,jm,m,?v,v")
4299        (match_operand:HFBF 1 "general_operand"
4300          "r  ,F ,m ,r<hfbfconstf>,C ,v, v,v ,v,r ,m"))]
4301  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4302   && (lra_in_progress
4303       || reload_completed
4304       || !CONST_DOUBLE_P (operands[1])
4305       || (TARGET_SSE2
4306           && standard_sse_constant_p (operands[1], <MODE>mode) == 1)
4307       || memory_operand (operands[0], <MODE>mode))"
4309   switch (get_attr_type (insn))
4310     {
4311     case TYPE_IMOVX:
4312       /* movzwl is faster than movw on p2 due to partial word stalls,
4313          though not as fast as an aligned movl.  */
4314       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
4316     case TYPE_SSEMOV:
4317       return ix86_output_ssemov (insn, operands);
4319     case TYPE_SSELOG1:
4320       if (satisfies_constraint_C (operands[1]))
4321         return standard_sse_constant_opcode (insn, operands);
4323       if (SSE_REG_P (operands[0]))
4324         return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
4325       else
4326         return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
4328     default:
4329       if (get_attr_mode (insn) == MODE_SI)
4330         return "mov{l}\t{%k1, %k0|%k0, %k1}";
4331       else
4332         return "mov{w}\t{%1, %0|%0, %1}";
4333     }
4335   [(set (attr "isa")
4336         (cond [(eq_attr "alternative" "4,5,6,9,10")
4337                  (const_string "sse2")
4338                (eq_attr "alternative" "7")
4339                  (const_string "sse4_noavx")
4340                (eq_attr "alternative" "8")
4341                  (const_string "avx")
4342               ]
4343               (const_string "*")))
4344    (set (attr "addr")
4345         (if_then_else (eq_attr "alternative" "7")
4346                       (const_string "gpr16")
4347                       (const_string "*")))
4348    (set (attr "type")
4349         (cond [(eq_attr "alternative" "4")
4350                  (const_string "sselog1")
4351                (eq_attr "alternative" "5,6,9")
4352                  (const_string "ssemov")
4353                (eq_attr "alternative" "7,8,10")
4354                  (if_then_else
4355                    (match_test ("TARGET_AVX512FP16"))
4356                    (const_string "ssemov")
4357                    (const_string "sselog1"))
4358                (match_test "optimize_function_for_size_p (cfun)")
4359                  (const_string "imov")
4360                (and (eq_attr "alternative" "0")
4361                     (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4362                          (not (match_test "TARGET_HIMODE_MATH"))))
4363                  (const_string "imov")
4364                (and (eq_attr "alternative" "1,2")
4365                     (match_operand:HI 1 "aligned_operand"))
4366                  (const_string "imov")
4367                (and (match_test "TARGET_MOVX")
4368                     (eq_attr "alternative" "0,2"))
4369                  (const_string "imovx")
4370                  ]
4371               (const_string "imov")))
4372    (set (attr "prefix")
4373         (cond [(eq_attr "alternative" "4,5,6,7,8,9,10")
4374                  (const_string "maybe_vex")
4375               ]
4376               (const_string "orig")))
4377    (set (attr "mode")
4378         (cond [(eq_attr "alternative" "4")
4379                  (const_string "V4SF")
4380                (eq_attr "alternative" "6,9")
4381                  (if_then_else
4382                    (match_test "TARGET_AVX512FP16")
4383                    (const_string "HI")
4384                    (const_string "SI"))
4385                (eq_attr "alternative" "7,8,10")
4386                  (if_then_else
4387                    (match_test "TARGET_AVX512FP16")
4388                    (const_string "HI")
4389                    (const_string "TI"))
4390                (eq_attr "alternative" "5")
4391                  (cond [(match_test "TARGET_AVX512VL")
4392                         (const_string "V4SF")
4393                         (match_test "TARGET_AVX512FP16")
4394                           (const_string "HF")
4395                         (match_test "TARGET_AVX512F")
4396                           (const_string "SF")
4397                         (match_test "TARGET_AVX")
4398                           (const_string "V4SF")
4399                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4400                              (match_test "TARGET_SSE_SPLIT_REGS"))
4401                           (const_string "V4SF")
4402                        ]
4403                        (const_string "SF"))
4404                (eq_attr "type" "imovx")
4405                  (const_string "SI")
4406                (and (eq_attr "alternative" "1,2")
4407                     (match_operand:HI 1 "aligned_operand"))
4408                  (const_string "SI")
4409                (and (eq_attr "alternative" "0")
4410                     (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4411                          (not (match_test "TARGET_HIMODE_MATH"))))
4412                  (const_string "SI")
4413               ]
4414               (const_string "HI")))
4415    (set (attr "enabled")
4416         (cond [(and (match_test "<MODE>mode == BFmode")
4417                     (eq_attr "alternative" "1"))
4418                 (symbol_ref "false")
4419               ]
4420               (const_string "*")))])
4422 (define_split
4423   [(set (match_operand 0 "any_fp_register_operand")
4424         (match_operand 1 "memory_operand"))]
4425   "reload_completed
4426    && (GET_MODE (operands[0]) == TFmode
4427        || GET_MODE (operands[0]) == XFmode
4428        || GET_MODE (operands[0]) == DFmode
4429        || GET_MODE (operands[0]) == SFmode)
4430    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4431   [(set (match_dup 0) (match_dup 2))]
4432   "operands[2] = find_constant_src (curr_insn);")
4434 (define_split
4435   [(set (match_operand 0 "any_fp_register_operand")
4436         (float_extend (match_operand 1 "memory_operand")))]
4437   "reload_completed
4438    && (GET_MODE (operands[0]) == TFmode
4439        || GET_MODE (operands[0]) == XFmode
4440        || GET_MODE (operands[0]) == DFmode)
4441    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4442   [(set (match_dup 0) (match_dup 2))]
4443   "operands[2] = find_constant_src (curr_insn);")
4445 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
4446 (define_split
4447   [(set (match_operand:X87MODEF 0 "fp_register_operand")
4448         (match_operand:X87MODEF 1 "immediate_operand"))]
4449   "reload_completed
4450    && (standard_80387_constant_p (operands[1]) == 8
4451        || standard_80387_constant_p (operands[1]) == 9)"
4452   [(set (match_dup 0)(match_dup 1))
4453    (set (match_dup 0)
4454         (neg:X87MODEF (match_dup 0)))]
4456   if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
4457     operands[1] = CONST0_RTX (<MODE>mode);
4458   else
4459     operands[1] = CONST1_RTX (<MODE>mode);
4462 (define_insn "*swapxf"
4463   [(set (match_operand:XF 0 "register_operand" "+f")
4464         (match_operand:XF 1 "register_operand" "+f"))
4465    (set (match_dup 1)
4466         (match_dup 0))]
4467   "TARGET_80387"
4469   if (STACK_TOP_P (operands[0]))
4470     return "fxch\t%1";
4471   else
4472     return "fxch\t%0";
4474   [(set_attr "type" "fxch")
4475    (set_attr "mode" "XF")])
4478 ;; Zero extension instructions
4480 (define_insn_and_split "zero_extendditi2"
4481   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4482         (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "rm,r")))]
4483   "TARGET_64BIT"
4484   "#"
4485   "&& reload_completed"
4486   [(set (match_dup 3) (match_dup 1))
4487    (set (match_dup 4) (const_int 0))]
4488   "split_double_mode (TImode, &operands[0], 1, &operands[3], &operands[4]);")
4490 (define_expand "zero_extendsidi2"
4491   [(set (match_operand:DI 0 "nonimmediate_operand")
4492         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
4494 (define_insn "*zero_extendsidi2"
4495   [(set (match_operand:DI 0 "nonimmediate_operand"
4496                 "=r,?r,?o,r   ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r,*k")
4497         (zero_extend:DI
4498          (match_operand:SI 1 "x86_64_zext_operand"
4499                 "0 ,rm,r ,rmWz,0,r  ,m   ,v ,r ,m ,*x,*v,*k,*km")))]
4500   ""
4502   switch (get_attr_type (insn))
4503     {
4504     case TYPE_IMOVX:
4505       if (ix86_use_lea_for_mov (insn, operands))
4506         return "lea{l}\t{%E1, %k0|%k0, %E1}";
4507       else
4508         return "mov{l}\t{%1, %k0|%k0, %1}";
4510     case TYPE_MULTI:
4511       return "#";
4513     case TYPE_MMXMOV:
4514       return "movd\t{%1, %0|%0, %1}";
4516     case TYPE_SSEMOV:
4517       if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
4518         {
4519           if (EXT_REX_SSE_REG_P (operands[0])
4520               || EXT_REX_SSE_REG_P (operands[1]))
4521             return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
4522           else
4523             return "%vpmovzxdq\t{%1, %0|%0, %1}";
4524         }
4526       if (GENERAL_REG_P (operands[0]))
4527         return "%vmovd\t{%1, %k0|%k0, %1}";
4529       return "%vmovd\t{%1, %0|%0, %1}";
4531     case TYPE_MSKMOV:
4532       return "kmovd\t{%1, %k0|%k0, %1}";
4534     default:
4535       gcc_unreachable ();
4536     }
4538   [(set (attr "isa")
4539      (cond [(eq_attr "alternative" "0,1,2")
4540               (const_string "nox64")
4541             (eq_attr "alternative" "3")
4542               (const_string "x64")
4543             (eq_attr "alternative" "7,8,9")
4544               (const_string "sse2")
4545             (eq_attr "alternative" "10")
4546               (const_string "sse4")
4547             (eq_attr "alternative" "11")
4548               (const_string "avx512f")
4549             (eq_attr "alternative" "12")
4550               (const_string "x64_avx512bw")
4551             (eq_attr "alternative" "13")
4552               (const_string "avx512bw_512")
4553            ]
4554            (const_string "*")))
4555    (set (attr "mmx_isa")
4556      (if_then_else (eq_attr "alternative" "5,6")
4557                    (const_string "native")
4558                    (const_string "*")))
4559    (set (attr "type")
4560      (cond [(eq_attr "alternative" "0,1,2,4")
4561               (const_string "multi")
4562             (eq_attr "alternative" "5,6")
4563               (const_string "mmxmov")
4564             (eq_attr "alternative" "7")
4565               (if_then_else (match_test "TARGET_64BIT")
4566                 (const_string "ssemov")
4567                 (const_string "multi"))
4568             (eq_attr "alternative" "8,9,10,11")
4569               (const_string "ssemov")
4570             (eq_attr "alternative" "12,13")
4571               (const_string "mskmov")
4572            ]
4573            (const_string "imovx")))
4574    (set (attr "prefix_extra")
4575      (if_then_else (eq_attr "alternative" "10,11")
4576        (const_string "1")
4577        (const_string "*")))
4578    (set (attr "prefix")
4579      (if_then_else (eq_attr "type" "ssemov")
4580        (const_string "maybe_vex")
4581        (const_string "orig")))
4582    (set (attr "prefix_0f")
4583      (if_then_else (eq_attr "type" "imovx")
4584        (const_string "0")
4585        (const_string "*")))
4586    (set (attr "mode")
4587      (cond [(eq_attr "alternative" "5,6")
4588               (const_string "DI")
4589             (and (eq_attr "alternative" "7")
4590                  (match_test "TARGET_64BIT"))
4591               (const_string "TI")
4592             (eq_attr "alternative" "8,10,11")
4593               (const_string "TI")
4594            ]
4595            (const_string "SI")))
4596    (set (attr "preferred_for_speed")
4597      (cond [(eq_attr "alternative" "7")
4598               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4599             (eq_attr "alternative" "5,8")
4600               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4601            ]
4602            (symbol_ref "true")))])
4604 (define_split
4605   [(set (match_operand:DI 0 "memory_operand")
4606         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
4607   "reload_completed"
4608   [(set (match_dup 4) (const_int 0))]
4609   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4611 (define_split
4612   [(set (match_operand:DI 0 "general_reg_operand")
4613         (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
4614   "!TARGET_64BIT && reload_completed
4615    && REGNO (operands[0]) == REGNO (operands[1])"
4616   [(set (match_dup 4) (const_int 0))]
4617   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4619 (define_split
4620   [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4621         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4622   "!TARGET_64BIT && reload_completed
4623    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4624   [(set (match_dup 3) (match_dup 1))
4625    (set (match_dup 4) (const_int 0))]
4626   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4628 (define_mode_attr kmov_isa
4629   [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw_512")])
4631 (define_insn "zero_extend<mode>di2"
4632   [(set (match_operand:DI 0 "register_operand" "=r,*r,*k")
4633         (zero_extend:DI
4634          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4635   "TARGET_64BIT"
4636   "@
4637    movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4638    kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
4639    kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4640   [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4641    (set_attr "type" "imovx,mskmov,mskmov")
4642    (set_attr "mode" "SI,<MODE>,<MODE>")])
4644 (define_expand "zero_extend<mode>si2"
4645   [(set (match_operand:SI 0 "register_operand")
4646         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4647   ""
4649   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4650     {
4651       operands[1] = force_reg (<MODE>mode, operands[1]);
4652       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4653       DONE;
4654     }
4657 (define_insn_and_split "zero_extend<mode>si2_and"
4658   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4659         (zero_extend:SI
4660           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4661    (clobber (reg:CC FLAGS_REG))]
4662   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4663   "#"
4664   "&& reload_completed"
4665   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4666               (clobber (reg:CC FLAGS_REG))])]
4668   if (!REG_P (operands[1])
4669       || REGNO (operands[0]) != REGNO (operands[1]))
4670     {
4671       ix86_expand_clear (operands[0]);
4673       gcc_assert (!TARGET_PARTIAL_REG_STALL);
4674       emit_insn (gen_rtx_SET
4675                  (gen_rtx_STRICT_LOW_PART
4676                   (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
4677                   operands[1]));
4678       DONE;
4679     }
4681   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4683   [(set_attr "type" "alu1")
4684    (set_attr "mode" "SI")])
4686 (define_insn "*zero_extend<mode>si2"
4687   [(set (match_operand:SI 0 "register_operand" "=r,*r,*k")
4688         (zero_extend:SI
4689           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4690   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4691   "@
4692    movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4693    kmov<mskmodesuffix>\t{%1, %0|%0, %1}
4694    kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4695   [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4696    (set_attr "type" "imovx,mskmov,mskmov")
4697    (set_attr "mode" "SI,<MODE>,<MODE>")])
4699 (define_expand "zero_extendqihi2"
4700   [(set (match_operand:HI 0 "register_operand")
4701         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4702   ""
4704   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4705     {
4706       operands[1] = force_reg (QImode, operands[1]);
4707       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4708       DONE;
4709     }
4712 (define_insn_and_split "zero_extendqihi2_and"
4713   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4714         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4715    (clobber (reg:CC FLAGS_REG))]
4716   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4717   "#"
4718   "&& reload_completed"
4719   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4720               (clobber (reg:CC FLAGS_REG))])]
4722   if (!REG_P (operands[1])
4723       || REGNO (operands[0]) != REGNO (operands[1]))
4724     {
4725       ix86_expand_clear (operands[0]);
4727       gcc_assert (!TARGET_PARTIAL_REG_STALL);
4728       emit_insn (gen_rtx_SET
4729                  (gen_rtx_STRICT_LOW_PART
4730                   (VOIDmode, gen_lowpart (QImode, operands[0])),
4731                   operands[1]));
4732       DONE;
4733     }
4735   operands[0] = gen_lowpart (SImode, operands[0]);
4737   [(set_attr "type" "alu1")
4738    (set_attr "mode" "SI")])
4740 ; zero extend to SImode to avoid partial register stalls
4741 (define_insn "*zero_extendqihi2"
4742   [(set (match_operand:HI 0 "register_operand" "=r,*r,*k")
4743         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k,*km")))]
4744   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4745   "@
4746    movz{bl|x}\t{%1, %k0|%k0, %1}
4747    kmovb\t{%1, %k0|%k0, %1}
4748    kmovb\t{%1, %0|%0, %1}"
4749   [(set_attr "isa" "*,avx512dq,avx512dq")
4750    (set_attr "type" "imovx,mskmov,mskmov")
4751    (set_attr "mode" "SI,QI,QI")])
4753 ;; Transform xorl; mov[bw] (set strict_low_part) into movz[bw]l.
4754 (define_peephole2
4755   [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
4756                    (const_int 0))
4757               (clobber (reg:CC FLAGS_REG))])
4758    (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4759         (match_operand:SWI12 2 "nonimmediate_operand"))]
4760   "REGNO (operands[0]) == REGNO (operands[1])
4761    && (<SWI48:MODE>mode != SImode
4762        || !TARGET_ZERO_EXTEND_WITH_AND
4763        || !optimize_function_for_speed_p (cfun))"
4764   [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4766 ;; Likewise, but preserving FLAGS_REG.
4767 (define_peephole2
4768   [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
4769    (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4770         (match_operand:SWI12 2 "nonimmediate_operand"))]
4771   "REGNO (operands[0]) == REGNO (operands[1])
4772    && (<SWI48:MODE>mode != SImode
4773        || !TARGET_ZERO_EXTEND_WITH_AND
4774        || !optimize_function_for_speed_p (cfun))"
4775   [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4777 ;; Sign extension instructions
4779 (define_expand "extendsidi2"
4780   [(set (match_operand:DI 0 "register_operand")
4781         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4782   ""
4784   if (!TARGET_64BIT)
4785     {
4786       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4787       DONE;
4788     }
4791 (define_insn "*extendsidi2_rex64"
4792   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4793         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4794   "TARGET_64BIT"
4795   "@
4796    {cltq|cdqe}
4797    movs{lq|x}\t{%1, %0|%0, %1}"
4798   [(set_attr "type" "imovx")
4799    (set_attr "mode" "DI")
4800    (set_attr "prefix_0f" "0")
4801    (set_attr "modrm" "0,1")])
4803 (define_insn "extendsidi2_1"
4804   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4805         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4806    (clobber (reg:CC FLAGS_REG))
4807    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4808   "!TARGET_64BIT"
4809   "#")
4811 (define_insn "extendditi2"
4812   [(set (match_operand:TI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4813         (sign_extend:TI (match_operand:DI 1 "register_operand" "0,0,r,r")))
4814    (clobber (reg:CC FLAGS_REG))
4815    (clobber (match_scratch:DI 2 "=X,X,X,&r"))]
4816   "TARGET_64BIT"
4817   "#")
4819 ;; Split the memory case.  If the source register doesn't die, it will stay
4820 ;; this way, if it does die, following peephole2s take care of it.
4821 (define_split
4822   [(set (match_operand:<DWI> 0 "memory_operand")
4823         (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4824    (clobber (reg:CC FLAGS_REG))
4825    (clobber (match_operand:DWIH 2 "register_operand"))]
4826   "reload_completed"
4827   [(const_int 0)]
4829   rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4831   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4833   emit_move_insn (operands[3], operands[1]);
4835   /* Generate a cltd if possible and doing so it profitable.  */
4836   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4837       && REGNO (operands[1]) == AX_REG
4838       && REGNO (operands[2]) == DX_REG)
4839     {
4840       emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[1], bits));
4841     }
4842   else
4843     {
4844       emit_move_insn (operands[2], operands[1]);
4845       emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[2], bits));
4846     }
4847   emit_move_insn (operands[4], operands[2]);
4848   DONE;
4851 ;; Peepholes for the case where the source register does die, after
4852 ;; being split with the above splitter.
4853 (define_peephole2
4854   [(set (match_operand:DWIH 0 "memory_operand")
4855         (match_operand:DWIH 1 "general_reg_operand"))
4856    (set (match_operand:DWIH 2 "general_reg_operand") (match_dup 1))
4857    (parallel [(set (match_dup 2)
4858                    (ashiftrt:DWIH (match_dup 2)
4859                                   (match_operand 4 "const_int_operand")))
4860                (clobber (reg:CC FLAGS_REG))])
4861    (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4862   "REGNO (operands[1]) != REGNO (operands[2])
4863    && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4864    && peep2_reg_dead_p (2, operands[1])
4865    && peep2_reg_dead_p (4, operands[2])
4866    && !reg_mentioned_p (operands[2], operands[3])"
4867   [(set (match_dup 0) (match_dup 1))
4868    (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4869               (clobber (reg:CC FLAGS_REG))])
4870    (set (match_dup 3) (match_dup 1))])
4872 (define_peephole2
4873   [(set (match_operand:DWIH 0 "memory_operand")
4874         (match_operand:DWIH 1 "general_reg_operand"))
4875    (parallel [(set (match_operand:DWIH 2 "general_reg_operand")
4876                    (ashiftrt:DWIH (match_dup 1)
4877                                   (match_operand 4 "const_int_operand")))
4878                (clobber (reg:CC FLAGS_REG))])
4879    (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4880   "/* cltd is shorter than sarl $31, %eax */
4881    !optimize_function_for_size_p (cfun)
4882    && REGNO (operands[1]) == AX_REG
4883    && REGNO (operands[2]) == DX_REG
4884    && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4885    && peep2_reg_dead_p (2, operands[1])
4886    && peep2_reg_dead_p (3, operands[2])
4887    && !reg_mentioned_p (operands[2], operands[3])"
4888   [(set (match_dup 0) (match_dup 1))
4889    (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4890               (clobber (reg:CC FLAGS_REG))])
4891    (set (match_dup 3) (match_dup 1))])
4893 ;; Extend to register case.  Optimize case where source and destination
4894 ;; registers match and cases where we can use cltd.
4895 (define_split
4896   [(set (match_operand:<DWI> 0 "register_operand")
4897         (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4898    (clobber (reg:CC FLAGS_REG))
4899    (clobber (match_scratch:DWIH 2))]
4900   "reload_completed"
4901   [(const_int 0)]
4903   rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4905   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4907   if (REGNO (operands[3]) != REGNO (operands[1]))
4908     emit_move_insn (operands[3], operands[1]);
4910   rtx src = operands[1];
4911   if (REGNO (operands[3]) == AX_REG)
4912     src = operands[3];
4914   /* Generate a cltd if possible and doing so it profitable.  */
4915   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4916       && REGNO (src) == AX_REG
4917       && REGNO (operands[4]) == DX_REG)
4918     {
4919       emit_insn (gen_ashr<mode>3_cvt (operands[4], src, bits));
4920       DONE;
4921     }
4923   if (REGNO (operands[4]) != REGNO (operands[1]))
4924     emit_move_insn (operands[4], operands[1]);
4926   emit_insn (gen_ashr<mode>3_cvt (operands[4], operands[4], bits));
4927   DONE;
4930 (define_insn "extend<mode>di2"
4931   [(set (match_operand:DI 0 "register_operand" "=r")
4932         (sign_extend:DI
4933          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4934   "TARGET_64BIT"
4935   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4936   [(set_attr "type" "imovx")
4937    (set_attr "mode" "DI")])
4939 (define_insn "extendhisi2"
4940   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4941         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4942   ""
4944   switch (get_attr_prefix_0f (insn))
4945     {
4946     case 0:
4947       return "{cwtl|cwde}";
4948     default:
4949       return "movs{wl|x}\t{%1, %0|%0, %1}";
4950     }
4952   [(set_attr "type" "imovx")
4953    (set_attr "mode" "SI")
4954    (set (attr "prefix_0f")
4955      ;; movsx is short decodable while cwtl is vector decoded.
4956      (if_then_else (and (eq_attr "cpu" "!k6")
4957                         (eq_attr "alternative" "0"))
4958         (const_string "0")
4959         (const_string "1")))
4960    (set (attr "znver1_decode")
4961      (if_then_else (eq_attr "prefix_0f" "0")
4962         (const_string "double")
4963         (const_string "direct")))
4964    (set (attr "modrm")
4965      (if_then_else (eq_attr "prefix_0f" "0")
4966         (const_string "0")
4967         (const_string "1")))])
4969 (define_insn "*extendhisi2_zext"
4970   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4971         (zero_extend:DI
4972          (sign_extend:SI
4973           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4974   "TARGET_64BIT"
4976   switch (get_attr_prefix_0f (insn))
4977     {
4978     case 0:
4979       return "{cwtl|cwde}";
4980     default:
4981       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4982     }
4984   [(set_attr "type" "imovx")
4985    (set_attr "mode" "SI")
4986    (set (attr "prefix_0f")
4987      ;; movsx is short decodable while cwtl is vector decoded.
4988      (if_then_else (and (eq_attr "cpu" "!k6")
4989                         (eq_attr "alternative" "0"))
4990         (const_string "0")
4991         (const_string "1")))
4992    (set (attr "modrm")
4993      (if_then_else (eq_attr "prefix_0f" "0")
4994         (const_string "0")
4995         (const_string "1")))])
4997 (define_insn "extendqisi2"
4998   [(set (match_operand:SI 0 "register_operand" "=r")
4999         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
5000   ""
5001   "movs{bl|x}\t{%1, %0|%0, %1}"
5002    [(set_attr "type" "imovx")
5003     (set_attr "mode" "SI")])
5005 (define_insn "*extendqisi2_zext"
5006   [(set (match_operand:DI 0 "register_operand" "=r")
5007         (zero_extend:DI
5008           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
5009   "TARGET_64BIT"
5010   "movs{bl|x}\t{%1, %k0|%k0, %1}"
5011    [(set_attr "type" "imovx")
5012     (set_attr "mode" "SI")])
5014 (define_insn "extendqihi2"
5015   [(set (match_operand:HI 0 "register_operand" "=*a,r")
5016         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
5017   ""
5019   switch (get_attr_prefix_0f (insn))
5020     {
5021     case 0:
5022       return "{cbtw|cbw}";
5023     default:
5024       return "movs{bw|x}\t{%1, %0|%0, %1}";
5025     }
5027   [(set_attr "type" "imovx")
5028    (set_attr "mode" "HI")
5029    (set (attr "prefix_0f")
5030      ;; movsx is short decodable while cwtl is vector decoded.
5031      (if_then_else (and (eq_attr "cpu" "!k6")
5032                         (eq_attr "alternative" "0"))
5033         (const_string "0")
5034         (const_string "1")))
5035    (set (attr "modrm")
5036      (if_then_else (eq_attr "prefix_0f" "0")
5037         (const_string "0")
5038         (const_string "1")))])
5040 (define_insn "*extendqi<SWI24:mode>_ext_1"
5041   [(set (match_operand:SWI24 0 "register_operand" "=R")
5042         (sign_extend:SWI24
5043           (subreg:QI
5044             (match_operator:SWI248 2 "extract_operator"
5045               [(match_operand 1 "int248_register_operand" "Q")
5046                (const_int 8)
5047                (const_int 8)]) 0)))]
5048   ""
5049   "movs{b<SWI24:imodesuffix>|x}\t{%h1, %0|%0, %h1}"
5050    [(set_attr "type" "imovx")
5051     (set_attr "mode" "<SWI24:MODE>")])
5053 ;; Conversions between float and double.
5055 ;; These are all no-ops in the model used for the 80387.
5056 ;; So just emit moves.
5058 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
5059 (define_split
5060   [(set (match_operand:DF 0 "push_operand")
5061         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
5062   "reload_completed"
5063   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
5064    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
5066 (define_split
5067   [(set (match_operand:XF 0 "push_operand")
5068         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
5069   "reload_completed"
5070   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
5071    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
5072   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
5074 (define_expand "extendsfdf2"
5075   [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
5076         (float_extend:DF (match_operand:SF 1 "general_operand")))]
5077   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5079   /* ??? Needed for compress_float_constant since all fp constants
5080      are TARGET_LEGITIMATE_CONSTANT_P.  */
5081   if (CONST_DOUBLE_P (operands[1]))
5082     {
5083       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
5084           && standard_80387_constant_p (operands[1]) > 0)
5085         {
5086           operands[1] = simplify_const_unary_operation
5087             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
5088           emit_move_insn_1 (operands[0], operands[1]);
5089           DONE;
5090         }
5091       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
5092     }
5095 (define_insn "*extendsfdf2"
5096   [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
5097         (float_extend:DF
5098           (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
5099   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5101   switch (which_alternative)
5102     {
5103     case 0:
5104     case 1:
5105       return output_387_reg_move (insn, operands);
5107     case 2:
5108       return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
5109     case 3:
5110       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
5112     default:
5113       gcc_unreachable ();
5114     }
5116   [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5117    (set_attr "avx_partial_xmm_update" "false,false,false,true")
5118    (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
5119    (set_attr "mode" "SF,XF,DF,DF")
5120    (set (attr "enabled")
5121      (if_then_else
5122        (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5123        (if_then_else
5124          (eq_attr "alternative" "0,1")
5125          (symbol_ref "TARGET_MIX_SSE_I387")
5126          (symbol_ref "true"))
5127        (if_then_else
5128          (eq_attr "alternative" "0,1")
5129          (symbol_ref "true")
5130          (symbol_ref "false"))))])
5132 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
5133    cvtss2sd:
5134       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
5135       cvtps2pd xmm2,xmm1
5136    We do the conversion post reload to avoid producing of 128bit spills
5137    that might lead to ICE on 32bit target.  The sequence unlikely combine
5138    anyway.  */
5139 (define_split
5140   [(set (match_operand:DF 0 "sse_reg_operand")
5141         (float_extend:DF
5142           (match_operand:SF 1 "nonimmediate_operand")))]
5143   "TARGET_USE_VECTOR_FP_CONVERTS
5144    && optimize_insn_for_speed_p ()
5145    && reload_completed
5146    && (!EXT_REX_SSE_REG_P (operands[0])
5147        || TARGET_AVX512VL || TARGET_EVEX512)"
5148    [(set (match_dup 2)
5149          (float_extend:V2DF
5150            (vec_select:V2SF
5151              (match_dup 3)
5152              (parallel [(const_int 0) (const_int 1)]))))]
5154   operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5155   operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
5156   /* Use movss for loading from memory, unpcklps reg, reg for registers.
5157      Try to avoid move when unpacking can be done in source.  */
5158   if (REG_P (operands[1]))
5159     {
5160       /* If it is unsafe to overwrite upper half of source, we need
5161          to move to destination and unpack there.  */
5162       if (REGNO (operands[0]) != REGNO (operands[1])
5163           || (EXT_REX_SSE_REG_P (operands[1])
5164               && !TARGET_AVX512VL))
5165         {
5166           rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
5167           emit_move_insn (tmp, operands[1]);
5168         }
5169       else
5170         operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
5171       /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
5172          =v, v, then vbroadcastss will be only needed for AVX512F without
5173          AVX512VL.  */
5174       if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
5175         emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
5176                                                operands[3]));
5177       else
5178         {
5179           rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
5180           emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
5181         }
5182     }
5183   else
5184     emit_insn (gen_vec_setv4sf_0 (operands[3],
5185                                   CONST0_RTX (V4SFmode), operands[1]));
5188 ;; It's more profitable to split and then extend in the same register.
5189 (define_peephole2
5190   [(set (match_operand:DF 0 "sse_reg_operand")
5191         (float_extend:DF
5192           (match_operand:SF 1 "memory_operand")))]
5193   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5194    && optimize_insn_for_speed_p ()"
5195   [(set (match_dup 2) (match_dup 1))
5196    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
5197   "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
5199 ;; Break partial SSE register dependency stall.  This splitter should split
5200 ;; late in the pass sequence (after register rename pass), so allocated
5201 ;; registers won't change anymore
5203 (define_split
5204   [(set (match_operand:DF 0 "sse_reg_operand")
5205         (float_extend:DF
5206           (match_operand:SF 1 "nonimmediate_operand")))]
5207   "!TARGET_AVX
5208    && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5209    && epilogue_completed
5210    && optimize_function_for_speed_p (cfun)
5211    && (!REG_P (operands[1])
5212        || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5213    && (!EXT_REX_SSE_REG_P (operands[0])
5214        || TARGET_AVX512VL)"
5215   [(set (match_dup 0)
5216         (vec_merge:V2DF
5217           (vec_duplicate:V2DF
5218             (float_extend:DF
5219               (match_dup 1)))
5220           (match_dup 0)
5221           (const_int 1)))]
5223   operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5224   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5227 (define_expand "extendhfsf2"
5228   [(set (match_operand:SF 0 "register_operand")
5229         (float_extend:SF
5230           (match_operand:HF 1 "nonimmediate_operand")))]
5231   "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5233   if (!TARGET_AVX512FP16)
5234     {
5235       rtx res = gen_reg_rtx (V4SFmode);
5236       rtx tmp = gen_reg_rtx (V8HFmode);
5237       rtx zero = force_reg (V8HFmode, CONST0_RTX (V8HFmode));
5239       emit_insn (gen_vec_setv8hf_0 (tmp, zero, operands[1]));
5240       emit_insn (gen_vcvtph2ps (res, gen_lowpart (V8HImode, tmp)));
5241       emit_move_insn (operands[0], gen_lowpart (SFmode, res));
5242       DONE;
5243     }
5246 (define_expand "extendhfdf2"
5247   [(set (match_operand:DF 0 "register_operand")
5248         (float_extend:DF
5249           (match_operand:HF 1 "nonimmediate_operand")))]
5250   "TARGET_AVX512FP16")
5252 (define_insn "*extendhf<mode>2"
5253   [(set (match_operand:MODEF 0 "register_operand" "=v")
5254         (float_extend:MODEF
5255           (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5256   "TARGET_AVX512FP16"
5257   "vcvtsh2<ssemodesuffix>\t{%1, %0, %0|%0, %0, %1}"
5258   [(set_attr "type" "ssecvt")
5259    (set_attr "prefix" "evex")
5260    (set_attr "mode" "<MODE>")])
5262 (define_expand "extendbfsf2"
5263   [(set (match_operand:SF 0 "register_operand")
5264         (unspec:SF
5265           [(match_operand:BF 1 "register_operand")]
5266          UNSPEC_CVTBFSF))]
5267  "TARGET_SSE2 && !HONOR_NANS (BFmode)")
5269 ;; Don't use float_extend since psrlld doesn't raise
5270 ;; exceptions and turn a sNaN into a qNaN.
5271 (define_insn "extendbfsf2_1"
5272   [(set (match_operand:SF 0 "register_operand"   "=x,Yv,v")
5273         (unspec:SF
5274           [(match_operand:BF 1 "register_operand" " 0,Yv,v")]
5275           UNSPEC_CVTBFSF))]
5276  "TARGET_SSE2"
5277  "@
5278   pslld\t{$16, %0|%0, 16}
5279   vpslld\t{$16, %1, %0|%0, %1, 16}
5280   vpslld\t{$16, %g1, %g0|%g0, %g1, 16}"
5281   [(set_attr "isa" "noavx,avx,*")
5282    (set_attr "type" "sseishft1")
5283    (set_attr "length_immediate" "1")
5284    (set_attr "prefix_data16" "1,*,*")
5285    (set_attr "prefix" "orig,maybe_evex,evex")
5286    (set_attr "mode" "TI,TI,XI")
5287    (set_attr "memory" "none")
5288    (set (attr "enabled")
5289      (if_then_else (eq_attr "alternative" "2")
5290        (symbol_ref "TARGET_AVX512F && TARGET_EVEX512
5291                     && !TARGET_AVX512VL && !TARGET_PREFER_AVX256")
5292        (const_string "*")))])
5294 (define_expand "extend<mode>xf2"
5295   [(set (match_operand:XF 0 "nonimmediate_operand")
5296         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
5297   "TARGET_80387"
5299   /* ??? Needed for compress_float_constant since all fp constants
5300      are TARGET_LEGITIMATE_CONSTANT_P.  */
5301   if (CONST_DOUBLE_P (operands[1]))
5302     {
5303       if (standard_80387_constant_p (operands[1]) > 0)
5304         {
5305           operands[1] = simplify_const_unary_operation
5306             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
5307           emit_move_insn_1 (operands[0], operands[1]);
5308           DONE;
5309         }
5310       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
5311     }
5314 (define_insn "*extend<mode>xf2_i387"
5315   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
5316         (float_extend:XF
5317           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
5318   "TARGET_80387"
5319   "* return output_387_reg_move (insn, operands);"
5320   [(set_attr "type" "fmov")
5321    (set_attr "mode" "<MODE>,XF")])
5323 ;; %%% This seems like bad news.
5324 ;; This cannot output into an f-reg because there is no way to be sure
5325 ;; of truncating in that case.  Otherwise this is just like a simple move
5326 ;; insn.  So we pretend we can output to a reg in order to get better
5327 ;; register preferencing, but we really use a stack slot.
5329 ;; Conversion from DFmode to SFmode.
5331 (define_insn "truncdfsf2"
5332   [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
5333         (float_truncate:SF
5334           (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
5335   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5337   switch (which_alternative)
5338     {
5339     case 0:
5340     case 1:
5341       return output_387_reg_move (insn, operands);
5343     case 2:
5344       return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
5345     case 3:
5346       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
5348     default:
5349       gcc_unreachable ();
5350     }
5352   [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5353    (set_attr "avx_partial_xmm_update" "false,false,false,true")
5354    (set_attr "mode" "SF")
5355    (set (attr "enabled")
5356      (if_then_else
5357        (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5358        (cond [(eq_attr "alternative" "0")
5359                 (symbol_ref "TARGET_MIX_SSE_I387")
5360               (eq_attr "alternative" "1")
5361                 (symbol_ref "TARGET_MIX_SSE_I387
5362                              && flag_unsafe_math_optimizations")
5363            ]
5364            (symbol_ref "true"))
5365        (cond [(eq_attr "alternative" "0")
5366                 (symbol_ref "true")
5367               (eq_attr "alternative" "1")
5368                 (symbol_ref "flag_unsafe_math_optimizations")
5369            ]
5370            (symbol_ref "false"))))])
5372 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
5373    cvtsd2ss:
5374       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
5375       cvtpd2ps xmm2,xmm1
5376    We do the conversion post reload to avoid producing of 128bit spills
5377    that might lead to ICE on 32bit target.  The sequence unlikely combine
5378    anyway.  */
5379 (define_split
5380   [(set (match_operand:SF 0 "sse_reg_operand")
5381         (float_truncate:SF
5382           (match_operand:DF 1 "nonimmediate_operand")))]
5383   "TARGET_USE_VECTOR_FP_CONVERTS
5384    && optimize_insn_for_speed_p ()
5385    && reload_completed
5386    && (!EXT_REX_SSE_REG_P (operands[0])
5387        || TARGET_AVX512VL)"
5388    [(set (match_dup 2)
5389          (vec_concat:V4SF
5390            (float_truncate:V2SF
5391              (match_dup 4))
5392            (match_dup 3)))]
5394   operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5395   operands[3] = CONST0_RTX (V2SFmode);
5396   operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
5397   /* Use movsd for loading from memory, unpcklpd for registers.
5398      Try to avoid move when unpacking can be done in source, or SSE3
5399      movddup is available.  */
5400   if (REG_P (operands[1]))
5401     {
5402       if ((!TARGET_SSE3 && REGNO (operands[0]) != REGNO (operands[1]))
5403           || (EXT_REX_SSE_REG_P (operands[1]) && !TARGET_AVX512VL))
5404         {
5405           rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
5406           emit_move_insn (tmp, operands[1]);
5407           operands[1] = tmp;
5408         }
5409       else if (!TARGET_SSE3)
5410         operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
5411       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
5412     }
5413   else
5414     emit_insn (gen_vec_concatv2df (operands[4], operands[1],
5415                                    CONST0_RTX (DFmode)));
5418 ;; It's more profitable to split and then truncate in the same register.
5419 (define_peephole2
5420   [(set (match_operand:SF 0 "sse_reg_operand")
5421         (float_truncate:SF
5422           (match_operand:DF 1 "memory_operand")))]
5423   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5424    && optimize_insn_for_speed_p ()"
5425   [(set (match_dup 2) (match_dup 1))
5426    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
5427   "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
5429 ;; Break partial SSE register dependency stall.  This splitter should split
5430 ;; late in the pass sequence (after register rename pass), so allocated
5431 ;; registers won't change anymore
5433 (define_split
5434   [(set (match_operand:SF 0 "sse_reg_operand")
5435         (float_truncate:SF
5436           (match_operand:DF 1 "nonimmediate_operand")))]
5437   "!TARGET_AVX
5438    && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5439    && epilogue_completed
5440    && optimize_function_for_speed_p (cfun)
5441    && (!REG_P (operands[1])
5442        || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5443    && (!EXT_REX_SSE_REG_P (operands[0])
5444        || TARGET_AVX512VL)"
5445   [(set (match_dup 0)
5446         (vec_merge:V4SF
5447           (vec_duplicate:V4SF
5448             (float_truncate:SF
5449               (match_dup 1)))
5450           (match_dup 0)
5451           (const_int 1)))]
5453   operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5454   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5457 ;; Conversion from XFmode to {SF,DF}mode
5459 (define_insn "truncxf<mode>2"
5460   [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
5461         (float_truncate:MODEF
5462           (match_operand:XF 1 "register_operand" "f,f")))]
5463   "TARGET_80387"
5464   "* return output_387_reg_move (insn, operands);"
5465   [(set_attr "type" "fmov")
5466    (set_attr "mode" "<MODE>")
5467    (set (attr "enabled")
5468      (cond [(eq_attr "alternative" "1")
5469               (symbol_ref "flag_unsafe_math_optimizations")
5470            ]
5471            (symbol_ref "true")))])
5473 ;; Conversion from {SF,DF}mode to HFmode.
5475 (define_expand "truncsfhf2"
5476   [(set (match_operand:HF 0 "register_operand")
5477         (float_truncate:HF
5478           (match_operand:SF 1 "nonimmediate_operand")))]
5479   "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5480   {
5481     if (!TARGET_AVX512FP16)
5482     {
5483       rtx res = gen_reg_rtx (V8HFmode);
5484       rtx tmp = gen_reg_rtx (V4SFmode);
5485       rtx zero = force_reg (V4SFmode, CONST0_RTX (V4SFmode));
5487       emit_insn (gen_vec_setv4sf_0 (tmp, zero, operands[1]));
5488       emit_insn (gen_vcvtps2ph (gen_lowpart (V8HImode, res), tmp, GEN_INT (4)));
5489       emit_move_insn (operands[0], gen_lowpart (HFmode, res));
5490       DONE;
5491     }
5492   })
5494 (define_expand "truncdfhf2"
5495   [(set (match_operand:HF 0 "register_operand")
5496         (float_truncate:HF
5497           (match_operand:DF 1 "nonimmediate_operand")))]
5498   "TARGET_AVX512FP16")
5500 (define_insn "*trunc<mode>hf2"
5501   [(set (match_operand:HF 0 "register_operand" "=v")
5502        (float_truncate:HF
5503          (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5504   "TARGET_AVX512FP16"
5505   "vcvt<ssemodesuffix>2sh\t{%1, %d0|%d0, %1}"
5506   [(set_attr "type" "ssecvt")
5507    (set_attr "prefix" "evex")
5508    (set_attr "mode" "HF")])
5510 (define_insn "truncsfbf2"
5511   [(set (match_operand:BF 0 "register_operand" "=x, v")
5512         (float_truncate:BF
5513           (match_operand:SF 1 "register_operand" "x,v")))]
5514   "((TARGET_AVX512BF16 && TARGET_AVX512VL) || TARGET_AVXNECONVERT)
5515    && !HONOR_NANS (BFmode) && flag_unsafe_math_optimizations"
5516   "@
5517   %{vex%} vcvtneps2bf16\t{%1, %0|%0, %1}
5518   vcvtneps2bf16\t{%1, %0|%0, %1}"
5519   [(set_attr "isa" "avxneconvert,avx512bf16vl")
5520    (set_attr "prefix" "vex,evex")])
5522 ;; Signed conversion to DImode.
5524 (define_expand "fix_truncxfdi2"
5525   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5526                    (fix:DI (match_operand:XF 1 "register_operand")))
5527               (clobber (reg:CC FLAGS_REG))])]
5528   "TARGET_80387"
5530   if (TARGET_FISTTP)
5531    {
5532      emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5533      DONE;
5534    }
5537 (define_expand "fix_trunc<mode>di2"
5538   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5539                    (fix:DI (match_operand:MODEF 1 "register_operand")))
5540               (clobber (reg:CC FLAGS_REG))])]
5541   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
5543   if (TARGET_FISTTP
5544       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5545    {
5546      emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5547      DONE;
5548    }
5549   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
5550    {
5551      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
5552      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
5553      if (out != operands[0])
5554         emit_move_insn (operands[0], out);
5555      DONE;
5556    }
5559 (define_insn "fix<fixunssuffix>_trunchf<mode>2"
5560   [(set (match_operand:SWI48 0 "register_operand" "=r")
5561         (any_fix:SWI48
5562           (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5563   "TARGET_AVX512FP16"
5564   "vcvttsh2<fixsuffix>si\t{%1, %0|%0, %1}"
5565   [(set_attr "type" "sseicvt")
5566    (set_attr "prefix" "evex")
5567    (set_attr "mode" "<MODE>")])
5569 ;; Signed conversion to SImode.
5571 (define_expand "fix_truncxfsi2"
5572   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5573                    (fix:SI (match_operand:XF 1 "register_operand")))
5574               (clobber (reg:CC FLAGS_REG))])]
5575   "TARGET_80387"
5577   if (TARGET_FISTTP)
5578    {
5579      emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5580      DONE;
5581    }
5584 (define_expand "fix_trunc<mode>si2"
5585   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5586                    (fix:SI (match_operand:MODEF 1 "register_operand")))
5587               (clobber (reg:CC FLAGS_REG))])]
5588   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
5590   if (TARGET_FISTTP
5591       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5592    {
5593      emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5594      DONE;
5595    }
5596   if (SSE_FLOAT_MODE_P (<MODE>mode))
5597    {
5598      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
5599      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
5600      if (out != operands[0])
5601         emit_move_insn (operands[0], out);
5602      DONE;
5603    }
5606 ;; Signed conversion to HImode.
5608 (define_expand "fix_trunc<mode>hi2"
5609   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
5610                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
5611               (clobber (reg:CC FLAGS_REG))])]
5612   "TARGET_80387
5613    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5615   if (TARGET_FISTTP)
5616    {
5617      emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
5618      DONE;
5619    }
5622 ;; Unsigned conversion to DImode
5624 (define_insn "fixuns_trunc<mode>di2"
5625   [(set (match_operand:DI 0 "register_operand" "=r")
5626         (unsigned_fix:DI
5627           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5628   "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5629   "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5630   [(set_attr "type" "sseicvt")
5631    (set_attr "prefix" "evex")
5632    (set_attr "mode" "DI")])
5634 ;; Unsigned conversion to SImode.
5636 (define_expand "fixuns_trunc<mode>si2"
5637   [(parallel
5638     [(set (match_operand:SI 0 "register_operand")
5639           (unsigned_fix:SI
5640             (match_operand:MODEF 1 "nonimmediate_operand")))
5641      (use (match_dup 2))
5642      (clobber (scratch:<ssevecmode>))
5643      (clobber (scratch:<ssevecmode>))])]
5644   "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
5646   machine_mode mode = <MODE>mode;
5647   machine_mode vecmode = <ssevecmode>mode;
5648   REAL_VALUE_TYPE TWO31r;
5649   rtx two31;
5651   if (TARGET_AVX512F)
5652     {
5653       emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
5654       DONE;
5655     }
5657   if (optimize_insn_for_size_p ())
5658     FAIL;
5660   real_ldexp (&TWO31r, &dconst1, 31);
5661   two31 = const_double_from_real_value (TWO31r, mode);
5662   two31 = ix86_build_const_vector (vecmode, true, two31);
5663   operands[2] = force_reg (vecmode, two31);
5666 (define_insn "fixuns_trunc<mode>si2_avx512f"
5667   [(set (match_operand:SI 0 "register_operand" "=r")
5668         (unsigned_fix:SI
5669           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5670   "TARGET_AVX512F && TARGET_SSE_MATH"
5671   "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5672   [(set_attr "type" "sseicvt")
5673    (set_attr "prefix" "evex")
5674    (set_attr "mode" "SI")])
5676 (define_insn "*fixuns_trunchfsi2zext"
5677   [(set (match_operand:DI 0 "register_operand" "=r")
5678         (zero_extend:DI
5679           (unsigned_fix:SI
5680             (match_operand:HF 1 "nonimmediate_operand" "vm"))))]
5681   "TARGET_64BIT && TARGET_AVX512FP16"
5682   "vcvttsh2usi\t{%1, %k0|%k0, %1}"
5683   [(set_attr "type" "sseicvt")
5684    (set_attr "prefix" "evex")
5685    (set_attr "mode" "SI")])
5687 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
5688   [(set (match_operand:DI 0 "register_operand" "=r")
5689         (zero_extend:DI
5690           (unsigned_fix:SI
5691             (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
5692   "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5693   "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
5694   [(set_attr "type" "sseicvt")
5695    (set_attr "prefix" "evex")
5696    (set_attr "mode" "SI")])
5698 (define_insn_and_split "*fixuns_trunc<mode>_1"
5699   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5700         (unsigned_fix:SI
5701           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5702    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
5703    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5704    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5705   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5706    && optimize_function_for_speed_p (cfun)"
5707   "#"
5708   "&& reload_completed"
5709   [(const_int 0)]
5711   ix86_split_convert_uns_si_sse (operands);
5712   DONE;
5715 ;; Unsigned conversion to HImode.
5716 ;; Without these patterns, we'll try the unsigned SI conversion which
5717 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5719 (define_expand "fixuns_trunchfhi2"
5720   [(set (match_dup 2)
5721         (fix:SI (match_operand:HF 1 "nonimmediate_operand")))
5722    (set (match_operand:HI 0 "nonimmediate_operand")
5723         (subreg:HI (match_dup 2) 0))]
5724   "TARGET_AVX512FP16"
5725   "operands[2] = gen_reg_rtx (SImode);")
5727 (define_expand "fixuns_trunc<mode>hi2"
5728   [(set (match_dup 2)
5729         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5730    (set (match_operand:HI 0 "nonimmediate_operand")
5731         (subreg:HI (match_dup 2) 0))]
5732   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5733   "operands[2] = gen_reg_rtx (SImode);")
5735 ;; When SSE is available, it is always faster to use it!
5736 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5737   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5738         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5739   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5740    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5741   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5742   [(set_attr "type" "sseicvt")
5743    (set_attr "prefix" "maybe_vex")
5744    (set (attr "prefix_rex")
5745         (if_then_else
5746           (match_test "<SWI48:MODE>mode == DImode")
5747           (const_string "1")
5748           (const_string "*")))
5749    (set_attr "mode" "<MODEF:MODE>")
5750    (set_attr "athlon_decode" "double,vector")
5751    (set_attr "amdfam10_decode" "double,double")
5752    (set_attr "bdver1_decode" "double,double")])
5754 ;; Avoid vector decoded forms of the instruction.
5755 (define_peephole2
5756   [(match_scratch:MODEF 2 "x")
5757    (set (match_operand:SWI48 0 "register_operand")
5758         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5759   "TARGET_AVOID_VECTOR_DECODE
5760    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5761    && optimize_insn_for_speed_p ()"
5762   [(set (match_dup 2) (match_dup 1))
5763    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5765 (define_insn "fix_trunc<mode>_i387_fisttp"
5766   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
5767         (fix:SWI248x (match_operand 1 "register_operand" "f")))
5768    (clobber (match_scratch:XF 2 "=&f"))]
5769   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5770    && TARGET_FISTTP
5771    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5772          && (TARGET_64BIT || <MODE>mode != DImode))
5773         && TARGET_SSE_MATH)"
5774   "* return output_fix_trunc (insn, operands, true);"
5775   [(set_attr "type" "fisttp")
5776    (set_attr "mode" "<MODE>")])
5778 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5779 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5780 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5781 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5782 ;; function in i386.cc.
5783 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5784   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5785         (fix:SWI248x (match_operand 1 "register_operand")))
5786    (clobber (reg:CC FLAGS_REG))]
5787   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5788    && !TARGET_FISTTP
5789    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5790          && (TARGET_64BIT || <MODE>mode != DImode))
5791    && ix86_pre_reload_split ()"
5792   "#"
5793   "&& 1"
5794   [(const_int 0)]
5796   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5798   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5799   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5801   emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5802                                        operands[2], operands[3]));
5803   DONE;
5805   [(set_attr "type" "fistp")
5806    (set_attr "i387_cw" "trunc")
5807    (set_attr "mode" "<MODE>")])
5809 (define_insn "fix_truncdi_i387"
5810   [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
5811         (fix:DI (match_operand 1 "register_operand" "f")))
5812    (use (match_operand:HI 2 "memory_operand" "m"))
5813    (use (match_operand:HI 3 "memory_operand" "m"))
5814    (clobber (match_scratch:XF 4 "=&f"))]
5815   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5816    && !TARGET_FISTTP
5817    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5818   "* return output_fix_trunc (insn, operands, false);"
5819   [(set_attr "type" "fistp")
5820    (set_attr "i387_cw" "trunc")
5821    (set_attr "mode" "DI")])
5823 (define_insn "fix_trunc<mode>_i387"
5824   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
5825         (fix:SWI24 (match_operand 1 "register_operand" "f")))
5826    (use (match_operand:HI 2 "memory_operand" "m"))
5827    (use (match_operand:HI 3 "memory_operand" "m"))]
5828   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5829    && !TARGET_FISTTP
5830    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5831   "* return output_fix_trunc (insn, operands, false);"
5832   [(set_attr "type" "fistp")
5833    (set_attr "i387_cw" "trunc")
5834    (set_attr "mode" "<MODE>")])
5836 (define_insn "x86_fnstcw_1"
5837   [(set (match_operand:HI 0 "memory_operand" "=m")
5838         (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
5839   "TARGET_80387"
5840   "fnstcw\t%0"
5841   [(set (attr "length")
5842         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5843    (set_attr "mode" "HI")
5844    (set_attr "unit" "i387")
5845    (set_attr "bdver1_decode" "vector")])
5847 ;; Conversion between fixed point and floating point.
5849 ;; Even though we only accept memory inputs, the backend _really_
5850 ;; wants to be able to do this between registers.  Thankfully, LRA
5851 ;; will fix this up for us during register allocation.
5853 (define_insn "floathi<mode>2"
5854   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5855         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5856   "TARGET_80387
5857    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5858        || TARGET_MIX_SSE_I387)"
5859   "fild%Z1\t%1"
5860   [(set_attr "type" "fmov")
5861    (set_attr "mode" "<MODE>")
5862    (set_attr "znver1_decode" "double")
5863    (set_attr "fp_int_src" "true")])
5865 (define_insn "float<SWI48x:mode>xf2"
5866   [(set (match_operand:XF 0 "register_operand" "=f")
5867         (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5868   "TARGET_80387"
5869   "fild%Z1\t%1"
5870   [(set_attr "type" "fmov")
5871    (set_attr "mode" "XF")
5872    (set_attr "znver1_decode" "double")
5873    (set_attr "fp_int_src" "true")])
5875 (define_expand "float<SWI48x:mode><MODEF:mode>2"
5876   [(set (match_operand:MODEF 0 "register_operand")
5877         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
5878   "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
5879    || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5880        && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
5882 (define_insn "*float<SWI48:mode><MODEF:mode>2"
5883   [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5884         (float:MODEF
5885           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5886   "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5887    || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5888   "@
5889    fild%Z1\t%1
5890    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5891    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5892   [(set_attr "type" "fmov,sseicvt,sseicvt")
5893    (set_attr "avx_partial_xmm_update" "false,true,true")
5894    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5895    (set_attr "mode" "<MODEF:MODE>")
5896    (set (attr "prefix_rex")
5897      (if_then_else
5898        (and (eq_attr "prefix" "maybe_vex")
5899             (match_test "<SWI48:MODE>mode == DImode"))
5900        (const_string "1")
5901        (const_string "*")))
5902    (set_attr "unit" "i387,*,*")
5903    (set_attr "athlon_decode" "*,double,direct")
5904    (set_attr "amdfam10_decode" "*,vector,double")
5905    (set_attr "bdver1_decode" "*,double,direct")
5906    (set_attr "znver1_decode" "double,*,*")
5907    (set_attr "fp_int_src" "true")
5908    (set (attr "enabled")
5909      (if_then_else
5910        (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
5911        (if_then_else
5912          (eq_attr "alternative" "0")
5913          (symbol_ref "TARGET_MIX_SSE_I387
5914                       && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5915                                            <SWI48:MODE>mode)")
5916          (symbol_ref "true"))
5917        (if_then_else
5918          (eq_attr "alternative" "0")
5919          (symbol_ref "true")
5920          (symbol_ref "false"))))
5921    (set (attr "preferred_for_speed")
5922      (cond [(eq_attr "alternative" "1")
5923               (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5924            (symbol_ref "true")))])
5926 (define_insn "float<floatunssuffix><mode>hf2"
5927   [(set (match_operand:HF 0 "register_operand" "=v")
5928         (any_float:HF
5929           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5930   "TARGET_AVX512FP16"
5931   "vcvt<floatsuffix>si2sh<rex64suffix>\t{%1, %d0|%d0, %1}"
5932   [(set_attr "type" "sseicvt")
5933    (set_attr "prefix" "evex")
5934    (set_attr "mode" "HF")])
5936 (define_insn "*floatdi<MODEF:mode>2_i387"
5937   [(set (match_operand:MODEF 0 "register_operand" "=f")
5938         (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
5939   "!TARGET_64BIT
5940    && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
5941   "fild%Z1\t%1"
5942   [(set_attr "type" "fmov")
5943    (set_attr "mode" "<MODEF:MODE>")
5944    (set_attr "znver1_decode" "double")
5945    (set_attr "fp_int_src" "true")])
5947 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5948 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5949 ;; alternative in sse2_loadld.
5950 (define_split
5951   [(set (match_operand:MODEF 0 "sse_reg_operand")
5952         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5953   "TARGET_SSE2
5954    && TARGET_USE_VECTOR_CONVERTS
5955    && optimize_function_for_speed_p (cfun)
5956    && reload_completed
5957    && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5958    && (!EXT_REX_SSE_REG_P (operands[0])
5959        || TARGET_AVX512VL)"
5960   [(const_int 0)]
5962   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5963   operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5965   emit_insn (gen_sse2_loadld (operands[4],
5966                               CONST0_RTX (V4SImode), operands[1]));
5968   if (<ssevecmode>mode == V4SFmode)
5969     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5970   else
5971     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5972   DONE;
5975 ;; Avoid store forwarding (partial memory) stall penalty
5976 ;; by passing DImode value through XMM registers.  */
5978 (define_split
5979   [(set (match_operand:X87MODEF 0 "register_operand")
5980         (float:X87MODEF
5981           (match_operand:DI 1 "register_operand")))]
5982   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5983    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5984    && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
5985    && can_create_pseudo_p ()"
5986   [(const_int 0)]
5988   rtx s = assign_386_stack_local (DImode, SLOT_FLOATxFDI_387);
5989   emit_insn (gen_floatdi<mode>2_i387_with_xmm (operands[0], operands[1], s));
5990   DONE;
5993 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
5994   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5995         (float:X87MODEF
5996           (match_operand:DI 1 "register_operand" "r,r")))
5997    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5998    (clobber (match_scratch:V4SI 3 "=x,x"))
5999    (clobber (match_scratch:V4SI 4 "=X,x"))]
6000   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
6001    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6002    && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
6003   "#"
6004   "&& reload_completed"
6005   [(set (match_dup 2) (match_dup 3))
6006    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
6008   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
6009      Assemble the 64-bit DImode value in an xmm register.  */
6010   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
6011                               gen_lowpart (SImode, operands[1])));
6012   if (TARGET_SSE4_1)
6013     emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
6014                                   gen_highpart (SImode, operands[1]),
6015                                   GEN_INT (2)));
6016   else
6017     {
6018       emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
6019                                   gen_highpart (SImode, operands[1])));
6020       emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
6021                                              operands[4]));
6022     }
6023   operands[3] = gen_lowpart (DImode, operands[3]);
6025   [(set_attr "isa" "sse4,*")
6026    (set_attr "type" "multi")
6027    (set_attr "mode" "<X87MODEF:MODE>")
6028    (set_attr "unit" "i387")
6029    (set_attr "fp_int_src" "true")])
6031 ;; Break partial SSE register dependency stall.  This splitter should split
6032 ;; late in the pass sequence (after register rename pass), so allocated
6033 ;; registers won't change anymore
6035 (define_split
6036   [(set (match_operand:MODEF 0 "sse_reg_operand")
6037         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
6038   "!TARGET_AVX
6039    && TARGET_SSE_PARTIAL_REG_CONVERTS_DEPENDENCY
6040    && epilogue_completed
6041    && optimize_function_for_speed_p (cfun)
6042    && (!EXT_REX_SSE_REG_P (operands[0])
6043        || TARGET_AVX512VL)"
6044   [(set (match_dup 0)
6045         (vec_merge:<MODEF:ssevecmode>
6046           (vec_duplicate:<MODEF:ssevecmode>
6047             (float:MODEF
6048               (match_dup 1)))
6049           (match_dup 0)
6050           (const_int 1)))]
6052   const machine_mode vmode = <MODEF:ssevecmode>mode;
6054   operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
6055   emit_move_insn (operands[0], CONST0_RTX (vmode));
6058 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
6059   [(set (match_operand:MODEF 0 "register_operand")
6060         (unsigned_float:MODEF
6061           (match_operand:SWI12 1 "nonimmediate_operand")))]
6062   "!TARGET_64BIT
6063    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
6065   operands[1] = convert_to_mode (SImode, operands[1], 1);
6066   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
6067   DONE;
6070 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
6071   [(set (match_operand:MODEF 0 "register_operand" "=v")
6072         (unsigned_float:MODEF
6073           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
6074   "TARGET_AVX512F && TARGET_SSE_MATH"
6075   "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
6076   [(set_attr "type" "sseicvt")
6077    (set_attr "avx_partial_xmm_update" "true")
6078    (set_attr "prefix" "evex")
6079    (set_attr "mode" "<MODEF:MODE>")])
6081 ;; Avoid store forwarding (partial memory) stall penalty by extending
6082 ;; SImode value to DImode through XMM register instead of pushing two
6083 ;; SImode values to stack. Also note that fild loads from memory only.
6085 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
6086   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
6087         (unsigned_float:X87MODEF
6088           (match_operand:SI 1 "nonimmediate_operand" "rm")))
6089    (clobber (match_operand:DI 2 "memory_operand" "=m"))
6090    (clobber (match_scratch:DI 3 "=x"))]
6091   "!TARGET_64BIT
6092    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6093    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
6094   "#"
6095   "&& reload_completed"
6096   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
6097    (set (match_dup 2) (match_dup 3))
6098    (set (match_dup 0)
6099         (float:X87MODEF (match_dup 2)))]
6100   ""
6101   [(set_attr "type" "multi")
6102    (set_attr "mode" "<MODE>")])
6104 (define_expand "floatunssi<mode>2"
6105   [(set (match_operand:X87MODEF 0 "register_operand")
6106         (unsigned_float:X87MODEF
6107           (match_operand:SI 1 "nonimmediate_operand")))]
6108   "(!TARGET_64BIT
6109     && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6110     && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
6111    || ((!TARGET_64BIT || TARGET_AVX512F)
6112        && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6114   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
6115     {
6116       emit_insn (gen_floatunssi<mode>2_i387_with_xmm
6117                   (operands[0], operands[1],
6118                    assign_386_stack_local (DImode, SLOT_TEMP)));
6119       DONE;
6120     }
6121   if (!TARGET_AVX512F)
6122     {
6123       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6124       DONE;
6125     }
6128 (define_expand "floatunsdisf2"
6129   [(set (match_operand:SF 0 "register_operand")
6130         (unsigned_float:SF
6131           (match_operand:DI 1 "nonimmediate_operand")))]
6132   "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
6134   if (!TARGET_AVX512F)
6135     {
6136       x86_emit_floatuns (operands);
6137       DONE;
6138     }
6141 (define_expand "floatunsdidf2"
6142   [(set (match_operand:DF 0 "register_operand")
6143         (unsigned_float:DF
6144           (match_operand:DI 1 "nonimmediate_operand")))]
6145   "((TARGET_64BIT && TARGET_AVX512F)
6146     || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6147    && TARGET_SSE2 && TARGET_SSE_MATH"
6149   if (!TARGET_64BIT)
6150     {
6151       ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6152       DONE;
6153     }
6154   if (!TARGET_AVX512F)
6155     {
6156       x86_emit_floatuns (operands);
6157       DONE;
6158     }
6161 ;; Load effective address instructions
6163 (define_insn "*lea<mode>"
6164   [(set (match_operand:SWI48 0 "register_operand" "=r")
6165         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
6166   "ix86_hardreg_mov_ok (operands[0], operands[1])"
6168   if (SImode_address_operand (operands[1], VOIDmode))
6169     {
6170       gcc_assert (TARGET_64BIT);
6171       return "lea{l}\t{%E1, %k0|%k0, %E1}";
6172     }
6173   else 
6174     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
6176   [(set_attr "type" "lea")
6177    (set (attr "mode")
6178      (if_then_else
6179        (match_operand 1 "SImode_address_operand")
6180        (const_string "SI")
6181        (const_string "<MODE>")))])
6183 (define_peephole2
6184   [(set (match_operand:SWI48 0 "register_operand")
6185         (match_operand:SWI48 1 "address_no_seg_operand"))]
6186   "ix86_hardreg_mov_ok (operands[0], operands[1])
6187    && peep2_regno_dead_p (0, FLAGS_REG)
6188    && ix86_avoid_lea_for_addr (peep2_next_insn (0), operands)"
6189   [(const_int 0)]
6191   machine_mode mode = <MODE>mode;
6193   /* Emit all operations in SImode for zero-extended addresses.  */
6194   if (SImode_address_operand (operands[1], VOIDmode))
6195     mode = SImode;
6197   ix86_split_lea_for_addr (peep2_next_insn (0), operands, mode);
6199   /* Zero-extend return register to DImode for zero-extended addresses.  */
6200   if (mode != <MODE>mode)
6201     emit_insn (gen_zero_extendsidi2 (operands[0],
6202                                      gen_lowpart (mode, operands[0])));
6204   DONE;
6207 ;; ix86_split_lea_for_addr emits the shifts as MULT to avoid it from being
6208 ;; peephole2 optimized back into a lea.  Split that into the shift during
6209 ;; the following split pass.
6210 (define_split
6211   [(set (match_operand:SWI48 0 "general_reg_operand")
6212         (mult:SWI48 (match_dup 0) (match_operand:SWI48 1 "const1248_operand")))
6213    (clobber (reg:CC FLAGS_REG))]
6214   "reload_completed"
6215   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
6216               (clobber (reg:CC FLAGS_REG))])]
6217   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
6219 ;; Add instructions
6221 (define_expand "add<mode>3"
6222   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6223         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6224                     (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6225   ""
6226   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
6228 (define_insn_and_split "*add<dwi>3_doubleword"
6229   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6230         (plus:<DWI>
6231           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
6232           (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
6233    (clobber (reg:CC FLAGS_REG))]
6234   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
6235   "#"
6236   "&& reload_completed"
6237   [(parallel [(set (reg:CCC FLAGS_REG)
6238                    (compare:CCC
6239                      (plus:DWIH (match_dup 1) (match_dup 2))
6240                      (match_dup 1)))
6241               (set (match_dup 0)
6242                    (plus:DWIH (match_dup 1) (match_dup 2)))])
6243    (parallel [(set (match_dup 3)
6244                    (plus:DWIH
6245                      (plus:DWIH
6246                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6247                        (match_dup 4))
6248                      (match_dup 5)))
6249               (clobber (reg:CC FLAGS_REG))])]
6251   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6252   if (operands[2] == const0_rtx)
6253     {
6254       if (operands[5] != const0_rtx)
6255         ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
6256       else if (!rtx_equal_p (operands[3], operands[4]))
6257         emit_move_insn (operands[3], operands[4]);
6258       else
6259         emit_note (NOTE_INSN_DELETED);
6260       DONE;
6261     }
6264 (define_insn_and_split "*add<dwi>3_doubleword_zext"
6265   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6266         (plus:<DWI>
6267           (zero_extend:<DWI>
6268             (match_operand:DWIH 2 "nonimmediate_operand" "rm,r")) 
6269           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")))
6270    (clobber (reg:CC FLAGS_REG))]
6271   "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
6272   "#"
6273   "&& reload_completed"
6274   [(parallel [(set (reg:CCC FLAGS_REG)
6275                    (compare:CCC
6276                      (plus:DWIH (match_dup 1) (match_dup 2))
6277                      (match_dup 1)))
6278               (set (match_dup 0)
6279                    (plus:DWIH (match_dup 1) (match_dup 2)))])
6280    (parallel [(set (match_dup 3)
6281                    (plus:DWIH
6282                      (plus:DWIH
6283                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6284                        (match_dup 4))
6285                      (const_int 0)))
6286               (clobber (reg:CC FLAGS_REG))])]
6287  "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
6289 (define_insn_and_split "*add<dwi>3_doubleword_concat"
6290   [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6291         (plus:<DWI>
6292           (any_or_plus:<DWI>
6293             (ashift:<DWI>
6294               (zero_extend:<DWI>
6295                 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6296               (match_operand:QI 3 "const_int_operand"))
6297             (zero_extend:<DWI>
6298               (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6299           (match_operand:<DWI> 1 "register_operand" "0")))
6300    (clobber (reg:CC FLAGS_REG))]
6301   "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6302   "#"
6303   "&& reload_completed"
6304   [(parallel [(set (reg:CCC FLAGS_REG)
6305                    (compare:CCC
6306                      (plus:DWIH (match_dup 1) (match_dup 4))
6307                      (match_dup 1)))
6308               (set (match_dup 0)
6309                    (plus:DWIH (match_dup 1) (match_dup 4)))])
6310    (parallel [(set (match_dup 5)
6311                    (plus:DWIH
6312                      (plus:DWIH
6313                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6314                        (match_dup 6))
6315                      (match_dup 2)))
6316               (clobber (reg:CC FLAGS_REG))])]
6317  "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[5]);")
6319 (define_insn_and_split "*add<dwi>3_doubleword_concat_zext"
6320   [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6321         (plus:<DWI>
6322           (any_or_plus:<DWI>
6323             (ashift:<DWI>
6324               (zero_extend:<DWI>
6325                 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6326               (match_operand:QI 3 "const_int_operand"))
6327             (zero_extend:<DWI>
6328               (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6329           (zero_extend:<DWI>
6330             (match_operand:DWIH 1 "nonimmediate_operand" "rm"))))
6331    (clobber (reg:CC FLAGS_REG))]
6332   "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6333   "#"
6334   "&& reload_completed"
6335   [(set (match_dup 0) (match_dup 4))
6336    (set (match_dup 5) (match_dup 2))
6337    (parallel [(set (reg:CCC FLAGS_REG)
6338                    (compare:CCC
6339                      (plus:DWIH (match_dup 0) (match_dup 1))
6340                      (match_dup 0)))
6341               (set (match_dup 0)
6342                    (plus:DWIH (match_dup 0) (match_dup 1)))])
6343    (parallel [(set (match_dup 5)
6344                    (plus:DWIH
6345                      (plus:DWIH
6346                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6347                        (match_dup 5))
6348                      (const_int 0)))
6349               (clobber (reg:CC FLAGS_REG))])]
6350  "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[5]);")
6352 (define_insn "*add<mode>_1"
6353   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
6354         (plus:SWI48
6355           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6356           (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le")))
6357    (clobber (reg:CC FLAGS_REG))]
6358   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6360   switch (get_attr_type (insn))
6361     {
6362     case TYPE_LEA:
6363       return "#";
6365     case TYPE_INCDEC:
6366       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6367       if (operands[2] == const1_rtx)
6368         return "inc{<imodesuffix>}\t%0";
6369       else
6370         {
6371           gcc_assert (operands[2] == constm1_rtx);
6372           return "dec{<imodesuffix>}\t%0";
6373         }
6375     default:
6376       /* For most processors, ADD is faster than LEA.  This alternative
6377          was added to use ADD as much as possible.  */
6378       if (which_alternative == 2)
6379         std::swap (operands[1], operands[2]);
6380         
6381       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6382       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6383         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6385       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6386     }
6388   [(set (attr "type")
6389      (cond [(eq_attr "alternative" "3")
6390               (const_string "lea")
6391             (match_operand:SWI48 2 "incdec_operand")
6392               (const_string "incdec")
6393            ]
6394            (const_string "alu")))
6395    (set (attr "length_immediate")
6396       (if_then_else
6397         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6398         (const_string "1")
6399         (const_string "*")))
6400    (set_attr "mode" "<MODE>")])
6402 ;; It may seem that nonimmediate operand is proper one for operand 1.
6403 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6404 ;; we take care in ix86_binary_operator_ok to not allow two memory
6405 ;; operands so proper swapping will be done in reload.  This allow
6406 ;; patterns constructed from addsi_1 to match.
6408 (define_insn "addsi_1_zext"
6409   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6410         (zero_extend:DI
6411           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
6412                    (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le"))))
6413    (clobber (reg:CC FLAGS_REG))]
6414   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6416   switch (get_attr_type (insn))
6417     {
6418     case TYPE_LEA:
6419       return "#";
6421     case TYPE_INCDEC:
6422       if (operands[2] == const1_rtx)
6423         return "inc{l}\t%k0";
6424       else
6425         {
6426           gcc_assert (operands[2] == constm1_rtx);
6427           return "dec{l}\t%k0";
6428         }
6430     default:
6431       /* For most processors, ADD is faster than LEA.  This alternative
6432          was added to use ADD as much as possible.  */
6433       if (which_alternative == 1)
6434         std::swap (operands[1], operands[2]);
6436       if (x86_maybe_negate_const_int (&operands[2], SImode))
6437         return "sub{l}\t{%2, %k0|%k0, %2}";
6439       return "add{l}\t{%2, %k0|%k0, %2}";
6440     }
6442   [(set (attr "type")
6443      (cond [(eq_attr "alternative" "2")
6444               (const_string "lea")
6445             (match_operand:SI 2 "incdec_operand")
6446               (const_string "incdec")
6447            ]
6448            (const_string "alu")))
6449    (set (attr "length_immediate")
6450       (if_then_else
6451         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6452         (const_string "1")
6453         (const_string "*")))
6454    (set_attr "mode" "SI")])
6456 (define_insn "*addhi_1"
6457   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
6458         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
6459                  (match_operand:HI 2 "general_operand" "rn,m,0,ln")))
6460    (clobber (reg:CC FLAGS_REG))]
6461   "ix86_binary_operator_ok (PLUS, HImode, operands)"
6463   switch (get_attr_type (insn))
6464     {
6465     case TYPE_LEA:
6466       return "#";
6468     case TYPE_INCDEC:
6469       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6470       if (operands[2] == const1_rtx)
6471         return "inc{w}\t%0";
6472       else
6473         {
6474           gcc_assert (operands[2] == constm1_rtx);
6475           return "dec{w}\t%0";
6476         }
6478     default:
6479       /* For most processors, ADD is faster than LEA.  This alternative
6480          was added to use ADD as much as possible.  */
6481       if (which_alternative == 2)
6482         std::swap (operands[1], operands[2]);
6484       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6485       if (x86_maybe_negate_const_int (&operands[2], HImode))
6486         return "sub{w}\t{%2, %0|%0, %2}";
6488       return "add{w}\t{%2, %0|%0, %2}";
6489     }
6491   [(set (attr "type")
6492      (cond [(eq_attr "alternative" "3")
6493               (const_string "lea")
6494             (match_operand:HI 2 "incdec_operand")
6495               (const_string "incdec")
6496            ]
6497            (const_string "alu")))
6498    (set (attr "length_immediate")
6499       (if_then_else
6500         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6501         (const_string "1")
6502         (const_string "*")))
6503    (set_attr "mode" "HI,HI,HI,SI")])
6505 (define_insn "*addqi_1"
6506   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
6507         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
6508                  (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln")))
6509    (clobber (reg:CC FLAGS_REG))]
6510   "ix86_binary_operator_ok (PLUS, QImode, operands)"
6512   bool widen = (get_attr_mode (insn) != MODE_QI);
6514   switch (get_attr_type (insn))
6515     {
6516     case TYPE_LEA:
6517       return "#";
6519     case TYPE_INCDEC:
6520       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6521       if (operands[2] == const1_rtx)
6522         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6523       else
6524         {
6525           gcc_assert (operands[2] == constm1_rtx);
6526           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6527         }
6529     default:
6530       /* For most processors, ADD is faster than LEA.  These alternatives
6531          were added to use ADD as much as possible.  */
6532       if (which_alternative == 2 || which_alternative == 4)
6533         std::swap (operands[1], operands[2]);
6535       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6536       if (x86_maybe_negate_const_int (&operands[2], QImode))
6537         {
6538           if (widen)
6539             return "sub{l}\t{%2, %k0|%k0, %2}";
6540           else
6541             return "sub{b}\t{%2, %0|%0, %2}";
6542         }
6543       if (widen)
6544         return "add{l}\t{%k2, %k0|%k0, %k2}";
6545       else
6546         return "add{b}\t{%2, %0|%0, %2}";
6547     }
6549   [(set (attr "type")
6550      (cond [(eq_attr "alternative" "5")
6551               (const_string "lea")
6552             (match_operand:QI 2 "incdec_operand")
6553               (const_string "incdec")
6554            ]
6555            (const_string "alu")))
6556    (set (attr "length_immediate")
6557       (if_then_else
6558         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6559         (const_string "1")
6560         (const_string "*")))
6561    (set_attr "mode" "QI,QI,QI,SI,SI,SI")
6562    ;; Potential partial reg stall on alternatives 3 and 4.
6563    (set (attr "preferred_for_speed")
6564      (cond [(eq_attr "alternative" "3,4")
6565               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
6566            (symbol_ref "true")))])
6568 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6569 (define_insn_and_split "*add<mode>_1_slp"
6570   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
6571         (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
6572                     (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
6573    (clobber (reg:CC FLAGS_REG))]
6574   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6576   if (which_alternative)
6577     return "#";
6579   switch (get_attr_type (insn))
6580     {
6581     case TYPE_INCDEC:
6582       if (operands[2] == const1_rtx)
6583         return "inc{<imodesuffix>}\t%0";
6584       else
6585         {
6586           gcc_assert (operands[2] == constm1_rtx);
6587           return "dec{<imodesuffix>}\t%0";
6588         }
6590     default:
6591       if (x86_maybe_negate_const_int (&operands[2], QImode))
6592         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6594       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6595     }
6597   "&& reload_completed"
6598   [(set (strict_low_part (match_dup 0)) (match_dup 1))
6599    (parallel
6600      [(set (strict_low_part (match_dup 0))
6601            (plus:SWI12 (match_dup 0) (match_dup 2)))
6602       (clobber (reg:CC FLAGS_REG))])]
6603   ""
6604   [(set (attr "type")
6605      (if_then_else (match_operand:QI 2 "incdec_operand")
6606         (const_string "incdec")
6607         (const_string "alu")))
6608    (set_attr "mode" "<MODE>")])
6610 ;; Split non destructive adds if we cannot use lea.
6611 (define_split
6612   [(set (match_operand:SWI48 0 "register_operand")
6613         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
6614                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
6615    (clobber (reg:CC FLAGS_REG))]
6616   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6617   [(set (match_dup 0) (match_dup 1))
6618    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
6619               (clobber (reg:CC FLAGS_REG))])])
6621 ;; Split non destructive adds if we cannot use lea.
6622 (define_split
6623   [(set (match_operand:DI 0 "register_operand")
6624         (zero_extend:DI
6625           (plus:SI (match_operand:SI 1 "register_operand")
6626                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6627    (clobber (reg:CC FLAGS_REG))]
6628   "TARGET_64BIT
6629    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6630   [(set (match_dup 3) (match_dup 1))
6631    (parallel [(set (match_dup 0)
6632                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
6633               (clobber (reg:CC FLAGS_REG))])]
6634   "operands[3] = gen_lowpart (SImode, operands[0]);")
6636 ;; Convert add to the lea pattern to avoid flags dependency.
6637 (define_split
6638   [(set (match_operand:SWI 0 "register_operand")
6639         (plus:SWI (match_operand:SWI 1 "register_operand")
6640                   (match_operand:SWI 2 "<nonmemory_operand>")))
6641    (clobber (reg:CC FLAGS_REG))]
6642   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
6643   [(set (match_dup 0)
6644         (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
6646   if (<MODE>mode != <LEAMODE>mode)
6647     {
6648       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
6649       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
6650       operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
6651     }
6654 ;; Convert add to the lea pattern to avoid flags dependency.
6655 (define_split
6656   [(set (match_operand:DI 0 "register_operand")
6657         (zero_extend:DI
6658           (plus:SI (match_operand:SI 1 "register_operand")
6659                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6660    (clobber (reg:CC FLAGS_REG))]
6661   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6662   [(set (match_dup 0)
6663         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6665 (define_insn "*add<mode>_2"
6666   [(set (reg FLAGS_REG)
6667         (compare
6668           (plus:SWI
6669             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6670             (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,0"))
6671           (const_int 0)))
6672    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>")
6673         (plus:SWI (match_dup 1) (match_dup 2)))]
6674   "ix86_match_ccmode (insn, CCGOCmode)
6675    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6677   switch (get_attr_type (insn))
6678     {
6679     case TYPE_INCDEC:
6680       if (operands[2] == const1_rtx)
6681         return "inc{<imodesuffix>}\t%0";
6682       else
6683         {
6684           gcc_assert (operands[2] == constm1_rtx);
6685           return "dec{<imodesuffix>}\t%0";
6686         }
6688     default:
6689       if (which_alternative == 2)
6690         std::swap (operands[1], operands[2]);
6691         
6692       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6693       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6694         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6696       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6697     }
6699   [(set (attr "type")
6700      (if_then_else (match_operand:SWI 2 "incdec_operand")
6701         (const_string "incdec")
6702         (const_string "alu")))
6703    (set (attr "length_immediate")
6704       (if_then_else
6705         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6706         (const_string "1")
6707         (const_string "*")))
6708    (set_attr "mode" "<MODE>")])
6710 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6711 (define_insn "*addsi_2_zext"
6712   [(set (reg FLAGS_REG)
6713         (compare
6714           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6715                    (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6716           (const_int 0)))
6717    (set (match_operand:DI 0 "register_operand" "=r,r")
6718         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6719   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6720    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6722   switch (get_attr_type (insn))
6723     {
6724     case TYPE_INCDEC:
6725       if (operands[2] == const1_rtx)
6726         return "inc{l}\t%k0";
6727       else
6728         {
6729           gcc_assert (operands[2] == constm1_rtx);
6730           return "dec{l}\t%k0";
6731         }
6733     default:
6734       if (which_alternative == 1)
6735         std::swap (operands[1], operands[2]);
6737       if (x86_maybe_negate_const_int (&operands[2], SImode))
6738         return "sub{l}\t{%2, %k0|%k0, %2}";
6740       return "add{l}\t{%2, %k0|%k0, %2}";
6741     }
6743   [(set (attr "type")
6744      (if_then_else (match_operand:SI 2 "incdec_operand")
6745         (const_string "incdec")
6746         (const_string "alu")))
6747    (set (attr "length_immediate")
6748       (if_then_else
6749         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6750         (const_string "1")
6751         (const_string "*")))
6752    (set_attr "mode" "SI")])
6754 (define_insn "*add<mode>_3"
6755   [(set (reg FLAGS_REG)
6756         (compare
6757           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6758           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6759    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6760   "ix86_match_ccmode (insn, CCZmode)
6761    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6763   switch (get_attr_type (insn))
6764     {
6765     case TYPE_INCDEC:
6766       if (operands[2] == const1_rtx)
6767         return "inc{<imodesuffix>}\t%0";
6768       else
6769         {
6770           gcc_assert (operands[2] == constm1_rtx);
6771           return "dec{<imodesuffix>}\t%0";
6772         }
6774     default:
6775       if (which_alternative == 1)
6776         std::swap (operands[1], operands[2]);
6778       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6779       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6780         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6782       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6783     }
6785   [(set (attr "type")
6786      (if_then_else (match_operand:SWI 2 "incdec_operand")
6787         (const_string "incdec")
6788         (const_string "alu")))
6789    (set (attr "length_immediate")
6790       (if_then_else
6791         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6792         (const_string "1")
6793         (const_string "*")))
6794    (set_attr "mode" "<MODE>")])
6796 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6797 (define_insn "*addsi_3_zext"
6798   [(set (reg FLAGS_REG)
6799         (compare
6800           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6801           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6802    (set (match_operand:DI 0 "register_operand" "=r,r")
6803         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6804   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6805    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6807   switch (get_attr_type (insn))
6808     {
6809     case TYPE_INCDEC:
6810       if (operands[2] == const1_rtx)
6811         return "inc{l}\t%k0";
6812       else
6813         {
6814           gcc_assert (operands[2] == constm1_rtx);
6815           return "dec{l}\t%k0";
6816         }
6818     default:
6819       if (which_alternative == 1)
6820         std::swap (operands[1], operands[2]);
6822       if (x86_maybe_negate_const_int (&operands[2], SImode))
6823         return "sub{l}\t{%2, %k0|%k0, %2}";
6825       return "add{l}\t{%2, %k0|%k0, %2}";
6826     }
6828   [(set (attr "type")
6829      (if_then_else (match_operand:SI 2 "incdec_operand")
6830         (const_string "incdec")
6831         (const_string "alu")))
6832    (set (attr "length_immediate")
6833       (if_then_else
6834         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6835         (const_string "1")
6836         (const_string "*")))
6837    (set_attr "mode" "SI")])
6839 ; For comparisons against 1, -1 and 128, we may generate better code
6840 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6841 ; is matched then.  We can't accept general immediate, because for
6842 ; case of overflows,  the result is messed up.
6843 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6844 ; only for comparisons not depending on it.
6846 (define_insn "*adddi_4"
6847   [(set (reg FLAGS_REG)
6848         (compare
6849           (match_operand:DI 1 "nonimmediate_operand" "0")
6850           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6851    (clobber (match_scratch:DI 0 "=r"))]
6852   "TARGET_64BIT
6853    && ix86_match_ccmode (insn, CCGCmode)"
6855   switch (get_attr_type (insn))
6856     {
6857     case TYPE_INCDEC:
6858       if (operands[2] == constm1_rtx)
6859         return "inc{q}\t%0";
6860       else
6861         {
6862           gcc_assert (operands[2] == const1_rtx);
6863           return "dec{q}\t%0";
6864         }
6866     default:
6867       if (x86_maybe_negate_const_int (&operands[2], DImode))
6868         return "add{q}\t{%2, %0|%0, %2}";
6870       return "sub{q}\t{%2, %0|%0, %2}";
6871     }
6873   [(set (attr "type")
6874      (if_then_else (match_operand:DI 2 "incdec_operand")
6875         (const_string "incdec")
6876         (const_string "alu")))
6877    (set (attr "length_immediate")
6878       (if_then_else
6879         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6880         (const_string "1")
6881         (const_string "*")))
6882    (set_attr "mode" "DI")])
6884 ; For comparisons against 1, -1 and 128, we may generate better code
6885 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6886 ; is matched then.  We can't accept general immediate, because for
6887 ; case of overflows,  the result is messed up.
6888 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6889 ; only for comparisons not depending on it.
6891 (define_insn "*add<mode>_4"
6892   [(set (reg FLAGS_REG)
6893         (compare
6894           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6895           (match_operand:SWI124 2 "const_int_operand")))
6896    (clobber (match_scratch:SWI124 0 "=<r>"))]
6897   "ix86_match_ccmode (insn, CCGCmode)"
6899   switch (get_attr_type (insn))
6900     {
6901     case TYPE_INCDEC:
6902       if (operands[2] == constm1_rtx)
6903         return "inc{<imodesuffix>}\t%0";
6904       else
6905         {
6906           gcc_assert (operands[2] == const1_rtx);
6907           return "dec{<imodesuffix>}\t%0";
6908         }
6910     default:
6911       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6912         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6914       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6915     }
6917   [(set (attr "type")
6918      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6919         (const_string "incdec")
6920         (const_string "alu")))
6921    (set (attr "length_immediate")
6922       (if_then_else
6923         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6924         (const_string "1")
6925         (const_string "*")))
6926    (set_attr "mode" "<MODE>")])
6928 (define_insn "*add<mode>_5"
6929   [(set (reg FLAGS_REG)
6930         (compare
6931           (plus:SWI
6932             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6933             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6934           (const_int 0)))
6935    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6936   "ix86_match_ccmode (insn, CCGOCmode)
6937    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6939   switch (get_attr_type (insn))
6940     {
6941     case TYPE_INCDEC:
6942       if (operands[2] == const1_rtx)
6943         return "inc{<imodesuffix>}\t%0";
6944       else
6945         {
6946           gcc_assert (operands[2] == constm1_rtx);
6947           return "dec{<imodesuffix>}\t%0";
6948         }
6950     default:
6951       if (which_alternative == 1)
6952         std::swap (operands[1], operands[2]);
6954       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6955       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6956         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6958       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6959     }
6961   [(set (attr "type")
6962      (if_then_else (match_operand:SWI 2 "incdec_operand")
6963         (const_string "incdec")
6964         (const_string "alu")))
6965    (set (attr "length_immediate")
6966       (if_then_else
6967         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6968         (const_string "1")
6969         (const_string "*")))
6970    (set_attr "mode" "<MODE>")])
6972 (define_insn "*addqi_ext<mode>_0"
6973   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
6974         (plus:QI
6975           (subreg:QI
6976             (match_operator:SWI248 3 "extract_operator"
6977               [(match_operand 2 "int248_register_operand" "Q")
6978                (const_int 8)
6979                (const_int 8)]) 0)
6980           (match_operand:QI 1 "nonimmediate_operand" "0")))
6981    (clobber (reg:CC FLAGS_REG))]
6982   ""
6983   "add{b}\t{%h2, %0|%0, %h2}"
6984   [(set_attr "addr" "gpr8")
6985    (set_attr "type" "alu")
6986    (set_attr "mode" "QI")])
6988 (define_expand "addqi_ext_1"
6989   [(parallel
6990      [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
6991                             (const_int 8)
6992                             (const_int 8))
6993            (subreg:HI
6994              (plus:QI
6995                (subreg:QI
6996                  (zero_extract:HI (match_operand:HI 1 "register_operand")
6997                                   (const_int 8)
6998                                   (const_int 8)) 0)
6999                (match_operand:QI 2 "const_int_operand")) 0))
7000       (clobber (reg:CC FLAGS_REG))])])
7002 (define_insn "*addqi_ext<mode>_1"
7003   [(set (zero_extract:SWI248
7004           (match_operand 0 "int248_register_operand" "+Q")
7005           (const_int 8)
7006           (const_int 8))
7007         (subreg:SWI248
7008           (plus:QI
7009             (subreg:QI
7010               (match_operator:SWI248 3 "extract_operator"
7011                 [(match_operand 1 "int248_register_operand" "0")
7012                  (const_int 8)
7013                  (const_int 8)]) 0)
7014             (match_operand:QI 2 "general_operand" "QnBn")) 0))
7015    (clobber (reg:CC FLAGS_REG))]
7016   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
7017    rtx_equal_p (operands[0], operands[1])"
7019   switch (get_attr_type (insn))
7020     {
7021     case TYPE_INCDEC:
7022       if (operands[2] == const1_rtx)
7023         return "inc{b}\t%h0";
7024       else
7025         {
7026           gcc_assert (operands[2] == constm1_rtx);
7027           return "dec{b}\t%h0";
7028         }
7030     default:
7031       return "add{b}\t{%2, %h0|%h0, %2}";
7032     }
7034   [(set_attr "addr" "gpr8")
7035    (set (attr "type")
7036      (if_then_else (match_operand:QI 2 "incdec_operand")
7037         (const_string "incdec")
7038         (const_string "alu")))
7039    (set_attr "mode" "QI")])
7041 (define_insn "*addqi_ext<mode>_2"
7042   [(set (zero_extract:SWI248
7043           (match_operand 0 "int248_register_operand" "+Q")
7044           (const_int 8)
7045           (const_int 8))
7046         (subreg:SWI248
7047           (plus:QI
7048             (subreg:QI
7049               (match_operator:SWI248 3 "extract_operator"
7050                 [(match_operand 1 "int248_register_operand" "%0")
7051                  (const_int 8)
7052                  (const_int 8)]) 0)
7053             (subreg:QI
7054               (match_operator:SWI248 4 "extract_operator"
7055                 [(match_operand 2 "int248_register_operand" "Q")
7056                  (const_int 8)
7057                  (const_int 8)]) 0)) 0))
7058   (clobber (reg:CC FLAGS_REG))]
7059   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
7060    rtx_equal_p (operands[0], operands[1])
7061    || rtx_equal_p (operands[0], operands[2])"
7062   "add{b}\t{%h2, %h0|%h0, %h2}"
7063   [(set_attr "type" "alu")
7064    (set_attr "mode" "QI")])
7066 ;; Like DWI, but use POImode instead of OImode.
7067 (define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
7069 ;; Add with jump on overflow.
7070 (define_expand "addv<mode>4"
7071   [(parallel [(set (reg:CCO FLAGS_REG)
7072                    (eq:CCO
7073                      (plus:<DPWI>
7074                        (sign_extend:<DPWI>
7075                          (match_operand:SWIDWI 1 "nonimmediate_operand"))
7076                        (match_dup 4))
7077                          (sign_extend:<DPWI>
7078                            (plus:SWIDWI (match_dup 1)
7079                              (match_operand:SWIDWI 2
7080                                "<general_hilo_operand>")))))
7081               (set (match_operand:SWIDWI 0 "register_operand")
7082                    (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7083    (set (pc) (if_then_else
7084                (eq (reg:CCO FLAGS_REG) (const_int 0))
7085                (label_ref (match_operand 3))
7086                (pc)))]
7087   ""
7089   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
7090   if (CONST_SCALAR_INT_P (operands[2]))
7091     operands[4] = operands[2];
7092   else
7093     operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7096 (define_insn "*addv<mode>4"
7097   [(set (reg:CCO FLAGS_REG)
7098         (eq:CCO (plus:<DWI>
7099                    (sign_extend:<DWI>
7100                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7101                    (sign_extend:<DWI>
7102                       (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7103                 (sign_extend:<DWI>
7104                    (plus:SWI (match_dup 1) (match_dup 2)))))
7105    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7106         (plus:SWI (match_dup 1) (match_dup 2)))]
7107   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7108   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7109   [(set_attr "type" "alu")
7110    (set_attr "mode" "<MODE>")])
7112 (define_insn "addv<mode>4_1"
7113   [(set (reg:CCO FLAGS_REG)
7114         (eq:CCO (plus:<DWI>
7115                    (sign_extend:<DWI>
7116                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
7117                    (match_operand:<DWI> 3 "const_int_operand"))
7118                 (sign_extend:<DWI>
7119                    (plus:SWI
7120                      (match_dup 1)
7121                      (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7122    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7123         (plus:SWI (match_dup 1) (match_dup 2)))]
7124   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7125    && CONST_INT_P (operands[2])
7126    && INTVAL (operands[2]) == INTVAL (operands[3])"
7127   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7128   [(set_attr "type" "alu")
7129    (set_attr "mode" "<MODE>")
7130    (set (attr "length_immediate")
7131         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7132                   (const_string "1")
7133                (match_test "<MODE_SIZE> == 8")
7134                   (const_string "4")]
7135               (const_string "<MODE_SIZE>")))])
7137 ;; Quad word integer modes as mode attribute.
7138 (define_mode_attr QPWI [(SI "TI") (DI "POI")])
7140 (define_insn_and_split "*addv<dwi>4_doubleword"
7141   [(set (reg:CCO FLAGS_REG)
7142         (eq:CCO
7143           (plus:<QPWI>
7144             (sign_extend:<QPWI>
7145               (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0"))
7146             (sign_extend:<QPWI>
7147               (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7148           (sign_extend:<QPWI>
7149             (plus:<DWI> (match_dup 1) (match_dup 2)))))
7150    (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7151         (plus:<DWI> (match_dup 1) (match_dup 2)))]
7152   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
7153   "#"
7154   "&& reload_completed"
7155   [(parallel [(set (reg:CCC FLAGS_REG)
7156                    (compare:CCC
7157                      (plus:DWIH (match_dup 1) (match_dup 2))
7158                      (match_dup 1)))
7159               (set (match_dup 0)
7160                    (plus:DWIH (match_dup 1) (match_dup 2)))])
7161    (parallel [(set (reg:CCO FLAGS_REG)
7162                    (eq:CCO
7163                      (plus:<DWI>
7164                        (plus:<DWI>
7165                          (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7166                          (sign_extend:<DWI> (match_dup 4)))
7167                        (sign_extend:<DWI> (match_dup 5)))
7168                      (sign_extend:<DWI>
7169                        (plus:DWIH
7170                          (plus:DWIH
7171                            (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7172                            (match_dup 4))
7173                          (match_dup 5)))))
7174               (set (match_dup 3)
7175                    (plus:DWIH
7176                      (plus:DWIH
7177                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7178                        (match_dup 4))
7179                      (match_dup 5)))])]
7181   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7184 (define_insn_and_split "*addv<dwi>4_doubleword_1"
7185   [(set (reg:CCO FLAGS_REG)
7186         (eq:CCO
7187           (plus:<QPWI>
7188             (sign_extend:<QPWI>
7189               (match_operand:<DWI> 1 "nonimmediate_operand" "%0"))
7190             (match_operand:<QPWI> 3 "const_scalar_int_operand" "n"))
7191           (sign_extend:<QPWI>
7192             (plus:<DWI>
7193               (match_dup 1)
7194               (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7195    (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7196         (plus:<DWI> (match_dup 1) (match_dup 2)))]
7197   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)
7198    && CONST_SCALAR_INT_P (operands[2])
7199    && rtx_equal_p (operands[2], operands[3])"
7200   "#"
7201   "&& reload_completed"
7202   [(parallel [(set (reg:CCC FLAGS_REG)
7203                    (compare:CCC
7204                      (plus:DWIH (match_dup 1) (match_dup 2))
7205                      (match_dup 1)))
7206               (set (match_dup 0)
7207                    (plus:DWIH (match_dup 1) (match_dup 2)))])
7208    (parallel [(set (reg:CCO FLAGS_REG)
7209                    (eq:CCO
7210                      (plus:<DWI>
7211                        (plus:<DWI>
7212                          (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7213                          (sign_extend:<DWI> (match_dup 4)))
7214                        (match_dup 5))
7215                      (sign_extend:<DWI>
7216                        (plus:DWIH
7217                          (plus:DWIH
7218                            (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7219                            (match_dup 4))
7220                          (match_dup 5)))))
7221               (set (match_dup 3)
7222                    (plus:DWIH
7223                      (plus:DWIH
7224                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7225                        (match_dup 4))
7226                      (match_dup 5)))])]
7228   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7229   if (operands[2] == const0_rtx)
7230     {
7231       emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
7232                                     operands[5]));
7233       DONE;
7234     }
7237 (define_insn "*addv<mode>4_overflow_1"
7238   [(set (reg:CCO FLAGS_REG)
7239         (eq:CCO
7240           (plus:<DWI>
7241             (plus:<DWI>
7242               (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7243                 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7244               (sign_extend:<DWI>
7245                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")))
7246             (sign_extend:<DWI>
7247               (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7248           (sign_extend:<DWI>
7249             (plus:SWI
7250               (plus:SWI
7251                 (match_operator:SWI 5 "ix86_carry_flag_operator"
7252                   [(match_dup 3) (const_int 0)])
7253                 (match_dup 1))
7254               (match_dup 2)))))
7255    (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7256         (plus:SWI
7257           (plus:SWI
7258             (match_op_dup 5 [(match_dup 3) (const_int 0)])
7259             (match_dup 1))
7260           (match_dup 2)))]
7261   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7262   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7263   [(set_attr "type" "alu")
7264    (set_attr "mode" "<MODE>")])
7266 (define_insn "*addv<mode>4_overflow_2"
7267   [(set (reg:CCO FLAGS_REG)
7268         (eq:CCO
7269           (plus:<DWI>
7270             (plus:<DWI>
7271               (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7272                 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7273               (sign_extend:<DWI>
7274                 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
7275             (match_operand:<DWI> 6 "const_int_operand" "n"))
7276           (sign_extend:<DWI>
7277             (plus:SWI
7278               (plus:SWI
7279                 (match_operator:SWI 5 "ix86_carry_flag_operator"
7280                   [(match_dup 3) (const_int 0)])
7281                 (match_dup 1))
7282               (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7283    (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7284         (plus:SWI
7285           (plus:SWI
7286             (match_op_dup 5 [(match_dup 3) (const_int 0)])
7287             (match_dup 1))
7288           (match_dup 2)))]
7289   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7290    && CONST_INT_P (operands[2])
7291    && INTVAL (operands[2]) == INTVAL (operands[6])"
7292   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7293   [(set_attr "type" "alu")
7294    (set_attr "mode" "<MODE>")
7295    (set (attr "length_immediate")
7296      (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7297        (const_string "1")
7298        (const_string "4")))])
7300 (define_expand "uaddv<mode>4"
7301   [(parallel [(set (reg:CCC FLAGS_REG)
7302                    (compare:CCC
7303                      (plus:SWIDWI
7304                        (match_operand:SWIDWI 1 "nonimmediate_operand")
7305                        (match_operand:SWIDWI 2 "<general_hilo_operand>"))
7306                      (match_dup 1)))
7307               (set (match_operand:SWIDWI 0 "register_operand")
7308                    (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7309    (set (pc) (if_then_else
7310                (ltu (reg:CCC FLAGS_REG) (const_int 0))
7311                (label_ref (match_operand 3))
7312                (pc)))]
7313   ""
7314   "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
7316 ;; The lea patterns for modes less than 32 bits need to be matched by
7317 ;; several insns converted to real lea by splitters.
7319 (define_insn_and_split "*lea<mode>_general_1"
7320   [(set (match_operand:SWI12 0 "register_operand" "=r")
7321         (plus:SWI12
7322           (plus:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7323                       (match_operand:SWI12 2 "register_operand" "r"))
7324           (match_operand:SWI12 3 "immediate_operand" "i")))]
7325   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7326   "#"
7327   "&& reload_completed"
7328   [(set (match_dup 0)
7329         (plus:SI
7330           (plus:SI (match_dup 1) (match_dup 2))
7331           (match_dup 3)))]
7333   operands[0] = gen_lowpart (SImode, operands[0]);
7334   operands[1] = gen_lowpart (SImode, operands[1]);
7335   operands[2] = gen_lowpart (SImode, operands[2]);
7336   operands[3] = gen_lowpart (SImode, operands[3]);
7338   [(set_attr "type" "lea")
7339    (set_attr "mode" "SI")])
7341 (define_insn_and_split "*lea<mode>_general_2"
7342   [(set (match_operand:SWI12 0 "register_operand" "=r")
7343         (plus:SWI12
7344           (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7345                       (match_operand 2 "const248_operand" "n"))
7346           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7347   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7348   "#"
7349   "&& reload_completed"
7350   [(set (match_dup 0)
7351         (plus:SI
7352           (mult:SI (match_dup 1) (match_dup 2))
7353           (match_dup 3)))]
7355   operands[0] = gen_lowpart (SImode, operands[0]);
7356   operands[1] = gen_lowpart (SImode, operands[1]);
7357   operands[3] = gen_lowpart (SImode, operands[3]);
7359   [(set_attr "type" "lea")
7360    (set_attr "mode" "SI")])
7362 (define_insn_and_split "*lea<mode>_general_2b"
7363   [(set (match_operand:SWI12 0 "register_operand" "=r")
7364         (plus:SWI12
7365           (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7366                         (match_operand 2 "const123_operand" "n"))
7367           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7368   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7369   "#"
7370   "&& reload_completed"
7371   [(set (match_dup 0)
7372         (plus:SI
7373           (ashift:SI (match_dup 1) (match_dup 2))
7374           (match_dup 3)))]
7376   operands[0] = gen_lowpart (SImode, operands[0]);
7377   operands[1] = gen_lowpart (SImode, operands[1]);
7378   operands[3] = gen_lowpart (SImode, operands[3]);
7380   [(set_attr "type" "lea")
7381    (set_attr "mode" "SI")])
7383 (define_insn_and_split "*lea<mode>_general_3"
7384   [(set (match_operand:SWI12 0 "register_operand" "=r")
7385         (plus:SWI12
7386           (plus:SWI12
7387             (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7388                         (match_operand 2 "const248_operand" "n"))
7389             (match_operand:SWI12 3 "register_operand" "r"))
7390           (match_operand:SWI12 4 "immediate_operand" "i")))]
7391   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7392   "#"
7393   "&& reload_completed"
7394   [(set (match_dup 0)
7395         (plus:SI
7396           (plus:SI
7397             (mult:SI (match_dup 1) (match_dup 2))
7398             (match_dup 3))
7399           (match_dup 4)))]
7401   operands[0] = gen_lowpart (SImode, operands[0]);
7402   operands[1] = gen_lowpart (SImode, operands[1]);
7403   operands[3] = gen_lowpart (SImode, operands[3]);
7404   operands[4] = gen_lowpart (SImode, operands[4]);
7406   [(set_attr "type" "lea")
7407    (set_attr "mode" "SI")])
7409 (define_insn_and_split "*lea<mode>_general_3b"
7410   [(set (match_operand:SWI12 0 "register_operand" "=r")
7411         (plus:SWI12
7412           (plus:SWI12
7413             (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7414                           (match_operand 2 "const123_operand" "n"))
7415             (match_operand:SWI12 3 "register_operand" "r"))
7416           (match_operand:SWI12 4 "immediate_operand" "i")))]
7417   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7418   "#"
7419   "&& reload_completed"
7420   [(set (match_dup 0)
7421         (plus:SI
7422           (plus:SI
7423             (ashift:SI (match_dup 1) (match_dup 2))
7424             (match_dup 3))
7425           (match_dup 4)))]
7427   operands[0] = gen_lowpart (SImode, operands[0]);
7428   operands[1] = gen_lowpart (SImode, operands[1]);
7429   operands[3] = gen_lowpart (SImode, operands[3]);
7430   operands[4] = gen_lowpart (SImode, operands[4]);
7432   [(set_attr "type" "lea")
7433    (set_attr "mode" "SI")])
7435 (define_insn_and_split "*lea<mode>_general_4"
7436   [(set (match_operand:SWI12 0 "register_operand" "=r")
7437         (any_or:SWI12
7438           (ashift:SWI12
7439             (match_operand:SWI12 1 "register_no_SP_operand" "l")
7440             (match_operand 2 "const_0_to_3_operand"))
7441           (match_operand 3 "const_int_operand")))]
7442   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7443    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
7444        < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
7445   "#"
7446   "&& reload_completed"
7447   [(set (match_dup 0)
7448         (plus:SI
7449           (mult:SI (match_dup 1) (match_dup 2))
7450           (match_dup 3)))]
7452   operands[0] = gen_lowpart (SImode, operands[0]);
7453   operands[1] = gen_lowpart (SImode, operands[1]);
7454   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
7456   [(set_attr "type" "lea")
7457    (set_attr "mode" "SI")])
7459 (define_insn_and_split "*lea<mode>_general_4"
7460   [(set (match_operand:SWI48 0 "register_operand" "=r")
7461         (any_or:SWI48
7462           (ashift:SWI48
7463             (match_operand:SWI48 1 "register_no_SP_operand" "l")
7464             (match_operand 2 "const_0_to_3_operand"))
7465           (match_operand 3 "const_int_operand")))]
7466   "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
7467    < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
7468   "#"
7469   "&& reload_completed"
7470   [(set (match_dup 0)
7471         (plus:SWI48
7472           (mult:SWI48 (match_dup 1) (match_dup 2))
7473           (match_dup 3)))]
7474   "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
7475   [(set_attr "type" "lea")
7476    (set_attr "mode" "<MODE>")])
7478 ;; Subtract instructions
7480 (define_expand "sub<mode>3"
7481   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
7482         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
7483                      (match_operand:SDWIM 2 "<general_hilo_operand>")))]
7484   ""
7485   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7487 (define_insn_and_split "*sub<dwi>3_doubleword"
7488   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7489         (minus:<DWI>
7490           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7491           (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
7492    (clobber (reg:CC FLAGS_REG))]
7493   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7494   "#"
7495   "&& reload_completed"
7496   [(parallel [(set (reg:CC FLAGS_REG)
7497                    (compare:CC (match_dup 1) (match_dup 2)))
7498               (set (match_dup 0)
7499                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7500    (parallel [(set (match_dup 3)
7501                    (minus:DWIH
7502                      (minus:DWIH
7503                        (match_dup 4)
7504                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7505                      (match_dup 5)))
7506               (clobber (reg:CC FLAGS_REG))])]
7508   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7509   if (operands[2] == const0_rtx)
7510     {
7511       ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
7512       DONE;
7513     }
7516 (define_insn_and_split "*sub<dwi>3_doubleword_zext"
7517   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7518         (minus:<DWI>
7519           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7520           (zero_extend:<DWI>
7521             (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))))
7522    (clobber (reg:CC FLAGS_REG))]
7523   "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
7524   "#"
7525   "&& reload_completed"
7526   [(parallel [(set (reg:CC FLAGS_REG)
7527                    (compare:CC (match_dup 1) (match_dup 2)))
7528               (set (match_dup 0)
7529                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7530    (parallel [(set (match_dup 3)
7531                    (minus:DWIH
7532                      (minus:DWIH
7533                        (match_dup 4)
7534                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7535                      (const_int 0)))
7536               (clobber (reg:CC FLAGS_REG))])]
7537   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
7539 (define_insn "*sub<mode>_1"
7540   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7541         (minus:SWI
7542           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7543           (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7544    (clobber (reg:CC FLAGS_REG))]
7545   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7546   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7547   [(set_attr "type" "alu")
7548    (set_attr "mode" "<MODE>")])
7550 (define_insn "*subsi_1_zext"
7551   [(set (match_operand:DI 0 "register_operand" "=r")
7552         (zero_extend:DI
7553           (minus:SI (match_operand:SI 1 "register_operand" "0")
7554                     (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
7555    (clobber (reg:CC FLAGS_REG))]
7556   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7557   "sub{l}\t{%2, %k0|%k0, %2}"
7558   [(set_attr "type" "alu")
7559    (set_attr "mode" "SI")])
7561 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7562 (define_insn_and_split "*sub<mode>_1_slp"
7563   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
7564         (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
7565                      (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
7566    (clobber (reg:CC FLAGS_REG))]
7567   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7568   "@
7569    sub{<imodesuffix>}\t{%2, %0|%0, %2}
7570    #"
7571   "&& reload_completed"
7572   [(set (strict_low_part (match_dup 0)) (match_dup 1))
7573    (parallel
7574      [(set (strict_low_part (match_dup 0))
7575            (minus:SWI12 (match_dup 0) (match_dup 2)))
7576       (clobber (reg:CC FLAGS_REG))])]
7577   ""
7578   [(set_attr "type" "alu")
7579    (set_attr "mode" "<MODE>")])
7581 (define_insn "*sub<mode>_2"
7582   [(set (reg FLAGS_REG)
7583         (compare
7584           (minus:SWI
7585             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7586             (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
7587           (const_int 0)))
7588    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7589         (minus:SWI (match_dup 1) (match_dup 2)))]
7590   "ix86_match_ccmode (insn, CCGOCmode)
7591    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7592   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7593   [(set_attr "type" "alu")
7594    (set_attr "mode" "<MODE>")])
7596 (define_insn "*subsi_2_zext"
7597   [(set (reg FLAGS_REG)
7598         (compare
7599           (minus:SI (match_operand:SI 1 "register_operand" "0")
7600                     (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
7601           (const_int 0)))
7602    (set (match_operand:DI 0 "register_operand" "=r")
7603         (zero_extend:DI
7604           (minus:SI (match_dup 1)
7605                     (match_dup 2))))]
7606   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7607    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7608   "sub{l}\t{%2, %k0|%k0, %2}"
7609   [(set_attr "type" "alu")
7610    (set_attr "mode" "SI")])
7612 (define_insn "*subqi_ext<mode>_0"
7613   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
7614         (minus:QI
7615           (match_operand:QI 1 "nonimmediate_operand" "0")
7616           (subreg:QI
7617             (match_operator:SWI248 3 "extract_operator"
7618               [(match_operand 2 "int248_register_operand" "Q")
7619                (const_int 8)
7620                (const_int 8)]) 0)))
7621    (clobber (reg:CC FLAGS_REG))]
7622   ""
7623   "sub{b}\t{%h2, %0|%0, %h2}"
7624   [(set_attr "addr" "gpr8")
7625    (set_attr "type" "alu")
7626    (set_attr "mode" "QI")])
7628 (define_insn "*subqi_ext<mode>_2"
7629   [(set (zero_extract:SWI248
7630           (match_operand 0 "int248_register_operand" "+Q")
7631           (const_int 8)
7632           (const_int 8))
7633         (subreg:SWI248
7634           (minus:QI
7635             (subreg:QI
7636               (match_operator:SWI248 3 "extract_operator"
7637                 [(match_operand 1 "int248_register_operand" "0")
7638                  (const_int 8)
7639                  (const_int 8)]) 0)
7640             (subreg:QI
7641               (match_operator:SWI248 4 "extract_operator"
7642                 [(match_operand 2 "int248_register_operand" "Q")
7643                  (const_int 8)
7644                  (const_int 8)]) 0)) 0))
7645   (clobber (reg:CC FLAGS_REG))]
7646   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
7647    rtx_equal_p (operands[0], operands[1])"
7648   "sub{b}\t{%h2, %h0|%h0, %h2}"
7649   [(set_attr "type" "alu")
7650    (set_attr "mode" "QI")])
7652 ;; Subtract with jump on overflow.
7653 (define_expand "subv<mode>4"
7654   [(parallel [(set (reg:CCO FLAGS_REG)
7655                    (eq:CCO
7656                      (minus:<DPWI>
7657                        (sign_extend:<DPWI>
7658                          (match_operand:SWIDWI 1 "nonimmediate_operand"))
7659                        (match_dup 4))
7660                      (sign_extend:<DPWI>
7661                        (minus:SWIDWI (match_dup 1)
7662                                      (match_operand:SWIDWI 2
7663                                                 "<general_hilo_operand>")))))
7664               (set (match_operand:SWIDWI 0 "register_operand")
7665                    (minus:SWIDWI (match_dup 1) (match_dup 2)))])
7666    (set (pc) (if_then_else
7667                (eq (reg:CCO FLAGS_REG) (const_int 0))
7668                (label_ref (match_operand 3))
7669                (pc)))]
7670   ""
7672   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
7673   if (CONST_SCALAR_INT_P (operands[2]))
7674     operands[4] = operands[2];
7675   else
7676     operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7679 (define_insn "*subv<mode>4"
7680   [(set (reg:CCO FLAGS_REG)
7681         (eq:CCO (minus:<DWI>
7682                    (sign_extend:<DWI>
7683                       (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
7684                    (sign_extend:<DWI>
7685                       (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7686                 (sign_extend:<DWI>
7687                    (minus:SWI (match_dup 1) (match_dup 2)))))
7688    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7689         (minus:SWI (match_dup 1) (match_dup 2)))]
7690   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7691   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7692   [(set_attr "type" "alu")
7693    (set_attr "mode" "<MODE>")])
7695 (define_insn "subv<mode>4_1"
7696   [(set (reg:CCO FLAGS_REG)
7697         (eq:CCO (minus:<DWI>
7698                    (sign_extend:<DWI>
7699                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
7700                    (match_operand:<DWI> 3 "const_int_operand"))
7701                 (sign_extend:<DWI>
7702                    (minus:SWI
7703                      (match_dup 1)
7704                      (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7705    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7706         (minus:SWI (match_dup 1) (match_dup 2)))]
7707   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7708    && CONST_INT_P (operands[2])
7709    && INTVAL (operands[2]) == INTVAL (operands[3])"
7710   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7711   [(set_attr "type" "alu")
7712    (set_attr "mode" "<MODE>")
7713    (set (attr "length_immediate")
7714         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7715                   (const_string "1")
7716                (match_test "<MODE_SIZE> == 8")
7717                   (const_string "4")]
7718               (const_string "<MODE_SIZE>")))])
7720 (define_insn_and_split "*subv<dwi>4_doubleword"
7721   [(set (reg:CCO FLAGS_REG)
7722         (eq:CCO
7723           (minus:<QPWI>
7724             (sign_extend:<QPWI>
7725               (match_operand:<DWI> 1 "nonimmediate_operand" "0,0"))
7726             (sign_extend:<QPWI>
7727               (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7728           (sign_extend:<QPWI>
7729             (minus:<DWI> (match_dup 1) (match_dup 2)))))
7730    (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7731         (minus:<DWI> (match_dup 1) (match_dup 2)))]
7732   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7733   "#"
7734   "&& reload_completed"
7735   [(parallel [(set (reg:CC FLAGS_REG)
7736                    (compare:CC (match_dup 1) (match_dup 2)))
7737               (set (match_dup 0)
7738                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7739    (parallel [(set (reg:CCO FLAGS_REG)
7740                    (eq:CCO
7741                      (minus:<DWI>
7742                        (minus:<DWI>
7743                          (sign_extend:<DWI> (match_dup 4))
7744                          (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7745                        (sign_extend:<DWI> (match_dup 5)))
7746                      (sign_extend:<DWI>
7747                        (minus:DWIH
7748                          (minus:DWIH
7749                            (match_dup 4)
7750                            (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7751                          (match_dup 5)))))
7752               (set (match_dup 3)
7753                    (minus:DWIH
7754                      (minus:DWIH
7755                        (match_dup 4)
7756                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7757                      (match_dup 5)))])]
7759   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7762 (define_insn_and_split "*subv<dwi>4_doubleword_1"
7763   [(set (reg:CCO FLAGS_REG)
7764         (eq:CCO
7765           (minus:<QPWI>
7766             (sign_extend:<QPWI>
7767               (match_operand:<DWI> 1 "nonimmediate_operand" "0"))
7768             (match_operand:<QPWI> 3 "const_scalar_int_operand"))
7769           (sign_extend:<QPWI>
7770             (minus:<DWI>
7771               (match_dup 1)
7772               (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7773    (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7774         (minus:<DWI> (match_dup 1) (match_dup 2)))]
7775   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7776    && CONST_SCALAR_INT_P (operands[2])
7777    && rtx_equal_p (operands[2], operands[3])"
7778   "#"
7779   "&& reload_completed"
7780   [(parallel [(set (reg:CC FLAGS_REG)
7781                    (compare:CC (match_dup 1) (match_dup 2)))
7782               (set (match_dup 0)
7783                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7784    (parallel [(set (reg:CCO FLAGS_REG)
7785                    (eq:CCO
7786                      (minus:<DWI>
7787                        (minus:<DWI>
7788                          (sign_extend:<DWI> (match_dup 4))
7789                          (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7790                        (match_dup 5))
7791                      (sign_extend:<DWI>
7792                        (minus:DWIH
7793                          (minus:DWIH
7794                            (match_dup 4)
7795                            (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7796                          (match_dup 5)))))
7797               (set (match_dup 3)
7798                    (minus:DWIH
7799                      (minus:DWIH
7800                        (match_dup 4)
7801                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7802                      (match_dup 5)))])]
7804   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7805   if (operands[2] == const0_rtx)
7806     {
7807       emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
7808                                     operands[5]));
7809       DONE;
7810     }
7813 (define_insn "*subv<mode>4_overflow_1"
7814   [(set (reg:CCO FLAGS_REG)
7815         (eq:CCO
7816           (minus:<DWI>
7817             (minus:<DWI>
7818               (sign_extend:<DWI>
7819                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7820               (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7821                 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7822             (sign_extend:<DWI>
7823               (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7824           (sign_extend:<DWI>
7825             (minus:SWI
7826               (minus:SWI
7827                 (match_dup 1)
7828                 (match_operator:SWI 5 "ix86_carry_flag_operator"
7829                   [(match_dup 3) (const_int 0)]))
7830               (match_dup 2)))))
7831    (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7832         (minus:SWI
7833           (minus:SWI
7834             (match_dup 1)
7835             (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7836           (match_dup 2)))]
7837   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7838   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7839   [(set_attr "type" "alu")
7840    (set_attr "mode" "<MODE>")])
7842 (define_insn "*subv<mode>4_overflow_2"
7843   [(set (reg:CCO FLAGS_REG)
7844         (eq:CCO
7845           (minus:<DWI>
7846             (minus:<DWI>
7847               (sign_extend:<DWI>
7848                 (match_operand:SWI 1 "nonimmediate_operand" "%0"))
7849               (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7850                 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7851             (match_operand:<DWI> 6 "const_int_operand" "n"))
7852           (sign_extend:<DWI>
7853             (minus:SWI
7854               (minus:SWI
7855                 (match_dup 1)
7856                 (match_operator:SWI 5 "ix86_carry_flag_operator"
7857                   [(match_dup 3) (const_int 0)]))
7858               (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7859    (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7860         (minus:SWI
7861           (minus:SWI
7862             (match_dup 1)
7863             (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7864           (match_dup 2)))]
7865   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7866    && CONST_INT_P (operands[2])
7867    && INTVAL (operands[2]) == INTVAL (operands[6])"
7868   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7869   [(set_attr "type" "alu")
7870    (set_attr "mode" "<MODE>")
7871    (set (attr "length_immediate")
7872      (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7873        (const_string "1")
7874        (const_string "4")))])
7876 (define_expand "usubv<mode>4"
7877   [(parallel [(set (reg:CC FLAGS_REG)
7878                    (compare:CC
7879                      (match_operand:SWI 1 "nonimmediate_operand")
7880                      (match_operand:SWI 2 "<general_operand>")))
7881               (set (match_operand:SWI 0 "register_operand")
7882                    (minus:SWI (match_dup 1) (match_dup 2)))])
7883    (set (pc) (if_then_else
7884                (ltu (reg:CC FLAGS_REG) (const_int 0))
7885                (label_ref (match_operand 3))
7886                (pc)))]
7887   ""
7888   "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
7890 (define_insn "*sub<mode>_3"
7891   [(set (reg FLAGS_REG)
7892         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7893                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7894    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7895         (minus:SWI (match_dup 1) (match_dup 2)))]
7896   "ix86_match_ccmode (insn, CCmode)
7897    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7898   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7899   [(set_attr "type" "alu")
7900    (set_attr "mode" "<MODE>")])
7902 (define_peephole2
7903   [(parallel
7904      [(set (reg:CC FLAGS_REG)
7905            (compare:CC (match_operand:SWI 0 "general_reg_operand")
7906                        (match_operand:SWI 1 "general_gr_operand")))
7907       (set (match_dup 0)
7908            (minus:SWI (match_dup 0) (match_dup 1)))])]
7909   "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
7910   [(set (reg:CC FLAGS_REG)
7911         (compare:CC (match_dup 0) (match_dup 1)))])
7913 (define_peephole2
7914   [(set (match_operand:SWI 0 "general_reg_operand")
7915         (match_operand:SWI 1 "memory_operand"))
7916    (parallel [(set (reg:CC FLAGS_REG)
7917                    (compare:CC (match_dup 0)
7918                                (match_operand:SWI 2 "memory_operand")))
7919               (set (match_dup 0)
7920                    (minus:SWI (match_dup 0) (match_dup 2)))])
7921    (set (match_dup 1) (match_dup 0))]
7922   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
7923    && peep2_reg_dead_p (3, operands[0])
7924    && !reg_overlap_mentioned_p (operands[0], operands[1])
7925    && !reg_overlap_mentioned_p (operands[0], operands[2])"
7926   [(set (match_dup 0) (match_dup 2))
7927    (parallel [(set (reg:CC FLAGS_REG)
7928                    (compare:CC (match_dup 1) (match_dup 0)))
7929               (set (match_dup 1)
7930                    (minus:SWI (match_dup 1) (match_dup 0)))])])
7932 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
7933 ;; subl $1, %eax; jnc .Lxx;
7934 (define_peephole2
7935   [(parallel
7936      [(set (match_operand:SWI 0 "general_reg_operand")
7937            (plus:SWI (match_dup 0) (const_int -1)))
7938       (clobber (reg FLAGS_REG))])
7939    (set (reg:CCZ FLAGS_REG)
7940         (compare:CCZ (match_dup 0) (const_int -1)))
7941    (set (pc)
7942         (if_then_else (match_operator 1 "bt_comparison_operator"
7943                         [(reg:CCZ FLAGS_REG) (const_int 0)])
7944                       (match_operand 2)
7945                       (pc)))]
7946    "peep2_regno_dead_p (3, FLAGS_REG)"
7947    [(parallel
7948       [(set (reg:CC FLAGS_REG)
7949             (compare:CC (match_dup 0) (const_int 1)))
7950        (set (match_dup 0)
7951             (minus:SWI (match_dup 0) (const_int 1)))])
7952     (set (pc)
7953          (if_then_else (match_dup 3)
7954                        (match_dup 2)
7955                        (pc)))]
7957   rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
7958   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
7959                                 ? GEU : LTU, VOIDmode, cc, const0_rtx);
7962 ;; Help combine use borrow flag to test for -1 after dec (add $-1).
7963 (define_insn_and_split "*dec_cmov<mode>"
7964   [(set (match_operand:SWI248 0 "register_operand" "=r")
7965         (if_then_else:SWI248
7966          (match_operator 1 "bt_comparison_operator"
7967           [(match_operand:SWI248 2 "register_operand" "0") (const_int 0)])
7968          (plus:SWI248 (match_dup 2) (const_int -1))
7969          (match_operand:SWI248 3 "nonimmediate_operand" "rm")))
7970    (clobber (reg:CC FLAGS_REG))]
7971   "TARGET_CMOVE"
7972   "#"
7973   "&& reload_completed"
7974   [(parallel [(set (reg:CC FLAGS_REG)
7975                    (compare:CC (match_dup 2) (const_int 1)))
7976               (set (match_dup 0) (minus:SWI248 (match_dup 2) (const_int 1)))])
7977    (set (match_dup 0)
7978         (if_then_else:SWI248 (match_dup 4) (match_dup 0) (match_dup 3)))]
7980   rtx cc = gen_rtx_REG (CCCmode, FLAGS_REG);
7981   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
7982                                 ? GEU : LTU, VOIDmode, cc, const0_rtx);
7985 (define_insn "*subsi_3_zext"
7986   [(set (reg FLAGS_REG)
7987         (compare (match_operand:SI 1 "register_operand" "0")
7988                  (match_operand:SI 2 "x86_64_general_operand" "rBMe")))
7989    (set (match_operand:DI 0 "register_operand" "=r")
7990         (zero_extend:DI
7991           (minus:SI (match_dup 1)
7992                     (match_dup 2))))]
7993   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7994    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7995   "sub{l}\t{%2, %1|%1, %2}"
7996   [(set_attr "type" "alu")
7997    (set_attr "mode" "SI")])
7999 ;; Add with carry and subtract with borrow
8001 (define_insn "@add<mode>3_carry"
8002   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8003         (plus:SWI
8004           (plus:SWI
8005             (match_operator:SWI 4 "ix86_carry_flag_operator"
8006              [(match_operand 3 "flags_reg_operand") (const_int 0)])
8007             (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
8008           (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8009    (clobber (reg:CC FLAGS_REG))]
8010   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8011   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8012   [(set_attr "type" "alu")
8013    (set_attr "use_carry" "1")
8014    (set_attr "pent_pair" "pu")
8015    (set_attr "mode" "<MODE>")])
8017 (define_peephole2
8018   [(set (match_operand:SWI 0 "general_reg_operand")
8019         (match_operand:SWI 1 "memory_operand"))
8020    (parallel [(set (match_dup 0)
8021                    (plus:SWI
8022                      (plus:SWI
8023                        (match_operator:SWI 4 "ix86_carry_flag_operator"
8024                          [(match_operand 3 "flags_reg_operand")
8025                           (const_int 0)])
8026                        (match_dup 0))
8027                      (match_operand:SWI 2 "memory_operand")))
8028               (clobber (reg:CC FLAGS_REG))])
8029    (set (match_dup 1) (match_dup 0))]
8030   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8031    && peep2_reg_dead_p (3, operands[0])
8032    && !reg_overlap_mentioned_p (operands[0], operands[1])
8033    && !reg_overlap_mentioned_p (operands[0], operands[2])"
8034   [(set (match_dup 0) (match_dup 2))
8035    (parallel [(set (match_dup 1)
8036                    (plus:SWI (plus:SWI (match_op_dup 4
8037                                          [(match_dup 3) (const_int 0)])
8038                                        (match_dup 1))
8039                              (match_dup 0)))
8040               (clobber (reg:CC FLAGS_REG))])])
8042 (define_peephole2
8043   [(set (match_operand:SWI 0 "general_reg_operand")
8044         (match_operand:SWI 1 "memory_operand"))
8045    (parallel [(set (match_dup 0)
8046                    (plus:SWI
8047                      (plus:SWI
8048                        (match_operator:SWI 4 "ix86_carry_flag_operator"
8049                          [(match_operand 3 "flags_reg_operand")
8050                           (const_int 0)])
8051                        (match_dup 0))
8052                      (match_operand:SWI 2 "memory_operand")))
8053               (clobber (reg:CC FLAGS_REG))])
8054    (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8055    (set (match_dup 1) (match_dup 5))]
8056   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8057    && peep2_reg_dead_p (3, operands[0])
8058    && peep2_reg_dead_p (4, operands[5])
8059    && !reg_overlap_mentioned_p (operands[0], operands[1])
8060    && !reg_overlap_mentioned_p (operands[0], operands[2])
8061    && !reg_overlap_mentioned_p (operands[5], operands[1])"
8062   [(set (match_dup 0) (match_dup 2))
8063    (parallel [(set (match_dup 1)
8064                    (plus:SWI (plus:SWI (match_op_dup 4
8065                                          [(match_dup 3) (const_int 0)])
8066                                        (match_dup 1))
8067                              (match_dup 0)))
8068               (clobber (reg:CC FLAGS_REG))])])
8070 (define_insn "*add<mode>3_carry_0"
8071   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8072         (plus:SWI
8073           (match_operator:SWI 2 "ix86_carry_flag_operator"
8074             [(reg FLAGS_REG) (const_int 0)])
8075           (match_operand:SWI 1 "nonimmediate_operand" "0")))
8076    (clobber (reg:CC FLAGS_REG))]
8077   "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8078   "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
8079   [(set_attr "type" "alu")
8080    (set_attr "use_carry" "1")
8081    (set_attr "pent_pair" "pu")
8082    (set_attr "mode" "<MODE>")])
8084 (define_insn "*add<mode>3_carry_0r"
8085   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8086         (plus:SWI
8087           (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8088             [(reg FLAGS_REG) (const_int 0)])
8089           (match_operand:SWI 1 "nonimmediate_operand" "0")))
8090    (clobber (reg:CC FLAGS_REG))]
8091   "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8092   "sbb{<imodesuffix>}\t{$-1, %0|%0, -1}"
8093   [(set_attr "type" "alu")
8094    (set_attr "use_carry" "1")
8095    (set_attr "pent_pair" "pu")
8096    (set_attr "mode" "<MODE>")])
8098 (define_insn "*addsi3_carry_zext"
8099   [(set (match_operand:DI 0 "register_operand" "=r")
8100         (zero_extend:DI
8101           (plus:SI
8102             (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
8103                       [(reg FLAGS_REG) (const_int 0)])
8104                      (match_operand:SI 1 "register_operand" "%0"))
8105             (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8106    (clobber (reg:CC FLAGS_REG))]
8107   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8108   "adc{l}\t{%2, %k0|%k0, %2}"
8109   [(set_attr "type" "alu")
8110    (set_attr "use_carry" "1")
8111    (set_attr "pent_pair" "pu")
8112    (set_attr "mode" "SI")])
8114 (define_insn "*addsi3_carry_zext_0"
8115   [(set (match_operand:DI 0 "register_operand" "=r")
8116         (zero_extend:DI
8117           (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
8118                     [(reg FLAGS_REG) (const_int 0)])
8119                    (match_operand:SI 1 "register_operand" "0"))))
8120    (clobber (reg:CC FLAGS_REG))]
8121   "TARGET_64BIT"
8122   "adc{l}\t{$0, %k0|%k0, 0}"
8123   [(set_attr "type" "alu")
8124    (set_attr "use_carry" "1")
8125    (set_attr "pent_pair" "pu")
8126    (set_attr "mode" "SI")])
8128 (define_insn "*addsi3_carry_zext_0r"
8129   [(set (match_operand:DI 0 "register_operand" "=r")
8130         (zero_extend:DI
8131           (plus:SI (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8132                     [(reg FLAGS_REG) (const_int 0)])
8133                    (match_operand:SI 1 "register_operand" "0"))))
8134    (clobber (reg:CC FLAGS_REG))]
8135   "TARGET_64BIT"
8136   "sbb{l}\t{$-1, %k0|%k0, -1}"
8137   [(set_attr "type" "alu")
8138    (set_attr "use_carry" "1")
8139    (set_attr "pent_pair" "pu")
8140    (set_attr "mode" "SI")])
8142 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
8144 (define_insn "addcarry<mode>"
8145   [(set (reg:CCC FLAGS_REG)
8146         (compare:CCC
8147           (zero_extend:<DWI>
8148             (plus:SWI48
8149               (plus:SWI48
8150                 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8151                   [(match_operand 3 "flags_reg_operand") (const_int 0)])
8152                 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0"))
8153               (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))
8154           (plus:<DWI>
8155             (zero_extend:<DWI> (match_dup 2))
8156             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8157               [(match_dup 3) (const_int 0)]))))
8158    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8159         (plus:SWI48 (plus:SWI48 (match_op_dup 5
8160                                  [(match_dup 3) (const_int 0)])
8161                                 (match_dup 1))
8162                     (match_dup 2)))]
8163   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8164   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8165   [(set_attr "type" "alu")
8166    (set_attr "use_carry" "1")
8167    (set_attr "pent_pair" "pu")
8168    (set_attr "mode" "<MODE>")])
8170 (define_peephole2
8171   [(parallel [(set (reg:CCC FLAGS_REG)
8172                    (compare:CCC
8173                      (zero_extend:<DWI>
8174                        (plus:SWI48
8175                          (plus:SWI48
8176                            (match_operator:SWI48 4 "ix86_carry_flag_operator"
8177                              [(match_operand 2 "flags_reg_operand")
8178                               (const_int 0)])
8179                            (match_operand:SWI48 0 "general_reg_operand"))
8180                          (match_operand:SWI48 1 "memory_operand")))
8181                      (plus:<DWI>
8182                        (zero_extend:<DWI> (match_dup 1))
8183                        (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8184                          [(match_dup 2) (const_int 0)]))))
8185               (set (match_dup 0)
8186                    (plus:SWI48 (plus:SWI48 (match_op_dup 4
8187                                              [(match_dup 2) (const_int 0)])
8188                                            (match_dup 0))
8189                                (match_dup 1)))])
8190    (set (match_dup 1) (match_dup 0))]
8191   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8192    && peep2_reg_dead_p (2, operands[0])
8193    && !reg_overlap_mentioned_p (operands[0], operands[1])"
8194   [(parallel [(set (reg:CCC FLAGS_REG)
8195                    (compare:CCC
8196                      (zero_extend:<DWI>
8197                        (plus:SWI48
8198                          (plus:SWI48
8199                            (match_op_dup 4
8200                              [(match_dup 2) (const_int 0)])
8201                            (match_dup 1))
8202                          (match_dup 0)))
8203                      (plus:<DWI>
8204                        (zero_extend:<DWI> (match_dup 0))
8205                        (match_op_dup 3
8206                          [(match_dup 2) (const_int 0)]))))
8207               (set (match_dup 1)
8208                    (plus:SWI48 (plus:SWI48 (match_op_dup 4
8209                                              [(match_dup 2) (const_int 0)])
8210                                            (match_dup 1))
8211                                (match_dup 0)))])])
8213 (define_peephole2
8214   [(set (match_operand:SWI48 0 "general_reg_operand")
8215         (match_operand:SWI48 1 "memory_operand"))
8216    (parallel [(set (reg:CCC FLAGS_REG)
8217                    (compare:CCC
8218                      (zero_extend:<DWI>
8219                        (plus:SWI48
8220                          (plus:SWI48
8221                            (match_operator:SWI48 5 "ix86_carry_flag_operator"
8222                              [(match_operand 3 "flags_reg_operand")
8223                               (const_int 0)])
8224                            (match_dup 0))
8225                          (match_operand:SWI48 2 "memory_operand")))
8226                      (plus:<DWI>
8227                        (zero_extend:<DWI> (match_dup 2))
8228                        (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8229                          [(match_dup 3) (const_int 0)]))))
8230               (set (match_dup 0)
8231                    (plus:SWI48 (plus:SWI48 (match_op_dup 5
8232                                              [(match_dup 3) (const_int 0)])
8233                                            (match_dup 0))
8234                                (match_dup 2)))])
8235    (set (match_dup 1) (match_dup 0))]
8236   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8237    && peep2_reg_dead_p (3, operands[0])
8238    && !reg_overlap_mentioned_p (operands[0], operands[1])
8239    && !reg_overlap_mentioned_p (operands[0], operands[2])"
8240   [(set (match_dup 0) (match_dup 2))
8241    (parallel [(set (reg:CCC FLAGS_REG)
8242                    (compare:CCC
8243                      (zero_extend:<DWI>
8244                        (plus:SWI48
8245                          (plus:SWI48
8246                            (match_op_dup 5
8247                              [(match_dup 3) (const_int 0)])
8248                            (match_dup 1))
8249                          (match_dup 0)))
8250                      (plus:<DWI>
8251                        (zero_extend:<DWI> (match_dup 0))
8252                        (match_op_dup 4
8253                          [(match_dup 3) (const_int 0)]))))
8254               (set (match_dup 1)
8255                    (plus:SWI48 (plus:SWI48 (match_op_dup 5
8256                                              [(match_dup 3) (const_int 0)])
8257                                            (match_dup 1))
8258                                (match_dup 0)))])])
8260 (define_peephole2
8261   [(parallel [(set (reg:CCC FLAGS_REG)
8262                    (compare:CCC
8263                      (zero_extend:<DWI>
8264                        (plus:SWI48
8265                          (plus:SWI48
8266                            (match_operator:SWI48 4 "ix86_carry_flag_operator"
8267                              [(match_operand 2 "flags_reg_operand")
8268                               (const_int 0)])
8269                            (match_operand:SWI48 0 "general_reg_operand"))
8270                          (match_operand:SWI48 1 "memory_operand")))
8271                      (plus:<DWI>
8272                        (zero_extend:<DWI> (match_dup 1))
8273                        (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8274                          [(match_dup 2) (const_int 0)]))))
8275               (set (match_dup 0)
8276                    (plus:SWI48 (plus:SWI48 (match_op_dup 4
8277                                              [(match_dup 2) (const_int 0)])
8278                                            (match_dup 0))
8279                                (match_dup 1)))])
8280    (set (match_operand:QI 5 "general_reg_operand")
8281         (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8282    (set (match_operand:SWI48 6 "general_reg_operand")
8283         (zero_extend:SWI48 (match_dup 5)))
8284    (set (match_dup 1) (match_dup 0))]
8285   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8286    && peep2_reg_dead_p (4, operands[0])
8287    && !reg_overlap_mentioned_p (operands[0], operands[1])
8288    && !reg_overlap_mentioned_p (operands[0], operands[5])
8289    && !reg_overlap_mentioned_p (operands[5], operands[1])
8290    && !reg_overlap_mentioned_p (operands[0], operands[6])
8291    && !reg_overlap_mentioned_p (operands[6], operands[1])"
8292   [(parallel [(set (reg:CCC FLAGS_REG)
8293                    (compare:CCC
8294                      (zero_extend:<DWI>
8295                        (plus:SWI48
8296                          (plus:SWI48
8297                            (match_op_dup 4
8298                              [(match_dup 2) (const_int 0)])
8299                            (match_dup 1))
8300                          (match_dup 0)))
8301                      (plus:<DWI>
8302                        (zero_extend:<DWI> (match_dup 0))
8303                        (match_op_dup 3
8304                          [(match_dup 2) (const_int 0)]))))
8305               (set (match_dup 1)
8306                    (plus:SWI48 (plus:SWI48 (match_op_dup 4
8307                                              [(match_dup 2) (const_int 0)])
8308                                            (match_dup 1))
8309                                (match_dup 0)))])
8310    (set (match_dup 5) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8311    (set (match_dup 6) (zero_extend:SWI48 (match_dup 5)))])
8313 (define_expand "addcarry<mode>_0"
8314   [(parallel
8315      [(set (reg:CCC FLAGS_REG)
8316            (compare:CCC
8317              (plus:SWI48
8318                (match_operand:SWI48 1 "nonimmediate_operand")
8319                (match_operand:SWI48 2 "x86_64_general_operand"))
8320              (match_dup 1)))
8321       (set (match_operand:SWI48 0 "nonimmediate_operand")
8322            (plus:SWI48 (match_dup 1) (match_dup 2)))])]
8323   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
8325 (define_insn "*addcarry<mode>_1"
8326   [(set (reg:CCC FLAGS_REG)
8327         (compare:CCC
8328           (zero_extend:<DWI>
8329             (plus:SWI48
8330               (plus:SWI48
8331                 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8332                   [(match_operand 3 "flags_reg_operand") (const_int 0)])
8333                 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
8334               (match_operand:SWI48 2 "x86_64_immediate_operand" "e")))
8335           (plus:<DWI>
8336             (match_operand:<DWI> 6 "const_scalar_int_operand")
8337             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8338               [(match_dup 3) (const_int 0)]))))
8339    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8340         (plus:SWI48 (plus:SWI48 (match_op_dup 5
8341                                  [(match_dup 3) (const_int 0)])
8342                                 (match_dup 1))
8343                     (match_dup 2)))]
8344   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
8345    && CONST_INT_P (operands[2])
8346    /* Check that operands[6] is operands[2] zero extended from
8347       <MODE>mode to <DWI>mode.  */
8348    && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0)
8349        ? (CONST_INT_P (operands[6])
8350           && UINTVAL (operands[6]) == (UINTVAL (operands[2])
8351                                        & GET_MODE_MASK (<MODE>mode)))
8352        : (CONST_WIDE_INT_P (operands[6])
8353           && CONST_WIDE_INT_NUNITS (operands[6]) == 2
8354           && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
8355               == UINTVAL (operands[2]))
8356           && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
8357   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8358   [(set_attr "type" "alu")
8359    (set_attr "use_carry" "1")
8360    (set_attr "pent_pair" "pu")
8361    (set_attr "mode" "<MODE>")
8362    (set (attr "length_immediate")
8363      (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8364        (const_string "1")
8365        (const_string "4")))])
8367 (define_insn "@sub<mode>3_carry"
8368   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8369         (minus:SWI
8370           (minus:SWI
8371             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
8372             (match_operator:SWI 4 "ix86_carry_flag_operator"
8373              [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8374           (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8375    (clobber (reg:CC FLAGS_REG))]
8376   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8377   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8378   [(set_attr "type" "alu")
8379    (set_attr "use_carry" "1")
8380    (set_attr "pent_pair" "pu")
8381    (set_attr "mode" "<MODE>")])
8383 (define_peephole2
8384   [(set (match_operand:SWI 0 "general_reg_operand")
8385         (match_operand:SWI 1 "memory_operand"))
8386    (parallel [(set (match_dup 0)
8387                    (minus:SWI
8388                      (minus:SWI
8389                        (match_dup 0)
8390                        (match_operator:SWI 4 "ix86_carry_flag_operator"
8391                          [(match_operand 3 "flags_reg_operand")
8392                           (const_int 0)]))
8393                      (match_operand:SWI 2 "memory_operand")))
8394               (clobber (reg:CC FLAGS_REG))])
8395    (set (match_dup 1) (match_dup 0))]
8396   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8397    && peep2_reg_dead_p (3, operands[0])
8398    && !reg_overlap_mentioned_p (operands[0], operands[1])
8399    && !reg_overlap_mentioned_p (operands[0], operands[2])"
8400   [(set (match_dup 0) (match_dup 2))
8401    (parallel [(set (match_dup 1)
8402                    (minus:SWI (minus:SWI (match_dup 1)
8403                                          (match_op_dup 4
8404                                            [(match_dup 3) (const_int 0)]))
8405                               (match_dup 0)))
8406               (clobber (reg:CC FLAGS_REG))])])
8408 (define_peephole2
8409   [(set (match_operand:SWI 0 "general_reg_operand")
8410         (match_operand:SWI 1 "memory_operand"))
8411    (parallel [(set (match_dup 0)
8412                    (minus:SWI
8413                      (minus:SWI
8414                        (match_dup 0)
8415                        (match_operator:SWI 4 "ix86_carry_flag_operator"
8416                          [(match_operand 3 "flags_reg_operand")
8417                           (const_int 0)]))
8418                      (match_operand:SWI 2 "memory_operand")))
8419               (clobber (reg:CC FLAGS_REG))])
8420    (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8421    (set (match_dup 1) (match_dup 5))]
8422   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8423    && peep2_reg_dead_p (3, operands[0])
8424    && peep2_reg_dead_p (4, operands[5])
8425    && !reg_overlap_mentioned_p (operands[0], operands[1])
8426    && !reg_overlap_mentioned_p (operands[0], operands[2])
8427    && !reg_overlap_mentioned_p (operands[5], operands[1])"
8428   [(set (match_dup 0) (match_dup 2))
8429    (parallel [(set (match_dup 1)
8430                    (minus:SWI (minus:SWI (match_dup 1)
8431                                          (match_op_dup 4
8432                                            [(match_dup 3) (const_int 0)]))
8433                               (match_dup 0)))
8434               (clobber (reg:CC FLAGS_REG))])])
8436 (define_insn "*sub<mode>3_carry_0"
8437   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8438         (minus:SWI
8439           (match_operand:SWI 1 "nonimmediate_operand" "0")
8440           (match_operator:SWI 2 "ix86_carry_flag_operator"
8441             [(reg FLAGS_REG) (const_int 0)])))
8442    (clobber (reg:CC FLAGS_REG))]
8443   "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8444   "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
8445   [(set_attr "type" "alu")
8446    (set_attr "use_carry" "1")
8447    (set_attr "pent_pair" "pu")
8448    (set_attr "mode" "<MODE>")])
8450 (define_insn "*sub<mode>3_carry_0r"
8451   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8452         (minus:SWI
8453           (match_operand:SWI 1 "nonimmediate_operand" "0")
8454           (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8455             [(reg FLAGS_REG) (const_int 0)])))
8456    (clobber (reg:CC FLAGS_REG))]
8457   "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8458   "adc{<imodesuffix>}\t{$-1, %0|%0, -1}"
8459   [(set_attr "type" "alu")
8460    (set_attr "use_carry" "1")
8461    (set_attr "pent_pair" "pu")
8462    (set_attr "mode" "<MODE>")])
8464 (define_insn "*subsi3_carry_zext"
8465   [(set (match_operand:DI 0 "register_operand" "=r")
8466         (zero_extend:DI
8467           (minus:SI
8468             (minus:SI
8469               (match_operand:SI 1 "register_operand" "0")
8470               (match_operator:SI 3 "ix86_carry_flag_operator"
8471                [(reg FLAGS_REG) (const_int 0)]))
8472             (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8473    (clobber (reg:CC FLAGS_REG))]
8474   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8475   "sbb{l}\t{%2, %k0|%k0, %2}"
8476   [(set_attr "type" "alu")
8477    (set_attr "use_carry" "1")
8478    (set_attr "pent_pair" "pu")
8479    (set_attr "mode" "SI")])
8481 (define_insn "*subsi3_carry_zext_0"
8482   [(set (match_operand:DI 0 "register_operand" "=r")
8483         (zero_extend:DI
8484           (minus:SI
8485             (match_operand:SI 1 "register_operand" "0")
8486             (match_operator:SI 2 "ix86_carry_flag_operator"
8487               [(reg FLAGS_REG) (const_int 0)]))))
8488    (clobber (reg:CC FLAGS_REG))]
8489   "TARGET_64BIT"
8490   "sbb{l}\t{$0, %k0|%k0, 0}"
8491   [(set_attr "type" "alu")
8492    (set_attr "use_carry" "1")
8493    (set_attr "pent_pair" "pu")
8494    (set_attr "mode" "SI")])
8496 (define_insn "*subsi3_carry_zext_0r"
8497   [(set (match_operand:DI 0 "register_operand" "=r")
8498         (zero_extend:DI
8499           (minus:SI
8500             (match_operand:SI 1 "register_operand" "0")
8501             (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8502               [(reg FLAGS_REG) (const_int 0)]))))
8503    (clobber (reg:CC FLAGS_REG))]
8504   "TARGET_64BIT"
8505   "adc{l}\t{$-1, %k0|%k0, -1}"
8506   [(set_attr "type" "alu")
8507    (set_attr "use_carry" "1")
8508    (set_attr "pent_pair" "pu")
8509    (set_attr "mode" "SI")])
8511 (define_insn "@sub<mode>3_carry_ccc"
8512   [(set (reg:CCC FLAGS_REG)
8513         (compare:CCC
8514           (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8515           (plus:<DWI>
8516             (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8517             (zero_extend:<DWI>
8518               (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
8519    (clobber (match_scratch:DWIH 0 "=r"))]
8520   ""
8521   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8522   [(set_attr "type" "alu")
8523    (set_attr "mode" "<MODE>")])
8525 (define_insn "*sub<mode>3_carry_ccc_1"
8526   [(set (reg:CCC FLAGS_REG)
8527         (compare:CCC
8528           (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8529           (plus:<DWI>
8530             (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8531             (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
8532    (clobber (match_scratch:DWIH 0 "=r"))]
8533   ""
8535   operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
8536   return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
8538   [(set_attr "type" "alu")
8539    (set_attr "mode" "<MODE>")])
8541 ;; The sign flag is set from the
8542 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
8543 ;; result, the overflow flag likewise, but the overflow flag is also
8544 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
8545 (define_insn "@sub<mode>3_carry_ccgz"
8546   [(set (reg:CCGZ FLAGS_REG)
8547         (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
8548                       (match_operand:DWIH 2 "x86_64_general_operand" "rBMe")
8549                       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
8550                      UNSPEC_SBB))
8551    (clobber (match_scratch:DWIH 0 "=r"))]
8552   ""
8553   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8554   [(set_attr "type" "alu")
8555    (set_attr "mode" "<MODE>")])
8557 (define_insn "subborrow<mode>"
8558   [(set (reg:CCC FLAGS_REG)
8559         (compare:CCC
8560           (zero_extend:<DWI>
8561             (match_operand:SWI48 1 "nonimmediate_operand" "0,0"))
8562           (plus:<DWI>
8563             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8564               [(match_operand 3 "flags_reg_operand") (const_int 0)])
8565             (zero_extend:<DWI>
8566               (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))))
8567    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8568         (minus:SWI48 (minus:SWI48
8569                        (match_dup 1)
8570                        (match_operator:SWI48 5 "ix86_carry_flag_operator"
8571                          [(match_dup 3) (const_int 0)]))
8572                      (match_dup 2)))]
8573   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8574   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8575   [(set_attr "type" "alu")
8576    (set_attr "use_carry" "1")
8577    (set_attr "pent_pair" "pu")
8578    (set_attr "mode" "<MODE>")])
8580 (define_peephole2
8581   [(set (match_operand:SWI48 0 "general_reg_operand")
8582         (match_operand:SWI48 1 "memory_operand"))
8583    (parallel [(set (reg:CCC FLAGS_REG)
8584                    (compare:CCC
8585                      (zero_extend:<DWI> (match_dup 0))
8586                      (plus:<DWI>
8587                        (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8588                          [(match_operand 3 "flags_reg_operand") (const_int 0)])
8589                        (zero_extend:<DWI>
8590                          (match_operand:SWI48 2 "memory_operand")))))
8591               (set (match_dup 0)
8592                    (minus:SWI48
8593                      (minus:SWI48
8594                        (match_dup 0)
8595                        (match_operator:SWI48 5 "ix86_carry_flag_operator"
8596                          [(match_dup 3) (const_int 0)]))
8597                      (match_dup 2)))])
8598    (set (match_dup 1) (match_dup 0))]
8599   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8600    && peep2_reg_dead_p (3, operands[0])
8601    && !reg_overlap_mentioned_p (operands[0], operands[1])
8602    && !reg_overlap_mentioned_p (operands[0], operands[2])"
8603   [(set (match_dup 0) (match_dup 2))
8604    (parallel [(set (reg:CCC FLAGS_REG)
8605                    (compare:CCC
8606                      (zero_extend:<DWI> (match_dup 1))
8607                      (plus:<DWI> (match_op_dup 4
8608                                    [(match_dup 3) (const_int 0)])
8609                                  (zero_extend:<DWI> (match_dup 0)))))
8610               (set (match_dup 1)
8611                    (minus:SWI48 (minus:SWI48 (match_dup 1)
8612                                              (match_op_dup 5
8613                                                [(match_dup 3) (const_int 0)]))
8614                                 (match_dup 0)))])])
8616 (define_peephole2
8617   [(set (match_operand:SWI48 6 "general_reg_operand")
8618         (match_operand:SWI48 7 "memory_operand"))
8619    (set (match_operand:SWI48 8 "general_reg_operand")
8620         (match_operand:SWI48 9 "memory_operand"))
8621    (parallel [(set (reg:CCC FLAGS_REG)
8622                    (compare:CCC
8623                      (zero_extend:<DWI>
8624                        (match_operand:SWI48 0 "general_reg_operand"))
8625                      (plus:<DWI>
8626                        (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8627                          [(match_operand 3 "flags_reg_operand") (const_int 0)])
8628                        (zero_extend:<DWI>
8629                          (match_operand:SWI48 2 "general_reg_operand")))))
8630               (set (match_dup 0)
8631                    (minus:SWI48
8632                      (minus:SWI48
8633                        (match_dup 0)
8634                        (match_operator:SWI48 5 "ix86_carry_flag_operator"
8635                          [(match_dup 3) (const_int 0)]))
8636                      (match_dup 2)))])
8637    (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8638   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8639    && peep2_reg_dead_p (4, operands[0])
8640    && peep2_reg_dead_p (3, operands[2])
8641    && !reg_overlap_mentioned_p (operands[0], operands[1])
8642    && !reg_overlap_mentioned_p (operands[2], operands[1])
8643    && !reg_overlap_mentioned_p (operands[6], operands[9])
8644    && (rtx_equal_p (operands[6], operands[0])
8645        ? (rtx_equal_p (operands[7], operands[1])
8646           && rtx_equal_p (operands[8], operands[2]))
8647        : (rtx_equal_p (operands[8], operands[0])
8648           && rtx_equal_p (operands[9], operands[1])
8649           && rtx_equal_p (operands[6], operands[2])))"
8650   [(set (match_dup 0) (match_dup 9))
8651    (parallel [(set (reg:CCC FLAGS_REG)
8652                    (compare:CCC
8653                      (zero_extend:<DWI> (match_dup 1))
8654                      (plus:<DWI> (match_op_dup 4
8655                                    [(match_dup 3) (const_int 0)])
8656                                  (zero_extend:<DWI> (match_dup 0)))))
8657               (set (match_dup 1)
8658                    (minus:SWI48 (minus:SWI48 (match_dup 1)
8659                                              (match_op_dup 5
8660                                                [(match_dup 3) (const_int 0)]))
8661                                 (match_dup 0)))])]
8663   if (!rtx_equal_p (operands[6], operands[0]))
8664     operands[9] = operands[7];
8667 (define_peephole2
8668   [(set (match_operand:SWI48 6 "general_reg_operand")
8669         (match_operand:SWI48 7 "memory_operand"))
8670    (set (match_operand:SWI48 8 "general_reg_operand")
8671         (match_operand:SWI48 9 "memory_operand"))
8672    (parallel [(set (reg:CCC FLAGS_REG)
8673                    (compare:CCC
8674                      (zero_extend:<DWI>
8675                        (match_operand:SWI48 0 "general_reg_operand"))
8676                      (plus:<DWI>
8677                        (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8678                          [(match_operand 3 "flags_reg_operand") (const_int 0)])
8679                        (zero_extend:<DWI>
8680                          (match_operand:SWI48 2 "general_reg_operand")))))
8681               (set (match_dup 0)
8682                    (minus:SWI48
8683                      (minus:SWI48
8684                        (match_dup 0)
8685                        (match_operator:SWI48 5 "ix86_carry_flag_operator"
8686                          [(match_dup 3) (const_int 0)]))
8687                      (match_dup 2)))])
8688    (set (match_operand:QI 10 "general_reg_operand")
8689         (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8690    (set (match_operand:SWI48 11 "general_reg_operand")
8691         (zero_extend:SWI48 (match_dup 10)))
8692    (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8693   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8694    && peep2_reg_dead_p (6, operands[0])
8695    && peep2_reg_dead_p (3, operands[2])
8696    && !reg_overlap_mentioned_p (operands[0], operands[1])
8697    && !reg_overlap_mentioned_p (operands[2], operands[1])
8698    && !reg_overlap_mentioned_p (operands[6], operands[9])
8699    && !reg_overlap_mentioned_p (operands[0], operands[10])
8700    && !reg_overlap_mentioned_p (operands[10], operands[1])
8701    && !reg_overlap_mentioned_p (operands[0], operands[11])
8702    && !reg_overlap_mentioned_p (operands[11], operands[1])
8703    && (rtx_equal_p (operands[6], operands[0])
8704        ? (rtx_equal_p (operands[7], operands[1])
8705           && rtx_equal_p (operands[8], operands[2]))
8706        : (rtx_equal_p (operands[8], operands[0])
8707           && rtx_equal_p (operands[9], operands[1])
8708           && rtx_equal_p (operands[6], operands[2])))"
8709   [(set (match_dup 0) (match_dup 9))
8710    (parallel [(set (reg:CCC FLAGS_REG)
8711                    (compare:CCC
8712                      (zero_extend:<DWI> (match_dup 1))
8713                      (plus:<DWI> (match_op_dup 4
8714                                    [(match_dup 3) (const_int 0)])
8715                                  (zero_extend:<DWI> (match_dup 0)))))
8716               (set (match_dup 1)
8717                    (minus:SWI48 (minus:SWI48 (match_dup 1)
8718                                              (match_op_dup 5
8719                                                [(match_dup 3) (const_int 0)]))
8720                                 (match_dup 0)))])
8721    (set (match_dup 10) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8722    (set (match_dup 11) (zero_extend:SWI48 (match_dup 10)))]
8724   if (!rtx_equal_p (operands[6], operands[0]))
8725     operands[9] = operands[7];
8728 (define_expand "subborrow<mode>_0"
8729   [(parallel
8730      [(set (reg:CC FLAGS_REG)
8731            (compare:CC
8732              (match_operand:SWI48 1 "nonimmediate_operand")
8733              (match_operand:SWI48 2 "<general_operand>")))
8734       (set (match_operand:SWI48 0 "register_operand")
8735            (minus:SWI48 (match_dup 1) (match_dup 2)))])]
8736   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
8738 (define_expand "uaddc<mode>5"
8739   [(match_operand:SWI48 0 "register_operand")
8740    (match_operand:SWI48 1 "register_operand")
8741    (match_operand:SWI48 2 "register_operand")
8742    (match_operand:SWI48 3 "register_operand")
8743    (match_operand:SWI48 4 "nonmemory_operand")]
8744   ""
8746   rtx cf = gen_rtx_REG (CCCmode, FLAGS_REG), pat, pat2;
8747   if (operands[4] == const0_rtx)
8748     emit_insn (gen_addcarry<mode>_0 (operands[0], operands[2], operands[3]));
8749   else
8750     {
8751       ix86_expand_carry (operands[4]);
8752       pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8753       pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8754       emit_insn (gen_addcarry<mode> (operands[0], operands[2], operands[3],
8755                                      cf, pat, pat2));
8756     }
8757   rtx cc = gen_reg_rtx (QImode);
8758   pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8759   emit_insn (gen_rtx_SET (cc, pat));
8760   emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8761   DONE;
8764 (define_expand "usubc<mode>5"
8765   [(match_operand:SWI48 0 "register_operand")
8766    (match_operand:SWI48 1 "register_operand")
8767    (match_operand:SWI48 2 "register_operand")
8768    (match_operand:SWI48 3 "register_operand")
8769    (match_operand:SWI48 4 "nonmemory_operand")]
8770   ""
8772   rtx cf, pat, pat2;
8773   if (operands[4] == const0_rtx)
8774     {
8775       cf = gen_rtx_REG (CCmode, FLAGS_REG);
8776       emit_insn (gen_subborrow<mode>_0 (operands[0], operands[2],
8777                                         operands[3]));
8778     }
8779   else
8780     {
8781       cf = gen_rtx_REG (CCCmode, FLAGS_REG);
8782       ix86_expand_carry (operands[4]);
8783       pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8784       pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8785       emit_insn (gen_subborrow<mode> (operands[0], operands[2], operands[3],
8786                                       cf, pat, pat2));
8787     }
8788   rtx cc = gen_reg_rtx (QImode);
8789   pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8790   emit_insn (gen_rtx_SET (cc, pat));
8791   emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8792   DONE;
8795 (define_mode_iterator CC_CCC [CC CCC])
8797 ;; Pre-reload splitter to optimize
8798 ;; *setcc_qi followed by *addqi3_cconly_overflow_1 with the same QI
8799 ;; operand and no intervening flags modifications into nothing.
8800 (define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1_<mode>"
8801   [(set (reg:CCC FLAGS_REG)
8802         (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
8803                      (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))))]
8804   "ix86_pre_reload_split ()"
8805   "#"
8806   "&& 1"
8807   [(const_int 0)]
8808   "emit_note (NOTE_INSN_DELETED); DONE;")
8810 ;; Set the carry flag from the carry flag.
8811 (define_insn_and_split "*setccc"
8812   [(set (reg:CCC FLAGS_REG)
8813         (reg:CCC FLAGS_REG))]
8814   "ix86_pre_reload_split ()"
8815   "#"
8816   "&& 1"
8817   [(const_int 0)]
8818   "emit_note (NOTE_INSN_DELETED); DONE;")
8820 ;; Set the carry flag from the carry flag.
8821 (define_insn_and_split "*setcc_qi_negqi_ccc_1_<mode>"
8822   [(set (reg:CCC FLAGS_REG)
8823         (ltu:CCC (reg:CC_CCC FLAGS_REG) (const_int 0)))]
8824   "ix86_pre_reload_split ()"
8825   "#"
8826   "&& 1"
8827   [(const_int 0)]
8828   "emit_note (NOTE_INSN_DELETED); DONE;")
8830 ;; Set the carry flag from the carry flag.
8831 (define_insn_and_split "*setcc_qi_negqi_ccc_2_<mode>"
8832   [(set (reg:CCC FLAGS_REG)
8833         (unspec:CCC [(ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
8834                      (const_int 0)] UNSPEC_CC_NE))]
8835   "ix86_pre_reload_split ()"
8836   "#"
8837   "&& 1"
8838   [(const_int 0)]
8839   "emit_note (NOTE_INSN_DELETED); DONE;")
8841 ;; Overflow setting add instructions
8843 (define_expand "addqi3_cconly_overflow"
8844   [(parallel
8845      [(set (reg:CCC FLAGS_REG)
8846            (compare:CCC
8847              (plus:QI
8848                (match_operand:QI 0 "nonimmediate_operand")
8849                (match_operand:QI 1 "general_operand"))
8850              (match_dup 0)))
8851       (clobber (scratch:QI))])]
8852   "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
8854 (define_insn "*add<mode>3_cconly_overflow_1"
8855   [(set (reg:CCC FLAGS_REG)
8856         (compare:CCC
8857           (plus:SWI
8858             (match_operand:SWI 1 "nonimmediate_operand" "%0")
8859             (match_operand:SWI 2 "<general_operand>" "<g>"))
8860           (match_dup 1)))
8861    (clobber (match_scratch:SWI 0 "=<r>"))]
8862   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8863   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8864   [(set_attr "type" "alu")
8865    (set_attr "mode" "<MODE>")])
8867 (define_insn "@add<mode>3_cc_overflow_1"
8868   [(set (reg:CCC FLAGS_REG)
8869         (compare:CCC
8870             (plus:SWI
8871                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8872                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
8873             (match_dup 1)))
8874    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8875         (plus:SWI (match_dup 1) (match_dup 2)))]
8876   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8877   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8878   [(set_attr "type" "alu")
8879    (set_attr "mode" "<MODE>")])
8881 (define_peephole2
8882   [(parallel [(set (reg:CCC FLAGS_REG)
8883                    (compare:CCC
8884                      (plus:SWI (match_operand:SWI 0 "general_reg_operand")
8885                                (match_operand:SWI 1 "memory_operand"))
8886                      (match_dup 0)))
8887               (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 1)))])
8888    (set (match_dup 1) (match_dup 0))]
8889   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8890    && peep2_reg_dead_p (2, operands[0])
8891    && !reg_overlap_mentioned_p (operands[0], operands[1])"
8892   [(parallel [(set (reg:CCC FLAGS_REG)
8893                    (compare:CCC
8894                      (plus:SWI (match_dup 1) (match_dup 0))
8895                      (match_dup 1)))
8896               (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
8898 (define_peephole2
8899   [(set (match_operand:SWI 0 "general_reg_operand")
8900         (match_operand:SWI 1 "memory_operand"))
8901    (parallel [(set (reg:CCC FLAGS_REG)
8902                    (compare:CCC
8903                      (plus:SWI (match_dup 0)
8904                                (match_operand:SWI 2 "memory_operand"))
8905                      (match_dup 0)))
8906               (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 2)))])
8907    (set (match_dup 1) (match_dup 0))]
8908   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8909    && peep2_reg_dead_p (3, operands[0])
8910    && !reg_overlap_mentioned_p (operands[0], operands[1])
8911    && !reg_overlap_mentioned_p (operands[0], operands[2])"
8912   [(set (match_dup 0) (match_dup 2))
8913    (parallel [(set (reg:CCC FLAGS_REG)
8914                    (compare:CCC
8915                      (plus:SWI (match_dup 1) (match_dup 0))
8916                      (match_dup 1)))
8917               (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
8919 (define_insn "*addsi3_zext_cc_overflow_1"
8920   [(set (reg:CCC FLAGS_REG)
8921         (compare:CCC
8922           (plus:SI
8923             (match_operand:SI 1 "nonimmediate_operand" "%0")
8924             (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
8925           (match_dup 1)))
8926    (set (match_operand:DI 0 "register_operand" "=r")
8927         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8928   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8929   "add{l}\t{%2, %k0|%k0, %2}"
8930   [(set_attr "type" "alu")
8931    (set_attr "mode" "SI")])
8933 (define_insn "*add<mode>3_cconly_overflow_2"
8934   [(set (reg:CCC FLAGS_REG)
8935         (compare:CCC
8936           (plus:SWI
8937             (match_operand:SWI 1 "nonimmediate_operand" "%0")
8938             (match_operand:SWI 2 "<general_operand>" "<g>"))
8939           (match_dup 2)))
8940    (clobber (match_scratch:SWI 0 "=<r>"))]
8941   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8942   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8943   [(set_attr "type" "alu")
8944    (set_attr "mode" "<MODE>")])
8946 (define_insn "*add<mode>3_cc_overflow_2"
8947   [(set (reg:CCC FLAGS_REG)
8948         (compare:CCC
8949             (plus:SWI
8950                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8951                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
8952             (match_dup 2)))
8953    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8954         (plus:SWI (match_dup 1) (match_dup 2)))]
8955   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8956   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8957   [(set_attr "type" "alu")
8958    (set_attr "mode" "<MODE>")])
8960 (define_insn "*addsi3_zext_cc_overflow_2"
8961   [(set (reg:CCC FLAGS_REG)
8962         (compare:CCC
8963           (plus:SI
8964             (match_operand:SI 1 "nonimmediate_operand" "%0")
8965             (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
8966           (match_dup 2)))
8967    (set (match_operand:DI 0 "register_operand" "=r")
8968         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8969   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8970   "add{l}\t{%2, %k0|%k0, %2}"
8971   [(set_attr "type" "alu")
8972    (set_attr "mode" "SI")])
8974 (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
8975   [(set (reg:CCC FLAGS_REG)
8976         (compare:CCC
8977           (plus:<DWI>
8978             (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
8979             (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o"))
8980           (match_dup 1)))
8981    (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
8982         (plus:<DWI> (match_dup 1) (match_dup 2)))]
8983   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
8984   "#"
8985   "&& reload_completed"
8986   [(parallel [(set (reg:CCC FLAGS_REG)
8987                    (compare:CCC
8988                      (plus:DWIH (match_dup 1) (match_dup 2))
8989                      (match_dup 1)))
8990               (set (match_dup 0)
8991                    (plus:DWIH (match_dup 1) (match_dup 2)))])
8992    (parallel [(set (reg:CCC FLAGS_REG)
8993                    (compare:CCC
8994                      (zero_extend:<DWI>
8995                        (plus:DWIH
8996                          (plus:DWIH
8997                            (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8998                            (match_dup 4))
8999                          (match_dup 5)))
9000                      (plus:<DWI>
9001                        (match_dup 6)
9002                        (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))))
9003               (set (match_dup 3)
9004                    (plus:DWIH
9005                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9006                                 (match_dup 4))
9007                      (match_dup 5)))])]
9009   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
9010   if (operands[2] == const0_rtx)
9011     {
9012       emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
9013       DONE;
9014     }
9015   if (CONST_INT_P (operands[5]))
9016     operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode,
9017                                             operands[5], <MODE>mode);
9018   else
9019     operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
9022 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
9023 ;; test, where the latter is preferrable if we have some carry consuming
9024 ;; instruction.
9025 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
9026 ;; + (1 - CF).
9027 (define_insn_and_split "*add<mode>3_eq"
9028   [(set (match_operand:SWI 0 "nonimmediate_operand")
9029         (plus:SWI
9030           (plus:SWI
9031             (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9032             (match_operand:SWI 1 "nonimmediate_operand"))
9033           (match_operand:SWI 2 "<general_operand>")))
9034    (clobber (reg:CC FLAGS_REG))]
9035   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9036    && ix86_pre_reload_split ()"
9037   "#"
9038   "&& 1"
9039   [(set (reg:CC FLAGS_REG)
9040         (compare:CC (match_dup 3) (const_int 1)))
9041    (parallel [(set (match_dup 0)
9042                    (plus:SWI
9043                      (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9044                                (match_dup 1))
9045                      (match_dup 2)))
9046               (clobber (reg:CC FLAGS_REG))])])
9048 (define_insn_and_split "*add<mode>3_ne"
9049   [(set (match_operand:SWI 0 "nonimmediate_operand")
9050         (plus:SWI
9051           (plus:SWI
9052             (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9053             (match_operand:SWI 1 "nonimmediate_operand"))
9054           (match_operand:SWI 2 "<immediate_operand>")))
9055    (clobber (reg:CC FLAGS_REG))]
9056   "CONST_INT_P (operands[2])
9057    && (<MODE>mode != DImode
9058        || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9059    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9060    && ix86_pre_reload_split ()"
9061   "#"
9062   "&& 1"
9063   [(set (reg:CC FLAGS_REG)
9064         (compare:CC (match_dup 3) (const_int 1)))
9065    (parallel [(set (match_dup 0)
9066                    (minus:SWI
9067                      (minus:SWI (match_dup 1)
9068                                 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9069                      (match_dup 2)))
9070               (clobber (reg:CC FLAGS_REG))])]
9072   operands[2] = gen_int_mode (~INTVAL (operands[2]),
9073                               <MODE>mode == DImode ? SImode : <MODE>mode);
9076 (define_insn_and_split "*add<mode>3_eq_0"
9077   [(set (match_operand:SWI 0 "nonimmediate_operand")
9078         (plus:SWI
9079           (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9080           (match_operand:SWI 1 "<general_operand>")))
9081    (clobber (reg:CC FLAGS_REG))]
9082   "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9083    && ix86_pre_reload_split ()"
9084   "#"
9085   "&& 1"
9086   [(set (reg:CC FLAGS_REG)
9087         (compare:CC (match_dup 2) (const_int 1)))
9088    (parallel [(set (match_dup 0)
9089                    (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9090                              (match_dup 1)))
9091               (clobber (reg:CC FLAGS_REG))])]
9093   if (!nonimmediate_operand (operands[1], <MODE>mode))
9094     operands[1] = force_reg (<MODE>mode, operands[1]);
9097 (define_insn_and_split "*add<mode>3_ne_0"
9098   [(set (match_operand:SWI 0 "nonimmediate_operand")
9099         (plus:SWI
9100           (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9101           (match_operand:SWI 1 "<general_operand>")))
9102    (clobber (reg:CC FLAGS_REG))]
9103   "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9104    && ix86_pre_reload_split ()"
9105   "#"
9106   "&& 1"
9107   [(set (reg:CC FLAGS_REG)
9108         (compare:CC (match_dup 2) (const_int 1)))
9109    (parallel [(set (match_dup 0)
9110                    (minus:SWI (minus:SWI
9111                                 (match_dup 1)
9112                                 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9113                               (const_int -1)))
9114               (clobber (reg:CC FLAGS_REG))])]
9116   if (!nonimmediate_operand (operands[1], <MODE>mode))
9117     operands[1] = force_reg (<MODE>mode, operands[1]);
9120 (define_insn_and_split "*sub<mode>3_eq"
9121   [(set (match_operand:SWI 0 "nonimmediate_operand")
9122         (minus:SWI
9123           (minus:SWI
9124             (match_operand:SWI 1 "nonimmediate_operand")
9125             (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9126                     (const_int 0)))
9127           (match_operand:SWI 2 "<general_operand>")))
9128    (clobber (reg:CC FLAGS_REG))]
9129   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9130    && ix86_pre_reload_split ()"
9131   "#"
9132   "&& 1"
9133   [(set (reg:CC FLAGS_REG)
9134         (compare:CC (match_dup 3) (const_int 1)))
9135    (parallel [(set (match_dup 0)
9136                    (minus:SWI
9137                      (minus:SWI (match_dup 1)
9138                                 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9139                      (match_dup 2)))
9140               (clobber (reg:CC FLAGS_REG))])])
9142 (define_insn_and_split "*sub<mode>3_ne"
9143   [(set (match_operand:SWI 0 "nonimmediate_operand")
9144         (plus:SWI
9145           (minus:SWI
9146             (match_operand:SWI 1 "nonimmediate_operand")
9147             (ne:SWI (match_operand 3 "int_nonimmediate_operand")
9148                     (const_int 0)))
9149           (match_operand:SWI 2 "<immediate_operand>")))
9150    (clobber (reg:CC FLAGS_REG))]
9151   "CONST_INT_P (operands[2])
9152    && (<MODE>mode != DImode
9153        || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9154    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9155    && ix86_pre_reload_split ()"
9156   "#"
9157   "&& 1"
9158   [(set (reg:CC FLAGS_REG)
9159         (compare:CC (match_dup 3) (const_int 1)))
9160    (parallel [(set (match_dup 0)
9161                    (plus:SWI
9162                      (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9163                                (match_dup 1))
9164                      (match_dup 2)))
9165               (clobber (reg:CC FLAGS_REG))])]
9167   operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
9168                               <MODE>mode == DImode ? SImode : <MODE>mode);
9171 (define_insn_and_split "*sub<mode>3_eq_1"
9172   [(set (match_operand:SWI 0 "nonimmediate_operand")
9173         (plus:SWI
9174           (minus:SWI
9175             (match_operand:SWI 1 "nonimmediate_operand")
9176             (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9177                     (const_int 0)))
9178           (match_operand:SWI 2 "<immediate_operand>")))
9179    (clobber (reg:CC FLAGS_REG))]
9180   "CONST_INT_P (operands[2])
9181    && (<MODE>mode != DImode
9182        || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9183    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9184    && ix86_pre_reload_split ()"
9185   "#"
9186   "&& 1"
9187   [(set (reg:CC FLAGS_REG)
9188         (compare:CC (match_dup 3) (const_int 1)))
9189    (parallel [(set (match_dup 0)
9190                    (minus:SWI
9191                      (minus:SWI (match_dup 1)
9192                                 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9193                      (match_dup 2)))
9194               (clobber (reg:CC FLAGS_REG))])]
9196   operands[2] = gen_int_mode (-INTVAL (operands[2]),
9197                               <MODE>mode == DImode ? SImode : <MODE>mode);
9200 (define_insn_and_split "*sub<mode>3_eq_0"
9201   [(set (match_operand:SWI 0 "nonimmediate_operand")
9202         (minus:SWI
9203           (match_operand:SWI 1 "<general_operand>")
9204           (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9205    (clobber (reg:CC FLAGS_REG))]
9206   "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9207    && ix86_pre_reload_split ()"
9208   "#"
9209   "&& 1"
9210   [(set (reg:CC FLAGS_REG)
9211         (compare:CC (match_dup 2) (const_int 1)))
9212    (parallel [(set (match_dup 0)
9213                    (minus:SWI (match_dup 1)
9214                               (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
9215               (clobber (reg:CC FLAGS_REG))])]
9217   if (!nonimmediate_operand (operands[1], <MODE>mode))
9218     operands[1] = force_reg (<MODE>mode, operands[1]);
9221 (define_insn_and_split "*sub<mode>3_ne_0"
9222   [(set (match_operand:SWI 0 "nonimmediate_operand")
9223         (minus:SWI
9224           (match_operand:SWI 1 "<general_operand>")
9225           (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9226    (clobber (reg:CC FLAGS_REG))]
9227   "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9228    && ix86_pre_reload_split ()"
9229   "#"
9230   "&& 1"
9231   [(set (reg:CC FLAGS_REG)
9232         (compare:CC (match_dup 2) (const_int 1)))
9233    (parallel [(set (match_dup 0)
9234                    (plus:SWI (plus:SWI
9235                                (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9236                                (match_dup 1))
9237                              (const_int -1)))
9238               (clobber (reg:CC FLAGS_REG))])]
9240   if (!nonimmediate_operand (operands[1], <MODE>mode))
9241     operands[1] = force_reg (<MODE>mode, operands[1]);
9244 ;; The patterns that match these are at the end of this file.
9246 (define_expand "<insn>xf3"
9247   [(set (match_operand:XF 0 "register_operand")
9248         (plusminus:XF
9249           (match_operand:XF 1 "register_operand")
9250           (match_operand:XF 2 "register_operand")))]
9251   "TARGET_80387")
9253 (define_expand "<insn>hf3"
9254   [(set (match_operand:HF 0 "register_operand")
9255         (plusminus:HF
9256           (match_operand:HF 1 "register_operand")
9257           (match_operand:HF 2 "nonimmediate_operand")))]
9258   "TARGET_AVX512FP16")
9260 (define_expand "<insn><mode>3"
9261   [(set (match_operand:MODEF 0 "register_operand")
9262         (plusminus:MODEF
9263           (match_operand:MODEF 1 "register_operand")
9264           (match_operand:MODEF 2 "nonimmediate_operand")))]
9265   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9266     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9268 ;; Multiply instructions
9270 (define_expand "mul<mode>3"
9271   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
9272                    (mult:SWIM248
9273                      (match_operand:SWIM248 1 "register_operand")
9274                      (match_operand:SWIM248 2 "<general_operand>")))
9275               (clobber (reg:CC FLAGS_REG))])])
9277 (define_expand "mulqi3"
9278   [(parallel [(set (match_operand:QI 0 "register_operand")
9279                    (mult:QI
9280                      (match_operand:QI 1 "register_operand")
9281                      (match_operand:QI 2 "nonimmediate_operand")))
9282               (clobber (reg:CC FLAGS_REG))])]
9283   "TARGET_QIMODE_MATH")
9285 ;; On AMDFAM10
9286 ;; IMUL reg32/64, reg32/64, imm8        Direct
9287 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
9288 ;; IMUL reg32/64, reg32/64, imm32       Direct
9289 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
9290 ;; IMUL reg32/64, reg32/64              Direct
9291 ;; IMUL reg32/64, mem32/64              Direct
9293 ;; On BDVER1, all above IMULs use DirectPath
9295 ;; On AMDFAM10
9296 ;; IMUL reg16, reg16, imm8      VectorPath
9297 ;; IMUL reg16, mem16, imm8      VectorPath
9298 ;; IMUL reg16, reg16, imm16     VectorPath
9299 ;; IMUL reg16, mem16, imm16     VectorPath
9300 ;; IMUL reg16, reg16            Direct
9301 ;; IMUL reg16, mem16            Direct
9303 ;; On BDVER1, all HI MULs use DoublePath
9305 (define_insn "*mul<mode>3_1"
9306   [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
9307         (mult:SWIM248
9308           (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
9309           (match_operand:SWIM248 2 "<general_operand>" "K,<i>,<m>r")))
9310    (clobber (reg:CC FLAGS_REG))]
9311   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9312   "@
9313    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9314    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9315    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9316   [(set_attr "type" "imul")
9317    (set_attr "prefix_0f" "0,0,1")
9318    (set (attr "athlon_decode")
9319         (cond [(eq_attr "cpu" "athlon")
9320                   (const_string "vector")
9321                (eq_attr "alternative" "1")
9322                   (const_string "vector")
9323                (and (eq_attr "alternative" "2")
9324                     (ior (match_test "<MODE>mode == HImode")
9325                          (match_operand 1 "memory_operand")))
9326                   (const_string "vector")]
9327               (const_string "direct")))
9328    (set (attr "amdfam10_decode")
9329         (cond [(and (eq_attr "alternative" "0,1")
9330                     (ior (match_test "<MODE>mode == HImode")
9331                          (match_operand 1 "memory_operand")))
9332                   (const_string "vector")]
9333               (const_string "direct")))
9334    (set (attr "bdver1_decode")
9335         (if_then_else
9336           (match_test "<MODE>mode == HImode")
9337             (const_string "double")
9338             (const_string "direct")))
9339    (set_attr "mode" "<MODE>")])
9341 (define_insn "*mulsi3_1_zext"
9342   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9343         (zero_extend:DI
9344           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
9345                    (match_operand:SI 2 "x86_64_general_operand" "K,e,BMr"))))
9346    (clobber (reg:CC FLAGS_REG))]
9347   "TARGET_64BIT
9348    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9349   "@
9350    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9351    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9352    imul{l}\t{%2, %k0|%k0, %2}"
9353   [(set_attr "type" "imul")
9354    (set_attr "prefix_0f" "0,0,1")
9355    (set (attr "athlon_decode")
9356         (cond [(eq_attr "cpu" "athlon")
9357                   (const_string "vector")
9358                (eq_attr "alternative" "1")
9359                   (const_string "vector")
9360                (and (eq_attr "alternative" "2")
9361                     (match_operand 1 "memory_operand"))
9362                   (const_string "vector")]
9363               (const_string "direct")))
9364    (set (attr "amdfam10_decode")
9365         (cond [(and (eq_attr "alternative" "0,1")
9366                     (match_operand 1 "memory_operand"))
9367                   (const_string "vector")]
9368               (const_string "direct")))
9369    (set_attr "bdver1_decode" "direct")
9370    (set_attr "mode" "SI")])
9372 ;;On AMDFAM10 and BDVER1
9373 ;; MUL reg8     Direct
9374 ;; MUL mem8     Direct
9376 (define_insn "*mulqi3_1"
9377   [(set (match_operand:QI 0 "register_operand" "=a")
9378         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9379                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
9380    (clobber (reg:CC FLAGS_REG))]
9381   "TARGET_QIMODE_MATH
9382    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9383   "mul{b}\t%2"
9384   [(set_attr "type" "imul")
9385    (set_attr "length_immediate" "0")
9386    (set (attr "athlon_decode")
9387      (if_then_else (eq_attr "cpu" "athlon")
9388         (const_string "vector")
9389         (const_string "direct")))
9390    (set_attr "amdfam10_decode" "direct")
9391    (set_attr "bdver1_decode" "direct")
9392    (set_attr "mode" "QI")])
9394 ;; Multiply with jump on overflow.
9395 (define_expand "mulv<mode>4"
9396   [(parallel [(set (reg:CCO FLAGS_REG)
9397                    (eq:CCO (mult:<DWI>
9398                               (sign_extend:<DWI>
9399                                  (match_operand:SWI248 1 "register_operand"))
9400                               (match_dup 4))
9401                            (sign_extend:<DWI>
9402                               (mult:SWI248 (match_dup 1)
9403                                            (match_operand:SWI248 2
9404                                               "<general_operand>")))))
9405               (set (match_operand:SWI248 0 "register_operand")
9406                    (mult:SWI248 (match_dup 1) (match_dup 2)))])
9407    (set (pc) (if_then_else
9408                (eq (reg:CCO FLAGS_REG) (const_int 0))
9409                (label_ref (match_operand 3))
9410                (pc)))]
9411   ""
9413   if (CONST_INT_P (operands[2]))
9414     operands[4] = operands[2];
9415   else
9416     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
9419 (define_insn "*mulv<mode>4"
9420   [(set (reg:CCO FLAGS_REG)
9421         (eq:CCO (mult:<DWI>
9422                    (sign_extend:<DWI>
9423                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
9424                    (sign_extend:<DWI>
9425                       (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
9426                 (sign_extend:<DWI>
9427                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
9428    (set (match_operand:SWI48 0 "register_operand" "=r,r")
9429         (mult:SWI48 (match_dup 1) (match_dup 2)))]
9430   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9431   "@
9432    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9433    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9434   [(set_attr "type" "imul")
9435    (set_attr "prefix_0f" "0,1")
9436    (set (attr "athlon_decode")
9437         (cond [(eq_attr "cpu" "athlon")
9438                   (const_string "vector")
9439                (eq_attr "alternative" "0")
9440                   (const_string "vector")
9441                (and (eq_attr "alternative" "1")
9442                     (match_operand 1 "memory_operand"))
9443                   (const_string "vector")]
9444               (const_string "direct")))
9445    (set (attr "amdfam10_decode")
9446         (cond [(and (eq_attr "alternative" "1")
9447                     (match_operand 1 "memory_operand"))
9448                   (const_string "vector")]
9449               (const_string "direct")))
9450    (set_attr "bdver1_decode" "direct")
9451    (set_attr "mode" "<MODE>")])
9453 (define_insn "*mulvhi4"
9454   [(set (reg:CCO FLAGS_REG)
9455         (eq:CCO (mult:SI
9456                    (sign_extend:SI
9457                       (match_operand:HI 1 "nonimmediate_operand" "%0"))
9458                    (sign_extend:SI
9459                       (match_operand:HI 2 "nonimmediate_operand" "mr")))
9460                 (sign_extend:SI
9461                    (mult:HI (match_dup 1) (match_dup 2)))))
9462    (set (match_operand:HI 0 "register_operand" "=r")
9463         (mult:HI (match_dup 1) (match_dup 2)))]
9464   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9465   "imul{w}\t{%2, %0|%0, %2}"
9466   [(set_attr "type" "imul")
9467    (set_attr "prefix_0f" "1")
9468    (set_attr "athlon_decode" "vector")
9469    (set_attr "amdfam10_decode" "direct")
9470    (set_attr "bdver1_decode" "double")
9471    (set_attr "mode" "HI")])
9473 (define_insn "*mulv<mode>4_1"
9474   [(set (reg:CCO FLAGS_REG)
9475         (eq:CCO (mult:<DWI>
9476                    (sign_extend:<DWI>
9477                       (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
9478                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
9479                 (sign_extend:<DWI>
9480                    (mult:SWI248 (match_dup 1)
9481                                 (match_operand:SWI248 2
9482                                    "<immediate_operand>" "K,<i>")))))
9483    (set (match_operand:SWI248 0 "register_operand" "=r,r")
9484         (mult:SWI248 (match_dup 1) (match_dup 2)))]
9485   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
9486    && CONST_INT_P (operands[2])
9487    && INTVAL (operands[2]) == INTVAL (operands[3])"
9488   "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9489   [(set_attr "type" "imul")
9490    (set (attr "prefix_0f")
9491         (if_then_else
9492           (match_test "<MODE>mode == HImode")
9493             (const_string "0")
9494             (const_string "*")))
9495    (set (attr "athlon_decode")
9496         (cond [(eq_attr "cpu" "athlon")
9497                   (const_string "vector")
9498                (eq_attr "alternative" "1")
9499                   (const_string "vector")]
9500               (const_string "direct")))
9501    (set (attr "amdfam10_decode")
9502         (cond [(ior (match_test "<MODE>mode == HImode")
9503                     (match_operand 1 "memory_operand"))
9504                   (const_string "vector")]
9505               (const_string "direct")))
9506    (set (attr "bdver1_decode")
9507         (if_then_else
9508           (match_test "<MODE>mode == HImode")
9509             (const_string "double")
9510             (const_string "direct")))
9511    (set_attr "mode" "<MODE>")
9512    (set (attr "length_immediate")
9513         (cond [(eq_attr "alternative" "0")
9514                   (const_string "1")
9515                (match_test "<MODE_SIZE> == 8")
9516                   (const_string "4")]
9517               (const_string "<MODE_SIZE>")))])
9519 (define_expand "umulv<mode>4"
9520   [(parallel [(set (reg:CCO FLAGS_REG)
9521                    (eq:CCO (mult:<DWI>
9522                               (zero_extend:<DWI>
9523                                  (match_operand:SWI248 1
9524                                                       "nonimmediate_operand"))
9525                               (zero_extend:<DWI>
9526                                  (match_operand:SWI248 2
9527                                                       "nonimmediate_operand")))
9528                            (zero_extend:<DWI>
9529                               (mult:SWI248 (match_dup 1) (match_dup 2)))))
9530               (set (match_operand:SWI248 0 "register_operand")
9531                    (mult:SWI248 (match_dup 1) (match_dup 2)))
9532               (clobber (scratch:SWI248))])
9533    (set (pc) (if_then_else
9534                (eq (reg:CCO FLAGS_REG) (const_int 0))
9535                (label_ref (match_operand 3))
9536                (pc)))]
9537   ""
9539   if (MEM_P (operands[1]) && MEM_P (operands[2]))
9540     operands[1] = force_reg (<MODE>mode, operands[1]);
9543 (define_insn "*umulv<mode>4"
9544   [(set (reg:CCO FLAGS_REG)
9545         (eq:CCO (mult:<DWI>
9546                    (zero_extend:<DWI>
9547                       (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
9548                    (zero_extend:<DWI>
9549                       (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
9550                 (zero_extend:<DWI>
9551                    (mult:SWI248 (match_dup 1) (match_dup 2)))))
9552    (set (match_operand:SWI248 0 "register_operand" "=a")
9553         (mult:SWI248 (match_dup 1) (match_dup 2)))
9554    (clobber (match_scratch:SWI248 3 "=d"))]
9555   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9556   "mul{<imodesuffix>}\t%2"
9557   [(set_attr "type" "imul")
9558    (set_attr "length_immediate" "0")
9559    (set (attr "athlon_decode")
9560      (if_then_else (eq_attr "cpu" "athlon")
9561        (const_string "vector")
9562        (const_string "double")))
9563    (set_attr "amdfam10_decode" "double")
9564    (set_attr "bdver1_decode" "direct")
9565    (set_attr "mode" "<MODE>")])
9567 (define_expand "<u>mulvqi4"
9568   [(parallel [(set (reg:CCO FLAGS_REG)
9569                    (eq:CCO (mult:HI
9570                               (any_extend:HI
9571                                  (match_operand:QI 1 "nonimmediate_operand"))
9572                               (any_extend:HI
9573                                  (match_operand:QI 2 "nonimmediate_operand")))
9574                            (any_extend:HI
9575                               (mult:QI (match_dup 1) (match_dup 2)))))
9576               (set (match_operand:QI 0 "register_operand")
9577                    (mult:QI (match_dup 1) (match_dup 2)))])
9578    (set (pc) (if_then_else
9579                (eq (reg:CCO FLAGS_REG) (const_int 0))
9580                (label_ref (match_operand 3))
9581                (pc)))]
9582   "TARGET_QIMODE_MATH"
9584   if (MEM_P (operands[1]) && MEM_P (operands[2]))
9585     operands[1] = force_reg (QImode, operands[1]);
9588 (define_insn "*<u>mulvqi4"
9589   [(set (reg:CCO FLAGS_REG)
9590         (eq:CCO (mult:HI
9591                    (any_extend:HI
9592                       (match_operand:QI 1 "nonimmediate_operand" "%0"))
9593                    (any_extend:HI
9594                       (match_operand:QI 2 "nonimmediate_operand" "qm")))
9595                 (any_extend:HI
9596                    (mult:QI (match_dup 1) (match_dup 2)))))
9597    (set (match_operand:QI 0 "register_operand" "=a")
9598         (mult:QI (match_dup 1) (match_dup 2)))]
9599   "TARGET_QIMODE_MATH
9600    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9601   "<sgnprefix>mul{b}\t%2"
9602   [(set_attr "type" "imul")
9603    (set_attr "length_immediate" "0")
9604    (set (attr "athlon_decode")
9605      (if_then_else (eq_attr "cpu" "athlon")
9606         (const_string "vector")
9607         (const_string "direct")))
9608    (set_attr "amdfam10_decode" "direct")
9609    (set_attr "bdver1_decode" "direct")
9610    (set_attr "mode" "QI")])
9612 (define_expand "<u>mul<mode><dwi>3"
9613   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
9614                    (mult:<DWI>
9615                      (any_extend:<DWI>
9616                        (match_operand:DWIH 1 "register_operand"))
9617                      (any_extend:<DWI>
9618                        (match_operand:DWIH 2 "nonimmediate_operand"))))
9619               (clobber (reg:CC FLAGS_REG))])])
9621 (define_expand "<u>mulqihi3"
9622   [(parallel [(set (match_operand:HI 0 "register_operand")
9623                    (mult:HI
9624                      (any_extend:HI
9625                        (match_operand:QI 1 "register_operand"))
9626                      (any_extend:HI
9627                        (match_operand:QI 2 "nonimmediate_operand"))))
9628               (clobber (reg:CC FLAGS_REG))])]
9629   "TARGET_QIMODE_MATH")
9631 (define_insn "*bmi2_umul<mode><dwi>3_1"
9632   [(set (match_operand:DWIH 0 "register_operand" "=r")
9633         (mult:DWIH
9634           (match_operand:DWIH 2 "register_operand" "%d")
9635           (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
9636    (set (match_operand:DWIH 1 "register_operand" "=r")
9637         (umul_highpart:DWIH (match_dup 2) (match_dup 3)))]
9638   "TARGET_BMI2"
9639   "mulx\t{%3, %0, %1|%1, %0, %3}"
9640   [(set_attr "type" "imulx")
9641    (set_attr "prefix" "vex")
9642    (set_attr "mode" "<MODE>")])
9644 ;; Tweak *bmi2_umul<mode><dwi>3_1 to eliminate following mov.
9645 (define_peephole2
9646   [(parallel [(set (match_operand:DWIH 0 "general_reg_operand")
9647                    (mult:DWIH (match_operand:DWIH 2 "register_operand")
9648                               (match_operand:DWIH 3 "nonimmediate_operand")))
9649               (set (match_operand:DWIH 1 "general_reg_operand")
9650                    (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])
9651    (set (match_operand:DWIH 4 "general_reg_operand")
9652         (match_operand:DWIH 5 "general_reg_operand"))]
9653   "TARGET_BMI2
9654    && ((REGNO (operands[5]) == REGNO (operands[0])
9655         && REGNO (operands[1]) != REGNO (operands[4]))
9656        || (REGNO (operands[5]) == REGNO (operands[1])
9657            && REGNO (operands[0]) != REGNO (operands[4])))
9658    && peep2_reg_dead_p (2, operands[5])"
9659   [(parallel [(set (match_dup 0) (mult:DWIH (match_dup 2) (match_dup 3)))
9660               (set (match_dup 1)
9661                    (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])]
9663   if (REGNO (operands[5]) == REGNO (operands[0]))
9664     operands[0] = operands[4];
9665   else
9666     operands[1] = operands[4];
9669 (define_insn "*umul<mode><dwi>3_1"
9670   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
9671         (mult:<DWI>
9672           (zero_extend:<DWI>
9673             (match_operand:DWIH 1 "register_operand" "%d,a"))
9674           (zero_extend:<DWI>
9675             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
9676    (clobber (reg:CC FLAGS_REG))]
9677   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9678   "@
9679    #
9680    mul{<imodesuffix>}\t%2"
9681   [(set_attr "isa" "bmi2,*")
9682    (set_attr "type" "imulx,imul")
9683    (set_attr "length_immediate" "*,0")
9684    (set (attr "athlon_decode")
9685         (cond [(eq_attr "alternative" "1")
9686                  (if_then_else (eq_attr "cpu" "athlon")
9687                    (const_string "vector")
9688                    (const_string "double"))]
9689               (const_string "*")))
9690    (set_attr "amdfam10_decode" "*,double")
9691    (set_attr "bdver1_decode" "*,direct")
9692    (set_attr "prefix" "vex,orig")
9693    (set_attr "mode" "<MODE>")])
9695 ;; Convert mul to the mulx pattern to avoid flags dependency.
9696 (define_split
9697  [(set (match_operand:<DWI> 0 "register_operand")
9698        (mult:<DWI>
9699          (zero_extend:<DWI>
9700            (match_operand:DWIH 1 "register_operand"))
9701          (zero_extend:<DWI>
9702            (match_operand:DWIH 2 "nonimmediate_operand"))))
9703   (clobber (reg:CC FLAGS_REG))]
9704  "TARGET_BMI2 && reload_completed
9705   && REGNO (operands[1]) == DX_REG"
9706   [(parallel [(set (match_dup 3)
9707                    (mult:DWIH (match_dup 1) (match_dup 2)))
9708               (set (match_dup 4)
9709                    (umul_highpart:DWIH (match_dup 1) (match_dup 2)))])]
9711   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
9713   operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9716 (define_insn "*mul<mode><dwi>3_1"
9717   [(set (match_operand:<DWI> 0 "register_operand" "=A")
9718         (mult:<DWI>
9719           (sign_extend:<DWI>
9720             (match_operand:DWIH 1 "register_operand" "%a"))
9721           (sign_extend:<DWI>
9722             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
9723    (clobber (reg:CC FLAGS_REG))]
9724   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9725   "imul{<imodesuffix>}\t%2"
9726   [(set_attr "type" "imul")
9727    (set_attr "length_immediate" "0")
9728    (set (attr "athlon_decode")
9729      (if_then_else (eq_attr "cpu" "athlon")
9730         (const_string "vector")
9731         (const_string "double")))
9732    (set_attr "amdfam10_decode" "double")
9733    (set_attr "bdver1_decode" "direct")
9734    (set_attr "mode" "<MODE>")])
9736 (define_insn "*<u>mulqihi3_1"
9737   [(set (match_operand:HI 0 "register_operand" "=a")
9738         (mult:HI
9739           (any_extend:HI
9740             (match_operand:QI 1 "register_operand" "%0"))
9741           (any_extend:HI
9742             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
9743    (clobber (reg:CC FLAGS_REG))]
9744   "TARGET_QIMODE_MATH
9745    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9746   "<sgnprefix>mul{b}\t%2"
9747   [(set_attr "type" "imul")
9748    (set_attr "length_immediate" "0")
9749    (set (attr "athlon_decode")
9750      (if_then_else (eq_attr "cpu" "athlon")
9751         (const_string "vector")
9752         (const_string "direct")))
9753    (set_attr "amdfam10_decode" "direct")
9754    (set_attr "bdver1_decode" "direct")
9755    (set_attr "mode" "QI")])
9757 ;; Widening multiplication peephole2s to tweak register allocation.
9758 ;; mov imm,%rdx; mov %rdi,%rax; mulq %rdx  ->  mov imm,%rax; mulq %rdi
9759 (define_peephole2
9760   [(set (match_operand:DWIH 0 "general_reg_operand")
9761         (match_operand:DWIH 1 "immediate_operand"))
9762    (set (match_operand:DWIH 2 "general_reg_operand")
9763         (match_operand:DWIH 3 "general_reg_operand"))
9764    (parallel [(set (match_operand:<DWI> 4 "general_reg_operand")
9765                    (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9766                                (zero_extend:<DWI> (match_dup 0))))
9767               (clobber (reg:CC FLAGS_REG))])]
9768   "REGNO (operands[3]) != AX_REG
9769    && REGNO (operands[0]) != REGNO (operands[2])
9770    && REGNO (operands[0]) != REGNO (operands[3])
9771    && (REGNO (operands[0]) == REGNO (operands[4])
9772        || REGNO (operands[0]) == DX_REG
9773        || peep2_reg_dead_p (3, operands[0]))"
9774   [(set (match_dup 2) (match_dup 1))
9775    (parallel [(set (match_dup 4)
9776                    (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9777                                (zero_extend:<DWI> (match_dup 3))))
9778               (clobber (reg:CC FLAGS_REG))])])
9780 ;; mov imm,%rax; mov %rdi,%rdx; mulx %rax  ->  mov imm,%rdx; mulx %rdi
9781 (define_peephole2
9782   [(set (match_operand:DWIH 0 "general_reg_operand")
9783         (match_operand:DWIH 1 "immediate_operand"))
9784    (set (match_operand:DWIH 2 "general_reg_operand")
9785         (match_operand:DWIH 3 "general_reg_operand"))
9786    (parallel [(set (match_operand:DWIH 4 "general_reg_operand")
9787                    (mult:DWIH (match_dup 2) (match_dup 0)))
9788               (set (match_operand:DWIH 5 "general_reg_operand")
9789                    (umul_highpart:DWIH (match_dup 2) (match_dup 0)))])]
9790   "REGNO (operands[3]) != DX_REG
9791    && REGNO (operands[0]) != REGNO (operands[2])
9792    && REGNO (operands[0]) != REGNO (operands[3])
9793    && (REGNO (operands[0]) == REGNO (operands[4])
9794        || REGNO (operands[0]) == REGNO (operands[5])
9795        || peep2_reg_dead_p (3, operands[0]))"
9796   [(set (match_dup 2) (match_dup 1))
9797    (parallel [(set (match_dup 4)
9798                    (mult:DWIH (match_dup 2) (match_dup 3)))
9799               (set (match_dup 5)
9800                    (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])])
9802 ;; Highpart multiplication patterns
9803 (define_insn "<s>mul<mode>3_highpart"
9804   [(set (match_operand:DWIH 0 "register_operand" "=d")
9805         (any_mul_highpart:DWIH
9806           (match_operand:DWIH 1 "register_operand" "%a")
9807           (match_operand:DWIH 2 "nonimmediate_operand" "rm")))
9808    (clobber (match_scratch:DWIH 3 "=1"))
9809    (clobber (reg:CC FLAGS_REG))]
9810   ""
9811   "<sgnprefix>mul{<imodesuffix>}\t%2"
9812   [(set_attr "type" "imul")
9813    (set_attr "length_immediate" "0")
9814    (set (attr "athlon_decode")
9815      (if_then_else (eq_attr "cpu" "athlon")
9816         (const_string "vector")
9817         (const_string "double")))
9818    (set_attr "amdfam10_decode" "double")
9819    (set_attr "bdver1_decode" "direct")
9820    (set_attr "mode" "<MODE>")])
9822 (define_insn "*<s>mulsi3_highpart_zext"
9823   [(set (match_operand:DI 0 "register_operand" "=d")
9824         (zero_extend:DI 
9825           (any_mul_highpart:SI
9826             (match_operand:SI 1 "register_operand" "%a")
9827             (match_operand:SI 2 "nonimmediate_operand" "rm"))))
9828    (clobber (match_scratch:SI 3 "=1"))
9829    (clobber (reg:CC FLAGS_REG))]
9830   "TARGET_64BIT"
9831   "<sgnprefix>mul{l}\t%2"
9832   [(set_attr "type" "imul")
9833    (set_attr "length_immediate" "0")
9834    (set (attr "athlon_decode")
9835      (if_then_else (eq_attr "cpu" "athlon")
9836         (const_string "vector")
9837         (const_string "double")))
9838    (set_attr "amdfam10_decode" "double")
9839    (set_attr "bdver1_decode" "direct")
9840    (set_attr "mode" "SI")])
9842 (define_insn "*<s>muldi3_highpart_1"
9843   [(set (match_operand:DI 0 "register_operand" "=d")
9844         (truncate:DI
9845           (lshiftrt:TI
9846             (mult:TI
9847               (any_extend:TI
9848                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
9849               (any_extend:TI
9850                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
9851             (const_int 64))))
9852    (clobber (match_scratch:DI 3 "=1"))
9853    (clobber (reg:CC FLAGS_REG))]
9854   "TARGET_64BIT
9855    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9856   "<sgnprefix>mul{q}\t%2"
9857   [(set_attr "type" "imul")
9858    (set_attr "length_immediate" "0")
9859    (set (attr "athlon_decode")
9860      (if_then_else (eq_attr "cpu" "athlon")
9861         (const_string "vector")
9862         (const_string "double")))
9863    (set_attr "amdfam10_decode" "double")
9864    (set_attr "bdver1_decode" "direct")
9865    (set_attr "mode" "DI")])
9867 (define_insn "*<s>mulsi3_highpart_zext"
9868   [(set (match_operand:DI 0 "register_operand" "=d")
9869         (zero_extend:DI (truncate:SI
9870           (lshiftrt:DI
9871             (mult:DI (any_extend:DI
9872                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
9873                      (any_extend:DI
9874                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
9875             (const_int 32)))))
9876    (clobber (match_scratch:SI 3 "=1"))
9877    (clobber (reg:CC FLAGS_REG))]
9878   "TARGET_64BIT
9879    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9880   "<sgnprefix>mul{l}\t%2"
9881   [(set_attr "type" "imul")
9882    (set_attr "length_immediate" "0")
9883    (set (attr "athlon_decode")
9884      (if_then_else (eq_attr "cpu" "athlon")
9885         (const_string "vector")
9886         (const_string "double")))
9887    (set_attr "amdfam10_decode" "double")
9888    (set_attr "bdver1_decode" "direct")
9889    (set_attr "mode" "SI")])
9891 (define_insn "*<s>mulsi3_highpart_1"
9892   [(set (match_operand:SI 0 "register_operand" "=d")
9893         (truncate:SI
9894           (lshiftrt:DI
9895             (mult:DI
9896               (any_extend:DI
9897                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
9898               (any_extend:DI
9899                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9900             (const_int 32))))
9901    (clobber (match_scratch:SI 3 "=1"))
9902    (clobber (reg:CC FLAGS_REG))]
9903   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9904   "<sgnprefix>mul{l}\t%2"
9905   [(set_attr "type" "imul")
9906    (set_attr "length_immediate" "0")
9907    (set (attr "athlon_decode")
9908      (if_then_else (eq_attr "cpu" "athlon")
9909         (const_string "vector")
9910         (const_string "double")))
9911    (set_attr "amdfam10_decode" "double")
9912    (set_attr "bdver1_decode" "direct")
9913    (set_attr "mode" "SI")])
9915 ;; Highpart multiplication peephole2s to tweak register allocation.
9916 ;; mov imm,%rdx; mov %rdi,%rax; imulq %rdx  ->  mov imm,%rax; imulq %rdi
9917 (define_peephole2
9918   [(set (match_operand:SWI48 0 "general_reg_operand")
9919         (match_operand:SWI48 1 "immediate_operand"))
9920    (set (match_operand:SWI48 2 "general_reg_operand")
9921         (match_operand:SWI48 3 "general_reg_operand"))
9922    (parallel [(set (match_operand:SWI48 4 "general_reg_operand")
9923                    (any_mul_highpart:SWI48 (match_dup 2) (match_dup 0)))
9924               (clobber (match_dup 2))
9925               (clobber (reg:CC FLAGS_REG))])]
9926   "REGNO (operands[3]) != AX_REG
9927    && REGNO (operands[0]) != REGNO (operands[2])
9928    && REGNO (operands[0]) != REGNO (operands[3])
9929    && (REGNO (operands[0]) == REGNO (operands[4])
9930        || peep2_reg_dead_p (3, operands[0]))"
9931   [(set (match_dup 2) (match_dup 1))
9932    (parallel [(set (match_dup 4)
9933                    (any_mul_highpart:SWI48 (match_dup 2) (match_dup 3)))
9934               (clobber (match_dup 2))
9935               (clobber (reg:CC FLAGS_REG))])])
9937 (define_peephole2
9938   [(set (match_operand:SI 0 "general_reg_operand")
9939         (match_operand:SI 1 "immediate_operand"))
9940    (set (match_operand:SI 2 "general_reg_operand")
9941         (match_operand:SI 3 "general_reg_operand"))
9942    (parallel [(set (match_operand:DI 4 "general_reg_operand")
9943                    (zero_extend:DI
9944                      (any_mul_highpart:SI (match_dup 2) (match_dup 0))))
9945               (clobber (match_dup 2))
9946               (clobber (reg:CC FLAGS_REG))])]
9947   "TARGET_64BIT
9948    && REGNO (operands[3]) != AX_REG
9949    && REGNO (operands[0]) != REGNO (operands[2])
9950    && REGNO (operands[2]) != REGNO (operands[3])
9951    && REGNO (operands[0]) != REGNO (operands[3])
9952    && (REGNO (operands[0]) == REGNO (operands[4])
9953        || peep2_reg_dead_p (3, operands[0]))"
9954   [(set (match_dup 2) (match_dup 1))
9955    (parallel [(set (match_dup 4)
9956                    (zero_extend:DI
9957                      (any_mul_highpart:SI (match_dup 2) (match_dup 3))))
9958               (clobber (match_dup 2))
9959               (clobber (reg:CC FLAGS_REG))])])
9961 ;; The patterns that match these are at the end of this file.
9963 (define_expand "mulxf3"
9964   [(set (match_operand:XF 0 "register_operand")
9965         (mult:XF (match_operand:XF 1 "register_operand")
9966                  (match_operand:XF 2 "register_operand")))]
9967   "TARGET_80387")
9969 (define_expand "mulhf3"
9970   [(set (match_operand:HF 0 "register_operand")
9971         (mult:HF (match_operand:HF 1 "register_operand")
9972                     (match_operand:HF 2 "nonimmediate_operand")))]
9973   "TARGET_AVX512FP16")
9975 (define_expand "mul<mode>3"
9976   [(set (match_operand:MODEF 0 "register_operand")
9977         (mult:MODEF (match_operand:MODEF 1 "register_operand")
9978                     (match_operand:MODEF 2 "nonimmediate_operand")))]
9979   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9980     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9982 ;; Divide instructions
9984 ;; The patterns that match these are at the end of this file.
9986 (define_expand "divxf3"
9987   [(set (match_operand:XF 0 "register_operand")
9988         (div:XF (match_operand:XF 1 "register_operand")
9989                 (match_operand:XF 2 "register_operand")))]
9990   "TARGET_80387")
9992 /* There is no more precision loss than Newton-Rhapson approximation
9993   when using HFmode rcp/rsqrt, so do the transformation directly under
9994   TARGET_RECIP_DIV and fast-math.  */
9995 (define_expand "divhf3"
9996   [(set (match_operand:HF 0 "register_operand")
9997         (div:HF (match_operand:HF 1 "register_operand")
9998                    (match_operand:HF 2 "nonimmediate_operand")))]
9999   "TARGET_AVX512FP16"
10001   if (TARGET_RECIP_DIV
10002       && optimize_insn_for_speed_p ()
10003       && flag_finite_math_only && !flag_trapping_math
10004       && flag_unsafe_math_optimizations)
10005     {
10006       rtx op = gen_reg_rtx (HFmode);
10007       operands[2] = force_reg (HFmode, operands[2]);
10008       emit_insn (gen_rcphf2 (op, operands[2]));
10009       emit_insn (gen_mulhf3 (operands[0], operands[1], op));
10010       DONE;
10011     }
10014 (define_expand "div<mode>3"
10015   [(set (match_operand:MODEF 0 "register_operand")
10016         (div:MODEF (match_operand:MODEF 1 "register_operand")
10017                    (match_operand:MODEF 2 "nonimmediate_operand")))]
10018   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
10019     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10021   if (<MODE>mode == SFmode
10022       && TARGET_SSE && TARGET_SSE_MATH
10023       && TARGET_RECIP_DIV
10024       && optimize_insn_for_speed_p ()
10025       && flag_finite_math_only && !flag_trapping_math
10026       && flag_unsafe_math_optimizations)
10027     {
10028       ix86_emit_swdivsf (operands[0], operands[1],
10029                          operands[2], SFmode);
10030       DONE;
10031     }
10034 ;; Divmod instructions.
10036 (define_code_iterator any_div [div udiv])
10037 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
10039 (define_expand "<u>divmod<mode>4"
10040   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
10041                    (any_div:SWIM248
10042                      (match_operand:SWIM248 1 "register_operand")
10043                      (match_operand:SWIM248 2 "nonimmediate_operand")))
10044               (set (match_operand:SWIM248 3 "register_operand")
10045                    (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
10046               (clobber (reg:CC FLAGS_REG))])])
10048 ;; Split with 8bit unsigned divide:
10049 ;;      if (dividend an divisor are in [0-255])
10050 ;;         use 8bit unsigned integer divide
10051 ;;       else
10052 ;;         use original integer divide
10053 (define_split
10054   [(set (match_operand:SWI48 0 "register_operand")
10055         (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
10056                        (match_operand:SWI48 3 "nonimmediate_operand")))
10057    (set (match_operand:SWI48 1 "register_operand")
10058         (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
10059    (clobber (reg:CC FLAGS_REG))]
10060   "TARGET_USE_8BIT_IDIV
10061    && TARGET_QIMODE_MATH
10062    && can_create_pseudo_p ()
10063    && !optimize_insn_for_size_p ()"
10064   [(const_int 0)]
10065   "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
10067 (define_split
10068   [(set (match_operand:DI 0 "register_operand")
10069         (zero_extend:DI
10070           (any_div:SI (match_operand:SI 2 "register_operand")
10071                       (match_operand:SI 3 "nonimmediate_operand"))))
10072    (set (match_operand:SI 1 "register_operand")
10073         (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10074    (clobber (reg:CC FLAGS_REG))]
10075   "TARGET_64BIT
10076    && TARGET_USE_8BIT_IDIV
10077    && TARGET_QIMODE_MATH
10078    && can_create_pseudo_p ()
10079    && !optimize_insn_for_size_p ()"
10080   [(const_int 0)]
10081   "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10083 (define_split
10084   [(set (match_operand:DI 1 "register_operand")
10085         (zero_extend:DI
10086           (<paired_mod>:SI (match_operand:SI 2 "register_operand")
10087                            (match_operand:SI 3 "nonimmediate_operand"))))
10088    (set (match_operand:SI 0 "register_operand")
10089         (any_div:SI  (match_dup 2) (match_dup 3)))
10090    (clobber (reg:CC FLAGS_REG))]
10091   "TARGET_64BIT
10092    && TARGET_USE_8BIT_IDIV
10093    && TARGET_QIMODE_MATH
10094    && can_create_pseudo_p ()
10095    && !optimize_insn_for_size_p ()"
10096   [(const_int 0)]
10097   "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10099 (define_insn_and_split "divmod<mode>4_1"
10100   [(set (match_operand:SWI48 0 "register_operand" "=a")
10101         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10102                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10103    (set (match_operand:SWI48 1 "register_operand" "=&d")
10104         (mod:SWI48 (match_dup 2) (match_dup 3)))
10105    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10106    (clobber (reg:CC FLAGS_REG))]
10107   ""
10108   "#"
10109   "reload_completed"
10110   [(parallel [(set (match_dup 1)
10111                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
10112               (clobber (reg:CC FLAGS_REG))])
10113    (parallel [(set (match_dup 0)
10114                    (div:SWI48 (match_dup 2) (match_dup 3)))
10115               (set (match_dup 1)
10116                    (mod:SWI48 (match_dup 2) (match_dup 3)))
10117               (use (match_dup 1))
10118               (clobber (reg:CC FLAGS_REG))])]
10120   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10122   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10123     operands[4] = operands[2];
10124   else
10125     {
10126       /* Avoid use of cltd in favor of a mov+shift.  */
10127       emit_move_insn (operands[1], operands[2]);
10128       operands[4] = operands[1];
10129     }
10131   [(set_attr "type" "multi")
10132    (set_attr "mode" "<MODE>")])
10134 (define_insn_and_split "udivmod<mode>4_1"
10135   [(set (match_operand:SWI48 0 "register_operand" "=a")
10136         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10137                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10138    (set (match_operand:SWI48 1 "register_operand" "=&d")
10139         (umod:SWI48 (match_dup 2) (match_dup 3)))
10140    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10141    (clobber (reg:CC FLAGS_REG))]
10142   ""
10143   "#"
10144   "reload_completed"
10145   [(set (match_dup 1) (const_int 0))
10146    (parallel [(set (match_dup 0)
10147                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
10148               (set (match_dup 1)
10149                    (umod:SWI48 (match_dup 2) (match_dup 3)))
10150               (use (match_dup 1))
10151               (clobber (reg:CC FLAGS_REG))])]
10152   ""
10153   [(set_attr "type" "multi")
10154    (set_attr "mode" "<MODE>")])
10156 (define_insn_and_split "divmodsi4_zext_1"
10157   [(set (match_operand:DI 0 "register_operand" "=a")
10158         (zero_extend:DI
10159           (div:SI (match_operand:SI 2 "register_operand" "0")
10160                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10161    (set (match_operand:SI 1 "register_operand" "=&d")
10162         (mod:SI (match_dup 2) (match_dup 3)))
10163    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10164    (clobber (reg:CC FLAGS_REG))]
10165   "TARGET_64BIT"
10166   "#"
10167   "&& reload_completed"
10168   [(parallel [(set (match_dup 1)
10169                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
10170               (clobber (reg:CC FLAGS_REG))])
10171    (parallel [(set (match_dup 0)
10172                    (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10173               (set (match_dup 1)
10174                    (mod:SI (match_dup 2) (match_dup 3)))
10175               (use (match_dup 1))
10176               (clobber (reg:CC FLAGS_REG))])]
10178   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10180   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10181     operands[4] = operands[2];
10182   else
10183     {
10184       /* Avoid use of cltd in favor of a mov+shift.  */
10185       emit_move_insn (operands[1], operands[2]);
10186       operands[4] = operands[1];
10187     }
10189   [(set_attr "type" "multi")
10190    (set_attr "mode" "SI")])
10192 (define_insn_and_split "udivmodsi4_zext_1"
10193   [(set (match_operand:DI 0 "register_operand" "=a")
10194         (zero_extend:DI
10195           (udiv:SI (match_operand:SI 2 "register_operand" "0")
10196                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10197    (set (match_operand:SI 1 "register_operand" "=&d")
10198         (umod:SI (match_dup 2) (match_dup 3)))
10199    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10200    (clobber (reg:CC FLAGS_REG))]
10201   "TARGET_64BIT"
10202   "#"
10203   "&& reload_completed"
10204   [(set (match_dup 1) (const_int 0))
10205    (parallel [(set (match_dup 0)
10206                    (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10207               (set (match_dup 1)
10208                    (umod:SI (match_dup 2) (match_dup 3)))
10209               (use (match_dup 1))
10210               (clobber (reg:CC FLAGS_REG))])]
10211   ""
10212   [(set_attr "type" "multi")
10213    (set_attr "mode" "SI")])
10215 (define_insn_and_split "divmodsi4_zext_2"
10216   [(set (match_operand:DI 1 "register_operand" "=&d")
10217         (zero_extend:DI
10218           (mod:SI (match_operand:SI 2 "register_operand" "0")
10219                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10220    (set (match_operand:SI 0 "register_operand" "=a")
10221         (div:SI (match_dup 2) (match_dup 3)))
10222    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10223    (clobber (reg:CC FLAGS_REG))]
10224   "TARGET_64BIT"
10225   "#"
10226   "&& reload_completed"
10227   [(parallel [(set (match_dup 6)
10228                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
10229               (clobber (reg:CC FLAGS_REG))])
10230    (parallel [(set (match_dup 1)
10231                    (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10232               (set (match_dup 0)
10233                    (div:SI (match_dup 2) (match_dup 3)))
10234               (use (match_dup 6))
10235               (clobber (reg:CC FLAGS_REG))])]
10237   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10238   operands[6] = gen_lowpart (SImode, operands[1]);
10240   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10241     operands[4] = operands[2];
10242   else
10243     {
10244       /* Avoid use of cltd in favor of a mov+shift.  */
10245       emit_move_insn (operands[6], operands[2]);
10246       operands[4] = operands[6];
10247     }
10249   [(set_attr "type" "multi")
10250    (set_attr "mode" "SI")])
10252 (define_insn_and_split "udivmodsi4_zext_2"
10253   [(set (match_operand:DI 1 "register_operand" "=&d")
10254         (zero_extend:DI
10255           (umod:SI (match_operand:SI 2 "register_operand" "0")
10256                  (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10257    (set (match_operand:SI 0 "register_operand" "=a")
10258         (udiv:SI (match_dup 2) (match_dup 3)))
10259    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10260    (clobber (reg:CC FLAGS_REG))]
10261   "TARGET_64BIT"
10262   "#"
10263   "&& reload_completed"
10264   [(set (match_dup 4) (const_int 0))
10265    (parallel [(set (match_dup 1)
10266                    (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10267               (set (match_dup 0)
10268                    (udiv:SI (match_dup 2) (match_dup 3)))
10269               (use (match_dup 4))
10270               (clobber (reg:CC FLAGS_REG))])]
10271   "operands[4] = gen_lowpart (SImode, operands[1]);"
10272   [(set_attr "type" "multi")
10273    (set_attr "mode" "SI")])
10275 (define_insn_and_split "*divmod<mode>4"
10276   [(set (match_operand:SWIM248 0 "register_operand" "=a")
10277         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10278                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10279    (set (match_operand:SWIM248 1 "register_operand" "=&d")
10280         (mod:SWIM248 (match_dup 2) (match_dup 3)))
10281    (clobber (reg:CC FLAGS_REG))]
10282   ""
10283   "#"
10284   "reload_completed"
10285   [(parallel [(set (match_dup 1)
10286                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
10287               (clobber (reg:CC FLAGS_REG))])
10288    (parallel [(set (match_dup 0)
10289                    (div:SWIM248 (match_dup 2) (match_dup 3)))
10290               (set (match_dup 1)
10291                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
10292               (use (match_dup 1))
10293               (clobber (reg:CC FLAGS_REG))])]
10295   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10297   if (<MODE>mode != HImode
10298       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
10299     operands[4] = operands[2];
10300   else
10301     {
10302       /* Avoid use of cltd in favor of a mov+shift.  */
10303       emit_move_insn (operands[1], operands[2]);
10304       operands[4] = operands[1];
10305     }
10307   [(set_attr "type" "multi")
10308    (set_attr "mode" "<MODE>")])
10310 (define_insn_and_split "*udivmod<mode>4"
10311   [(set (match_operand:SWIM248 0 "register_operand" "=a")
10312         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10313                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10314    (set (match_operand:SWIM248 1 "register_operand" "=&d")
10315         (umod:SWIM248 (match_dup 2) (match_dup 3)))
10316    (clobber (reg:CC FLAGS_REG))]
10317   ""
10318   "#"
10319   "reload_completed"
10320   [(set (match_dup 1) (const_int 0))
10321    (parallel [(set (match_dup 0)
10322                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
10323               (set (match_dup 1)
10324                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
10325               (use (match_dup 1))
10326               (clobber (reg:CC FLAGS_REG))])]
10327   ""
10328   [(set_attr "type" "multi")
10329    (set_attr "mode" "<MODE>")])
10331 ;; Optimize division or modulo by constant power of 2, if the constant
10332 ;; materializes only after expansion.
10333 (define_insn_and_split "*udivmod<mode>4_pow2"
10334   [(set (match_operand:SWI48 0 "register_operand" "=r")
10335         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10336                     (match_operand:SWI48 3 "const_int_operand")))
10337    (set (match_operand:SWI48 1 "register_operand" "=r")
10338         (umod:SWI48 (match_dup 2) (match_dup 3)))
10339    (clobber (reg:CC FLAGS_REG))]
10340   "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10341   "#"
10342   "&& reload_completed"
10343   [(set (match_dup 1) (match_dup 2))
10344    (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
10345               (clobber (reg:CC FLAGS_REG))])
10346    (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
10347               (clobber (reg:CC FLAGS_REG))])]
10349   int v = exact_log2 (UINTVAL (operands[3]));
10350   operands[4] = GEN_INT (v);
10351   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10353   [(set_attr "type" "multi")
10354    (set_attr "mode" "<MODE>")])
10356 (define_insn_and_split "*divmodsi4_zext_1"
10357   [(set (match_operand:DI 0 "register_operand" "=a")
10358         (zero_extend:DI
10359           (div:SI (match_operand:SI 2 "register_operand" "0")
10360                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10361    (set (match_operand:SI 1 "register_operand" "=&d")
10362         (mod:SI (match_dup 2) (match_dup 3)))
10363    (clobber (reg:CC FLAGS_REG))]
10364   "TARGET_64BIT"
10365   "#"
10366   "&& reload_completed"
10367   [(parallel [(set (match_dup 1)
10368                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
10369               (clobber (reg:CC FLAGS_REG))])
10370    (parallel [(set (match_dup 0)
10371                    (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10372               (set (match_dup 1)
10373                    (mod:SI (match_dup 2) (match_dup 3)))
10374               (use (match_dup 1))
10375               (clobber (reg:CC FLAGS_REG))])]
10377   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10379   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10380     operands[4] = operands[2];
10381   else
10382     {
10383       /* Avoid use of cltd in favor of a mov+shift.  */
10384       emit_move_insn (operands[1], operands[2]);
10385       operands[4] = operands[1];
10386     }
10388   [(set_attr "type" "multi")
10389    (set_attr "mode" "SI")])
10391 (define_insn_and_split "*udivmodsi4_zext_1"
10392   [(set (match_operand:DI 0 "register_operand" "=a")
10393         (zero_extend:DI
10394           (udiv:SI (match_operand:SI 2 "register_operand" "0")
10395                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10396    (set (match_operand:SI 1 "register_operand" "=&d")
10397         (umod:SI (match_dup 2) (match_dup 3)))
10398    (clobber (reg:CC FLAGS_REG))]
10399   "TARGET_64BIT"
10400   "#"
10401   "&& reload_completed"
10402   [(set (match_dup 1) (const_int 0))
10403    (parallel [(set (match_dup 0)
10404                    (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10405               (set (match_dup 1)
10406                    (umod:SI (match_dup 2) (match_dup 3)))
10407               (use (match_dup 1))
10408               (clobber (reg:CC FLAGS_REG))])]
10409   ""
10410   [(set_attr "type" "multi")
10411    (set_attr "mode" "SI")])
10413 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
10414   [(set (match_operand:DI 0 "register_operand" "=r")
10415         (zero_extend:DI
10416           (udiv:SI (match_operand:SI 2 "register_operand" "0")
10417                    (match_operand:SI 3 "const_int_operand"))))
10418    (set (match_operand:SI 1 "register_operand" "=r")
10419         (umod:SI (match_dup 2) (match_dup 3)))
10420    (clobber (reg:CC FLAGS_REG))]
10421   "TARGET_64BIT
10422    && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10423   "#"
10424   "&& reload_completed"
10425   [(set (match_dup 1) (match_dup 2))
10426    (parallel [(set (match_dup 0)
10427                    (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
10428               (clobber (reg:CC FLAGS_REG))])
10429    (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
10430               (clobber (reg:CC FLAGS_REG))])]
10432   int v = exact_log2 (UINTVAL (operands[3]));
10433   operands[4] = GEN_INT (v);
10434   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10436   [(set_attr "type" "multi")
10437    (set_attr "mode" "SI")])
10439 (define_insn_and_split "*divmodsi4_zext_2"
10440   [(set (match_operand:DI 1 "register_operand" "=&d")
10441         (zero_extend:DI
10442           (mod:SI (match_operand:SI 2 "register_operand" "0")
10443                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10444    (set (match_operand:SI 0 "register_operand" "=a")
10445         (div:SI (match_dup 2) (match_dup 3)))
10446    (clobber (reg:CC FLAGS_REG))]
10447   "TARGET_64BIT"
10448   "#"
10449   "&& reload_completed"
10450   [(parallel [(set (match_dup 6)
10451                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
10452               (clobber (reg:CC FLAGS_REG))])
10453    (parallel [(set (match_dup 1)
10454                    (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10455               (set (match_dup 0)
10456                    (div:SI (match_dup 2) (match_dup 3)))
10457               (use (match_dup 6))
10458               (clobber (reg:CC FLAGS_REG))])]
10460   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10461   operands[6] = gen_lowpart (SImode, operands[1]);
10463   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10464     operands[4] = operands[2];
10465   else
10466     {
10467       /* Avoid use of cltd in favor of a mov+shift.  */
10468       emit_move_insn (operands[6], operands[2]);
10469       operands[4] = operands[6];
10470     }
10472   [(set_attr "type" "multi")
10473    (set_attr "mode" "SI")])
10475 (define_insn_and_split "*udivmodsi4_zext_2"
10476   [(set (match_operand:DI 1 "register_operand" "=&d")
10477         (zero_extend:DI
10478           (umod:SI (match_operand:SI 2 "register_operand" "0")
10479                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10480    (set (match_operand:SI 0 "register_operand" "=a")
10481         (udiv:SI (match_dup 2) (match_dup 3)))
10482    (clobber (reg:CC FLAGS_REG))]
10483   "TARGET_64BIT"
10484   "#"
10485   "&& reload_completed"
10486   [(set (match_dup 4) (const_int 0))
10487    (parallel [(set (match_dup 1)
10488                    (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10489               (set (match_dup 0)
10490                    (udiv:SI (match_dup 2) (match_dup 3)))
10491               (use (match_dup 4))
10492               (clobber (reg:CC FLAGS_REG))])]
10493   "operands[4] = gen_lowpart (SImode, operands[1]);"
10494   [(set_attr "type" "multi")
10495    (set_attr "mode" "SI")])
10497 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
10498   [(set (match_operand:DI 1 "register_operand" "=r")
10499         (zero_extend:DI
10500           (umod:SI (match_operand:SI 2 "register_operand" "0")
10501                    (match_operand:SI 3 "const_int_operand"))))
10502    (set (match_operand:SI 0 "register_operand" "=r")
10503         (udiv:SI (match_dup 2) (match_dup 3)))
10504    (clobber (reg:CC FLAGS_REG))]
10505   "TARGET_64BIT
10506    && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10507   "#"
10508   "&& reload_completed"
10509   [(set (match_dup 1) (match_dup 2))
10510    (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
10511               (clobber (reg:CC FLAGS_REG))])
10512    (parallel [(set (match_dup 1)
10513                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
10514               (clobber (reg:CC FLAGS_REG))])]
10516   int v = exact_log2 (UINTVAL (operands[3]));
10517   operands[4] = GEN_INT (v);
10518   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10520   [(set_attr "type" "multi")
10521    (set_attr "mode" "SI")])
10523 (define_insn "*<u>divmod<mode>4_noext"
10524   [(set (match_operand:SWIM248 0 "register_operand" "=a")
10525         (any_div:SWIM248
10526           (match_operand:SWIM248 2 "register_operand" "0")
10527           (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10528    (set (match_operand:SWIM248 1 "register_operand" "=d")
10529         (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
10530    (use (match_operand:SWIM248 4 "register_operand" "1"))
10531    (clobber (reg:CC FLAGS_REG))]
10532   ""
10533   "<sgnprefix>div{<imodesuffix>}\t%3"
10534   [(set_attr "type" "idiv")
10535    (set_attr "mode" "<MODE>")])
10537 (define_insn "*<u>divmodsi4_noext_zext_1"
10538   [(set (match_operand:DI 0 "register_operand" "=a")
10539         (zero_extend:DI
10540           (any_div:SI (match_operand:SI 2 "register_operand" "0")
10541                       (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10542    (set (match_operand:SI 1 "register_operand" "=d")
10543         (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10544    (use (match_operand:SI 4 "register_operand" "1"))
10545    (clobber (reg:CC FLAGS_REG))]
10546   "TARGET_64BIT"
10547   "<sgnprefix>div{l}\t%3"
10548   [(set_attr "type" "idiv")
10549    (set_attr "mode" "SI")])
10551 (define_insn "*<u>divmodsi4_noext_zext_2"
10552   [(set (match_operand:DI 1 "register_operand" "=d")
10553         (zero_extend:DI
10554           (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
10555                            (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10556    (set (match_operand:SI 0 "register_operand" "=a")
10557         (any_div:SI (match_dup 2) (match_dup 3)))
10558    (use (match_operand:SI 4 "register_operand" "1"))
10559    (clobber (reg:CC FLAGS_REG))]
10560   "TARGET_64BIT"
10561   "<sgnprefix>div{l}\t%3"
10562   [(set_attr "type" "idiv")
10563    (set_attr "mode" "SI")])
10565 ;; Avoid sign-extension (using cdq) for constant numerators.
10566 (define_insn_and_split "*divmodsi4_const"
10567   [(set (match_operand:SI 0 "register_operand" "=&a")
10568         (div:SI (match_operand:SI 2 "const_int_operand")
10569                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
10570    (set (match_operand:SI 1 "register_operand" "=&d")
10571         (mod:SI (match_dup 2) (match_dup 3)))
10572    (clobber (reg:CC FLAGS_REG))]
10573   "!optimize_function_for_size_p (cfun)"
10574   "#"
10575   "&& reload_completed"
10576   [(set (match_dup 0) (match_dup 2))
10577    (set (match_dup 1) (match_dup 4))
10578    (parallel [(set (match_dup 0)
10579                    (div:SI (match_dup 0) (match_dup 3)))
10580               (set (match_dup 1)
10581                    (mod:SI (match_dup 0) (match_dup 3)))
10582               (use (match_dup 1))
10583               (clobber (reg:CC FLAGS_REG))])]
10585   operands[4] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
10587   [(set_attr "type" "multi")
10588    (set_attr "mode" "SI")])
10590 (define_expand "divmodqi4"
10591   [(parallel [(set (match_operand:QI 0 "register_operand")
10592                    (div:QI
10593                      (match_operand:QI 1 "register_operand")
10594                      (match_operand:QI 2 "nonimmediate_operand")))
10595               (set (match_operand:QI 3 "register_operand")
10596                    (mod:QI (match_dup 1) (match_dup 2)))
10597               (clobber (reg:CC FLAGS_REG))])]
10598   "TARGET_QIMODE_MATH"
10600   rtx div, mod;
10601   rtx tmp0, tmp1;
10603   tmp0 = gen_reg_rtx (HImode);
10604   tmp1 = gen_reg_rtx (HImode);
10606   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
10607   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
10608   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
10610   /* Extract remainder from AH.  */
10611   tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10612   tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10613   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10615   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
10616   set_unique_reg_note (insn, REG_EQUAL, mod);
10618   /* Extract quotient from AL.  */
10619   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10621   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
10622   set_unique_reg_note (insn, REG_EQUAL, div);
10624   DONE;
10627 (define_expand "udivmodqi4"
10628   [(parallel [(set (match_operand:QI 0 "register_operand")
10629                    (udiv:QI
10630                      (match_operand:QI 1 "register_operand")
10631                      (match_operand:QI 2 "nonimmediate_operand")))
10632               (set (match_operand:QI 3 "register_operand")
10633                    (umod:QI (match_dup 1) (match_dup 2)))
10634               (clobber (reg:CC FLAGS_REG))])]
10635   "TARGET_QIMODE_MATH"
10637   rtx div, mod;
10638   rtx tmp0, tmp1;
10640   tmp0 = gen_reg_rtx (HImode);
10641   tmp1 = gen_reg_rtx (HImode);
10643   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
10644   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
10645   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
10647   /* Extract remainder from AH.  */
10648   tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10649   tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10650   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10652   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
10653   set_unique_reg_note (insn, REG_EQUAL, mod);
10655   /* Extract quotient from AL.  */
10656   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10658   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
10659   set_unique_reg_note (insn, REG_EQUAL, div);
10661   DONE;
10664 ;; Divide AX by r/m8, with result stored in
10665 ;; AL <- Quotient
10666 ;; AH <- Remainder
10667 ;; Change div/mod to HImode and extend the second argument to HImode
10668 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
10669 ;; combine may fail.
10670 (define_insn "<u>divmodhiqi3"
10671   [(set (match_operand:HI 0 "register_operand" "=a")
10672         (ior:HI
10673           (ashift:HI
10674             (zero_extend:HI
10675               (truncate:QI
10676                 (mod:HI (match_operand:HI 1 "register_operand" "0")
10677                         (any_extend:HI
10678                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
10679             (const_int 8))
10680           (zero_extend:HI
10681             (truncate:QI
10682               (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
10683    (clobber (reg:CC FLAGS_REG))]
10684   "TARGET_QIMODE_MATH"
10685   "<sgnprefix>div{b}\t%2"
10686   [(set_attr "type" "idiv")
10687    (set_attr "mode" "QI")])
10689 ;; We cannot use div/idiv for double division, because it causes
10690 ;; "division by zero" on the overflow and that's not what we expect
10691 ;; from truncate.  Because true (non truncating) double division is
10692 ;; never generated, we can't create this insn anyway.
10694 ;(define_insn ""
10695 ;  [(set (match_operand:SI 0 "register_operand" "=a")
10696 ;       (truncate:SI
10697 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
10698 ;                  (zero_extend:DI
10699 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
10700 ;   (set (match_operand:SI 3 "register_operand" "=d")
10701 ;       (truncate:SI
10702 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
10703 ;   (clobber (reg:CC FLAGS_REG))]
10704 ;  ""
10705 ;  "div{l}\t{%2, %0|%0, %2}"
10706 ;  [(set_attr "type" "idiv")])
10708 ;;- Logical AND instructions
10710 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
10711 ;; Note that this excludes ah.
10713 (define_expand "@test<mode>_ccno_1"
10714   [(set (reg:CCNO FLAGS_REG)
10715         (compare:CCNO
10716           (and:SWI48
10717             (match_operand:SWI48 0 "nonimmediate_operand")
10718             (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
10719           (const_int 0)))])
10721 (define_expand "testqi_ccz_1"
10722   [(set (reg:CCZ FLAGS_REG)
10723         (compare:CCZ
10724           (and:QI
10725             (match_operand:QI 0 "nonimmediate_operand")
10726             (match_operand:QI 1 "nonmemory_operand"))
10727           (const_int 0)))])
10729 (define_insn "*testdi_1"
10730   [(set (reg FLAGS_REG)
10731         (compare
10732           (and:DI
10733             (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
10734             (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
10735          (const_int 0)))]
10736   "TARGET_64BIT
10737    && ix86_match_ccmode
10738         (insn,
10739          /* If we are going to emit testl instead of testq, and the operands[1]
10740             constant might have the SImode sign bit set, make sure the sign
10741             flag isn't tested, because the instruction will set the sign flag
10742             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
10743             conservatively assume it might have bit 31 set.  */
10744          (satisfies_constraint_Z (operands[1])
10745           && (!CONST_INT_P (operands[1])
10746               || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
10747          ? CCZmode : CCNOmode)"
10748   "@
10749    test{l}\t{%k1, %k0|%k0, %k1}
10750    test{q}\t{%1, %0|%0, %1}"
10751   [(set_attr "type" "test")
10752    (set_attr "mode" "SI,DI")])
10754 (define_insn "*testqi_1_maybe_si"
10755   [(set (reg FLAGS_REG)
10756         (compare
10757           (and:QI
10758             (match_operand:QI 0 "nonimmediate_operand" "%qm,qm,r")
10759             (match_operand:QI 1 "nonmemory_operand" "q,n,n"))
10760           (const_int 0)))]
10761   "ix86_match_ccmode (insn,
10762                       CONST_INT_P (operands[1])
10763                       && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
10765   if (get_attr_mode (insn) == MODE_SI)
10766     {
10767       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
10768         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
10769       return "test{l}\t{%1, %k0|%k0, %1}";
10770     }
10771   return "test{b}\t{%1, %0|%0, %1}";
10773   [(set_attr "type" "test")
10774    (set (attr "mode")
10775      (cond [(eq_attr "alternative" "2")
10776               (const_string "SI")
10777             (and (match_test "optimize_insn_for_size_p ()")
10778                  (and (match_operand 0 "ext_QIreg_operand")
10779                       (match_operand 1 "const_0_to_127_operand")))
10780               (const_string "SI")
10781            ]
10782            (const_string "QI")))
10783    (set_attr "pent_pair" "uv,np,np")])
10785 (define_insn "*test<mode>_1"
10786   [(set (reg FLAGS_REG)
10787         (compare
10788           (and:SWI124
10789             (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
10790             (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
10791          (const_int 0)))]
10792   "ix86_match_ccmode (insn, CCNOmode)"
10793   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
10794   [(set_attr "type" "test")
10795    (set_attr "mode" "<MODE>")
10796    (set_attr "pent_pair" "uv,uv,np")])
10798 (define_expand "testqi_ext_1_ccno"
10799   [(set (reg:CCNO FLAGS_REG)
10800         (compare:CCNO
10801           (and:QI
10802             (subreg:QI
10803               (zero_extract:HI
10804                 (match_operand:HI 0 "register_operand")
10805                 (const_int 8)
10806                 (const_int 8)) 0)
10807               (match_operand:QI 1 "const_int_operand"))
10808           (const_int 0)))])
10810 (define_insn "*testqi_ext<mode>_1"
10811   [(set (reg FLAGS_REG)
10812         (compare
10813           (and:QI
10814             (subreg:QI
10815               (match_operator:SWI248 2 "extract_operator"
10816                 [(match_operand 0 "int248_register_operand" "Q")
10817                  (const_int 8)
10818                  (const_int 8)]) 0)
10819             (match_operand:QI 1 "general_operand" "QnBn"))
10820           (const_int 0)))]
10821   "ix86_match_ccmode (insn, CCNOmode)"
10822   "test{b}\t{%1, %h0|%h0, %1}"
10823   [(set_attr "addr" "gpr8")
10824    (set_attr "type" "test")
10825    (set_attr "mode" "QI")])
10827 (define_insn "*testqi_ext<mode>_2"
10828   [(set (reg FLAGS_REG)
10829         (compare
10830           (and:QI
10831             (subreg:QI
10832               (match_operator:SWI248 2 "extract_operator"
10833                 [(match_operand 0 "int248_register_operand" "Q")
10834                  (const_int 8)
10835                  (const_int 8)]) 0)
10836             (subreg:QI
10837               (match_operator:SWI248 3 "extract_operator"
10838                 [(match_operand 1 "int248_register_operand" "Q")
10839                  (const_int 8)
10840                  (const_int 8)]) 0))
10841           (const_int 0)))]
10842   "ix86_match_ccmode (insn, CCNOmode)"
10843   "test{b}\t{%h1, %h0|%h0, %h1}"
10844   [(set_attr "type" "test")
10845    (set_attr "mode" "QI")])
10847 ;; Provide a *testti instruction that STV can implement using ptest.
10848 ;; This pattern splits into *andti3_doubleword and *cmpti_doubleword.
10849 (define_insn_and_split "*testti_doubleword"
10850   [(set (reg:CCZ FLAGS_REG)
10851         (compare:CCZ
10852           (and:TI (match_operand:TI 0 "register_operand")
10853                   (match_operand:TI 1 "general_operand"))
10854           (const_int 0)))]
10855   "TARGET_64BIT
10856    && ix86_pre_reload_split ()"
10857   "#"
10858   "&& 1"
10859   [(parallel [(set (match_dup 2) (and:TI (match_dup 0) (match_dup 1)))
10860               (clobber (reg:CC FLAGS_REG))])
10861    (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
10863   operands[2] = gen_reg_rtx (TImode);
10864   if (!x86_64_hilo_general_operand (operands[1], TImode))
10865     operands[1] = force_reg (TImode, operands[1]);
10868 ;; Combine likes to form bit extractions for some tests.  Humor it.
10869 (define_insn_and_split "*testqi_ext_3"
10870   [(set (match_operand 0 "flags_reg_operand")
10871         (match_operator 1 "compare_operator"
10872           [(zero_extract:SWI248
10873              (match_operand 2 "int_nonimmediate_operand" "rm")
10874              (match_operand:QI 3 "const_int_operand")
10875              (match_operand:QI 4 "const_int_operand"))
10876            (const_int 0)]))]
10877   "/* Ensure that resulting mask is zero or sign extended operand.  */
10878    INTVAL (operands[4]) >= 0
10879    && ((INTVAL (operands[3]) > 0
10880         && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
10881        || (<MODE>mode == DImode
10882            && INTVAL (operands[3]) > 32
10883            && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
10884    && ix86_match_ccmode (insn,
10885                          /* If zero_extract mode precision is the same
10886                             as len, the SF of the zero_extract
10887                             comparison will be the most significant
10888                             extracted bit, but this could be matched
10889                             after splitting only for pos 0 len all bits
10890                             trivial extractions.  Require CCZmode.  */
10891                          (GET_MODE_PRECISION (<MODE>mode)
10892                           == INTVAL (operands[3]))
10893                          /* Otherwise, require CCZmode if we'd use a mask
10894                             with the most significant bit set and can't
10895                             widen it to wider mode.  *testdi_1 also
10896                             requires CCZmode if the mask has bit
10897                             31 set and all bits above it clear.  */
10898                          || (INTVAL (operands[3]) + INTVAL (operands[4])
10899                              >= 32)
10900                          /* We can't widen also if val is not a REG.  */
10901                          || (INTVAL (operands[3]) + INTVAL (operands[4])
10902                              == GET_MODE_PRECISION (GET_MODE (operands[2]))
10903                              && !register_operand (operands[2],
10904                                                    GET_MODE (operands[2])))
10905                          /* And we shouldn't widen if
10906                             TARGET_PARTIAL_REG_STALL.  */
10907                          || (TARGET_PARTIAL_REG_STALL
10908                              && (INTVAL (operands[3]) + INTVAL (operands[4])
10909                                  >= (paradoxical_subreg_p (operands[2])
10910                                      && (GET_MODE_CLASS
10911                                           (GET_MODE (SUBREG_REG (operands[2])))
10912                                          == MODE_INT)
10913                                      ? GET_MODE_PRECISION
10914                                          (GET_MODE (SUBREG_REG (operands[2])))
10915                                      : GET_MODE_PRECISION
10916                                          (GET_MODE (operands[2])))))
10917                          ? CCZmode : CCNOmode)"
10918   "#"
10919   "&& 1"
10920   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
10922   rtx val = operands[2];
10923   HOST_WIDE_INT len = INTVAL (operands[3]);
10924   HOST_WIDE_INT pos = INTVAL (operands[4]);
10925   machine_mode mode = GET_MODE (val);
10927   if (SUBREG_P (val))
10928     {
10929       machine_mode submode = GET_MODE (SUBREG_REG (val));
10931       /* Narrow paradoxical subregs to prevent partial register stalls.  */
10932       if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
10933           && GET_MODE_CLASS (submode) == MODE_INT
10934           && (GET_MODE (operands[0]) == CCZmode
10935               || pos + len < GET_MODE_PRECISION (submode)
10936               || REG_P (SUBREG_REG (val))))
10937         {
10938           val = SUBREG_REG (val);
10939           mode = submode;
10940         }
10941     }
10943   /* Small HImode tests can be converted to QImode.  */
10944   if (pos + len <= 8
10945       && register_operand (val, HImode))
10946     {
10947       rtx nval = gen_lowpart (QImode, val);
10948       if (!MEM_P (nval)
10949           || GET_MODE (operands[0]) == CCZmode
10950           || pos + len < 8)
10951         {
10952           val = nval;
10953           mode = QImode;
10954         }
10955     }
10957   gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
10959   /* If the mask is going to have the sign bit set in the mode
10960      we want to do the comparison in and user isn't interested just
10961      in the zero flag, then we must widen the target mode.  */
10962   if (pos + len == GET_MODE_PRECISION (mode)
10963       && GET_MODE (operands[0]) != CCZmode)
10964     {
10965       gcc_assert (pos + len < 32 && !MEM_P (val));
10966       mode = SImode;
10967       val = gen_lowpart (mode, val);
10968     }
10970   wide_int mask
10971     = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
10973   operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
10976 ;; Split and;cmp (as optimized by combine) into not;test
10977 ;; Except when TARGET_BMI provides andn (*andn_<mode>_ccno).
10978 (define_insn_and_split "*test<mode>_not"
10979   [(set (reg:CCZ FLAGS_REG)
10980         (compare:CCZ
10981           (and:SWI
10982             (not:SWI (match_operand:SWI 0 "register_operand"))
10983             (match_operand:SWI 1 "<nonmemory_szext_operand>"))
10984           (const_int 0)))]
10985   "ix86_pre_reload_split ()
10986    && (!TARGET_BMI || !REG_P (operands[1]))"
10987   "#"
10988   "&& 1"
10989   [(set (match_dup 2) (not:SWI (match_dup 0)))
10990    (set (reg:CCZ FLAGS_REG)
10991         (compare:CCZ (and:SWI (match_dup 2) (match_dup 1))
10992                      (const_int 0)))]
10993   "operands[2] = gen_reg_rtx (<MODE>mode);")
10995 ;; Split and;cmp (as optimized by combine) into andn;cmp $0
10996 (define_insn_and_split "*test<mode>_not_doubleword"
10997   [(set (reg:CCZ FLAGS_REG)
10998         (compare:CCZ
10999           (and:DWI
11000             (not:DWI (match_operand:DWI 0 "nonimmediate_operand"))
11001             (match_operand:DWI 1 "nonimmediate_operand"))
11002           (const_int 0)))]
11003   "ix86_pre_reload_split ()"
11004   "#"
11005   "&& 1"
11006   [(parallel
11007       [(set (match_dup 2) (and:DWI (not:DWI (match_dup 0)) (match_dup 1)))
11008        (clobber (reg:CC FLAGS_REG))])
11009    (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
11011   operands[0] = force_reg (<MODE>mode, operands[0]);
11012   operands[2] = gen_reg_rtx (<MODE>mode);
11015 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
11016 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
11017 ;; this is relatively important trick.
11018 ;; Do the conversion only post-reload to avoid limiting of the register class
11019 ;; to QI regs.
11020 (define_split
11021   [(set (match_operand 0 "flags_reg_operand")
11022         (match_operator 1 "compare_operator"
11023           [(and (match_operand 2 "QIreg_operand")
11024                 (match_operand 3 "const_int_operand"))
11025            (const_int 0)]))]
11026    "reload_completed
11027     && GET_MODE (operands[2]) != QImode
11028     && ((ix86_match_ccmode (insn, CCZmode)
11029          && !(INTVAL (operands[3]) & ~(255 << 8)))
11030         || (ix86_match_ccmode (insn, CCNOmode)
11031             && !(INTVAL (operands[3]) & ~(127 << 8))))"
11032   [(set (match_dup 0)
11033         (match_op_dup 1
11034           [(and:QI
11035              (subreg:QI
11036                (zero_extract:HI (match_dup 2)
11037                                 (const_int 8)
11038                                 (const_int 8)) 0)
11039              (match_dup 3))
11040            (const_int 0)]))]
11042   operands[2] = gen_lowpart (HImode, operands[2]);
11043   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
11046 (define_split
11047   [(set (match_operand 0 "flags_reg_operand")
11048         (match_operator 1 "compare_operator"
11049           [(and (match_operand 2 "nonimmediate_operand")
11050                 (match_operand 3 "const_int_operand"))
11051            (const_int 0)]))]
11052    "reload_completed
11053     && GET_MODE (operands[2]) != QImode
11054     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
11055     && ((ix86_match_ccmode (insn, CCZmode)
11056          && !(INTVAL (operands[3]) & ~255))
11057         || (ix86_match_ccmode (insn, CCNOmode)
11058             && !(INTVAL (operands[3]) & ~127)))"
11059   [(set (match_dup 0)
11060         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
11061                          (const_int 0)]))]
11063   operands[2] = gen_lowpart (QImode, operands[2]);
11064   operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
11067 ;; Narrow test instructions with immediate operands that test
11068 ;; memory locations for zero.  E.g. testl $0x00aa0000, mem can be
11069 ;; converted to testb $0xaa, mem+2.  Reject volatile locations and
11070 ;; targets where reading (possibly unaligned) part of memory
11071 ;; location after a large write to the same address causes
11072 ;; store-to-load forwarding stall.
11073 (define_peephole2
11074   [(set (reg:CCZ FLAGS_REG)
11075         (compare:CCZ
11076           (and:SWI248 (match_operand:SWI248 0 "memory_operand")
11077                       (match_operand 1 "const_int_operand"))
11078           (const_int 0)))]
11079   "!TARGET_PARTIAL_MEMORY_READ_STALL && !MEM_VOLATILE_P (operands[0])"
11080   [(set (reg:CCZ FLAGS_REG)
11081         (compare:CCZ (match_dup 2) (const_int 0)))]
11083   unsigned HOST_WIDE_INT ival = UINTVAL (operands[1]);
11084   int first_nonzero_byte, bitsize;
11085   rtx new_addr, new_const;
11086   machine_mode new_mode;
11088   if (ival == 0)
11089     FAIL;
11091   /* Clear bits outside mode width.  */
11092   ival &= GET_MODE_MASK (<MODE>mode);
11094   first_nonzero_byte = ctz_hwi (ival) / BITS_PER_UNIT;
11096   ival >>= first_nonzero_byte * BITS_PER_UNIT;
11098   bitsize = sizeof (ival) * BITS_PER_UNIT - clz_hwi (ival);
11100   if (bitsize <= GET_MODE_BITSIZE (QImode))
11101     new_mode = QImode;
11102   else if (bitsize <= GET_MODE_BITSIZE (HImode))
11103     new_mode = HImode;
11104   else if (bitsize <= GET_MODE_BITSIZE (SImode))
11105     new_mode = SImode;
11106   else
11107     new_mode = DImode;
11109   if (GET_MODE_SIZE (new_mode) >= GET_MODE_SIZE (<MODE>mode))
11110     FAIL;
11112   new_addr = adjust_address (operands[0], new_mode, first_nonzero_byte);
11113   new_const = gen_int_mode (ival, new_mode);
11115   operands[2] = gen_rtx_AND (new_mode, new_addr, new_const);
11118 ;; %%% This used to optimize known byte-wide and operations to memory,
11119 ;; and sometimes to QImode registers.  If this is considered useful,
11120 ;; it should be done with splitters.
11122 (define_expand "and<mode>3"
11123   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
11124         (and:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
11125                    (match_operand:SDWIM 2 "<general_szext_operand>")))]
11126   ""
11128   machine_mode mode = <MODE>mode;
11130   if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
11131       && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
11132     operands[2] = force_reg (<MODE>mode, operands[2]);
11134   if (GET_MODE_SIZE (<MODE>mode) <= UNITS_PER_WORD
11135       && const_int_operand (operands[2], <MODE>mode)
11136       && register_operand (operands[0], <MODE>mode)
11137       && !(TARGET_ZERO_EXTEND_WITH_AND
11138            && optimize_function_for_speed_p (cfun)))
11139     {
11140       unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11142       if (ival == GET_MODE_MASK (SImode))
11143         mode = SImode;
11144       else if (ival == GET_MODE_MASK (HImode))
11145         mode = HImode;
11146       else if (ival == GET_MODE_MASK (QImode))
11147         mode = QImode;
11148     }
11150   if (mode != <MODE>mode)
11151     emit_insn (gen_extend_insn
11152                (operands[0], gen_lowpart (mode, operands[1]),
11153                 <MODE>mode, mode, 1));
11154   else
11155     ix86_expand_binary_operator (AND, <MODE>mode, operands);
11157   DONE;
11160 (define_insn_and_split "*and<dwi>3_doubleword"
11161   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
11162         (and:<DWI>
11163          (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
11164          (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
11165    (clobber (reg:CC FLAGS_REG))]
11166   "ix86_binary_operator_ok (AND, <DWI>mode, operands)"
11167   "#"
11168   "&& reload_completed"
11169   [(const_int:DWIH 0)]
11171   bool emit_insn_deleted_note_p = false;
11173   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
11175   if (operands[2] == const0_rtx)
11176     emit_move_insn (operands[0], const0_rtx);
11177   else if (operands[2] == constm1_rtx)
11178     emit_insn_deleted_note_p = true;
11179   else
11180     ix86_expand_binary_operator (AND, <MODE>mode, &operands[0]);
11182   if (operands[5] == const0_rtx)
11183     emit_move_insn (operands[3], const0_rtx);
11184   else if (operands[5] == constm1_rtx)
11185     {
11186       if (emit_insn_deleted_note_p)
11187         emit_note (NOTE_INSN_DELETED);
11188     }
11189   else
11190     ix86_expand_binary_operator (AND, <MODE>mode, &operands[3]);
11192   DONE;
11195 (define_insn "*anddi_1"
11196   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,?k")
11197         (and:DI
11198          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
11199          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L,k")))
11200    (clobber (reg:CC FLAGS_REG))]
11201   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
11202   "@
11203    and{l}\t{%k2, %k0|%k0, %k2}
11204    and{q}\t{%2, %0|%0, %2}
11205    and{q}\t{%2, %0|%0, %2}
11206    #
11207    #"
11208   [(set_attr "isa" "x64,x64,x64,x64,avx512bw_512")
11209    (set_attr "type" "alu,alu,alu,imovx,msklog")
11210    (set_attr "length_immediate" "*,*,*,0,*")
11211    (set (attr "prefix_rex")
11212      (if_then_else
11213        (and (eq_attr "type" "imovx")
11214             (and (match_test "INTVAL (operands[2]) == 0xff")
11215                  (match_operand 1 "ext_QIreg_operand")))
11216        (const_string "1")
11217        (const_string "*")))
11218    (set_attr "mode" "SI,DI,DI,SI,DI")])
11220 (define_insn_and_split "*anddi_1_btr"
11221   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11222         (and:DI
11223          (match_operand:DI 1 "nonimmediate_operand" "%0")
11224          (match_operand:DI 2 "const_int_operand" "n")))
11225    (clobber (reg:CC FLAGS_REG))]
11226   "TARGET_64BIT && TARGET_USE_BT
11227    && ix86_binary_operator_ok (AND, DImode, operands)
11228    && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
11229   "#"
11230   "&& reload_completed"
11231   [(parallel [(set (zero_extract:DI (match_dup 0)
11232                                     (const_int 1)
11233                                     (match_dup 3))
11234                    (const_int 0))
11235               (clobber (reg:CC FLAGS_REG))])]
11236   "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
11237   [(set_attr "type" "alu1")
11238    (set_attr "prefix_0f" "1")
11239    (set_attr "znver1_decode" "double")
11240    (set_attr "mode" "DI")])
11242 ;; Turn *anddi_1 into *andsi_1_zext if possible.
11243 (define_split
11244   [(set (match_operand:DI 0 "register_operand")
11245         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
11246                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
11247    (clobber (reg:CC FLAGS_REG))]
11248   "TARGET_64BIT"
11249   [(parallel [(set (match_dup 0)
11250                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
11251               (clobber (reg:CC FLAGS_REG))])]
11253   if (GET_CODE (operands[2]) == SYMBOL_REF
11254       || GET_CODE (operands[2]) == LABEL_REF)
11255     {
11256       operands[2] = shallow_copy_rtx (operands[2]);
11257       PUT_MODE (operands[2], SImode);
11258     }
11259   else if (GET_CODE (operands[2]) == CONST)
11260     {
11261       /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
11262       operands[2] = copy_rtx (operands[2]);
11263       PUT_MODE (operands[2], SImode);
11264       PUT_MODE (XEXP (operands[2], 0), SImode);
11265       PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
11266     }    
11267   else
11268     operands[2] = gen_lowpart (SImode, operands[2]);
11271 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11272 (define_insn "*andsi_1_zext"
11273   [(set (match_operand:DI 0 "register_operand" "=r")
11274         (zero_extend:DI
11275           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
11276                   (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
11277    (clobber (reg:CC FLAGS_REG))]
11278   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
11279   "and{l}\t{%2, %k0|%k0, %2}"
11280   [(set_attr "type" "alu")
11281    (set_attr "mode" "SI")])
11283 (define_insn "*and<mode>_1"
11284   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya,?k")
11285         (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm,k")
11286                    (match_operand:SWI24 2 "<general_operand>" "r<i>,<m>,L,k")))
11287    (clobber (reg:CC FLAGS_REG))]
11288   "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11289   "@
11290    and{<imodesuffix>}\t{%2, %0|%0, %2}
11291    and{<imodesuffix>}\t{%2, %0|%0, %2}
11292    #
11293    #"
11294   [(set (attr "isa")
11295         (cond [(eq_attr "alternative" "3")
11296                  (if_then_else (eq_attr "mode" "SI")
11297                    (const_string "avx512bw")
11298                    (const_string "avx512f"))
11299               ]
11300               (const_string "*")))
11301    (set_attr "type" "alu,alu,imovx,msklog")
11302    (set_attr "length_immediate" "*,*,0,*")
11303    (set (attr "prefix_rex")
11304      (if_then_else
11305        (and (eq_attr "type" "imovx")
11306             (and (match_test "INTVAL (operands[2]) == 0xff")
11307                  (match_operand 1 "ext_QIreg_operand")))
11308        (const_string "1")
11309        (const_string "*")))
11310    (set_attr "mode" "<MODE>,<MODE>,SI,<MODE>")])
11312 (define_insn "*andqi_1"
11313   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11314         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11315                 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
11316    (clobber (reg:CC FLAGS_REG))]
11317   "ix86_binary_operator_ok (AND, QImode, operands)"
11318   "@
11319    and{b}\t{%2, %0|%0, %2}
11320    and{b}\t{%2, %0|%0, %2}
11321    and{l}\t{%k2, %k0|%k0, %k2}
11322    #"
11323   [(set_attr "type" "alu,alu,alu,msklog")
11324    (set (attr "mode")
11325         (cond [(eq_attr "alternative" "2")
11326                  (const_string "SI")
11327                 (and (eq_attr "alternative" "3")
11328                      (match_test "!TARGET_AVX512DQ"))
11329                  (const_string "HI")
11330                ]
11331                (const_string "QI")))
11332    ;; Potential partial reg stall on alternative 2.
11333    (set (attr "preferred_for_speed")
11334      (cond [(eq_attr "alternative" "2")
11335               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11336            (symbol_ref "true")))])
11338 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11339 (define_insn_and_split "*and<mode>_1_slp"
11340   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
11341         (and:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
11342                    (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
11343    (clobber (reg:CC FLAGS_REG))]
11344   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11345   "@
11346    and{<imodesuffix>}\t{%2, %0|%0, %2}
11347    #"
11348   "&& reload_completed"
11349   [(set (strict_low_part (match_dup 0)) (match_dup 1))
11350    (parallel
11351      [(set (strict_low_part (match_dup 0))
11352            (and:SWI12 (match_dup 0) (match_dup 2)))
11353       (clobber (reg:CC FLAGS_REG))])]
11354   ""
11355   [(set_attr "type" "alu")
11356    (set_attr "mode" "<MODE>")])
11358 (define_split
11359   [(set (match_operand:SWI248 0 "register_operand")
11360         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
11361                     (match_operand:SWI248 2 "const_int_operand")))
11362    (clobber (reg:CC FLAGS_REG))]
11363   "reload_completed
11364    && (!REG_P (operands[1])
11365        || REGNO (operands[0]) != REGNO (operands[1]))"
11366   [(const_int 0)]
11368   unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11369   machine_mode mode;
11371   if (ival == GET_MODE_MASK (SImode))
11372     mode = SImode;
11373   else if (ival == GET_MODE_MASK (HImode))
11374     mode = HImode;
11375   else if (ival == GET_MODE_MASK (QImode))
11376     mode = QImode;
11377   else
11378     gcc_unreachable ();
11380   /* Zero extend to SImode to avoid partial register stalls.  */
11381   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
11382     operands[0] = gen_lowpart (SImode, operands[0]);
11384   emit_insn (gen_extend_insn
11385              (operands[0], gen_lowpart (mode, operands[1]),
11386               GET_MODE (operands[0]), mode, 1));
11387   DONE;
11390 (define_split
11391   [(set (match_operand:SWI48 0 "register_operand")
11392         (and:SWI48 (match_dup 0)
11393                    (const_int -65536)))
11394    (clobber (reg:CC FLAGS_REG))]
11395   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
11396     || optimize_function_for_size_p (cfun)"
11397   [(set (strict_low_part (match_dup 1)) (const_int 0))]
11398   "operands[1] = gen_lowpart (HImode, operands[0]);")
11400 (define_split
11401   [(set (match_operand:SWI248 0 "any_QIreg_operand")
11402         (and:SWI248 (match_dup 0)
11403                     (const_int -256)))
11404    (clobber (reg:CC FLAGS_REG))]
11405   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11406    && reload_completed"
11407   [(set (strict_low_part (match_dup 1)) (const_int 0))]
11408   "operands[1] = gen_lowpart (QImode, operands[0]);")
11410 (define_split
11411   [(set (match_operand:SWI248 0 "QIreg_operand")
11412         (and:SWI248 (match_dup 0)
11413                     (const_int -65281)))
11414    (clobber (reg:CC FLAGS_REG))]
11415   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11416    && reload_completed"
11417   [(parallel
11418      [(set (zero_extract:HI (match_dup 0)
11419                             (const_int 8)
11420                             (const_int 8))
11421            (subreg:HI
11422              (xor:QI
11423                (subreg:QI
11424                  (zero_extract:HI (match_dup 0)
11425                                   (const_int 8)
11426                                   (const_int 8)) 0)
11427                (subreg:QI
11428                  (zero_extract:HI (match_dup 0)
11429                                   (const_int 8)
11430                                   (const_int 8)) 0)) 0))
11431       (clobber (reg:CC FLAGS_REG))])]
11432   "operands[0] = gen_lowpart (HImode, operands[0]);")
11434 (define_insn "*anddi_2"
11435   [(set (reg FLAGS_REG)
11436         (compare
11437          (and:DI
11438           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
11439           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m"))
11440          (const_int 0)))
11441    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
11442         (and:DI (match_dup 1) (match_dup 2)))]
11443   "TARGET_64BIT
11444    && ix86_match_ccmode
11445         (insn,
11446          /* If we are going to emit andl instead of andq, and the operands[2]
11447             constant might have the SImode sign bit set, make sure the sign
11448             flag isn't tested, because the instruction will set the sign flag
11449             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
11450             conservatively assume it might have bit 31 set.  */
11451          (satisfies_constraint_Z (operands[2])
11452           && (!CONST_INT_P (operands[2])
11453               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
11454          ? CCZmode : CCNOmode)
11455    && ix86_binary_operator_ok (AND, DImode, operands)"
11456   "@
11457    and{l}\t{%k2, %k0|%k0, %k2}
11458    and{q}\t{%2, %0|%0, %2}
11459    and{q}\t{%2, %0|%0, %2}"
11460   [(set_attr "type" "alu")
11461    (set_attr "mode" "SI,DI,DI")])
11463 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11464 (define_insn "*andsi_2_zext"
11465   [(set (reg FLAGS_REG)
11466         (compare (and:SI
11467                   (match_operand:SI 1 "nonimmediate_operand" "%0")
11468                   (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
11469                  (const_int 0)))
11470    (set (match_operand:DI 0 "register_operand" "=r")
11471         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
11472   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11473    && ix86_binary_operator_ok (AND, SImode, operands)"
11474   "and{l}\t{%2, %k0|%k0, %2}"
11475   [(set_attr "type" "alu")
11476    (set_attr "mode" "SI")])
11478 (define_insn "*andqi_2_maybe_si"
11479   [(set (reg FLAGS_REG)
11480         (compare (and:QI
11481                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
11482                   (match_operand:QI 2 "general_operand" "qn,m,n"))
11483                  (const_int 0)))
11484    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
11485         (and:QI (match_dup 1) (match_dup 2)))]
11486   "ix86_binary_operator_ok (AND, QImode, operands)
11487    && ix86_match_ccmode (insn,
11488                          CONST_INT_P (operands[2])
11489                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
11491   if (get_attr_mode (insn) == MODE_SI)
11492     {
11493       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
11494         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
11495       return "and{l}\t{%2, %k0|%k0, %2}";
11496     }
11497   return "and{b}\t{%2, %0|%0, %2}";
11499   [(set_attr "type" "alu")
11500    (set (attr "mode")
11501      (cond [(eq_attr "alternative" "2")
11502               (const_string "SI")
11503             (and (match_test "optimize_insn_for_size_p ()")
11504                  (and (match_operand 0 "ext_QIreg_operand")
11505                       (match_operand 2 "const_0_to_127_operand")))
11506               (const_string "SI")
11507            ]
11508            (const_string "QI")))
11509    ;; Potential partial reg stall on alternative 2.
11510    (set (attr "preferred_for_speed")
11511      (cond [(eq_attr "alternative" "2")
11512               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11513            (symbol_ref "true")))])
11515 (define_insn "*and<mode>_2"
11516   [(set (reg FLAGS_REG)
11517         (compare (and:SWI124
11518                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
11519                   (match_operand:SWI124 2 "<general_operand>" "<r><i>,<m>"))
11520                  (const_int 0)))
11521    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>")
11522         (and:SWI124 (match_dup 1) (match_dup 2)))]
11523   "ix86_match_ccmode (insn, CCNOmode)
11524    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11525   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
11526   [(set_attr "type" "alu")
11527    (set_attr "mode" "<MODE>")])
11529 (define_insn "*andqi_ext<mode>_0"
11530   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
11531         (and:QI
11532           (subreg:QI
11533             (match_operator:SWI248 3 "extract_operator"
11534               [(match_operand 2 "int248_register_operand" "Q")
11535                (const_int 8)
11536                (const_int 8)]) 0)
11537           (match_operand:QI 1 "nonimmediate_operand" "0")))
11538    (clobber (reg:CC FLAGS_REG))]
11539   ""
11540   "and{b}\t{%h2, %0|%0, %h2}"
11541   [(set_attr "addr" "gpr8")
11542    (set_attr "type" "alu")
11543    (set_attr "mode" "QI")])
11545 (define_expand "andqi_ext_1"
11546   [(parallel
11547      [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
11548                             (const_int 8)
11549                             (const_int 8))
11550            (subreg:HI
11551              (and:QI
11552                (subreg:QI
11553                  (zero_extract:HI (match_operand:HI 1 "register_operand")
11554                                   (const_int 8)
11555                                   (const_int 8)) 0)
11556                (match_operand:QI 2 "const_int_operand")) 0))
11557       (clobber (reg:CC FLAGS_REG))])])
11559 (define_insn "*andqi_ext<mode>_1"
11560   [(set (zero_extract:SWI248
11561           (match_operand 0 "int248_register_operand" "+Q")
11562           (const_int 8)
11563           (const_int 8))
11564         (subreg:SWI248
11565           (and:QI
11566             (subreg:QI
11567               (match_operator:SWI248 3 "extract_operator"
11568                 [(match_operand 1 "int248_register_operand" "0")
11569                  (const_int 8)
11570                  (const_int 8)]) 0)
11571             (match_operand:QI 2 "general_operand" "QnBn")) 0))
11572    (clobber (reg:CC FLAGS_REG))]
11573   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
11574    rtx_equal_p (operands[0], operands[1])"
11575   "and{b}\t{%2, %h0|%h0, %2}"
11576   [(set_attr "addr" "gpr8")
11577    (set_attr "type" "alu")
11578    (set_attr "mode" "QI")])
11580 ;; Generated by peephole translating test to and.  This shows up
11581 ;; often in fp comparisons.
11582 (define_insn "*andqi_ext<mode>_1_cc"
11583   [(set (reg FLAGS_REG)
11584         (compare
11585           (and:QI
11586             (subreg:QI
11587               (match_operator:SWI248 3 "extract_operator"
11588                 [(match_operand 1 "int248_register_operand" "0")
11589                  (const_int 8)
11590                  (const_int 8)]) 0)
11591             (match_operand:QI 2 "general_operand" "QnBn"))
11592           (const_int 0)))
11593    (set (zero_extract:SWI248
11594           (match_operand 0 "int248_register_operand" "+Q")
11595           (const_int 8)
11596           (const_int 8))
11597         (subreg:SWI248
11598           (and:QI
11599             (subreg:QI
11600               (match_op_dup 3
11601                 [(match_dup 1)
11602                  (const_int 8)
11603                  (const_int 8)]) 0)
11604             (match_dup 2)) 0))]
11605   "ix86_match_ccmode (insn, CCNOmode)
11606    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
11607    && rtx_equal_p (operands[0], operands[1])"
11608   "and{b}\t{%2, %h0|%h0, %2}"
11609   [(set_attr "addr" "gpr8")
11610    (set_attr "type" "alu")
11611    (set_attr "mode" "QI")])
11613 (define_insn "*andqi_ext<mode>_2"
11614   [(set (zero_extract:SWI248
11615           (match_operand 0 "int248_register_operand" "+Q")
11616           (const_int 8)
11617           (const_int 8))
11618         (subreg:SWI248
11619           (and:QI
11620             (subreg:QI
11621               (match_operator:SWI248 3 "extract_operator"
11622                 [(match_operand 1 "int248_register_operand" "%0")
11623                  (const_int 8)
11624                  (const_int 8)]) 0)
11625             (subreg:QI
11626               (match_operator:SWI248 4 "extract_operator"
11627                 [(match_operand 2 "int248_register_operand" "Q")
11628                  (const_int 8)
11629                  (const_int 8)]) 0)) 0))
11630    (clobber (reg:CC FLAGS_REG))]
11631   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
11632    rtx_equal_p (operands[0], operands[1])
11633    || rtx_equal_p (operands[0], operands[2])"
11634   "and{b}\t{%h2, %h0|%h0, %h2}"
11635   [(set_attr "type" "alu")
11636    (set_attr "mode" "QI")])
11638 ;; *andqi_ext<mode>_3 is defined via *<code>qi_ext<mode>_3 below.
11640 ;; Convert wide AND instructions with immediate operand to shorter QImode
11641 ;; equivalents when possible.
11642 ;; Don't do the splitting with memory operands, since it introduces risk
11643 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
11644 ;; for size, but that can (should?) be handled by generic code instead.
11645 (define_split
11646   [(set (match_operand:SWI248 0 "QIreg_operand")
11647         (and:SWI248 (match_operand:SWI248 1 "register_operand")
11648                     (match_operand:SWI248 2 "const_int_operand")))
11649    (clobber (reg:CC FLAGS_REG))]
11650    "reload_completed
11651     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11652     && !(~INTVAL (operands[2]) & ~(255 << 8))"
11653   [(parallel
11654      [(set (zero_extract:HI (match_dup 0)
11655                             (const_int 8)
11656                             (const_int 8))
11657            (subreg:HI
11658              (and:QI
11659                (subreg:QI
11660                  (zero_extract:HI (match_dup 1)
11661                                   (const_int 8)
11662                                   (const_int 8)) 0)
11663                (match_dup 2)) 0))
11664       (clobber (reg:CC FLAGS_REG))])]
11666   operands[0] = gen_lowpart (HImode, operands[0]);
11667   operands[1] = gen_lowpart (HImode, operands[1]);
11668   operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
11671 ;; Since AND can be encoded with sign extended immediate, this is only
11672 ;; profitable when 7th bit is not set.
11673 (define_split
11674   [(set (match_operand:SWI248 0 "any_QIreg_operand")
11675         (and:SWI248 (match_operand:SWI248 1 "general_operand")
11676                     (match_operand:SWI248 2 "const_int_operand")))
11677    (clobber (reg:CC FLAGS_REG))]
11678    "reload_completed
11679     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11680     && !(~INTVAL (operands[2]) & ~255)
11681     && !(INTVAL (operands[2]) & 128)"
11682   [(parallel [(set (strict_low_part (match_dup 0))
11683                    (and:QI (match_dup 1)
11684                            (match_dup 2)))
11685               (clobber (reg:CC FLAGS_REG))])]
11687   operands[0] = gen_lowpart (QImode, operands[0]);
11688   operands[1] = gen_lowpart (QImode, operands[1]);
11689   operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
11692 (define_insn_and_split "*andn<dwi>3_doubleword_bmi"
11693   [(set (match_operand:<DWI> 0 "register_operand" "=&r,r,r")
11694         (and:<DWI>
11695           (not:<DWI> (match_operand:<DWI> 1 "register_operand" "r,0,r"))
11696           (match_operand:<DWI> 2 "nonimmediate_operand" "ro,ro,0")))
11697    (clobber (reg:CC FLAGS_REG))]
11698   "TARGET_BMI"
11699   "#"
11700   "&& reload_completed"
11701   [(parallel [(set (match_dup 0)
11702                    (and:DWIH (not:DWIH (match_dup 1)) (match_dup 2)))
11703               (clobber (reg:CC FLAGS_REG))])
11704    (parallel [(set (match_dup 3)
11705                    (and:DWIH (not:DWIH (match_dup 4)) (match_dup 5)))
11706               (clobber (reg:CC FLAGS_REG))])]
11707   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
11709 (define_insn_and_split "*andn<mode>3_doubleword"
11710   [(set (match_operand:DWI 0 "register_operand")
11711         (and:DWI
11712           (not:DWI (match_operand:DWI 1 "register_operand"))
11713           (match_operand:DWI 2 "nonimmediate_operand")))
11714    (clobber (reg:CC FLAGS_REG))]
11715   "!TARGET_BMI
11716    && ix86_pre_reload_split ()"
11717   "#"
11718   "&& 1"
11719   [(set (match_dup 3) (not:DWI (match_dup 1)))
11720    (parallel [(set (match_dup 0)
11721                    (and:DWI (match_dup 3) (match_dup 2)))
11722               (clobber (reg:CC FLAGS_REG))])]
11723   "operands[3] = gen_reg_rtx (<MODE>mode);")
11725 (define_insn "*andn<mode>_1"
11726   [(set (match_operand:SWI48 0 "register_operand" "=r,r,?k")
11727         (and:SWI48
11728           (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r,k"))
11729           (match_operand:SWI48 2 "nonimmediate_operand" "r,m,k")))
11730    (clobber (reg:CC FLAGS_REG))]
11731   "TARGET_BMI
11732    || (TARGET_AVX512BW && (<MODE>mode == SImode || TARGET_EVEX512))"
11733   "@
11734    andn\t{%2, %1, %0|%0, %1, %2}
11735    andn\t{%2, %1, %0|%0, %1, %2}
11736    #"
11737   [(set_attr "isa" "bmi,bmi,<kmov_isa>")
11738    (set_attr "type" "bitmanip,bitmanip,msklog")
11739    (set_attr "btver2_decode" "direct, double,*")
11740    (set_attr "mode" "<MODE>")])
11742 (define_insn "*andn<mode>_1"
11743   [(set (match_operand:SWI12 0 "register_operand" "=r,?k")
11744         (and:SWI12
11745           (not:SWI12 (match_operand:SWI12 1 "register_operand" "r,k"))
11746           (match_operand:SWI12 2 "register_operand" "r,k")))
11747    (clobber (reg:CC FLAGS_REG))]
11748   "TARGET_BMI || TARGET_AVX512BW"
11749   "@
11750    andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
11751    #"
11752   [(set_attr "isa" "bmi,avx512f")
11753    (set_attr "type" "bitmanip,msklog")
11754    (set_attr "btver2_decode" "direct,*")
11755    (set (attr "mode")
11756         (cond [(eq_attr "alternative" "0")
11757                  (const_string "SI")
11758                (and (eq_attr "alternative" "1")
11759                     (match_test "!TARGET_AVX512DQ"))
11760                   (const_string "HI")
11761               ]
11762               (const_string "<MODE>")))])
11764 (define_insn "*andn_<mode>_ccno"
11765   [(set (reg FLAGS_REG)
11766         (compare
11767           (and:SWI48
11768             (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
11769             (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
11770           (const_int 0)))
11771    (clobber (match_scratch:SWI48 0 "=r,r"))]
11772   "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
11773   "andn\t{%2, %1, %0|%0, %1, %2}"
11774   [(set_attr "type" "bitmanip")
11775    (set_attr "btver2_decode" "direct, double")
11776    (set_attr "mode" "<MODE>")])
11778 ;; Split *andnsi_1 after reload with -Oz when not;and is shorter.
11779 (define_split
11780   [(set (match_operand:SI 0 "register_operand")
11781         (and:SI (not:SI (match_operand:SI 1 "register_operand"))
11782                 (match_operand:SI 2 "nonimmediate_operand")))
11783    (clobber (reg:CC FLAGS_REG))]
11784   "reload_completed
11785    && optimize_insn_for_size_p () && optimize_size > 1
11786    && REGNO (operands[0]) == REGNO (operands[1])
11787    && LEGACY_INT_REG_P (operands[0])
11788    && !REX_INT_REG_P (operands[2])
11789    && !reg_overlap_mentioned_p (operands[0], operands[2])"
11790   [(set (match_dup 0) (not:SI (match_dup 1)))
11791    (parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
11792               (clobber (reg:CC FLAGS_REG))])])
11794 ;; Split *andn_si_ccno with -Oz when not;test is shorter.
11795 (define_split
11796   [(set (match_operand 0 "flags_reg_operand")
11797         (match_operator 1 "compare_operator"
11798           [(and:SI (not:SI (match_operand:SI 2 "general_reg_operand"))
11799                    (match_operand:SI 3 "nonimmediate_operand"))
11800            (const_int 0)]))
11801    (clobber (match_dup 2))]
11802   "reload_completed
11803    && optimize_insn_for_size_p () && optimize_size > 1
11804    && LEGACY_INT_REG_P (operands[2])
11805    && !REX_INT_REG_P (operands[3])
11806    && !reg_overlap_mentioned_p (operands[2], operands[3])"
11807   [(set (match_dup 2) (not:SI (match_dup 2)))
11808    (set (match_dup 0) (match_op_dup 1
11809                         [(and:SI (match_dup 3) (match_dup 2))
11810                          (const_int 0)]))])
11812 ;; Variant 1 of 4: Split ((A | B) ^ A) ^ C as (B & ~A) ^ C.
11813 (define_split
11814   [(set (match_operand:SWI48 0 "register_operand")
11815         (xor:SWI48
11816            (xor:SWI48
11817               (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11818                          (match_operand:SWI48 2 "nonimmediate_operand"))
11819               (match_dup 1))
11820            (match_operand:SWI48 3 "nonimmediate_operand")))
11821    (clobber (reg:CC FLAGS_REG))]
11822   "TARGET_BMI"
11823   [(parallel
11824       [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
11825        (clobber (reg:CC FLAGS_REG))])
11826    (parallel
11827       [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11828        (clobber (reg:CC FLAGS_REG))])]
11829   "operands[4] = gen_reg_rtx (<MODE>mode);")
11831 ;; Variant 2 of 4: Split ((A | B) ^ B) ^ C as (A & ~B) ^ C.
11832 (define_split
11833   [(set (match_operand:SWI48 0 "register_operand")
11834         (xor:SWI48
11835            (xor:SWI48
11836               (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11837                          (match_operand:SWI48 2 "register_operand"))
11838               (match_dup 2))
11839            (match_operand:SWI48 3 "nonimmediate_operand")))
11840    (clobber (reg:CC FLAGS_REG))]
11841   "TARGET_BMI"
11842   [(parallel
11843       [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
11844        (clobber (reg:CC FLAGS_REG))])
11845    (parallel
11846       [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11847        (clobber (reg:CC FLAGS_REG))])]
11848   "operands[4] = gen_reg_rtx (<MODE>mode);")
11850 ;; Variant 3 of 4: Split ((A | B) ^ C) ^ A as (B & ~A) ^ C.
11851 (define_split
11852   [(set (match_operand:SWI48 0 "register_operand")
11853         (xor:SWI48
11854            (xor:SWI48
11855               (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11856                          (match_operand:SWI48 2 "nonimmediate_operand"))
11857               (match_operand:SWI48 3 "nonimmediate_operand"))
11858            (match_dup 1)))
11859    (clobber (reg:CC FLAGS_REG))]
11860   "TARGET_BMI"
11861   [(parallel
11862       [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
11863        (clobber (reg:CC FLAGS_REG))])
11864    (parallel
11865       [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11866        (clobber (reg:CC FLAGS_REG))])]
11867   "operands[4] = gen_reg_rtx (<MODE>mode);")
11869 ;; Variant 4 of 4: Split ((A | B) ^ C) ^ B as (A & ~B) ^ C.
11870 (define_split
11871   [(set (match_operand:SWI48 0 "register_operand")
11872         (xor:SWI48
11873            (xor:SWI48
11874               (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11875                          (match_operand:SWI48 2 "register_operand"))
11876               (match_operand:SWI48 3 "nonimmediate_operand"))
11877            (match_dup 2)))
11878    (clobber (reg:CC FLAGS_REG))]
11879   "TARGET_BMI"
11880   [(parallel
11881       [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
11882        (clobber (reg:CC FLAGS_REG))])
11883    (parallel
11884       [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11885        (clobber (reg:CC FLAGS_REG))])]
11886   "operands[4] = gen_reg_rtx (<MODE>mode);")
11888 ;; Logical inclusive and exclusive OR instructions
11890 ;; %%% This used to optimize known byte-wide and operations to memory.
11891 ;; If this is considered useful, it should be done with splitters.
11893 (define_expand "<code><mode>3"
11894   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
11895         (any_or:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
11896                       (match_operand:SDWIM 2 "<general_operand>")))]
11897   ""
11899   if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
11900       && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
11901     operands[2] = force_reg (<MODE>mode, operands[2]);
11903   ix86_expand_binary_operator (<CODE>, <MODE>mode, operands);
11904   DONE;
11907 (define_insn_and_split "*<code><dwi>3_doubleword"
11908   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
11909         (any_or:<DWI>
11910          (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
11911          (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
11912    (clobber (reg:CC FLAGS_REG))]
11913   "ix86_binary_operator_ok (<CODE>, <DWI>mode, operands)"
11914   "#"
11915   "&& reload_completed"
11916   [(const_int:DWIH 0)]
11918   /* This insn may disappear completely when operands[2] == const0_rtx
11919      and operands[0] == operands[1], which requires a NOTE_INSN_DELETED.  */
11920   bool emit_insn_deleted_note_p = false;
11922   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
11924   if (operands[2] == const0_rtx)
11925     emit_insn_deleted_note_p = true;
11926   else if (operands[2] == constm1_rtx)
11927     {
11928       if (<CODE> == IOR)
11929         emit_move_insn (operands[0], constm1_rtx);
11930       else
11931         ix86_expand_unary_operator (NOT, <MODE>mode, &operands[0]);
11932     }
11933   else
11934     ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[0]);
11936   if (operands[5] == const0_rtx)
11937     {
11938       if (emit_insn_deleted_note_p)
11939         emit_note (NOTE_INSN_DELETED);
11940     }
11941   else if (operands[5] == constm1_rtx)
11942     {
11943       if (<CODE> == IOR)
11944         emit_move_insn (operands[3], constm1_rtx);
11945       else
11946         ix86_expand_unary_operator (NOT, <MODE>mode, &operands[3]);
11947     }
11948   else
11949     ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[3]);
11951   DONE;
11954 (define_insn "*<code><mode>_1"
11955   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
11956         (any_or:SWI248
11957          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
11958          (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k")))
11959    (clobber (reg:CC FLAGS_REG))]
11960   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11961   "@
11962    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11963    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11964    #"
11965   [(set_attr "isa" "*,*,<kmov_isa>")
11966    (set_attr "type" "alu, alu, msklog")
11967    (set_attr "mode" "<MODE>")])
11969 (define_insn_and_split "*notxor<mode>_1"
11970   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
11971         (not:SWI248
11972           (xor:SWI248
11973             (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
11974             (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k"))))
11975    (clobber (reg:CC FLAGS_REG))]
11976   "ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
11977   "#"
11978   "&& reload_completed"
11979   [(parallel
11980     [(set (match_dup 0)
11981           (xor:SWI248 (match_dup 1) (match_dup 2)))
11982      (clobber (reg:CC FLAGS_REG))])
11983    (set (match_dup 0)
11984         (not:SWI248 (match_dup 0)))]
11986   if (MASK_REG_P (operands[0]))
11987     {
11988       emit_insn (gen_kxnor<mode> (operands[0], operands[1], operands[2]));
11989       DONE;
11990     }
11992   [(set_attr "isa" "*,*,<kmov_isa>")
11993    (set_attr "type" "alu, alu, msklog")
11994    (set_attr "mode" "<MODE>")])
11996 (define_insn_and_split "*iordi_1_bts"
11997   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11998         (ior:DI
11999          (match_operand:DI 1 "nonimmediate_operand" "%0")
12000          (match_operand:DI 2 "const_int_operand" "n")))
12001    (clobber (reg:CC FLAGS_REG))]
12002   "TARGET_64BIT && TARGET_USE_BT
12003    && ix86_binary_operator_ok (IOR, DImode, operands)
12004    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
12005   "#"
12006   "&& reload_completed"
12007   [(parallel [(set (zero_extract:DI (match_dup 0)
12008                                     (const_int 1)
12009                                     (match_dup 3))
12010                    (const_int 1))
12011               (clobber (reg:CC FLAGS_REG))])]
12012   "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
12013   [(set_attr "type" "alu1")
12014    (set_attr "prefix_0f" "1")
12015    (set_attr "znver1_decode" "double")
12016    (set_attr "mode" "DI")])
12018 (define_insn_and_split "*xordi_1_btc"
12019   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12020         (xor:DI
12021          (match_operand:DI 1 "nonimmediate_operand" "%0")
12022          (match_operand:DI 2 "const_int_operand" "n")))
12023    (clobber (reg:CC FLAGS_REG))]
12024   "TARGET_64BIT && TARGET_USE_BT
12025    && ix86_binary_operator_ok (XOR, DImode, operands)
12026    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
12027   "#"
12028   "&& reload_completed"
12029   [(parallel [(set (zero_extract:DI (match_dup 0)
12030                                     (const_int 1)
12031                                     (match_dup 3))
12032                    (not:DI (zero_extract:DI (match_dup 0)
12033                                             (const_int 1)
12034                                             (match_dup 3))))
12035               (clobber (reg:CC FLAGS_REG))])]
12036   "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
12037   [(set_attr "type" "alu1")
12038    (set_attr "prefix_0f" "1")
12039    (set_attr "znver1_decode" "double")
12040    (set_attr "mode" "DI")])
12042 ;; Optimize a ^ ((a ^ b) & mask) to (~mask & a) | (b & mask)
12043 (define_insn_and_split "*xor2andn"
12044   [(set (match_operand:SWI248 0 "register_operand")
12045         (xor:SWI248
12046           (and:SWI248
12047             (xor:SWI248
12048               (match_operand:SWI248 1 "nonimmediate_operand")
12049               (match_operand:SWI248 2 "nonimmediate_operand"))
12050             (match_operand:SWI248 3 "nonimmediate_operand"))
12051           (match_dup 1)))
12052     (clobber (reg:CC FLAGS_REG))]
12053   "TARGET_BMI && ix86_pre_reload_split ()"
12054   "#"
12055   "&& 1"
12056   [(parallel [(set (match_dup 4)
12057                 (and:SWI248
12058                   (not:SWI248
12059                     (match_dup 3))
12060                   (match_dup 1)))
12061               (clobber (reg:CC FLAGS_REG))])
12062    (parallel [(set (match_dup 5)
12063                 (and:SWI248
12064                   (match_dup 3)
12065                   (match_dup 2)))
12066               (clobber (reg:CC FLAGS_REG))])
12067    (parallel [(set (match_dup 0)
12068                 (ior:SWI248
12069                   (match_dup 4)
12070                   (match_dup 5)))
12071               (clobber (reg:CC FLAGS_REG))])]
12073   operands[1] = force_reg (<MODE>mode, operands[1]);
12074   operands[3] = force_reg (<MODE>mode, operands[3]);
12075   operands[4] = gen_reg_rtx (<MODE>mode);
12076   operands[5] = gen_reg_rtx (<MODE>mode);
12079 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12080 (define_insn "*<code>si_1_zext"
12081   [(set (match_operand:DI 0 "register_operand" "=r")
12082         (zero_extend:DI
12083          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12084                     (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
12085    (clobber (reg:CC FLAGS_REG))]
12086   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12087   "<logic>{l}\t{%2, %k0|%k0, %2}"
12088   [(set_attr "type" "alu")
12089    (set_attr "mode" "SI")])
12091 (define_insn "*<code>si_1_zext_imm"
12092   [(set (match_operand:DI 0 "register_operand" "=r")
12093         (any_or:DI
12094          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
12095          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
12096    (clobber (reg:CC FLAGS_REG))]
12097   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12098   "<logic>{l}\t{%2, %k0|%k0, %2}"
12099   [(set_attr "type" "alu")
12100    (set_attr "mode" "SI")])
12102 (define_insn "*<code>qi_1"
12103   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
12104         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
12105                    (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
12106    (clobber (reg:CC FLAGS_REG))]
12107   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
12108   "@
12109    <logic>{b}\t{%2, %0|%0, %2}
12110    <logic>{b}\t{%2, %0|%0, %2}
12111    <logic>{l}\t{%k2, %k0|%k0, %k2}
12112    #"
12113   [(set_attr "isa" "*,*,*,avx512f")
12114    (set_attr "type" "alu,alu,alu,msklog")
12115    (set (attr "mode")
12116         (cond [(eq_attr "alternative" "2")
12117                  (const_string "SI")
12118                 (and (eq_attr "alternative" "3")
12119                      (match_test "!TARGET_AVX512DQ"))
12120                  (const_string "HI")
12121                ]
12122                (const_string "QI")))
12123    ;; Potential partial reg stall on alternative 2.
12124    (set (attr "preferred_for_speed")
12125      (cond [(eq_attr "alternative" "2")
12126               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12127            (symbol_ref "true")))])
12129 (define_insn_and_split "*notxorqi_1"
12130   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
12131         (not:QI
12132           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
12133                   (match_operand:QI 2 "general_operand" "qn,m,rn,k"))))
12134    (clobber (reg:CC FLAGS_REG))]
12135   "ix86_binary_operator_ok (XOR, QImode, operands)"
12136   "#"
12137   "&& reload_completed"
12138   [(parallel
12139     [(set (match_dup 0)
12140           (xor:QI (match_dup 1) (match_dup 2)))
12141      (clobber (reg:CC FLAGS_REG))])
12142    (set (match_dup 0)
12143         (not:QI (match_dup 0)))]
12145   if (mask_reg_operand (operands[0], QImode))
12146     {
12147       emit_insn (gen_kxnorqi (operands[0], operands[1], operands[2]));
12148       DONE;
12149     }
12151   [(set_attr "isa" "*,*,*,avx512f")
12152    (set_attr "type" "alu,alu,alu,msklog")
12153    (set (attr "mode")
12154         (cond [(eq_attr "alternative" "2")
12155                  (const_string "SI")
12156                 (and (eq_attr "alternative" "3")
12157                      (match_test "!TARGET_AVX512DQ"))
12158                  (const_string "HI")
12159                ]
12160                (const_string "QI")))
12161    ;; Potential partial reg stall on alternative 2.
12162    (set (attr "preferred_for_speed")
12163      (cond [(eq_attr "alternative" "2")
12164               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12165            (symbol_ref "true")))])
12167 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12168 (define_insn_and_split "*<code><mode>_1_slp"
12169   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
12170         (any_or:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
12171                       (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
12172    (clobber (reg:CC FLAGS_REG))]
12173   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12174   "@
12175    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12176    #"
12177   "&& reload_completed"
12178   [(set (strict_low_part (match_dup 0)) (match_dup 1))
12179    (parallel
12180      [(set (strict_low_part (match_dup 0))
12181            (any_or:SWI12 (match_dup 0) (match_dup 2)))
12182       (clobber (reg:CC FLAGS_REG))])]
12183   ""
12184   [(set_attr "type" "alu")
12185    (set_attr "mode" "<MODE>")])
12187 ;; convert (sign_extend:WIDE (any_logic:NARROW (memory, immediate)))
12188 ;; to (any_logic:WIDE (sign_extend (memory)), (sign_extend (immediate))).
12189 ;; This eliminates sign extension after logic operation.
12191 (define_split
12192   [(set (match_operand:SWI248 0 "register_operand")
12193         (sign_extend:SWI248
12194           (any_logic:QI (match_operand:QI 1 "memory_operand")
12195                         (match_operand:QI 2 "const_int_operand"))))]
12196   ""
12197   [(set (match_dup 3) (sign_extend:SWI248 (match_dup 1)))
12198    (set (match_dup 0) (any_logic:SWI248 (match_dup 3) (match_dup 2)))]
12199   "operands[3] = gen_reg_rtx (<MODE>mode);")
12201 (define_split
12202   [(set (match_operand:SWI48 0 "register_operand")
12203         (sign_extend:SWI48
12204           (any_logic:HI (match_operand:HI 1 "memory_operand")
12205                         (match_operand:HI 2 "const_int_operand"))))]
12206   ""
12207   [(set (match_dup 3) (sign_extend:SWI48 (match_dup 1)))
12208    (set (match_dup 0) (any_logic:SWI48 (match_dup 3) (match_dup 2)))]
12209   "operands[3] = gen_reg_rtx (<MODE>mode);")
12211 (define_split
12212   [(set (match_operand:DI 0 "register_operand")
12213         (sign_extend:DI
12214           (any_logic:SI (match_operand:SI 1 "memory_operand")
12215                         (match_operand:SI 2 "const_int_operand"))))]
12216   "TARGET_64BIT"
12217   [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
12218    (set (match_dup 0) (any_logic:DI (match_dup 3) (match_dup 2)))]
12219   "operands[3] = gen_reg_rtx (DImode);")
12221 (define_insn "*<code><mode>_2"
12222   [(set (reg FLAGS_REG)
12223         (compare (any_or:SWI
12224                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
12225                   (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
12226                  (const_int 0)))
12227    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
12228         (any_or:SWI (match_dup 1) (match_dup 2)))]
12229   "ix86_match_ccmode (insn, CCNOmode)
12230    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12231   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12232   [(set_attr "type" "alu")
12233    (set_attr "mode" "<MODE>")])
12235 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12236 ;; ??? Special case for immediate operand is missing - it is tricky.
12237 (define_insn "*<code>si_2_zext"
12238   [(set (reg FLAGS_REG)
12239         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12240                             (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
12241                  (const_int 0)))
12242    (set (match_operand:DI 0 "register_operand" "=r")
12243         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
12244   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12245    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12246   "<logic>{l}\t{%2, %k0|%k0, %2}"
12247   [(set_attr "type" "alu")
12248    (set_attr "mode" "SI")])
12250 (define_insn "*<code>si_2_zext_imm"
12251   [(set (reg FLAGS_REG)
12252         (compare (any_or:SI
12253                   (match_operand:SI 1 "nonimmediate_operand" "%0")
12254                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
12255                  (const_int 0)))
12256    (set (match_operand:DI 0 "register_operand" "=r")
12257         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12258   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12259    && 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><mode>_3"
12265   [(set (reg FLAGS_REG)
12266         (compare (any_or:SWI
12267                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
12268                   (match_operand:SWI 2 "<general_operand>" "<g>"))
12269                  (const_int 0)))
12270    (clobber (match_scratch:SWI 0 "=<r>"))]
12271   "ix86_match_ccmode (insn, CCNOmode)
12272    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12273   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12274   [(set_attr "type" "alu")
12275    (set_attr "mode" "<MODE>")])
12277 (define_insn "*<code>qi_ext<mode>_0"
12278   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
12279         (any_or:QI
12280           (subreg:QI
12281             (match_operator:SWI248 3 "extract_operator"
12282               [(match_operand 2 "int248_register_operand" "Q")
12283                (const_int 8)
12284                (const_int 8)]) 0)
12285           (match_operand:QI 1 "nonimmediate_operand" "0")))
12286    (clobber (reg:CC FLAGS_REG))]
12287   ""
12288   "<logic>{b}\t{%h2, %0|%0, %h2}"
12289   [(set_attr "addr" "gpr8")
12290    (set_attr "type" "alu")
12291    (set_attr "mode" "QI")])
12293 (define_insn "*<code>qi_ext<mode>_1"
12294   [(set (zero_extract:SWI248
12295           (match_operand 0 "int248_register_operand" "+Q")
12296           (const_int 8)
12297           (const_int 8))
12298         (subreg:SWI248
12299           (any_or:QI
12300             (subreg:QI
12301               (match_operator:SWI248 3 "extract_operator"
12302                 [(match_operand 1 "int248_register_operand" "0")
12303                  (const_int 8)
12304                  (const_int 8)]) 0)
12305             (match_operand:QI 2 "general_operand" "QnBn")) 0))
12306    (clobber (reg:CC FLAGS_REG))]
12307   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12308    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
12309    && rtx_equal_p (operands[0], operands[1])"
12310   "<logic>{b}\t{%2, %h0|%h0, %2}"
12311   [(set_attr "addr" "gpr8")
12312    (set_attr "type" "alu")
12313    (set_attr "mode" "QI")])
12315 (define_insn "*<code>qi_ext<mode>_2"
12316   [(set (zero_extract:SWI248
12317           (match_operand 0 "int248_register_operand" "+Q")
12318           (const_int 8)
12319           (const_int 8))
12320         (subreg:SWI248
12321           (any_or:QI
12322             (subreg:QI
12323               (match_operator:SWI248 3 "extract_operator"
12324                 [(match_operand 1 "int248_register_operand" "%0")
12325                  (const_int 8)
12326                  (const_int 8)]) 0)
12327             (subreg:QI
12328               (match_operator:SWI248 4 "extract_operator"
12329                 [(match_operand 2 "int248_register_operand" "Q")
12330                  (const_int 8)
12331                  (const_int 8)]) 0)) 0))
12332    (clobber (reg:CC FLAGS_REG))]
12333   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12334    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
12335    && (rtx_equal_p (operands[0], operands[1])
12336        || rtx_equal_p (operands[0], operands[2]))"
12337   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
12338   [(set_attr "type" "alu")
12339    (set_attr "mode" "QI")])
12341 (define_insn "*<code>qi_ext<mode>_3"
12342   [(set (zero_extract:SWI248
12343           (match_operand 0 "int248_register_operand" "+Q")
12344           (const_int 8)
12345           (const_int 8))
12346         (zero_extract:SWI248
12347           (any_logic:SWI248
12348             (match_operand 1 "int248_register_operand" "%0")
12349             (match_operand 2 "int248_register_operand" "Q"))
12350           (const_int 8)
12351           (const_int 8)))
12352    (clobber (reg:CC FLAGS_REG))]
12353   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12354    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
12355    && (rtx_equal_p (operands[0], operands[1])
12356        || rtx_equal_p (operands[0], operands[2]))"
12357   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
12358   [(set_attr "type" "alu")
12359    (set_attr "mode" "QI")])
12361 ;; Convert wide OR instructions with immediate operand to shorter QImode
12362 ;; equivalents when possible.
12363 ;; Don't do the splitting with memory operands, since it introduces risk
12364 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
12365 ;; for size, but that can (should?) be handled by generic code instead.
12366 (define_split
12367   [(set (match_operand:SWI248 0 "QIreg_operand")
12368         (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
12369                        (match_operand:SWI248 2 "const_int_operand")))
12370    (clobber (reg:CC FLAGS_REG))]
12371    "reload_completed
12372     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12373     && !(INTVAL (operands[2]) & ~(255 << 8))"
12374   [(parallel
12375      [(set (zero_extract:HI (match_dup 0)
12376                             (const_int 8)
12377                             (const_int 8))
12378            (subreg:HI
12379              (any_or:QI
12380                (subreg:QI
12381                  (zero_extract:HI (match_dup 1)
12382                                   (const_int 8)
12383                                   (const_int 8)) 0)
12384                (match_dup 2)) 0))
12385       (clobber (reg:CC FLAGS_REG))])]
12387   /* Handle the case where INTVAL (operands[2]) == 0.  */
12388   if (operands[2] == const0_rtx)
12389     {
12390       if (!rtx_equal_p (operands[0], operands[1]))
12391         emit_move_insn (operands[0], operands[1]);
12392       else
12393         emit_note (NOTE_INSN_DELETED);
12394       DONE;
12395     }
12396   operands[0] = gen_lowpart (HImode, operands[0]);
12397   operands[1] = gen_lowpart (HImode, operands[1]);
12398   operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
12401 ;; Since OR can be encoded with sign extended immediate, this is only
12402 ;; profitable when 7th bit is set.
12403 (define_split
12404   [(set (match_operand:SWI248 0 "any_QIreg_operand")
12405         (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
12406                        (match_operand:SWI248 2 "const_int_operand")))
12407    (clobber (reg:CC FLAGS_REG))]
12408    "reload_completed
12409     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12410     && !(INTVAL (operands[2]) & ~255)
12411     && (INTVAL (operands[2]) & 128)"
12412   [(parallel [(set (strict_low_part (match_dup 0))
12413                    (any_or:QI (match_dup 1)
12414                               (match_dup 2)))
12415               (clobber (reg:CC FLAGS_REG))])]
12417   operands[0] = gen_lowpart (QImode, operands[0]);
12418   operands[1] = gen_lowpart (QImode, operands[1]);
12419   operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
12422 (define_expand "xorqi_ext_1_cc"
12423   [(parallel
12424      [(set (reg:CCNO FLAGS_REG)
12425            (compare:CCNO
12426              (xor:QI
12427                (subreg:QI
12428                  (zero_extract:HI (match_operand:HI 1 "register_operand")
12429                                   (const_int 8)
12430                                   (const_int 8)) 0)
12431                (match_operand:QI 2 "const_int_operand"))
12432              (const_int 0)))
12433       (set (zero_extract:HI (match_operand:HI 0 "register_operand")
12434                             (const_int 8)
12435                             (const_int 8))
12436            (subreg:HI
12437              (xor: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))])])
12444 (define_insn "*xorqi_ext<mode>_1_cc"
12445   [(set (reg FLAGS_REG)
12446         (compare
12447           (xor:QI
12448             (subreg:QI
12449               (match_operator:SWI248 3 "extract_operator"
12450                 [(match_operand 1 "int248_register_operand" "0")
12451                  (const_int 8)
12452                  (const_int 8)]) 0)
12453             (match_operand:QI 2 "general_operand" "QnBn"))
12454           (const_int 0)))
12455    (set (zero_extract:SWI248
12456           (match_operand 0 "int248_register_operand" "+Q")
12457           (const_int 8)
12458           (const_int 8))
12459         (subreg:SWI248
12460           (xor:QI
12461             (subreg:QI
12462               (match_op_dup 3
12463                 [(match_dup 1)
12464                  (const_int 8)
12465                  (const_int 8)]) 0)
12466           (match_dup 2)) 0))]
12467   "ix86_match_ccmode (insn, CCNOmode)
12468    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
12469    && rtx_equal_p (operands[0], operands[1])"
12470   "xor{b}\t{%2, %h0|%h0, %2}"
12471   [(set_attr "addr" "gpr8")
12472    (set_attr "type" "alu")
12473    (set_attr "mode" "QI")])
12475 ;; Peephole2 rega = 0; rega op= regb into rega = regb.
12476 (define_peephole2
12477   [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12478                    (const_int 0))
12479               (clobber (reg:CC FLAGS_REG))])
12480    (parallel [(set (match_dup 0)
12481                    (any_or_plus:SWI (match_dup 0)
12482                                     (match_operand:SWI 1 "<general_operand>")))
12483               (clobber (reg:CC FLAGS_REG))])]
12484   "!reg_mentioned_p (operands[0], operands[1])"
12485   [(set (match_dup 0) (match_dup 1))])
12487 ;; Peephole2 dead instruction in rega = 0; rega op= rega.
12488 (define_peephole2
12489   [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12490                    (const_int 0))
12491               (clobber (reg:CC FLAGS_REG))])
12492    (parallel [(set (match_dup 0)
12493                    (any_or_plus:SWI (match_dup 0) (match_dup 0)))
12494               (clobber (reg:CC FLAGS_REG))])]
12495   ""
12496   [(parallel [(set (match_dup 0) (const_int 0))
12497               (clobber (reg:CC FLAGS_REG))])])
12499 ;; Split DST = (HI<<32)|LO early to minimize register usage.
12500 (define_insn_and_split "*concat<mode><dwi>3_1"
12501   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12502         (any_or_plus:<DWI>
12503           (ashift:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r")
12504                         (match_operand:QI 2 "const_int_operand"))
12505           (zero_extend:<DWI>
12506             (match_operand:DWIH 3 "nonimmediate_operand" "r,m"))))]
12507   "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12508   "#"
12509   "&& reload_completed"
12510   [(const_int 0)]
12512   split_double_concat (<DWI>mode, operands[0], operands[3],
12513                        gen_lowpart (<MODE>mode, operands[1]));
12514   DONE;
12517 (define_insn_and_split "*concat<mode><dwi>3_2"
12518   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12519         (any_or_plus:<DWI>
12520           (zero_extend:<DWI>
12521             (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
12522           (ashift:<DWI> (match_operand:<DWI> 2 "register_operand" "r,r")
12523                         (match_operand:QI 3 "const_int_operand"))))]
12524   "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12525   "#"
12526   "&& reload_completed"
12527   [(const_int 0)]
12529   split_double_concat (<DWI>mode, operands[0], operands[1],
12530                        gen_lowpart (<MODE>mode, operands[2]));
12531   DONE;
12534 (define_insn_and_split "*concat<mode><dwi>3_3"
12535   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r,x")
12536         (any_or_plus:<DWI>
12537           (ashift:<DWI>
12538             (zero_extend:<DWI>
12539               (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m,x"))
12540             (match_operand:QI 2 "const_int_operand"))
12541           (zero_extend:<DWI>
12542             (match_operand:DWIH 3 "nonimmediate_operand" "r,r,m,m,0"))))]
12543   "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12544   "#"
12545   "&& reload_completed"
12546   [(const_int 0)]
12548   if (SSE_REG_P (operands[0]))
12549     {
12550       rtx tmp = gen_rtx_REG (V2DImode, REGNO (operands[0]));
12551       emit_insn (gen_vec_concatv2di (tmp, operands[3], operands[1]));
12552     }
12553   else
12554     split_double_concat (<DWI>mode, operands[0], operands[3], operands[1]);
12555   DONE;
12557   [(set_attr "isa" "*,*,*,x64,x64")])
12559 (define_insn_and_split "*concat<mode><dwi>3_4"
12560   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
12561         (any_or_plus:<DWI>
12562           (zero_extend:<DWI>
12563             (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
12564           (ashift:<DWI>
12565             (zero_extend:<DWI>
12566               (match_operand:DWIH 2 "nonimmediate_operand" "r,r,m,m"))
12567             (match_operand:QI 3 "const_int_operand"))))]
12568   "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12569   "#"
12570   "&& reload_completed"
12571   [(const_int 0)]
12573   split_double_concat (<DWI>mode, operands[0], operands[1], operands[2]);
12574   DONE;
12576   [(set_attr "isa" "*,*,*,x64")])
12578 (define_insn_and_split "*concat<half><mode>3_5"
12579   [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o,o")
12580         (any_or_plus:DWI
12581           (ashift:DWI (match_operand:DWI 1 "register_operand" "r,r,r")
12582                       (match_operand:QI 2 "const_int_operand"))
12583           (match_operand:DWI 3 "const_scalar_int_operand" "n,n,Wd")))]
12584   "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT / 2
12585    && (<MODE>mode == DImode
12586        ? CONST_INT_P (operands[3])
12587          && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12588        : CONST_INT_P (operands[3])
12589        ? INTVAL (operands[3]) >= 0
12590        : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12591          && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12592    && !(CONST_INT_P (operands[3])
12593         ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12594         : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12595                                                                      0)),
12596                                         VOIDmode))"
12597   "#"
12598   "&& reload_completed"
12599   [(const_int 0)]
12601   rtx op3 = simplify_subreg (<HALF>mode, operands[3], <MODE>mode, 0);
12602   split_double_concat (<MODE>mode, operands[0], op3,
12603                        gen_lowpart (<HALF>mode, operands[1]));
12604   DONE;
12606   [(set_attr "isa" "*,nox64,x64")])
12608 (define_insn_and_split "*concat<mode><dwi>3_6"
12609   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12610         (any_or_plus:<DWI>
12611           (ashift:<DWI>
12612             (zero_extend:<DWI>
12613               (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12614             (match_operand:QI 2 "const_int_operand"))
12615           (match_operand:<DWI> 3 "const_scalar_int_operand" "n,n,Wd,n")))]
12616   "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT
12617    && (<DWI>mode == DImode
12618        ? CONST_INT_P (operands[3])
12619          && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12620        : CONST_INT_P (operands[3])
12621        ? INTVAL (operands[3]) >= 0
12622        : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12623          && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12624    && !(CONST_INT_P (operands[3])
12625         ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12626         : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12627                                                                      0)),
12628                                         VOIDmode))"
12629   "#"
12630   "&& reload_completed"
12631   [(const_int 0)]
12633   rtx op3 = simplify_subreg (<MODE>mode, operands[3], <DWI>mode, 0);
12634   split_double_concat (<DWI>mode, operands[0], op3, operands[1]);
12635   DONE;
12637   [(set_attr "isa" "*,nox64,x64,*")])
12639 (define_insn_and_split "*concat<mode><dwi>3_7"
12640   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12641         (any_or_plus:<DWI>
12642           (zero_extend:<DWI>
12643             (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12644           (match_operand:<DWI> 2 "const_scalar_int_operand" "n,n,Wd,n")))]
12645   "<DWI>mode == DImode
12646    ? CONST_INT_P (operands[2])
12647      && (UINTVAL (operands[2]) & GET_MODE_MASK (SImode)) == 0
12648      && !ix86_endbr_immediate_operand (operands[2], VOIDmode)
12649    : CONST_WIDE_INT_P (operands[2])
12650      && CONST_WIDE_INT_NUNITS (operands[2]) == 2
12651      && CONST_WIDE_INT_ELT (operands[2], 0) == 0
12652      && !ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[2],
12653                                                                     1)),
12654                                        VOIDmode)"
12655   "#"
12656   "&& reload_completed"
12657   [(const_int 0)]
12659   rtx op2;
12660   if (<DWI>mode == DImode)
12661     op2 = gen_int_mode (INTVAL (operands[2]) >> 32, <MODE>mode);
12662   else
12663     op2 = gen_int_mode (CONST_WIDE_INT_ELT (operands[2], 1), <MODE>mode);
12664   split_double_concat (<DWI>mode, operands[0], operands[1], op2);
12665   DONE;
12667   [(set_attr "isa" "*,nox64,x64,*")])
12669 ;; Negation instructions
12671 (define_expand "neg<mode>2"
12672   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12673         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
12674   ""
12675   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
12677 (define_insn_and_split "*neg<dwi>2_doubleword"
12678   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
12679         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
12680    (clobber (reg:CC FLAGS_REG))]
12681   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
12682   "#"
12683   "&& reload_completed"
12684   [(parallel
12685     [(set (reg:CCC FLAGS_REG)
12686           (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12687      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
12688    (parallel
12689     [(set (match_dup 2)
12690           (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12691                                 (match_dup 3))
12692                      (const_int 0)))
12693      (clobber (reg:CC FLAGS_REG))])
12694    (parallel
12695     [(set (match_dup 2)
12696           (neg:DWIH (match_dup 2)))
12697      (clobber (reg:CC FLAGS_REG))])]
12698   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
12700 ;; Convert:
12701 ;;   mov %esi, %edx
12702 ;;   negl %eax
12703 ;;   adcl $0, %edx
12704 ;;   negl %edx
12705 ;; to:
12706 ;;   xorl %edx, %edx
12707 ;;   negl %eax
12708 ;;   sbbl %esi, %edx
12710 (define_peephole2
12711   [(set (match_operand:SWI48 0 "general_reg_operand")
12712         (match_operand:SWI48 1 "nonimmediate_gr_operand"))
12713    (parallel
12714     [(set (reg:CCC FLAGS_REG)
12715           (unspec:CCC [(match_operand:SWI48 2 "general_reg_operand")
12716                        (const_int 0)] UNSPEC_CC_NE))
12717      (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12718    (parallel
12719     [(set (match_dup 0)
12720           (plus:SWI48 (plus:SWI48
12721                         (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12722                         (match_dup 0))
12723                       (const_int 0)))
12724      (clobber (reg:CC FLAGS_REG))])
12725    (parallel
12726     [(set (match_dup 0)
12727           (neg:SWI48 (match_dup 0)))
12728      (clobber (reg:CC FLAGS_REG))])]
12729   "REGNO (operands[0]) != REGNO (operands[2])
12730    && !reg_mentioned_p (operands[0], operands[1])
12731    && !reg_mentioned_p (operands[2], operands[1])"
12732   [(parallel
12733     [(set (reg:CCC FLAGS_REG)
12734           (unspec:CCC [(match_dup 2) (const_int 0)] UNSPEC_CC_NE))
12735      (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12736    (parallel
12737     [(set (match_dup 0)
12738           (minus:SWI48 (minus:SWI48
12739                          (match_dup 0)
12740                          (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0)))
12741                        (match_dup 1)))
12742      (clobber (reg:CC FLAGS_REG))])]
12743   "ix86_expand_clear (operands[0]);")
12745 ;; Convert:
12746 ;;   xorl %edx, %edx
12747 ;;   negl %eax
12748 ;;   adcl $0, %edx
12749 ;;   negl %edx
12750 ;; to:
12751 ;;   negl %eax
12752 ;;   sbbl %edx, %edx    // *x86_mov<mode>cc_0_m1
12754 (define_peephole2
12755   [(parallel
12756     [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
12757      (clobber (reg:CC FLAGS_REG))])
12758    (parallel
12759     [(set (reg:CCC FLAGS_REG)
12760           (unspec:CCC [(match_operand:SWI48 1 "general_reg_operand")
12761                        (const_int 0)] UNSPEC_CC_NE))
12762      (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12763    (parallel
12764     [(set (match_dup 0)
12765           (plus:SWI48 (plus:SWI48
12766                         (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12767                         (match_dup 0))
12768                       (const_int 0)))
12769      (clobber (reg:CC FLAGS_REG))])
12770    (parallel
12771     [(set (match_dup 0)
12772           (neg:SWI48 (match_dup 0)))
12773      (clobber (reg:CC FLAGS_REG))])]
12774   "REGNO (operands[0]) != REGNO (operands[1])"
12775   [(parallel
12776     [(set (reg:CCC FLAGS_REG)
12777           (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12778      (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12779    (parallel
12780     [(set (match_dup 0)
12781           (if_then_else:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12782                               (const_int -1)
12783                               (const_int 0)))
12784      (clobber (reg:CC FLAGS_REG))])])
12786 (define_insn "*neg<mode>_1"
12787   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12788         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
12789    (clobber (reg:CC FLAGS_REG))]
12790   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12791   "neg{<imodesuffix>}\t%0"
12792   [(set_attr "type" "negnot")
12793    (set_attr "mode" "<MODE>")])
12795 (define_insn "*negsi_1_zext"
12796   [(set (match_operand:DI 0 "register_operand" "=r")
12797         (zero_extend:DI
12798           (neg:SI (match_operand:SI 1 "register_operand" "0"))))
12799    (clobber (reg:CC FLAGS_REG))]
12800   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
12801   "neg{l}\t%k0"
12802   [(set_attr "type" "negnot")
12803    (set_attr "mode" "SI")])
12805 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12806 (define_insn_and_split "*neg<mode>_1_slp"
12807   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
12808         (neg:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))
12809    (clobber (reg:CC FLAGS_REG))]
12810   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12811   "@
12812    neg{<imodesuffix>}\t%0
12813    #"
12814   "&& reload_completed"
12815   [(set (strict_low_part (match_dup 0)) (match_dup 1))
12816    (parallel
12817      [(set (strict_low_part (match_dup 0))
12818            (neg:SWI12 (match_dup 0)))
12819       (clobber (reg:CC FLAGS_REG))])]
12820   ""
12821   [(set_attr "type" "negnot")
12822    (set_attr "mode" "<MODE>")])
12824 (define_insn "*neg<mode>_2"
12825   [(set (reg FLAGS_REG)
12826         (compare
12827           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
12828           (const_int 0)))
12829    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12830         (neg:SWI (match_dup 1)))]
12831   "ix86_match_ccmode (insn, CCGOCmode)
12832    && ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12833   "neg{<imodesuffix>}\t%0"
12834   [(set_attr "type" "negnot")
12835    (set_attr "mode" "<MODE>")])
12837 (define_insn "*negsi_2_zext"
12838   [(set (reg FLAGS_REG)
12839         (compare
12840           (neg:SI (match_operand:SI 1 "register_operand" "0"))
12841           (const_int 0)))
12842    (set (match_operand:DI 0 "register_operand" "=r")
12843         (zero_extend:DI
12844           (neg:SI (match_dup 1))))]
12845   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12846    && ix86_unary_operator_ok (NEG, SImode, operands)"
12847   "neg{l}\t%k0"
12848   [(set_attr "type" "negnot")
12849    (set_attr "mode" "SI")])
12851 (define_insn "*neg<mode>_ccc_1"
12852   [(set (reg:CCC FLAGS_REG)
12853         (unspec:CCC
12854           [(match_operand:SWI 1 "nonimmediate_operand" "0")
12855            (const_int 0)] UNSPEC_CC_NE))
12856    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12857         (neg:SWI (match_dup 1)))]
12858   ""
12859   "neg{<imodesuffix>}\t%0"
12860   [(set_attr "type" "negnot")
12861    (set_attr "mode" "<MODE>")])
12863 (define_insn "*neg<mode>_ccc_2"
12864   [(set (reg:CCC FLAGS_REG)
12865         (unspec:CCC
12866           [(match_operand:SWI 1 "nonimmediate_operand" "0")
12867            (const_int 0)] UNSPEC_CC_NE))
12868    (clobber (match_scratch:SWI 0 "=<r>"))]
12869   ""
12870   "neg{<imodesuffix>}\t%0"
12871   [(set_attr "type" "negnot")
12872    (set_attr "mode" "<MODE>")])
12874 (define_expand "x86_neg<mode>_ccc"
12875   [(parallel
12876     [(set (reg:CCC FLAGS_REG)
12877           (unspec:CCC [(match_operand:SWI48 1 "register_operand")
12878                        (const_int 0)] UNSPEC_CC_NE))
12879      (set (match_operand:SWI48 0 "register_operand")
12880           (neg:SWI48 (match_dup 1)))])])
12882 (define_insn "*negqi_ext<mode>_2"
12883   [(set (zero_extract:SWI248
12884           (match_operand 0 "int248_register_operand" "+Q")
12885           (const_int 8)
12886           (const_int 8))
12887         (subreg:SWI248
12888           (neg:QI
12889             (subreg:QI
12890               (match_operator:SWI248 2 "extract_operator"
12891                 [(match_operand 1 "int248_register_operand" "0")
12892                  (const_int 8)
12893                  (const_int 8)]) 0)) 0))
12894    (clobber (reg:CC FLAGS_REG))]
12895   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
12896    rtx_equal_p (operands[0], operands[1])"
12897   "neg{b}\t%h0"
12898   [(set_attr "type" "negnot")
12899    (set_attr "mode" "QI")])
12901 ;; Negate with jump on overflow.
12902 (define_expand "negv<mode>3"
12903   [(parallel [(set (reg:CCO FLAGS_REG)
12904                    (unspec:CCO
12905                      [(match_operand:SWI 1 "register_operand")
12906                       (match_dup 3)] UNSPEC_CC_NE))
12907               (set (match_operand:SWI 0 "register_operand")
12908                    (neg:SWI (match_dup 1)))])
12909    (set (pc) (if_then_else
12910                (eq (reg:CCO FLAGS_REG) (const_int 0))
12911                (label_ref (match_operand 2))
12912                (pc)))]
12913   ""
12915   operands[3]
12916     = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
12917                     <MODE>mode);
12920 (define_insn "*negv<mode>3"
12921   [(set (reg:CCO FLAGS_REG)
12922         (unspec:CCO [(match_operand:SWI 1 "nonimmediate_operand" "0")
12923                      (match_operand:SWI 2 "const_int_operand")]
12924                     UNSPEC_CC_NE))
12925    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12926         (neg:SWI (match_dup 1)))]
12927   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
12928    && mode_signbit_p (<MODE>mode, operands[2])"
12929   "neg{<imodesuffix>}\t%0"
12930   [(set_attr "type" "negnot")
12931    (set_attr "mode" "<MODE>")])
12933 ;; Optimize *negsi_1 followed by *cmpsi_ccno_1 (PR target/91384)
12934 (define_peephole2
12935   [(set (match_operand:SWI 0 "general_reg_operand")
12936         (match_operand:SWI 1 "general_reg_operand"))
12937    (parallel [(set (match_dup 0) (neg:SWI (match_dup 0)))
12938               (clobber (reg:CC FLAGS_REG))])
12939    (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))]
12940   ""
12941   [(set (match_dup 0) (match_dup 1))
12942    (parallel [(set (reg:CCZ FLAGS_REG)
12943                    (compare:CCZ (neg:SWI (match_dup 0)) (const_int 0)))
12944               (set (match_dup 0) (neg:SWI (match_dup 0)))])])
12946 ;; Special expand pattern to handle integer mode abs
12948 (define_expand "abs<mode>2"
12949   [(parallel
12950     [(set (match_operand:SDWIM 0 "register_operand")
12951           (abs:SDWIM
12952             (match_operand:SDWIM 1 "general_operand")))
12953      (clobber (reg:CC FLAGS_REG))])]
12954   "TARGET_CMOVE
12955    && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)"
12957   if (TARGET_EXPAND_ABS)
12958     {
12959       machine_mode mode = <MODE>mode;
12960       operands[1] = force_reg (mode, operands[1]);
12962       /* Generate rtx abs using:
12963          abs (x) = (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)) */
12965       rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
12966       rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
12967                                            shift_amount, NULL_RTX,
12968                                            0, OPTAB_DIRECT);
12969       rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
12970                                          operands[0], 0, OPTAB_DIRECT);
12971       rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
12972                                            operands[0], 0, OPTAB_DIRECT);
12973       if (!rtx_equal_p (minus_dst, operands[0]))
12974         emit_move_insn (operands[0], minus_dst);
12975       DONE;
12976     }
12979 (define_insn_and_split "*abs<dwi>2_doubleword"
12980   [(set (match_operand:<DWI> 0 "register_operand")
12981         (abs:<DWI>
12982           (match_operand:<DWI> 1 "general_operand")))
12983    (clobber (reg:CC FLAGS_REG))]
12984   "TARGET_CMOVE
12985    && ix86_pre_reload_split ()"
12986    "#"
12987    "&& 1"
12988   [(parallel
12989     [(set (reg:CCC FLAGS_REG)
12990           (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12991      (set (match_dup 2) (neg:DWIH (match_dup 1)))])
12992    (parallel
12993     [(set (match_dup 5)
12994           (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12995                                 (match_dup 4))
12996                      (const_int 0)))
12997      (clobber (reg:CC FLAGS_REG))])
12998    (parallel
12999      [(set (reg:CCGOC FLAGS_REG)
13000            (compare:CCGOC
13001              (neg:DWIH (match_dup 5))
13002              (const_int 0)))
13003       (set (match_dup 5)
13004            (neg:DWIH (match_dup 5)))])
13005    (set (match_dup 0)
13006         (if_then_else:DWIH
13007           (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13008           (match_dup 2)
13009           (match_dup 1)))
13010    (set (match_dup 3)
13011         (if_then_else:DWIH
13012           (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13013           (match_dup 5)
13014           (match_dup 4)))]
13016   operands[1] = force_reg (<DWI>mode, operands[1]);
13017   operands[2] = gen_reg_rtx (<DWI>mode);
13019   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13022 (define_insn_and_split "*nabs<dwi>2_doubleword"
13023   [(set (match_operand:<DWI> 0 "register_operand")
13024         (neg:<DWI>
13025           (abs:<DWI>
13026             (match_operand:<DWI> 1 "general_operand"))))
13027    (clobber (reg:CC FLAGS_REG))]
13028   "TARGET_CMOVE
13029    && ix86_pre_reload_split ()"
13030    "#"
13031    "&& 1"
13032   [(parallel
13033     [(set (reg:CCC FLAGS_REG)
13034           (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13035      (set (match_dup 2) (neg:DWIH (match_dup 1)))])
13036    (parallel
13037     [(set (match_dup 5)
13038           (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
13039                                 (match_dup 4))
13040                      (const_int 0)))
13041      (clobber (reg:CC FLAGS_REG))])
13042    (parallel
13043      [(set (reg:CCGOC FLAGS_REG)
13044            (compare:CCGOC
13045              (neg:DWIH (match_dup 5))
13046              (const_int 0)))
13047       (set (match_dup 5)
13048            (neg:DWIH (match_dup 5)))])
13049    (set (match_dup 0)
13050         (if_then_else:DWIH
13051           (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13052           (match_dup 2)
13053           (match_dup 1)))
13054    (set (match_dup 3)
13055         (if_then_else:DWIH
13056           (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13057           (match_dup 5)
13058           (match_dup 4)))]
13060   operands[1] = force_reg (<DWI>mode, operands[1]);
13061   operands[2] = gen_reg_rtx (<DWI>mode);
13063   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13066 (define_insn_and_split "*abs<mode>2_1"
13067   [(set (match_operand:SWI 0 "register_operand")
13068         (abs:SWI
13069           (match_operand:SWI 1 "general_operand")))
13070    (clobber (reg:CC FLAGS_REG))]
13071   "TARGET_CMOVE
13072    && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
13073    && ix86_pre_reload_split ()"
13074    "#"
13075    "&& 1"
13076   [(parallel
13077      [(set (reg:CCGOC FLAGS_REG)
13078            (compare:CCGOC
13079              (neg:SWI (match_dup 1))
13080              (const_int 0)))
13081       (set (match_dup 2)
13082            (neg:SWI (match_dup 1)))])
13083    (set (match_dup 0)
13084         (if_then_else:SWI
13085           (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13086           (match_dup 2)
13087           (match_dup 1)))]
13089   operands[1] = force_reg (<MODE>mode, operands[1]);
13090   operands[2] = gen_reg_rtx (<MODE>mode);
13093 (define_insn_and_split "*nabs<mode>2_1"
13094   [(set (match_operand:SWI 0 "register_operand")
13095         (neg:SWI
13096           (abs:SWI
13097             (match_operand:SWI 1 "general_operand"))))
13098    (clobber (reg:CC FLAGS_REG))]
13099   "TARGET_CMOVE
13100    && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
13101    && ix86_pre_reload_split ()"
13102    "#"
13103    "&& 1"
13104   [(parallel
13105      [(set (reg:CCGOC FLAGS_REG)
13106            (compare:CCGOC
13107              (neg:SWI (match_dup 1))
13108              (const_int 0)))
13109       (set (match_dup 2)
13110            (neg:SWI (match_dup 1)))])
13111    (set (match_dup 0)
13112         (if_then_else:SWI
13113           (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13114           (match_dup 2)
13115           (match_dup 1)))]
13117   operands[1] = force_reg (<MODE>mode, operands[1]);
13118   operands[2] = gen_reg_rtx (<MODE>mode);
13121 (define_expand "<code>tf2"
13122   [(set (match_operand:TF 0 "register_operand")
13123         (absneg:TF (match_operand:TF 1 "register_operand")))]
13124   "TARGET_SSE"
13125   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
13127 (define_insn_and_split "*<code>tf2_1"
13128   [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13129         (absneg:TF
13130           (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
13131    (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13132   "TARGET_SSE"
13133   "#"
13134   "&& reload_completed"
13135   [(set (match_dup 0)
13136         (<absneg_op>:TF (match_dup 1) (match_dup 2)))]
13138   if (TARGET_AVX)
13139     {
13140       if (MEM_P (operands[1]))
13141         std::swap (operands[1], operands[2]);
13142     }
13143   else
13144    {
13145      if (operands_match_p (operands[0], operands[2]))
13146        std::swap (operands[1], operands[2]);
13147    }
13149   [(set_attr "isa" "noavx,noavx,avx,avx")])
13151 (define_insn_and_split "*nabstf2_1"
13152   [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13153         (neg:TF
13154           (abs:TF
13155             (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
13156    (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13157   "TARGET_SSE"
13158   "#"
13159   "&& reload_completed"
13160   [(set (match_dup 0)
13161         (ior:TF (match_dup 1) (match_dup 2)))]
13163   if (TARGET_AVX)
13164     {
13165       if (MEM_P (operands[1]))
13166         std::swap (operands[1], operands[2]);
13167     }
13168   else
13169    {
13170      if (operands_match_p (operands[0], operands[2]))
13171        std::swap (operands[1], operands[2]);
13172    }
13174   [(set_attr "isa" "noavx,noavx,avx,avx")])
13176 (define_expand "<code>hf2"
13177   [(set (match_operand:HF 0 "register_operand")
13178         (absneg:HF (match_operand:HF 1 "register_operand")))]
13179   "TARGET_AVX512FP16"
13180   "ix86_expand_fp_absneg_operator (<CODE>, HFmode, operands); DONE;")
13182 (define_expand "<code><mode>2"
13183   [(set (match_operand:X87MODEF 0 "register_operand")
13184         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
13185   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13186   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13188 ;; Changing of sign for FP values is doable using integer unit too.
13189 (define_insn "*<code><mode>2_i387_1"
13190   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
13191         (absneg:X87MODEF
13192           (match_operand:X87MODEF 1 "register_operand" "0,0")))
13193    (clobber (reg:CC FLAGS_REG))]
13194   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13195   "#")
13197 (define_split
13198   [(set (match_operand:X87MODEF 0 "fp_register_operand")
13199         (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
13200    (clobber (reg:CC FLAGS_REG))]
13201   "TARGET_80387 && reload_completed"
13202   [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
13204 (define_split
13205   [(set (match_operand:X87MODEF 0 "general_reg_operand")
13206         (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
13207    (clobber (reg:CC FLAGS_REG))]
13208   "TARGET_80387 && reload_completed"
13209   [(const_int 0)]
13210   "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13212 (define_insn_and_split "*<code>hf2_1"
13213   [(set (match_operand:HF 0 "register_operand" "=Yv")
13214         (absneg:HF
13215           (match_operand:HF 1 "register_operand" "Yv")))
13216    (use (match_operand:V8HF 2 "vector_operand" "Yvm"))
13217    (clobber (reg:CC FLAGS_REG))]
13218   "TARGET_AVX512FP16"
13219   "#"
13220   "&& reload_completed"
13221   [(set (match_dup 0)
13222         (<absneg_op>:V8HF (match_dup 1) (match_dup 2)))]
13224   operands[0] = lowpart_subreg (V8HFmode, operands[0], HFmode);
13225   operands[1] = lowpart_subreg (V8HFmode, operands[1], HFmode);
13228 (define_insn "*<code><mode>2_1"
13229   [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
13230         (absneg:MODEF
13231           (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
13232    (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
13233    (clobber (reg:CC FLAGS_REG))]
13234   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13235   "#"
13236   [(set_attr "isa" "noavx,noavx,avx,*,*")
13237    (set (attr "enabled")
13238      (if_then_else
13239        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
13240        (if_then_else
13241          (eq_attr "alternative" "3,4")
13242          (symbol_ref "TARGET_MIX_SSE_I387")
13243          (const_string "*"))
13244        (if_then_else
13245          (eq_attr "alternative" "3,4")
13246          (symbol_ref "true")
13247          (symbol_ref "false"))))])
13249 (define_split
13250   [(set (match_operand:MODEF 0 "sse_reg_operand")
13251         (absneg:MODEF
13252           (match_operand:MODEF 1 "sse_reg_operand")))
13253    (use (match_operand:<ssevecmodef> 2 "vector_operand"))
13254    (clobber (reg:CC FLAGS_REG))]
13255   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13256    && reload_completed"
13257   [(set (match_dup 0)
13258         (<absneg_op>:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13260   machine_mode mode = <MODE>mode;
13261   machine_mode vmode = <ssevecmodef>mode;
13263   operands[0] = lowpart_subreg (vmode, operands[0], mode);
13264   operands[1] = lowpart_subreg (vmode, operands[1], mode);
13266   if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13267     std::swap (operands[1], operands[2]);
13270 (define_split
13271   [(set (match_operand:MODEF 0 "fp_register_operand")
13272         (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
13273    (use (match_operand 2))
13274    (clobber (reg:CC FLAGS_REG))]
13275   "TARGET_80387 && reload_completed"
13276   [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
13278 (define_split
13279   [(set (match_operand:MODEF 0 "general_reg_operand")
13280         (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
13281    (use (match_operand 2))
13282    (clobber (reg:CC FLAGS_REG))]
13283   "TARGET_80387 && reload_completed"
13284   [(const_int 0)]
13285   "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13287 (define_insn_and_split "*nabs<mode>2_1"
13288   [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
13289         (neg:MODEF
13290           (abs:MODEF
13291             (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
13292    (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
13293   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13294   "#"
13295   "&& reload_completed"
13296   [(set (match_dup 0)
13297         (ior:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13299   machine_mode mode = <MODE>mode;
13300   machine_mode vmode = <ssevecmodef>mode;
13302   operands[0] = lowpart_subreg (vmode, operands[0], mode);
13303   operands[1] = lowpart_subreg (vmode, operands[1], mode);
13305   if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13306     std::swap (operands[1], operands[2]);
13308   [(set_attr "isa" "noavx,noavx,avx")])
13310 ;; Conditionalize these after reload. If they match before reload, we
13311 ;; lose the clobber and ability to use integer instructions.
13313 (define_insn "*<code><mode>2_i387"
13314   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
13315         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
13316   "TARGET_80387 && reload_completed"
13317   "<absneg_mnemonic>"
13318   [(set_attr "type" "fsgn")
13319    (set_attr "mode" "<MODE>")])
13321 ;; Copysign instructions
13323 (define_expand "copysign<mode>3"
13324   [(match_operand:SSEMODEF 0 "register_operand")
13325    (match_operand:SSEMODEF 1 "nonmemory_operand")
13326    (match_operand:SSEMODEF 2 "register_operand")]
13327   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13328    || (TARGET_SSE && (<MODE>mode == TFmode))
13329    || (TARGET_AVX512FP16 && (<MODE>mode ==HFmode))"
13330   "ix86_expand_copysign (operands); DONE;")
13332 (define_expand "xorsign<mode>3"
13333   [(match_operand:MODEFH 0 "register_operand")
13334    (match_operand:MODEFH 1 "register_operand")
13335    (match_operand:MODEFH 2 "register_operand")]
13336   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13337   || <MODE>mode == HFmode"
13339   if (rtx_equal_p (operands[1], operands[2]))
13340     emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
13341   else
13342     ix86_expand_xorsign (operands);
13343   DONE;
13346 ;; One complement instructions
13348 (define_expand "one_cmpl<mode>2"
13349   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
13350         (not:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
13351   ""
13352   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
13354 (define_insn_and_split "*one_cmpl<dwi>2_doubleword"
13355   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
13356         (not:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))]
13357   "ix86_unary_operator_ok (NOT, <DWI>mode, operands)"
13358   "#"
13359   "&& reload_completed"
13360   [(set (match_dup 0)
13361         (not:DWIH (match_dup 1)))
13362    (set (match_dup 2)
13363         (not:DWIH (match_dup 3)))]
13364   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
13366 (define_insn "*one_cmpl<mode>2_1"
13367   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,?k")
13368         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,k")))]
13369   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13370   "@
13371    not{<imodesuffix>}\t%0
13372    #"
13373   [(set_attr "isa" "*,<kmov_isa>")
13374    (set_attr "type" "negnot,msklog")
13375    (set_attr "mode" "<MODE>")])
13377 (define_insn "*one_cmplsi2_1_zext"
13378   [(set (match_operand:DI 0 "register_operand" "=r,?k")
13379         (zero_extend:DI
13380           (not:SI (match_operand:SI 1 "register_operand" "0,k"))))]
13381   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
13382   "@
13383    not{l}\t%k0
13384    #"
13385   [(set_attr "isa" "x64,avx512bw_512")
13386    (set_attr "type" "negnot,msklog")
13387    (set_attr "mode" "SI,SI")])
13389 (define_insn "*one_cmplqi2_1"
13390   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,?k")
13391         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
13392   "ix86_unary_operator_ok (NOT, QImode, operands)"
13393   "@
13394    not{b}\t%0
13395    not{l}\t%k0
13396    #"
13397   [(set_attr "isa" "*,*,avx512f")
13398    (set_attr "type" "negnot,negnot,msklog")
13399    (set (attr "mode")
13400         (cond [(eq_attr "alternative" "1")
13401                  (const_string "SI")
13402                 (and (eq_attr "alternative" "2")
13403                      (match_test "!TARGET_AVX512DQ"))
13404                  (const_string "HI")
13405                ]
13406                (const_string "QI")))
13407    ;; Potential partial reg stall on alternative 1.
13408    (set (attr "preferred_for_speed")
13409      (cond [(eq_attr "alternative" "1")
13410               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
13411            (symbol_ref "true")))])
13413 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13414 (define_insn_and_split "*one_cmpl<mode>_1_slp"
13415   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
13416         (not:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))]
13417   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
13418   "@
13419    not{<imodesuffix>}\t%0
13420    #"
13421   "&& reload_completed"
13422   [(set (strict_low_part (match_dup 0)) (match_dup 1))
13423    (set (strict_low_part (match_dup 0))
13424         (not:SWI12 (match_dup 0)))]
13425   ""
13426   [(set_attr "type" "negnot")
13427    (set_attr "mode" "<MODE>")])
13429 (define_insn "*one_cmpl<mode>2_2"
13430   [(set (reg FLAGS_REG)
13431         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
13432                  (const_int 0)))
13433    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13434         (not:SWI (match_dup 1)))]
13435   "ix86_match_ccmode (insn, CCNOmode)
13436    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13437   "#"
13438   [(set_attr "type" "alu1")
13439    (set_attr "mode" "<MODE>")])
13441 (define_split
13442   [(set (match_operand 0 "flags_reg_operand")
13443         (match_operator 2 "compare_operator"
13444           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
13445            (const_int 0)]))
13446    (set (match_operand:SWI 1 "nonimmediate_operand")
13447         (not:SWI (match_dup 3)))]
13448   "ix86_match_ccmode (insn, CCNOmode)"
13449   [(parallel [(set (match_dup 0)
13450                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
13451                                     (const_int 0)]))
13452               (set (match_dup 1)
13453                    (xor:SWI (match_dup 3) (const_int -1)))])])
13455 (define_insn "*one_cmplsi2_2_zext"
13456   [(set (reg FLAGS_REG)
13457         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
13458                  (const_int 0)))
13459    (set (match_operand:DI 0 "register_operand" "=r")
13460         (zero_extend:DI (not:SI (match_dup 1))))]
13461   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
13462    && ix86_unary_operator_ok (NOT, SImode, operands)"
13463   "#"
13464   [(set_attr "type" "alu1")
13465    (set_attr "mode" "SI")])
13467 (define_split
13468   [(set (match_operand 0 "flags_reg_operand")
13469         (match_operator 2 "compare_operator"
13470           [(not:SI (match_operand:SI 3 "register_operand"))
13471            (const_int 0)]))
13472    (set (match_operand:DI 1 "register_operand")
13473         (zero_extend:DI (not:SI (match_dup 3))))]
13474   "ix86_match_ccmode (insn, CCNOmode)"
13475   [(parallel [(set (match_dup 0)
13476                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
13477                                     (const_int 0)]))
13478               (set (match_dup 1)
13479                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
13481 ;; Shift instructions
13483 ;; DImode shifts are implemented using the i386 "shift double" opcode,
13484 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
13485 ;; is variable, then the count is in %cl and the "imm" operand is dropped
13486 ;; from the assembler input.
13488 ;; This instruction shifts the target reg/mem as usual, but instead of
13489 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
13490 ;; is a left shift double, bits are taken from the high order bits of
13491 ;; reg, else if the insn is a shift right double, bits are taken from the
13492 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
13493 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
13495 ;; Since sh[lr]d does not change the `reg' operand, that is done
13496 ;; separately, making all shifts emit pairs of shift double and normal
13497 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
13498 ;; support a 63 bit shift, each shift where the count is in a reg expands
13499 ;; to a pair of shifts, a branch, a shift by 32 and a label.
13501 ;; If the shift count is a constant, we need never emit more than one
13502 ;; shift pair, instead using moves and sign extension for counts greater
13503 ;; than 31.
13505 (define_expand "ashl<mode>3"
13506   [(set (match_operand:SDWIM 0 "<shift_operand>")
13507         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
13508                       (match_operand:QI 2 "nonmemory_operand")))]
13509   ""
13510   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
13512 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
13513   [(set (match_operand:<DWI> 0 "register_operand")
13514         (ashift:<DWI>
13515           (match_operand:<DWI> 1 "register_operand")
13516           (subreg:QI
13517             (and
13518               (match_operand 2 "int248_register_operand" "c")
13519               (match_operand 3 "const_int_operand")) 0)))
13520    (clobber (reg:CC FLAGS_REG))]
13521   "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13522     || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13523          == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13524    && ix86_pre_reload_split ()"
13525   "#"
13526   "&& 1"
13527   [(parallel
13528      [(set (match_dup 6)
13529            (ior:DWIH (ashift:DWIH (match_dup 6)
13530                        (and:QI (match_dup 2) (match_dup 8)))
13531                      (subreg:DWIH
13532                        (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13533                          (minus:QI (match_dup 9)
13534                                    (and:QI (match_dup 2) (match_dup 8)))) 0)))
13535       (clobber (reg:CC FLAGS_REG))])
13536    (parallel
13537      [(set (match_dup 4)
13538            (ashift:DWIH (match_dup 5) (match_dup 2)))
13539       (clobber (reg:CC FLAGS_REG))])]
13541   if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13542     {
13543       operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13544       operands[2] = gen_lowpart (QImode, operands[2]);
13545       emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13546                                             operands[2]));
13547       DONE;
13548     }
13550   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13552   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13553   operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13555   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13556       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13557     {
13558       rtx xops[3];
13559       xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
13560       xops[1] = operands[2];
13561       xops[2] = GEN_INT (INTVAL (operands[3])
13562                          & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
13563       ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
13564       operands[2] = xops[0];
13565     }
13567   operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13568   operands[2] = gen_lowpart (QImode, operands[2]);
13570   if (!rtx_equal_p (operands[6], operands[7]))
13571     emit_move_insn (operands[6], operands[7]);
13574 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
13575   [(set (match_operand:<DWI> 0 "register_operand")
13576         (ashift:<DWI>
13577           (match_operand:<DWI> 1 "register_operand")
13578           (and:QI
13579             (match_operand:QI 2 "register_operand" "c")
13580             (match_operand:QI 3 "const_int_operand"))))
13581    (clobber (reg:CC FLAGS_REG))]
13582   "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13583     || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13584          == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13585    && ix86_pre_reload_split ()"
13586   "#"
13587   "&& 1"
13588   [(parallel
13589      [(set (match_dup 6)
13590            (ior:DWIH (ashift:DWIH (match_dup 6)
13591                        (and:QI (match_dup 2) (match_dup 8)))
13592                      (subreg:DWIH
13593                        (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13594                          (minus:QI (match_dup 9)
13595                                    (and:QI (match_dup 2) (match_dup 8)))) 0)))
13596       (clobber (reg:CC FLAGS_REG))])
13597    (parallel
13598      [(set (match_dup 4)
13599            (ashift:DWIH (match_dup 5) (match_dup 2)))
13600       (clobber (reg:CC FLAGS_REG))])]
13602   if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13603     {
13604       emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13605                                             operands[2]));
13606       DONE;
13607     }
13609   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13611   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13612   operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13614   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13615       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13616     {
13617       rtx tem = gen_reg_rtx (QImode);
13618       emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
13619       operands[2] = tem;
13620     }
13622   if (!rtx_equal_p (operands[6], operands[7]))
13623     emit_move_insn (operands[6], operands[7]);
13626 (define_insn "ashl<mode>3_doubleword"
13627   [(set (match_operand:DWI 0 "register_operand" "=&r")
13628         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
13629                     (match_operand:QI 2 "nonmemory_operand" "<S>c")))
13630    (clobber (reg:CC FLAGS_REG))]
13631   ""
13632   "#"
13633   [(set_attr "type" "multi")])
13635 (define_split
13636   [(set (match_operand:DWI 0 "register_operand")
13637         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
13638                     (match_operand:QI 2 "nonmemory_operand")))
13639    (clobber (reg:CC FLAGS_REG))]
13640   "epilogue_completed"
13641   [(const_int 0)]
13642   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
13644 ;; By default we don't ask for a scratch register, because when DWImode
13645 ;; values are manipulated, registers are already at a premium.  But if
13646 ;; we have one handy, we won't turn it away.
13648 (define_peephole2
13649   [(match_scratch:DWIH 3 "r")
13650    (parallel [(set (match_operand:<DWI> 0 "register_operand")
13651                    (ashift:<DWI>
13652                      (match_operand:<DWI> 1 "nonmemory_operand")
13653                      (match_operand:QI 2 "nonmemory_operand")))
13654               (clobber (reg:CC FLAGS_REG))])
13655    (match_dup 3)]
13656   "TARGET_CMOVE"
13657   [(const_int 0)]
13658   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
13660 (define_insn_and_split "*ashl<dwi>3_doubleword_highpart"
13661   [(set (match_operand:<DWI> 0 "register_operand" "=r")
13662         (ashift:<DWI>
13663           (any_extend:<DWI> (match_operand:DWIH 1 "nonimmediate_operand" "rm"))
13664           (match_operand:QI 2 "const_int_operand")))
13665    (clobber (reg:CC FLAGS_REG))]
13666   "INTVAL (operands[2]) >= <MODE_SIZE> * BITS_PER_UNIT
13667    && INTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT * 2"
13668   "#"
13669   "&& reload_completed"
13670   [(const_int 0)]
13672   split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[3]);
13673   int bits = INTVAL (operands[2]) - (<MODE_SIZE> * BITS_PER_UNIT);
13674   if (!rtx_equal_p (operands[3], operands[1]))
13675     emit_move_insn (operands[3], operands[1]);
13676   if (bits > 0)
13677     emit_insn (gen_ashl<mode>3 (operands[3], operands[3], GEN_INT (bits)));
13678   ix86_expand_clear (operands[0]);
13679   DONE;
13682 (define_insn "x86_64_shld"
13683   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13684         (ior:DI (ashift:DI (match_dup 0)
13685                   (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
13686                           (const_int 63)))
13687                 (subreg:DI
13688                   (lshiftrt:TI
13689                     (zero_extend:TI
13690                       (match_operand:DI 1 "register_operand" "r"))
13691                     (minus:QI (const_int 64)
13692                               (and:QI (match_dup 2) (const_int 63)))) 0)))
13693    (clobber (reg:CC FLAGS_REG))]
13694   "TARGET_64BIT"
13695   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
13696   [(set_attr "type" "ishift")
13697    (set_attr "prefix_0f" "1")
13698    (set_attr "mode" "DI")
13699    (set_attr "athlon_decode" "vector")
13700    (set_attr "amdfam10_decode" "vector")
13701    (set_attr "bdver1_decode" "vector")])
13703 (define_insn "x86_64_shld_1"
13704   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13705         (ior:DI (ashift:DI (match_dup 0)
13706                            (match_operand:QI 2 "const_0_to_63_operand"))
13707                 (subreg:DI
13708                   (lshiftrt:TI
13709                     (zero_extend:TI
13710                       (match_operand:DI 1 "register_operand" "r"))
13711                     (match_operand:QI 3 "const_0_to_255_operand")) 0)))
13712    (clobber (reg:CC FLAGS_REG))]
13713   "TARGET_64BIT
13714    && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
13715   "shld{q}\t{%2, %1, %0|%0, %1, %2}"
13716   [(set_attr "type" "ishift")
13717    (set_attr "prefix_0f" "1")
13718    (set_attr "mode" "DI")
13719    (set_attr "length_immediate" "1")
13720    (set_attr "athlon_decode" "vector")
13721    (set_attr "amdfam10_decode" "vector")
13722    (set_attr "bdver1_decode" "vector")])
13724 (define_insn_and_split "*x86_64_shld_shrd_1_nozext"
13725   [(set (match_operand:DI 0 "nonimmediate_operand")
13726         (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
13727                              (match_operand:QI 2 "const_0_to_63_operand"))
13728                 (lshiftrt:DI
13729                   (match_operand:DI 1 "nonimmediate_operand")
13730                   (match_operand:QI 3 "const_0_to_63_operand"))))
13731    (clobber (reg:CC FLAGS_REG))]
13732   "TARGET_64BIT
13733    && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
13734    && ix86_pre_reload_split ()"
13735   "#"
13736   "&& 1"
13737   [(const_int 0)]
13739   if (rtx_equal_p (operands[4], operands[0]))
13740     {
13741       operands[1] = force_reg (DImode, operands[1]);
13742       emit_insn (gen_x86_64_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13743     }
13744   else if (rtx_equal_p (operands[1], operands[0]))
13745     {
13746       operands[4] = force_reg (DImode, operands[4]);
13747       emit_insn (gen_x86_64_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13748     }
13749   else
13750    {
13751      operands[1] = force_reg (DImode, operands[1]);
13752      rtx tmp = gen_reg_rtx (DImode);
13753      emit_move_insn (tmp, operands[4]);
13754      emit_insn (gen_x86_64_shld_1 (tmp, operands[1], operands[2], operands[3]));
13755      emit_move_insn (operands[0], tmp);
13756    }
13757    DONE;
13760 (define_insn_and_split "*x86_64_shld_2"
13761   [(set (match_operand:DI 0 "nonimmediate_operand")
13762         (ior:DI (ashift:DI (match_dup 0)
13763                            (match_operand:QI 2 "nonmemory_operand"))
13764                 (lshiftrt:DI (match_operand:DI 1 "register_operand")
13765                              (minus:QI (const_int 64) (match_dup 2)))))
13766    (clobber (reg:CC FLAGS_REG))]
13767   "TARGET_64BIT && ix86_pre_reload_split ()"
13768   "#"
13769   "&& 1"
13770   [(parallel [(set (match_dup 0)
13771                    (ior:DI (ashift:DI (match_dup 0)
13772                                       (and:QI (match_dup 2) (const_int 63)))
13773                            (subreg:DI
13774                              (lshiftrt:TI
13775                                (zero_extend:TI (match_dup 1))
13776                                  (minus:QI (const_int 64)
13777                                            (and:QI (match_dup 2)
13778                                                    (const_int 63)))) 0)))
13779               (clobber (reg:CC FLAGS_REG))])])
13781 (define_insn "x86_shld"
13782   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13783         (ior:SI (ashift:SI (match_dup 0)
13784                   (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
13785                           (const_int 31)))
13786                 (subreg:SI
13787                   (lshiftrt:DI
13788                     (zero_extend:DI
13789                       (match_operand:SI 1 "register_operand" "r"))
13790                     (minus:QI (const_int 32)
13791                               (and:QI (match_dup 2) (const_int 31)))) 0)))
13792    (clobber (reg:CC FLAGS_REG))]
13793   ""
13794   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
13795   [(set_attr "type" "ishift")
13796    (set_attr "prefix_0f" "1")
13797    (set_attr "mode" "SI")
13798    (set_attr "pent_pair" "np")
13799    (set_attr "athlon_decode" "vector")
13800    (set_attr "amdfam10_decode" "vector")
13801    (set_attr "bdver1_decode" "vector")])
13803 (define_insn "x86_shld_1"
13804   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13805         (ior:SI (ashift:SI (match_dup 0)
13806                            (match_operand:QI 2 "const_0_to_31_operand"))
13807                 (subreg:SI
13808                   (lshiftrt:DI
13809                     (zero_extend:DI
13810                       (match_operand:SI 1 "register_operand" "r"))
13811                     (match_operand:QI 3 "const_0_to_63_operand")) 0)))
13812    (clobber (reg:CC FLAGS_REG))]
13813   "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
13814   "shld{l}\t{%2, %1, %0|%0, %1, %2}"
13815   [(set_attr "type" "ishift")
13816    (set_attr "prefix_0f" "1")
13817    (set_attr "length_immediate" "1")
13818    (set_attr "mode" "SI")
13819    (set_attr "pent_pair" "np")
13820    (set_attr "athlon_decode" "vector")
13821    (set_attr "amdfam10_decode" "vector")
13822    (set_attr "bdver1_decode" "vector")])
13824 (define_insn_and_split "*x86_shld_shrd_1_nozext"
13825   [(set (match_operand:SI 0 "nonimmediate_operand")
13826         (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
13827                              (match_operand:QI 2 "const_0_to_31_operand"))
13828                (lshiftrt:SI
13829                    (match_operand:SI 1 "nonimmediate_operand")
13830                    (match_operand:QI 3 "const_0_to_31_operand"))))
13831    (clobber (reg:CC FLAGS_REG))]
13832   "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
13833    && ix86_pre_reload_split ()"
13834   "#"
13835   "&& 1"
13836   [(const_int 0)]
13838   if (rtx_equal_p (operands[4], operands[0]))
13839     {
13840       operands[1] = force_reg (SImode, operands[1]);
13841       emit_insn (gen_x86_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13842     }
13843   else if (rtx_equal_p (operands[1], operands[0]))
13844     {
13845       operands[4] = force_reg (SImode, operands[4]);
13846       emit_insn (gen_x86_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13847     }
13848   else
13849    {
13850      operands[1] = force_reg (SImode, operands[1]);
13851      rtx tmp = gen_reg_rtx (SImode);
13852      emit_move_insn (tmp, operands[4]);
13853      emit_insn (gen_x86_shld_1 (tmp, operands[1], operands[2], operands[3]));
13854      emit_move_insn (operands[0], tmp);
13855    }
13856    DONE;
13859 (define_insn_and_split "*x86_shld_2"
13860   [(set (match_operand:SI 0 "nonimmediate_operand")
13861         (ior:SI (ashift:SI (match_dup 0)
13862                            (match_operand:QI 2 "nonmemory_operand"))
13863                 (lshiftrt:SI (match_operand:SI 1 "register_operand")
13864                              (minus:QI (const_int 32) (match_dup 2)))))
13865    (clobber (reg:CC FLAGS_REG))]
13866   "TARGET_64BIT && ix86_pre_reload_split ()"
13867   "#"
13868   "&& 1"
13869   [(parallel [(set (match_dup 0)
13870                    (ior:SI (ashift:SI (match_dup 0)
13871                                       (and:QI (match_dup 2) (const_int 31)))
13872                            (subreg:SI
13873                              (lshiftrt:DI
13874                                (zero_extend:DI (match_dup 1))
13875                                  (minus:QI (const_int 32)
13876                                            (and:QI (match_dup 2)
13877                                                    (const_int 31)))) 0)))
13878               (clobber (reg:CC FLAGS_REG))])])
13880 (define_expand "@x86_shift<mode>_adj_1"
13881   [(set (reg:CCZ FLAGS_REG)
13882         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
13883                              (match_dup 4))
13884                      (const_int 0)))
13885    (set (match_operand:SWI48 0 "register_operand")
13886         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
13887                             (match_operand:SWI48 1 "register_operand")
13888                             (match_dup 0)))
13889    (set (match_dup 1)
13890         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
13891                             (match_operand:SWI48 3 "register_operand")
13892                             (match_dup 1)))]
13893   "TARGET_CMOVE"
13894   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
13896 (define_expand "@x86_shift<mode>_adj_2"
13897   [(use (match_operand:SWI48 0 "register_operand"))
13898    (use (match_operand:SWI48 1 "register_operand"))
13899    (use (match_operand:QI 2 "register_operand"))]
13900   ""
13902   rtx_code_label *label = gen_label_rtx ();
13903   rtx tmp;
13905   emit_insn (gen_testqi_ccz_1 (operands[2],
13906                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
13908   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
13909   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
13910   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
13911                               gen_rtx_LABEL_REF (VOIDmode, label),
13912                               pc_rtx);
13913   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
13914   JUMP_LABEL (tmp) = label;
13916   emit_move_insn (operands[0], operands[1]);
13917   ix86_expand_clear (operands[1]);
13919   emit_label (label);
13920   LABEL_NUSES (label) = 1;
13922   DONE;
13925 ;; Avoid useless masking of count operand.
13926 (define_insn_and_split "*ashl<mode>3_mask"
13927   [(set (match_operand:SWI48 0 "nonimmediate_operand")
13928         (ashift:SWI48
13929           (match_operand:SWI48 1 "nonimmediate_operand")
13930           (subreg:QI
13931             (and
13932               (match_operand 2 "int248_register_operand" "c,r")
13933               (match_operand 3 "const_int_operand")) 0)))
13934    (clobber (reg:CC FLAGS_REG))]
13935   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
13936    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
13937       == GET_MODE_BITSIZE (<MODE>mode)-1
13938    && ix86_pre_reload_split ()"
13939   "#"
13940   "&& 1"
13941   [(parallel
13942      [(set (match_dup 0)
13943            (ashift:SWI48 (match_dup 1)
13944                          (match_dup 2)))
13945       (clobber (reg:CC FLAGS_REG))])]
13947   operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13948   operands[2] = gen_lowpart (QImode, operands[2]);
13950   [(set_attr "isa" "*,bmi2")])
13952 (define_insn_and_split "*ashl<mode>3_mask_1"
13953   [(set (match_operand:SWI48 0 "nonimmediate_operand")
13954         (ashift:SWI48
13955           (match_operand:SWI48 1 "nonimmediate_operand")
13956           (and:QI
13957             (match_operand:QI 2 "register_operand" "c,r")
13958             (match_operand:QI 3 "const_int_operand"))))
13959    (clobber (reg:CC FLAGS_REG))]
13960   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
13961    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
13962       == GET_MODE_BITSIZE (<MODE>mode)-1
13963    && ix86_pre_reload_split ()"
13964   "#"
13965   "&& 1"
13966   [(parallel
13967      [(set (match_dup 0)
13968            (ashift:SWI48 (match_dup 1)
13969                          (match_dup 2)))
13970       (clobber (reg:CC FLAGS_REG))])]
13971   ""
13972   [(set_attr "isa" "*,bmi2")])
13974 (define_insn "*bmi2_ashl<mode>3_1"
13975   [(set (match_operand:SWI48 0 "register_operand" "=r")
13976         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13977                       (match_operand:SWI48 2 "register_operand" "r")))]
13978   "TARGET_BMI2"
13979   "shlx\t{%2, %1, %0|%0, %1, %2}"
13980   [(set_attr "type" "ishiftx")
13981    (set_attr "mode" "<MODE>")])
13983 (define_insn "*ashl<mode>3_1"
13984   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,?k")
13985         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm,k")
13986                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r,<KS>")))
13987    (clobber (reg:CC FLAGS_REG))]
13988   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
13990   switch (get_attr_type (insn))
13991     {
13992     case TYPE_LEA:
13993     case TYPE_ISHIFTX:
13994     case TYPE_MSKLOG:
13995       return "#";
13997     case TYPE_ALU:
13998       gcc_assert (operands[2] == const1_rtx);
13999       gcc_assert (rtx_equal_p (operands[0], operands[1]));
14000       return "add{<imodesuffix>}\t%0, %0";
14002     default:
14003       if (operands[2] == const1_rtx
14004           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14005         return "sal{<imodesuffix>}\t%0";
14006       else
14007         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14008     }
14010   [(set_attr "isa" "*,*,bmi2,<kmov_isa>")
14011    (set (attr "type")
14012      (cond [(eq_attr "alternative" "1")
14013               (const_string "lea")
14014             (eq_attr "alternative" "2")
14015               (const_string "ishiftx")
14016             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14017                       (match_operand 0 "register_operand"))
14018                  (match_operand 2 "const1_operand"))
14019               (const_string "alu")
14020             (eq_attr "alternative" "3")
14021               (const_string "msklog")
14022            ]
14023            (const_string "ishift")))
14024    (set (attr "length_immediate")
14025      (if_then_else
14026        (ior (eq_attr "type" "alu")
14027             (and (eq_attr "type" "ishift")
14028                  (and (match_operand 2 "const1_operand")
14029                       (ior (match_test "TARGET_SHIFT1")
14030                            (match_test "optimize_function_for_size_p (cfun)")))))
14031        (const_string "0")
14032        (const_string "*")))
14033    (set_attr "mode" "<MODE>")])
14035 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14036 (define_split
14037   [(set (match_operand:SWI48 0 "register_operand")
14038         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
14039                       (match_operand:QI 2 "register_operand")))
14040    (clobber (reg:CC FLAGS_REG))]
14041   "TARGET_BMI2 && reload_completed"
14042   [(set (match_dup 0)
14043         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
14044   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
14046 (define_insn "*bmi2_ashlsi3_1_zext"
14047   [(set (match_operand:DI 0 "register_operand" "=r")
14048         (zero_extend:DI
14049           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
14050                      (match_operand:SI 2 "register_operand" "r"))))]
14051   "TARGET_64BIT && TARGET_BMI2"
14052   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
14053   [(set_attr "type" "ishiftx")
14054    (set_attr "mode" "SI")])
14056 (define_insn "*ashlsi3_1_zext"
14057   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
14058         (zero_extend:DI
14059           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
14060                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
14061    (clobber (reg:CC FLAGS_REG))]
14062   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14064   switch (get_attr_type (insn))
14065     {
14066     case TYPE_LEA:
14067     case TYPE_ISHIFTX:
14068       return "#";
14070     case TYPE_ALU:
14071       gcc_assert (operands[2] == const1_rtx);
14072       return "add{l}\t%k0, %k0";
14074     default:
14075       if (operands[2] == const1_rtx
14076           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14077         return "sal{l}\t%k0";
14078       else
14079         return "sal{l}\t{%2, %k0|%k0, %2}";
14080     }
14082   [(set_attr "isa" "*,*,bmi2")
14083    (set (attr "type")
14084      (cond [(eq_attr "alternative" "1")
14085               (const_string "lea")
14086             (eq_attr "alternative" "2")
14087               (const_string "ishiftx")
14088             (and (match_test "TARGET_DOUBLE_WITH_ADD")
14089                  (match_operand 2 "const1_operand"))
14090               (const_string "alu")
14091            ]
14092            (const_string "ishift")))
14093    (set (attr "length_immediate")
14094      (if_then_else
14095        (ior (eq_attr "type" "alu")
14096             (and (eq_attr "type" "ishift")
14097                  (and (match_operand 2 "const1_operand")
14098                       (ior (match_test "TARGET_SHIFT1")
14099                            (match_test "optimize_function_for_size_p (cfun)")))))
14100        (const_string "0")
14101        (const_string "*")))
14102    (set_attr "mode" "SI")])
14104 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14105 (define_split
14106   [(set (match_operand:DI 0 "register_operand")
14107         (zero_extend:DI
14108           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
14109                      (match_operand:QI 2 "register_operand"))))
14110    (clobber (reg:CC FLAGS_REG))]
14111   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
14112   [(set (match_dup 0)
14113         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14114   "operands[2] = gen_lowpart (SImode, operands[2]);")
14116 (define_insn "*ashlhi3_1"
14117   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp,?k")
14118         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l,k")
14119                    (match_operand:QI 2 "nonmemory_operand" "cI,M,Ww")))
14120    (clobber (reg:CC FLAGS_REG))]
14121   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
14123   switch (get_attr_type (insn))
14124     {
14125     case TYPE_LEA:
14126     case TYPE_MSKLOG:
14127       return "#";
14129     case TYPE_ALU:
14130       gcc_assert (operands[2] == const1_rtx);
14131       return "add{w}\t%0, %0";
14133     default:
14134       if (operands[2] == const1_rtx
14135           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14136         return "sal{w}\t%0";
14137       else
14138         return "sal{w}\t{%2, %0|%0, %2}";
14139     }
14141   [(set_attr "isa" "*,*,avx512f")
14142    (set (attr "type")
14143      (cond [(eq_attr "alternative" "1")
14144               (const_string "lea")
14145             (eq_attr "alternative" "2")
14146               (const_string "msklog")
14147             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14148                       (match_operand 0 "register_operand"))
14149                  (match_operand 2 "const1_operand"))
14150               (const_string "alu")
14151            ]
14152            (const_string "ishift")))
14153    (set (attr "length_immediate")
14154      (if_then_else
14155        (ior (eq_attr "type" "alu")
14156             (and (eq_attr "type" "ishift")
14157                  (and (match_operand 2 "const1_operand")
14158                       (ior (match_test "TARGET_SHIFT1")
14159                            (match_test "optimize_function_for_size_p (cfun)")))))
14160        (const_string "0")
14161        (const_string "*")))
14162    (set_attr "mode" "HI,SI,HI")])
14164 (define_insn "*ashlqi3_1"
14165   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp,?k")
14166         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l,k")
14167                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M,Wb")))
14168    (clobber (reg:CC FLAGS_REG))]
14169   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
14171   switch (get_attr_type (insn))
14172     {
14173     case TYPE_LEA:
14174     case TYPE_MSKLOG:
14175       return "#";
14177     case TYPE_ALU:
14178       gcc_assert (operands[2] == const1_rtx);
14179       if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
14180         return "add{l}\t%k0, %k0";
14181       else
14182         return "add{b}\t%0, %0";
14184     default:
14185       if (operands[2] == const1_rtx
14186           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14187         {
14188           if (get_attr_mode (insn) == MODE_SI)
14189             return "sal{l}\t%k0";
14190           else
14191             return "sal{b}\t%0";
14192         }
14193       else
14194         {
14195           if (get_attr_mode (insn) == MODE_SI)
14196             return "sal{l}\t{%2, %k0|%k0, %2}";
14197           else
14198             return "sal{b}\t{%2, %0|%0, %2}";
14199         }
14200     }
14202   [(set_attr "isa" "*,*,*,avx512dq")
14203    (set (attr "type")
14204      (cond [(eq_attr "alternative" "2")
14205               (const_string "lea")
14206             (eq_attr "alternative" "3")
14207               (const_string "msklog")
14208             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14209                       (match_operand 0 "register_operand"))
14210                  (match_operand 2 "const1_operand"))
14211               (const_string "alu")
14212            ]
14213            (const_string "ishift")))
14214    (set (attr "length_immediate")
14215      (if_then_else
14216        (ior (eq_attr "type" "alu")
14217             (and (eq_attr "type" "ishift")
14218                  (and (match_operand 2 "const1_operand")
14219                       (ior (match_test "TARGET_SHIFT1")
14220                            (match_test "optimize_function_for_size_p (cfun)")))))
14221        (const_string "0")
14222        (const_string "*")))
14223    (set_attr "mode" "QI,SI,SI,QI")
14224    ;; Potential partial reg stall on alternative 1.
14225    (set (attr "preferred_for_speed")
14226      (cond [(eq_attr "alternative" "1")
14227               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
14228            (symbol_ref "true")))])
14230 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14231 (define_insn_and_split "*ashl<mode>3_1_slp"
14232   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
14233         (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
14234                       (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
14235    (clobber (reg:CC FLAGS_REG))]
14236   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
14238   if (which_alternative)
14239     return "#";
14241   switch (get_attr_type (insn))
14242     {
14243     case TYPE_ALU:
14244       gcc_assert (operands[2] == const1_rtx);
14245       return "add{<imodesuffix>}\t%0, %0";
14247     default:
14248       if (operands[2] == const1_rtx
14249           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14250         return "sal{<imodesuffix>}\t%0";
14251       else
14252         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14253     }
14255   "&& reload_completed"
14256   [(set (strict_low_part (match_dup 0)) (match_dup 1))
14257    (parallel
14258      [(set (strict_low_part (match_dup 0))
14259            (ashift:SWI12 (match_dup 0) (match_dup 2)))
14260       (clobber (reg:CC FLAGS_REG))])]
14261   ""
14262   [(set (attr "type")
14263      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14264                  (match_operand 2 "const1_operand"))
14265               (const_string "alu")
14266            ]
14267            (const_string "ishift")))
14268    (set (attr "length_immediate")
14269      (if_then_else
14270        (ior (eq_attr "type" "alu")
14271             (and (eq_attr "type" "ishift")
14272                  (and (match_operand 2 "const1_operand")
14273                       (ior (match_test "TARGET_SHIFT1")
14274                            (match_test "optimize_function_for_size_p (cfun)")))))
14275        (const_string "0")
14276        (const_string "*")))
14277    (set_attr "mode" "<MODE>")])
14279 ;; Convert ashift to the lea pattern to avoid flags dependency.
14280 (define_split
14281   [(set (match_operand:SWI 0 "general_reg_operand")
14282         (ashift:SWI (match_operand:SWI 1 "index_reg_operand")
14283                     (match_operand 2 "const_0_to_3_operand")))
14284    (clobber (reg:CC FLAGS_REG))]
14285   "reload_completed
14286    && REGNO (operands[0]) != REGNO (operands[1])"
14287   [(set (match_dup 0)
14288         (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
14290   if (<MODE>mode != <LEAMODE>mode)
14291     {
14292       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
14293       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
14294     }
14295   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14298 ;; Convert ashift to the lea pattern to avoid flags dependency.
14299 (define_split
14300   [(set (match_operand:DI 0 "general_reg_operand")
14301         (zero_extend:DI
14302           (ashift:SI (match_operand:SI 1 "index_reg_operand")
14303                      (match_operand 2 "const_0_to_3_operand"))))
14304    (clobber (reg:CC FLAGS_REG))]
14305   "TARGET_64BIT && reload_completed
14306    && REGNO (operands[0]) != REGNO (operands[1])"
14307   [(set (match_dup 0)
14308         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
14310   operands[1] = gen_lowpart (SImode, operands[1]);
14311   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14314 ;; This pattern can't accept a variable shift count, since shifts by
14315 ;; zero don't affect the flags.  We assume that shifts by constant
14316 ;; zero are optimized away.
14317 (define_insn "*ashl<mode>3_cmp"
14318   [(set (reg FLAGS_REG)
14319         (compare
14320           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
14321                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14322           (const_int 0)))
14323    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
14324         (ashift:SWI (match_dup 1) (match_dup 2)))]
14325   "(optimize_function_for_size_p (cfun)
14326     || !TARGET_PARTIAL_FLAG_REG_STALL
14327     || (operands[2] == const1_rtx
14328         && (TARGET_SHIFT1
14329             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
14330    && ix86_match_ccmode (insn, CCGOCmode)
14331    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
14333   switch (get_attr_type (insn))
14334     {
14335     case TYPE_ALU:
14336       gcc_assert (operands[2] == const1_rtx);
14337       return "add{<imodesuffix>}\t%0, %0";
14339     default:
14340       if (operands[2] == const1_rtx
14341           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14342         return "sal{<imodesuffix>}\t%0";
14343       else
14344         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14345     }
14347   [(set (attr "type")
14348      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14349                       (match_operand 0 "register_operand"))
14350                  (match_operand 2 "const1_operand"))
14351               (const_string "alu")
14352            ]
14353            (const_string "ishift")))
14354    (set (attr "length_immediate")
14355      (if_then_else
14356        (ior (eq_attr "type" "alu")
14357             (and (eq_attr "type" "ishift")
14358                  (and (match_operand 2 "const1_operand")
14359                       (ior (match_test "TARGET_SHIFT1")
14360                            (match_test "optimize_function_for_size_p (cfun)")))))
14361        (const_string "0")
14362        (const_string "*")))
14363    (set_attr "mode" "<MODE>")])
14365 (define_insn "*ashlsi3_cmp_zext"
14366   [(set (reg FLAGS_REG)
14367         (compare
14368           (ashift:SI (match_operand:SI 1 "register_operand" "0")
14369                      (match_operand:QI 2 "const_1_to_31_operand"))
14370           (const_int 0)))
14371    (set (match_operand:DI 0 "register_operand" "=r")
14372         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14373   "TARGET_64BIT
14374    && (optimize_function_for_size_p (cfun)
14375        || !TARGET_PARTIAL_FLAG_REG_STALL
14376        || (operands[2] == const1_rtx
14377            && (TARGET_SHIFT1
14378                || TARGET_DOUBLE_WITH_ADD)))
14379    && ix86_match_ccmode (insn, CCGOCmode)
14380    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14382   switch (get_attr_type (insn))
14383     {
14384     case TYPE_ALU:
14385       gcc_assert (operands[2] == const1_rtx);
14386       return "add{l}\t%k0, %k0";
14388     default:
14389       if (operands[2] == const1_rtx
14390           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14391         return "sal{l}\t%k0";
14392       else
14393         return "sal{l}\t{%2, %k0|%k0, %2}";
14394     }
14396   [(set (attr "type")
14397      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14398                  (match_operand 2 "const1_operand"))
14399               (const_string "alu")
14400            ]
14401            (const_string "ishift")))
14402    (set (attr "length_immediate")
14403      (if_then_else
14404        (ior (eq_attr "type" "alu")
14405             (and (eq_attr "type" "ishift")
14406                  (and (match_operand 2 "const1_operand")
14407                       (ior (match_test "TARGET_SHIFT1")
14408                            (match_test "optimize_function_for_size_p (cfun)")))))
14409        (const_string "0")
14410        (const_string "*")))
14411    (set_attr "mode" "SI")])
14413 (define_insn "*ashl<mode>3_cconly"
14414   [(set (reg FLAGS_REG)
14415         (compare
14416           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
14417                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14418           (const_int 0)))
14419    (clobber (match_scratch:SWI 0 "=<r>"))]
14420   "(optimize_function_for_size_p (cfun)
14421     || !TARGET_PARTIAL_FLAG_REG_STALL
14422     || (operands[2] == const1_rtx
14423         && (TARGET_SHIFT1
14424             || TARGET_DOUBLE_WITH_ADD)))
14425    && ix86_match_ccmode (insn, CCGOCmode)"
14427   switch (get_attr_type (insn))
14428     {
14429     case TYPE_ALU:
14430       gcc_assert (operands[2] == const1_rtx);
14431       return "add{<imodesuffix>}\t%0, %0";
14433     default:
14434       if (operands[2] == const1_rtx
14435           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14436         return "sal{<imodesuffix>}\t%0";
14437       else
14438         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14439     }
14441   [(set (attr "type")
14442      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14443                       (match_operand 0 "register_operand"))
14444                  (match_operand 2 "const1_operand"))
14445               (const_string "alu")
14446            ]
14447            (const_string "ishift")))
14448    (set (attr "length_immediate")
14449      (if_then_else
14450        (ior (eq_attr "type" "alu")
14451             (and (eq_attr "type" "ishift")
14452                  (and (match_operand 2 "const1_operand")
14453                       (ior (match_test "TARGET_SHIFT1")
14454                            (match_test "optimize_function_for_size_p (cfun)")))))
14455        (const_string "0")
14456        (const_string "*")))
14457    (set_attr "mode" "<MODE>")])
14459 (define_insn "*ashlqi_ext<mode>_2"
14460   [(set (zero_extract:SWI248
14461           (match_operand 0 "int248_register_operand" "+Q")
14462           (const_int 8)
14463           (const_int 8))
14464         (subreg:SWI248
14465           (ashift:QI
14466             (subreg:QI
14467               (match_operator:SWI248 3 "extract_operator"
14468                 [(match_operand 1 "int248_register_operand" "0")
14469                  (const_int 8)
14470                  (const_int 8)]) 0)
14471             (match_operand:QI 2 "nonmemory_operand" "cI")) 0))
14472   (clobber (reg:CC FLAGS_REG))]
14473   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
14474    rtx_equal_p (operands[0], operands[1])"
14476   switch (get_attr_type (insn))
14477     {
14478     case TYPE_ALU:
14479       gcc_assert (operands[2] == const1_rtx);
14480       return "add{b}\t%h0, %h0";
14482     default:
14483       if (operands[2] == const1_rtx
14484           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14485         return "sal{b}\t%h0";
14486       else
14487         return "sal{b}\t{%2, %h0|%h0, %2}";
14488     }
14490   [(set (attr "type")
14491      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14492                  (match_operand 2 "const1_operand"))
14493               (const_string "alu")
14494            ]
14495            (const_string "ishift")))
14496    (set (attr "length_immediate")
14497      (if_then_else
14498        (ior (eq_attr "type" "alu")
14499             (and (eq_attr "type" "ishift")
14500                  (and (match_operand 2 "const1_operand")
14501                       (ior (match_test "TARGET_SHIFT1")
14502                            (match_test "optimize_function_for_size_p (cfun)")))))
14503        (const_string "0")
14504        (const_string "*")))
14505    (set_attr "mode" "QI")])
14507 ;; See comment above `ashl<mode>3' about how this works.
14509 (define_expand "<insn><mode>3"
14510   [(set (match_operand:SDWIM 0 "<shift_operand>")
14511         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
14512                            (match_operand:QI 2 "nonmemory_operand")))]
14513   ""
14514   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
14516 ;; Avoid useless masking of count operand.
14517 (define_insn_and_split "*<insn><mode>3_mask"
14518   [(set (match_operand:SWI48 0 "nonimmediate_operand")
14519         (any_shiftrt:SWI48
14520           (match_operand:SWI48 1 "nonimmediate_operand")
14521           (subreg:QI
14522             (and
14523               (match_operand 2 "int248_register_operand" "c,r")
14524               (match_operand 3 "const_int_operand")) 0)))
14525    (clobber (reg:CC FLAGS_REG))]
14526   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14527    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14528       == GET_MODE_BITSIZE (<MODE>mode)-1
14529    && ix86_pre_reload_split ()"
14530   "#"
14531   "&& 1"
14532   [(parallel
14533      [(set (match_dup 0)
14534            (any_shiftrt:SWI48 (match_dup 1)
14535                               (match_dup 2)))
14536       (clobber (reg:CC FLAGS_REG))])]
14538   operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14539   operands[2] = gen_lowpart (QImode, operands[2]);
14541   [(set_attr "isa" "*,bmi2")])
14543 (define_insn_and_split "*<insn><mode>3_mask_1"
14544   [(set (match_operand:SWI48 0 "nonimmediate_operand")
14545         (any_shiftrt:SWI48
14546           (match_operand:SWI48 1 "nonimmediate_operand")
14547           (and:QI
14548             (match_operand:QI 2 "register_operand" "c,r")
14549             (match_operand:QI 3 "const_int_operand"))))
14550    (clobber (reg:CC FLAGS_REG))]
14551   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14552    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14553       == GET_MODE_BITSIZE (<MODE>mode)-1
14554    && ix86_pre_reload_split ()"
14555   "#"
14556   "&& 1"
14557   [(parallel
14558      [(set (match_dup 0)
14559            (any_shiftrt:SWI48 (match_dup 1)
14560                               (match_dup 2)))
14561       (clobber (reg:CC FLAGS_REG))])]
14562   ""
14563   [(set_attr "isa" "*,bmi2")])
14565 (define_insn_and_split "*<insn><dwi>3_doubleword_mask"
14566   [(set (match_operand:<DWI> 0 "register_operand")
14567         (any_shiftrt:<DWI>
14568           (match_operand:<DWI> 1 "register_operand")
14569           (subreg:QI
14570             (and
14571               (match_operand 2 "int248_register_operand" "c")
14572               (match_operand 3 "const_int_operand")) 0)))
14573    (clobber (reg:CC FLAGS_REG))]
14574   "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14575     || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14576          == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14577    && ix86_pre_reload_split ()"
14578   "#"
14579   "&& 1"
14580   [(parallel
14581      [(set (match_dup 4)
14582            (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14583                        (and:QI (match_dup 2) (match_dup 8)))
14584                      (subreg:DWIH
14585                        (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14586                          (minus:QI (match_dup 9)
14587                                    (and:QI (match_dup 2) (match_dup 8)))) 0)))
14588       (clobber (reg:CC FLAGS_REG))])
14589    (parallel
14590      [(set (match_dup 6)
14591            (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14592       (clobber (reg:CC FLAGS_REG))])]
14594   if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14595     {
14596       operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14597       operands[2] = gen_lowpart (QImode, operands[2]);
14598       emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14599                                               operands[2]));
14600       DONE;
14601     }
14603   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14605   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14606   operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14608   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14609       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14610     {
14611       rtx xops[3];
14612       xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
14613       xops[1] = operands[2];
14614       xops[2] = GEN_INT (INTVAL (operands[3])
14615                          & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
14616       ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
14617       operands[2] = xops[0];
14618     }
14620   operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14621   operands[2] = gen_lowpart (QImode, operands[2]);
14623   if (!rtx_equal_p (operands[4], operands[5]))
14624     emit_move_insn (operands[4], operands[5]);
14627 (define_insn_and_split "*<insn><dwi>3_doubleword_mask_1"
14628   [(set (match_operand:<DWI> 0 "register_operand")
14629         (any_shiftrt:<DWI>
14630           (match_operand:<DWI> 1 "register_operand")
14631           (and:QI
14632             (match_operand:QI 2 "register_operand" "c")
14633             (match_operand:QI 3 "const_int_operand"))))
14634    (clobber (reg:CC FLAGS_REG))]
14635   "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14636     || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14637          == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14638    && ix86_pre_reload_split ()"
14639   "#"
14640   "&& 1"
14641   [(parallel
14642      [(set (match_dup 4)
14643            (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14644                        (and:QI (match_dup 2) (match_dup 8)))
14645                      (subreg:DWIH
14646                        (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14647                          (minus:QI (match_dup 9)
14648                                    (and:QI (match_dup 2) (match_dup 8)))) 0)))
14649       (clobber (reg:CC FLAGS_REG))])
14650    (parallel
14651      [(set (match_dup 6)
14652            (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14653       (clobber (reg:CC FLAGS_REG))])]
14655   if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14656     {
14657       emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14658                                               operands[2]));
14659       DONE;
14660     }
14662   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14664   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14665   operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14667   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14668       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14669     {
14670       rtx tem = gen_reg_rtx (QImode);
14671       emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
14672       operands[2] = tem;
14673     }
14675   if (!rtx_equal_p (operands[4], operands[5]))
14676     emit_move_insn (operands[4], operands[5]);
14679 (define_insn_and_split "<insn><mode>3_doubleword"
14680   [(set (match_operand:DWI 0 "register_operand" "=&r")
14681         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
14682                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
14683    (clobber (reg:CC FLAGS_REG))]
14684   ""
14685   "#"
14686   "epilogue_completed"
14687   [(const_int 0)]
14688   "ix86_split_<insn> (operands, NULL_RTX, <MODE>mode); DONE;"
14689   [(set_attr "type" "multi")])
14691 ;; By default we don't ask for a scratch register, because when DWImode
14692 ;; values are manipulated, registers are already at a premium.  But if
14693 ;; we have one handy, we won't turn it away.
14695 (define_peephole2
14696   [(match_scratch:DWIH 3 "r")
14697    (parallel [(set (match_operand:<DWI> 0 "register_operand")
14698                    (any_shiftrt:<DWI>
14699                      (match_operand:<DWI> 1 "register_operand")
14700                      (match_operand:QI 2 "nonmemory_operand")))
14701               (clobber (reg:CC FLAGS_REG))])
14702    (match_dup 3)]
14703   "TARGET_CMOVE"
14704   [(const_int 0)]
14705   "ix86_split_<insn> (operands, operands[3], <DWI>mode); DONE;")
14707 (define_insn "x86_64_shrd"
14708   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14709         (ior:DI (lshiftrt:DI (match_dup 0)
14710                   (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
14711                           (const_int 63)))
14712                 (subreg:DI
14713                   (ashift:TI
14714                     (zero_extend:TI
14715                       (match_operand:DI 1 "register_operand" "r"))
14716                     (minus:QI (const_int 64)
14717                               (and:QI (match_dup 2) (const_int 63)))) 0)))
14718    (clobber (reg:CC FLAGS_REG))]
14719   "TARGET_64BIT"
14720   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
14721   [(set_attr "type" "ishift")
14722    (set_attr "prefix_0f" "1")
14723    (set_attr "mode" "DI")
14724    (set_attr "athlon_decode" "vector")
14725    (set_attr "amdfam10_decode" "vector")
14726    (set_attr "bdver1_decode" "vector")])
14728 (define_insn "x86_64_shrd_1"
14729   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14730         (ior:DI (lshiftrt:DI (match_dup 0)
14731                              (match_operand:QI 2 "const_0_to_63_operand"))
14732                 (subreg:DI
14733                   (ashift:TI
14734                     (zero_extend:TI
14735                       (match_operand:DI 1 "register_operand" "r"))
14736                     (match_operand:QI 3 "const_0_to_255_operand")) 0)))
14737    (clobber (reg:CC FLAGS_REG))]
14738   "TARGET_64BIT
14739    && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
14740   "shrd{q}\t{%2, %1, %0|%0, %1, %2}"
14741   [(set_attr "type" "ishift")
14742    (set_attr "prefix_0f" "1")
14743    (set_attr "length_immediate" "1")
14744    (set_attr "mode" "DI")
14745    (set_attr "athlon_decode" "vector")
14746    (set_attr "amdfam10_decode" "vector")
14747    (set_attr "bdver1_decode" "vector")])
14749 (define_insn_and_split "*x86_64_shrd_shld_1_nozext"
14750   [(set (match_operand:DI 0 "nonimmediate_operand")
14751         (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
14752                              (match_operand:QI 2 "const_0_to_63_operand"))
14753                 (ashift:DI
14754                   (match_operand:DI 1 "nonimmediate_operand")
14755                   (match_operand:QI 3 "const_0_to_63_operand"))))
14756    (clobber (reg:CC FLAGS_REG))]
14757   "TARGET_64BIT
14758    && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
14759    && ix86_pre_reload_split ()"
14760   "#"
14761   "&& 1"
14762   [(const_int 0)]
14764   if (rtx_equal_p (operands[4], operands[0]))
14765     {
14766       operands[1] = force_reg (DImode, operands[1]);
14767       emit_insn (gen_x86_64_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14768     }
14769   else if (rtx_equal_p (operands[1], operands[0]))
14770     {
14771       operands[4] = force_reg (DImode, operands[4]);
14772       emit_insn (gen_x86_64_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14773     }
14774   else
14775    {
14776      operands[1] = force_reg (DImode, operands[1]);
14777      rtx tmp = gen_reg_rtx (DImode);
14778      emit_move_insn (tmp, operands[4]);
14779      emit_insn (gen_x86_64_shrd_1 (tmp, operands[1], operands[2], operands[3]));
14780      emit_move_insn (operands[0], tmp);
14781    }
14782    DONE;
14785 (define_insn_and_split "*x86_64_shrd_2"
14786   [(set (match_operand:DI 0 "nonimmediate_operand")
14787         (ior:DI (lshiftrt:DI (match_dup 0)
14788                              (match_operand:QI 2 "nonmemory_operand"))
14789                 (ashift:DI (match_operand:DI 1 "register_operand")
14790                            (minus:QI (const_int 64) (match_dup 2)))))
14791    (clobber (reg:CC FLAGS_REG))]
14792   "TARGET_64BIT && ix86_pre_reload_split ()"
14793   "#"
14794   "&& 1"
14795   [(parallel [(set (match_dup 0)
14796                    (ior:DI (lshiftrt:DI (match_dup 0)
14797                                         (and:QI (match_dup 2) (const_int 63)))
14798                            (subreg:DI
14799                              (ashift:TI
14800                                (zero_extend:TI (match_dup 1))
14801                                  (minus:QI (const_int 64)
14802                                            (and:QI (match_dup 2)
14803                                                    (const_int 63)))) 0)))
14804               (clobber (reg:CC FLAGS_REG))])])
14806 (define_insn "x86_shrd"
14807   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14808         (ior:SI (lshiftrt:SI (match_dup 0)
14809                   (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
14810                           (const_int 31)))
14811                 (subreg:SI
14812                   (ashift:DI
14813                     (zero_extend:DI
14814                       (match_operand:SI 1 "register_operand" "r"))
14815                     (minus:QI (const_int 32)
14816                               (and:QI (match_dup 2) (const_int 31)))) 0)))
14817    (clobber (reg:CC FLAGS_REG))]
14818   ""
14819   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
14820   [(set_attr "type" "ishift")
14821    (set_attr "prefix_0f" "1")
14822    (set_attr "mode" "SI")
14823    (set_attr "pent_pair" "np")
14824    (set_attr "athlon_decode" "vector")
14825    (set_attr "amdfam10_decode" "vector")
14826    (set_attr "bdver1_decode" "vector")])
14828 (define_insn "x86_shrd_1"
14829   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14830         (ior:SI (lshiftrt:SI (match_dup 0)
14831                              (match_operand:QI 2 "const_0_to_31_operand"))
14832                 (subreg:SI
14833                   (ashift:DI
14834                     (zero_extend:DI
14835                       (match_operand:SI 1 "register_operand" "r"))
14836                     (match_operand:QI 3 "const_0_to_63_operand")) 0)))
14837    (clobber (reg:CC FLAGS_REG))]
14838   "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
14839   "shrd{l}\t{%2, %1, %0|%0, %1, %2}"
14840   [(set_attr "type" "ishift")
14841    (set_attr "prefix_0f" "1")
14842    (set_attr "length_immediate" "1")
14843    (set_attr "mode" "SI")
14844    (set_attr "pent_pair" "np")
14845    (set_attr "athlon_decode" "vector")
14846    (set_attr "amdfam10_decode" "vector")
14847    (set_attr "bdver1_decode" "vector")])
14849 (define_insn_and_split "*x86_shrd_shld_1_nozext"
14850   [(set (match_operand:SI 0 "nonimmediate_operand")
14851         (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
14852                              (match_operand:QI 2 "const_0_to_31_operand"))
14853                (ashift:SI
14854                    (match_operand:SI 1 "nonimmediate_operand")
14855                    (match_operand:QI 3 "const_0_to_31_operand"))))
14856    (clobber (reg:CC FLAGS_REG))]
14857   "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
14858    && ix86_pre_reload_split ()"
14859   "#"
14860   "&& 1"
14861   [(const_int 0)]
14863   if (rtx_equal_p (operands[4], operands[0]))
14864     {
14865       operands[1] = force_reg (SImode, operands[1]);
14866       emit_insn (gen_x86_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14867     }
14868   else if (rtx_equal_p (operands[1], operands[0]))
14869     {
14870       operands[4] = force_reg (SImode, operands[4]);
14871       emit_insn (gen_x86_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14872     }
14873   else
14874    {
14875      operands[1] = force_reg (SImode, operands[1]);
14876      rtx tmp = gen_reg_rtx (SImode);
14877      emit_move_insn (tmp, operands[4]);
14878      emit_insn (gen_x86_shrd_1 (tmp, operands[1], operands[2], operands[3]));
14879      emit_move_insn (operands[0], tmp);
14880    }
14881    DONE;
14884 (define_insn_and_split "*x86_shrd_2"
14885   [(set (match_operand:SI 0 "nonimmediate_operand")
14886         (ior:SI (lshiftrt:SI (match_dup 0)
14887                              (match_operand:QI 2 "nonmemory_operand"))
14888                 (ashift:SI (match_operand:SI 1 "register_operand")
14889                            (minus:QI (const_int 32) (match_dup 2)))))
14890    (clobber (reg:CC FLAGS_REG))]
14891   "TARGET_64BIT && ix86_pre_reload_split ()"
14892   "#"
14893   "&& 1"
14894   [(parallel [(set (match_dup 0)
14895                    (ior:SI (lshiftrt:SI (match_dup 0)
14896                                         (and:QI (match_dup 2) (const_int 31)))
14897                            (subreg:SI
14898                              (ashift:DI
14899                                (zero_extend:DI (match_dup 1))
14900                                  (minus:QI (const_int 32)
14901                                            (and:QI (match_dup 2)
14902                                                    (const_int 31)))) 0)))
14903               (clobber (reg:CC FLAGS_REG))])])
14905 ;; Base name for insn mnemonic.
14906 (define_mode_attr cvt_mnemonic
14907   [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
14909 (define_insn "ashr<mode>3_cvt"
14910   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
14911         (ashiftrt:SWI48
14912           (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
14913           (match_operand:QI 2 "const_int_operand")))
14914    (clobber (reg:CC FLAGS_REG))]
14915   "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
14916    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
14917    && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
14918   "@
14919    <cvt_mnemonic>
14920    sar{<imodesuffix>}\t{%2, %0|%0, %2}"
14921   [(set_attr "type" "imovx,ishift")
14922    (set_attr "prefix_0f" "0,*")
14923    (set_attr "length_immediate" "0,*")
14924    (set_attr "modrm" "0,1")
14925    (set_attr "mode" "<MODE>")])
14927 (define_insn "*ashrsi3_cvt_zext"
14928   [(set (match_operand:DI 0 "register_operand" "=*d,r")
14929         (zero_extend:DI
14930           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
14931                        (match_operand:QI 2 "const_int_operand"))))
14932    (clobber (reg:CC FLAGS_REG))]
14933   "TARGET_64BIT && INTVAL (operands[2]) == 31
14934    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
14935    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
14936   "@
14937    {cltd|cdq}
14938    sar{l}\t{%2, %k0|%k0, %2}"
14939   [(set_attr "type" "imovx,ishift")
14940    (set_attr "prefix_0f" "0,*")
14941    (set_attr "length_immediate" "0,*")
14942    (set_attr "modrm" "0,1")
14943    (set_attr "mode" "SI")])
14945 (define_expand "@x86_shift<mode>_adj_3"
14946   [(use (match_operand:SWI48 0 "register_operand"))
14947    (use (match_operand:SWI48 1 "register_operand"))
14948    (use (match_operand:QI 2 "register_operand"))]
14949   ""
14951   rtx_code_label *label = gen_label_rtx ();
14952   rtx tmp;
14954   emit_insn (gen_testqi_ccz_1 (operands[2],
14955                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
14957   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
14958   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
14959   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
14960                               gen_rtx_LABEL_REF (VOIDmode, label),
14961                               pc_rtx);
14962   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
14963   JUMP_LABEL (tmp) = label;
14965   emit_move_insn (operands[0], operands[1]);
14966   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
14967                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
14968   emit_label (label);
14969   LABEL_NUSES (label) = 1;
14971   DONE;
14974 (define_insn "*bmi2_<insn><mode>3_1"
14975   [(set (match_operand:SWI48 0 "register_operand" "=r")
14976         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14977                            (match_operand:SWI48 2 "register_operand" "r")))]
14978   "TARGET_BMI2"
14979   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
14980   [(set_attr "type" "ishiftx")
14981    (set_attr "mode" "<MODE>")])
14983 (define_insn "*ashr<mode>3_1"
14984   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
14985         (ashiftrt:SWI48
14986           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
14987           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
14988    (clobber (reg:CC FLAGS_REG))]
14989   "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
14991   switch (get_attr_type (insn))
14992     {
14993     case TYPE_ISHIFTX:
14994       return "#";
14996     default:
14997       if (operands[2] == const1_rtx
14998           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14999         return "sar{<imodesuffix>}\t%0";
15000       else
15001         return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
15002     }
15004   [(set_attr "isa" "*,bmi2")
15005    (set_attr "type" "ishift,ishiftx")
15006    (set (attr "length_immediate")
15007      (if_then_else
15008        (and (match_operand 2 "const1_operand")
15009             (ior (match_test "TARGET_SHIFT1")
15010                  (match_test "optimize_function_for_size_p (cfun)")))
15011        (const_string "0")
15012        (const_string "*")))
15013    (set_attr "mode" "<MODE>")])
15015 ;; Specialization of *lshr<mode>3_1 below, extracting the SImode
15016 ;; highpart of a DI to be extracted, but allowing it to be clobbered.
15017 (define_insn_and_split "*highpartdisi2"
15018   [(set (subreg:DI (match_operand:SI 0 "register_operand" "=r,x,?k") 0)
15019         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,k")
15020                      (const_int 32)))
15021    (clobber (reg:CC FLAGS_REG))]
15022   "TARGET_64BIT"
15023   "#"
15024   "&& reload_completed"
15025   [(parallel
15026     [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 32)))
15027      (clobber (reg:CC FLAGS_REG))])]
15029   if (SSE_REG_P (operands[0]))
15030     {
15031       rtx tmp = gen_rtx_REG (V4SImode, REGNO (operands[0]));
15032       emit_insn (gen_sse_shufps_v4si (tmp, tmp, tmp,
15033                                       const1_rtx, const1_rtx,
15034                                       GEN_INT (5), GEN_INT (5)));
15035       DONE;
15036     }
15037   operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
15040 (define_insn "*lshr<mode>3_1"
15041   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,?k")
15042         (lshiftrt:SWI48
15043           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,k")
15044           (match_operand:QI 2 "nonmemory_operand" "c<S>,r,<KS>")))
15045    (clobber (reg:CC FLAGS_REG))]
15046   "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands)"
15048   switch (get_attr_type (insn))
15049     {
15050     case TYPE_ISHIFTX:
15051     case TYPE_MSKLOG:
15052       return "#";
15054     default:
15055       if (operands[2] == const1_rtx
15056           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15057         return "shr{<imodesuffix>}\t%0";
15058       else
15059         return "shr{<imodesuffix>}\t{%2, %0|%0, %2}";
15060     }
15062   [(set_attr "isa" "*,bmi2,<kmov_isa>")
15063    (set_attr "type" "ishift,ishiftx,msklog")
15064    (set (attr "length_immediate")
15065      (if_then_else
15066        (and (and (match_operand 2 "const1_operand")
15067                  (eq_attr "alternative" "0"))
15068             (ior (match_test "TARGET_SHIFT1")
15069                  (match_test "optimize_function_for_size_p (cfun)")))
15070        (const_string "0")
15071        (const_string "*")))
15072    (set_attr "mode" "<MODE>")])
15074 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15075 (define_split
15076   [(set (match_operand:SWI48 0 "register_operand")
15077         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15078                            (match_operand:QI 2 "register_operand")))
15079    (clobber (reg:CC FLAGS_REG))]
15080   "TARGET_BMI2 && reload_completed"
15081   [(set (match_dup 0)
15082         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
15083   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
15085 (define_insn "*bmi2_<insn>si3_1_zext"
15086   [(set (match_operand:DI 0 "register_operand" "=r")
15087         (zero_extend:DI
15088           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15089                           (match_operand:SI 2 "register_operand" "r"))))]
15090   "TARGET_64BIT && TARGET_BMI2"
15091   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
15092   [(set_attr "type" "ishiftx")
15093    (set_attr "mode" "SI")])
15095 (define_insn "*<insn>si3_1_zext"
15096   [(set (match_operand:DI 0 "register_operand" "=r,r")
15097         (zero_extend:DI
15098           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15099                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
15100    (clobber (reg:CC FLAGS_REG))]
15101   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15103   switch (get_attr_type (insn))
15104     {
15105     case TYPE_ISHIFTX:
15106       return "#";
15108     default:
15109       if (operands[2] == const1_rtx
15110           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15111         return "<shift>{l}\t%k0";
15112       else
15113         return "<shift>{l}\t{%2, %k0|%k0, %2}";
15114     }
15116   [(set_attr "isa" "*,bmi2")
15117    (set_attr "type" "ishift,ishiftx")
15118    (set (attr "length_immediate")
15119      (if_then_else
15120        (and (match_operand 2 "const1_operand")
15121             (ior (match_test "TARGET_SHIFT1")
15122                  (match_test "optimize_function_for_size_p (cfun)")))
15123        (const_string "0")
15124        (const_string "*")))
15125    (set_attr "mode" "SI")])
15127 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15128 (define_split
15129   [(set (match_operand:DI 0 "register_operand")
15130         (zero_extend:DI
15131           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
15132                           (match_operand:QI 2 "register_operand"))))
15133    (clobber (reg:CC FLAGS_REG))]
15134   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
15135   [(set (match_dup 0)
15136         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15137   "operands[2] = gen_lowpart (SImode, operands[2]);")
15139 (define_insn "*ashr<mode>3_1"
15140   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
15141         (ashiftrt:SWI12
15142           (match_operand:SWI12 1 "nonimmediate_operand" "0")
15143           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
15144    (clobber (reg:CC FLAGS_REG))]
15145   "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15147   if (operands[2] == const1_rtx
15148       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15149     return "sar{<imodesuffix>}\t%0";
15150   else
15151     return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
15153   [(set_attr "type" "ishift")
15154    (set (attr "length_immediate")
15155      (if_then_else
15156        (and (match_operand 2 "const1_operand")
15157             (ior (match_test "TARGET_SHIFT1")
15158                  (match_test "optimize_function_for_size_p (cfun)")))
15159        (const_string "0")
15160        (const_string "*")))
15161    (set_attr "mode" "<MODE>")])
15163 (define_insn "*lshrqi3_1"
15164   [(set (match_operand:QI 0 "nonimmediate_operand"  "=qm,?k")
15165         (lshiftrt:QI
15166           (match_operand:QI 1 "nonimmediate_operand" "0, k")
15167           (match_operand:QI 2 "nonmemory_operand"    "cI,Wb")))
15168    (clobber (reg:CC FLAGS_REG))]
15169   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
15171   switch (get_attr_type (insn))
15172     {
15173     case TYPE_ISHIFT:
15174       if (operands[2] == const1_rtx
15175           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15176         return "shr{b}\t%0";
15177       else
15178         return "shr{b}\t{%2, %0|%0, %2}";
15179     case TYPE_MSKLOG:
15180       return "#";
15181     default:
15182       gcc_unreachable ();
15183     }
15185   [(set_attr "isa" "*,avx512dq")
15186    (set_attr "type" "ishift,msklog")
15187    (set (attr "length_immediate")
15188      (if_then_else
15189        (and (and (match_operand 2 "const1_operand")
15190                  (eq_attr "alternative" "0"))
15191             (ior (match_test "TARGET_SHIFT1")
15192                  (match_test "optimize_function_for_size_p (cfun)")))
15193        (const_string "0")
15194        (const_string "*")))
15195    (set_attr "mode" "QI")])
15197 (define_insn "*lshrhi3_1"
15198   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm, ?k")
15199         (lshiftrt:HI
15200           (match_operand:HI 1 "nonimmediate_operand" "0, k")
15201           (match_operand:QI 2 "nonmemory_operand" "cI, Ww")))
15202    (clobber (reg:CC FLAGS_REG))]
15203   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
15205   switch (get_attr_type (insn))
15206     {
15207     case TYPE_ISHIFT:
15208       if (operands[2] == const1_rtx
15209           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15210         return "shr{w}\t%0";
15211       else
15212         return "shr{w}\t{%2, %0|%0, %2}";
15213     case TYPE_MSKLOG:
15214       return "#";
15215     default:
15216       gcc_unreachable ();
15217     }
15219   [(set_attr "isa" "*, avx512f")
15220    (set_attr "type" "ishift,msklog")
15221    (set (attr "length_immediate")
15222      (if_then_else
15223        (and (and (match_operand 2 "const1_operand")
15224                  (eq_attr "alternative" "0"))
15225             (ior (match_test "TARGET_SHIFT1")
15226                  (match_test "optimize_function_for_size_p (cfun)")))
15227        (const_string "0")
15228        (const_string "*")))
15229    (set_attr "mode" "HI")])
15231 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15232 (define_insn_and_split "*<insn><mode>3_1_slp"
15233   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15234         (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15235                            (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15236    (clobber (reg:CC FLAGS_REG))]
15237   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15239   if (which_alternative)
15240     return "#";
15242   if (operands[2] == const1_rtx
15243       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15244     return "<shift>{<imodesuffix>}\t%0";
15245   else
15246     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15248   "&& reload_completed"
15249   [(set (strict_low_part (match_dup 0)) (match_dup 1))
15250    (parallel
15251      [(set (strict_low_part (match_dup 0))
15252            (any_shiftrt:SWI12 (match_dup 0) (match_dup 2)))
15253       (clobber (reg:CC FLAGS_REG))])]
15254   ""
15255   [(set_attr "type" "ishift")
15256    (set (attr "length_immediate")
15257      (if_then_else
15258        (and (match_operand 2 "const1_operand")
15259             (ior (match_test "TARGET_SHIFT1")
15260                  (match_test "optimize_function_for_size_p (cfun)")))
15261        (const_string "0")
15262        (const_string "*")))
15263    (set_attr "mode" "<MODE>")])
15265 ;; This pattern can't accept a variable shift count, since shifts by
15266 ;; zero don't affect the flags.  We assume that shifts by constant
15267 ;; zero are optimized away.
15268 (define_insn "*<insn><mode>3_cmp"
15269   [(set (reg FLAGS_REG)
15270         (compare
15271           (any_shiftrt:SWI
15272             (match_operand:SWI 1 "nonimmediate_operand" "0")
15273             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15274           (const_int 0)))
15275    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
15276         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
15277   "(optimize_function_for_size_p (cfun)
15278     || !TARGET_PARTIAL_FLAG_REG_STALL
15279     || (operands[2] == const1_rtx
15280         && TARGET_SHIFT1))
15281    && ix86_match_ccmode (insn, CCGOCmode)
15282    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15284   if (operands[2] == const1_rtx
15285       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15286     return "<shift>{<imodesuffix>}\t%0";
15287   else
15288     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15290   [(set_attr "type" "ishift")
15291    (set (attr "length_immediate")
15292      (if_then_else
15293        (and (match_operand 2 "const1_operand")
15294             (ior (match_test "TARGET_SHIFT1")
15295                  (match_test "optimize_function_for_size_p (cfun)")))
15296        (const_string "0")
15297        (const_string "*")))
15298    (set_attr "mode" "<MODE>")])
15300 (define_insn "*<insn>si3_cmp_zext"
15301   [(set (reg FLAGS_REG)
15302         (compare
15303           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
15304                           (match_operand:QI 2 "const_1_to_31_operand"))
15305           (const_int 0)))
15306    (set (match_operand:DI 0 "register_operand" "=r")
15307         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15308   "TARGET_64BIT
15309    && (optimize_function_for_size_p (cfun)
15310        || !TARGET_PARTIAL_FLAG_REG_STALL
15311        || (operands[2] == const1_rtx
15312            && TARGET_SHIFT1))
15313    && ix86_match_ccmode (insn, CCGOCmode)
15314    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15316   if (operands[2] == const1_rtx
15317       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15318     return "<shift>{l}\t%k0";
15319   else
15320     return "<shift>{l}\t{%2, %k0|%k0, %2}";
15322   [(set_attr "type" "ishift")
15323    (set (attr "length_immediate")
15324      (if_then_else
15325        (and (match_operand 2 "const1_operand")
15326             (ior (match_test "TARGET_SHIFT1")
15327                  (match_test "optimize_function_for_size_p (cfun)")))
15328        (const_string "0")
15329        (const_string "*")))
15330    (set_attr "mode" "SI")])
15332 (define_insn "*<insn><mode>3_cconly"
15333   [(set (reg FLAGS_REG)
15334         (compare
15335           (any_shiftrt:SWI
15336             (match_operand:SWI 1 "register_operand" "0")
15337             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15338           (const_int 0)))
15339    (clobber (match_scratch:SWI 0 "=<r>"))]
15340   "(optimize_function_for_size_p (cfun)
15341     || !TARGET_PARTIAL_FLAG_REG_STALL
15342     || (operands[2] == const1_rtx
15343         && TARGET_SHIFT1))
15344    && ix86_match_ccmode (insn, CCGOCmode)"
15346   if (operands[2] == const1_rtx
15347       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15348     return "<shift>{<imodesuffix>}\t%0";
15349   else
15350     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15352   [(set_attr "type" "ishift")
15353    (set (attr "length_immediate")
15354      (if_then_else
15355        (and (match_operand 2 "const1_operand")
15356             (ior (match_test "TARGET_SHIFT1")
15357                  (match_test "optimize_function_for_size_p (cfun)")))
15358        (const_string "0")
15359        (const_string "*")))
15360    (set_attr "mode" "<MODE>")])
15362 (define_insn "*<insn>qi_ext<mode>_2"
15363   [(set (zero_extract:SWI248
15364           (match_operand 0 "int248_register_operand" "+Q")
15365           (const_int 8)
15366           (const_int 8))
15367         (subreg:SWI248
15368           (any_shiftrt:QI
15369             (subreg:QI
15370               (match_operator:SWI248 3 "extract_operator"
15371                 [(match_operand 1 "int248_register_operand" "0")
15372                  (const_int 8)
15373                  (const_int 8)]) 0)
15374             (match_operand:QI 2 "nonmemory_operand" "cI")) 0))
15375   (clobber (reg:CC FLAGS_REG))]
15376   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
15377    rtx_equal_p (operands[0], operands[1])"
15379   if (operands[2] == const1_rtx
15380       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15381     return "<shift>{b}\t%h0";
15382   else
15383     return "<shift>{b}\t{%2, %h0|%h0, %2}";
15385   [(set_attr "type" "ishift")
15386    (set (attr "length_immediate")
15387      (if_then_else
15388        (and (match_operand 2 "const1_operand")
15389             (ior (match_test "TARGET_SHIFT1")
15390                  (match_test "optimize_function_for_size_p (cfun)")))
15391        (const_string "0")
15392        (const_string "*")))
15393    (set_attr "mode" "QI")])
15395 (define_insn_and_split "*extend<dwi>2_doubleword_highpart"
15396   [(set (match_operand:<DWI> 0 "register_operand" "=r")
15397         (ashiftrt:<DWI>
15398           (ashift:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")
15399                         (match_operand:QI 2 "const_int_operand"))
15400           (match_operand:QI 3 "const_int_operand")))
15401    (clobber (reg:CC FLAGS_REG))]
15402   "INTVAL (operands[2]) == INTVAL (operands[3])
15403    && UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
15404   "#"
15405   "&& reload_completed"
15406   [(parallel [(set (match_dup 4)
15407                    (ashift:DWIH (match_dup 4) (match_dup 2)))
15408               (clobber (reg:CC FLAGS_REG))])
15409    (parallel [(set (match_dup 4)
15410                    (ashiftrt:DWIH (match_dup 4) (match_dup 2)))
15411               (clobber (reg:CC FLAGS_REG))])]
15412   "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[4]);")
15414 (define_insn_and_split "*extendv2di2_highpart_stv"
15415   [(set (match_operand:V2DI 0 "register_operand" "=v")
15416         (ashiftrt:V2DI
15417           (ashift:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "vm")
15418                        (match_operand:QI 2 "const_int_operand"))
15419           (match_operand:QI 3 "const_int_operand")))]
15420   "!TARGET_64BIT && TARGET_STV && TARGET_AVX512VL
15421    && INTVAL (operands[2]) == INTVAL (operands[3])
15422    && UINTVAL (operands[2]) < 32"
15423   "#"
15424   "&& reload_completed"
15425   [(set (match_dup 0)
15426         (ashift:V2DI (match_dup 1) (match_dup 2)))
15427    (set (match_dup 0)
15428         (ashiftrt:V2DI (match_dup 0) (match_dup 2)))])
15430 ;; Rotate instructions
15432 (define_expand "<insn>ti3"
15433   [(set (match_operand:TI 0 "register_operand")
15434         (any_rotate:TI (match_operand:TI 1 "register_operand")
15435                        (match_operand:QI 2 "nonmemory_operand")))]
15436   "TARGET_64BIT"
15438   if (const_1_to_63_operand (operands[2], VOIDmode))
15439     emit_insn (gen_ix86_<insn>ti3_doubleword
15440                 (operands[0], operands[1], operands[2]));
15441   else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 64)
15442     {
15443       operands[1] = force_reg (TImode, operands[1]);
15444       emit_insn (gen_<insn>64ti2_doubleword (operands[0], operands[1]));
15445     }
15446   else
15447     {
15448       rtx amount = force_reg (QImode, operands[2]);
15449       rtx src_lo = gen_lowpart (DImode, operands[1]);
15450       rtx src_hi = gen_highpart (DImode, operands[1]);
15451       rtx tmp_lo = gen_reg_rtx (DImode);
15452       rtx tmp_hi = gen_reg_rtx (DImode);
15453       emit_move_insn (tmp_lo, src_lo);
15454       emit_move_insn (tmp_hi, src_hi);
15455       rtx (*shiftd) (rtx, rtx, rtx)
15456             = (<CODE> == ROTATE) ? gen_x86_64_shld : gen_x86_64_shrd;
15457       emit_insn (shiftd (tmp_lo, src_hi, amount));
15458       emit_insn (shiftd (tmp_hi, src_lo, amount));
15459       rtx dst_lo = gen_lowpart (DImode, operands[0]);
15460       rtx dst_hi = gen_highpart (DImode, operands[0]);
15461       emit_move_insn (dst_lo, tmp_lo);
15462       emit_move_insn (dst_hi, tmp_hi);
15463       emit_insn (gen_x86_shiftdi_adj_1 (dst_lo, dst_hi, amount, tmp_lo));
15464     }
15465   DONE;
15468 (define_expand "<insn>di3"
15469   [(set (match_operand:DI 0 "shiftdi_operand")
15470         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
15471                        (match_operand:QI 2 "nonmemory_operand")))]
15472  ""
15474   if (TARGET_64BIT)
15475     ix86_expand_binary_operator (<CODE>, DImode, operands);
15476   else if (const_1_to_31_operand (operands[2], VOIDmode))
15477     emit_insn (gen_ix86_<insn>di3_doubleword
15478                 (operands[0], operands[1], operands[2]));
15479   else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 32)
15480     {
15481       operands[1] = force_reg (DImode, operands[1]);
15482       emit_insn (gen_<insn>32di2_doubleword (operands[0], operands[1]));
15483     }
15484   else
15485     FAIL;
15487   DONE;
15490 (define_expand "<insn><mode>3"
15491   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
15492         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
15493                             (match_operand:QI 2 "nonmemory_operand")))]
15494   ""
15495   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
15497 ;; Avoid useless masking of count operand.
15498 (define_insn_and_split "*<insn><mode>3_mask"
15499   [(set (match_operand:SWI 0 "nonimmediate_operand")
15500         (any_rotate:SWI
15501           (match_operand:SWI 1 "nonimmediate_operand")
15502           (subreg:QI
15503             (and
15504               (match_operand 2 "int248_register_operand" "c")
15505               (match_operand 3 "const_int_operand")) 0)))
15506    (clobber (reg:CC FLAGS_REG))]
15507   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15508    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15509       == GET_MODE_BITSIZE (<MODE>mode)-1
15510    && ix86_pre_reload_split ()"
15511   "#"
15512   "&& 1"
15513   [(parallel
15514      [(set (match_dup 0)
15515            (any_rotate:SWI (match_dup 1)
15516                            (match_dup 2)))
15517       (clobber (reg:CC FLAGS_REG))])]
15519   operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15520   operands[2] = gen_lowpart (QImode, operands[2]);
15523 (define_split
15524   [(set (match_operand:SWI 0 "register_operand")
15525         (any_rotate:SWI
15526           (match_operand:SWI 1 "const_int_operand")
15527           (subreg:QI
15528             (and
15529               (match_operand 2 "int248_register_operand")
15530               (match_operand 3 "const_int_operand")) 0)))]
15531  "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15532    == GET_MODE_BITSIZE (<MODE>mode) - 1"
15533  [(set (match_dup 4) (match_dup 1))
15534   (set (match_dup 0)
15535        (any_rotate:SWI (match_dup 4)
15536                        (subreg:QI (match_dup 2) 0)))]
15537  "operands[4] = gen_reg_rtx (<MODE>mode);")
15539 (define_insn_and_split "*<insn><mode>3_mask_1"
15540   [(set (match_operand:SWI 0 "nonimmediate_operand")
15541         (any_rotate:SWI
15542           (match_operand:SWI 1 "nonimmediate_operand")
15543           (and:QI
15544             (match_operand:QI 2 "register_operand" "c")
15545             (match_operand:QI 3 "const_int_operand"))))
15546    (clobber (reg:CC FLAGS_REG))]
15547   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15548    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15549       == GET_MODE_BITSIZE (<MODE>mode)-1
15550    && ix86_pre_reload_split ()"
15551   "#"
15552   "&& 1"
15553   [(parallel
15554      [(set (match_dup 0)
15555            (any_rotate:SWI (match_dup 1)
15556                            (match_dup 2)))
15557       (clobber (reg:CC FLAGS_REG))])])
15559 (define_split
15560   [(set (match_operand:SWI 0 "register_operand")
15561         (any_rotate:SWI
15562           (match_operand:SWI 1 "const_int_operand")
15563           (and:QI
15564             (match_operand:QI 2 "register_operand")
15565             (match_operand:QI 3 "const_int_operand"))))]
15566  "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15567   == GET_MODE_BITSIZE (<MODE>mode) - 1"
15568  [(set (match_dup 4) (match_dup 1))
15569   (set (match_dup 0)
15570        (any_rotate:SWI (match_dup 4) (match_dup 2)))]
15571  "operands[4] = gen_reg_rtx (<MODE>mode);")
15573 ;; Implement rotation using two double-precision
15574 ;; shift instructions and a scratch register.
15576 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
15577  [(set (match_operand:<DWI> 0 "register_operand" "=r")
15578        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15579                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15580   (clobber (reg:CC FLAGS_REG))
15581   (clobber (match_scratch:DWIH 3 "=&r"))]
15582  ""
15583  "#"
15584  "reload_completed"
15585  [(set (match_dup 3) (match_dup 4))
15586   (parallel
15587    [(set (match_dup 4)
15588          (ior:DWIH (ashift:DWIH (match_dup 4)
15589                                 (and:QI (match_dup 2) (match_dup 6)))
15590                    (subreg:DWIH
15591                      (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
15592                                      (minus:QI (match_dup 7)
15593                                                (and:QI (match_dup 2)
15594                                                        (match_dup 6)))) 0)))
15595     (clobber (reg:CC FLAGS_REG))])
15596   (parallel
15597    [(set (match_dup 5)
15598          (ior:DWIH (ashift:DWIH (match_dup 5)
15599                                 (and:QI (match_dup 2) (match_dup 6)))
15600                    (subreg:DWIH
15601                      (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 3))
15602                                      (minus:QI (match_dup 7)
15603                                                (and:QI (match_dup 2)
15604                                                        (match_dup 6)))) 0)))
15605     (clobber (reg:CC FLAGS_REG))])]
15607   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15608   operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15610   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15613 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
15614  [(set (match_operand:<DWI> 0 "register_operand" "=r")
15615        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15616                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15617   (clobber (reg:CC FLAGS_REG))
15618   (clobber (match_scratch:DWIH 3 "=&r"))]
15619  ""
15620  "#"
15621  "reload_completed"
15622  [(set (match_dup 3) (match_dup 4))
15623   (parallel
15624    [(set (match_dup 4)
15625          (ior:DWIH (lshiftrt:DWIH (match_dup 4)
15626                                   (and:QI (match_dup 2) (match_dup 6)))
15627                    (subreg:DWIH
15628                      (ashift:<DWI> (zero_extend:<DWI> (match_dup 5))
15629                                    (minus:QI (match_dup 7)
15630                                              (and:QI (match_dup 2)
15631                                                      (match_dup 6)))) 0)))
15632     (clobber (reg:CC FLAGS_REG))])
15633   (parallel
15634    [(set (match_dup 5)
15635          (ior:DWIH (lshiftrt:DWIH (match_dup 5)
15636                                   (and:QI (match_dup 2) (match_dup 6)))
15637                    (subreg:DWIH
15638                      (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
15639                                    (minus:QI (match_dup 7)
15640                                              (and:QI (match_dup 2)
15641                                                      (match_dup 6)))) 0)))
15642     (clobber (reg:CC FLAGS_REG))])]
15644   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15645   operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15647   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15650 (define_insn_and_split "<insn>32di2_doubleword"
15651  [(set (match_operand:DI 0 "register_operand" "=r,r")
15652        (any_rotate:DI (match_operand:DI 1 "register_operand" "0,r")
15653                       (const_int 32)))]
15654  "!TARGET_64BIT"
15655  "#"
15656  "&& reload_completed"
15657  [(set (match_dup 0) (match_dup 3))
15658   (set (match_dup 2) (match_dup 1))]
15660   split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
15661   if (rtx_equal_p (operands[0], operands[1]))
15662     {
15663       emit_insn (gen_swapsi (operands[0], operands[2]));
15664       DONE;
15665     }
15668 (define_insn_and_split "<insn>64ti2_doubleword"
15669  [(set (match_operand:TI 0 "register_operand" "=r,r")
15670        (any_rotate:TI (match_operand:TI 1 "register_operand" "0,r")
15671                       (const_int 64)))]
15672  "TARGET_64BIT"
15673  "#"
15674  "&& reload_completed"
15675  [(set (match_dup 0) (match_dup 3))
15676   (set (match_dup 2) (match_dup 1))]
15678   split_double_mode (TImode, &operands[0], 2, &operands[0], &operands[2]);
15679   if (rtx_equal_p (operands[0], operands[1]))
15680     {
15681       emit_insn (gen_swapdi (operands[0], operands[2]));
15682       DONE;
15683     }
15686 (define_mode_attr rorx_immediate_operand
15687         [(SI "const_0_to_31_operand")
15688          (DI "const_0_to_63_operand")])
15690 (define_insn "*bmi2_rorx<mode>3_1"
15691   [(set (match_operand:SWI48 0 "register_operand" "=r")
15692         (rotatert:SWI48
15693           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
15694           (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
15695   "TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15696   "rorx\t{%2, %1, %0|%0, %1, %2}"
15697   [(set_attr "type" "rotatex")
15698    (set_attr "mode" "<MODE>")])
15700 (define_insn "*<insn><mode>3_1"
15701   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
15702         (any_rotate:SWI48
15703           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
15704           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
15705    (clobber (reg:CC FLAGS_REG))]
15706   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15708   switch (get_attr_type (insn))
15709     {
15710     case TYPE_ROTATEX:
15711       return "#";
15713     default:
15714       if (operands[2] == const1_rtx
15715           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15716         return "<rotate>{<imodesuffix>}\t%0";
15717       else
15718         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15719     }
15721   [(set_attr "isa" "*,bmi2")
15722    (set_attr "type" "rotate,rotatex")
15723    (set (attr "preferred_for_size")
15724      (cond [(eq_attr "alternative" "0")
15725               (symbol_ref "true")]
15726            (symbol_ref "false")))
15727    (set (attr "length_immediate")
15728      (if_then_else
15729        (and (eq_attr "type" "rotate")
15730             (and (match_operand 2 "const1_operand")
15731                  (ior (match_test "TARGET_SHIFT1")
15732                       (match_test "optimize_function_for_size_p (cfun)"))))
15733        (const_string "0")
15734        (const_string "*")))
15735    (set_attr "mode" "<MODE>")])
15737 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15738 (define_split
15739   [(set (match_operand:SWI48 0 "register_operand")
15740         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15741                       (match_operand:QI 2 "const_int_operand")))
15742    (clobber (reg:CC FLAGS_REG))]
15743   "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15744   [(set (match_dup 0)
15745         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
15747   int bitsize = GET_MODE_BITSIZE (<MODE>mode);
15749   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15752 (define_split
15753   [(set (match_operand:SWI48 0 "register_operand")
15754         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15755                         (match_operand:QI 2 "const_int_operand")))
15756    (clobber (reg:CC FLAGS_REG))]
15757   "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15758   [(set (match_dup 0)
15759         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
15761 (define_insn "*bmi2_rorxsi3_1_zext"
15762   [(set (match_operand:DI 0 "register_operand" "=r")
15763         (zero_extend:DI
15764           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15765                        (match_operand:QI 2 "const_0_to_31_operand"))))]
15766   "TARGET_64BIT && TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15767   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
15768   [(set_attr "type" "rotatex")
15769    (set_attr "mode" "SI")])
15771 (define_insn "*<insn>si3_1_zext"
15772   [(set (match_operand:DI 0 "register_operand" "=r,r")
15773         (zero_extend:DI
15774           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15775                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
15776    (clobber (reg:CC FLAGS_REG))]
15777   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15779   switch (get_attr_type (insn))
15780     {
15781     case TYPE_ROTATEX:
15782       return "#";
15784     default:
15785       if (operands[2] == const1_rtx
15786           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15787         return "<rotate>{l}\t%k0";
15788       else
15789         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
15790     }
15792   [(set_attr "isa" "*,bmi2")
15793    (set_attr "type" "rotate,rotatex")
15794    (set (attr "preferred_for_size")
15795      (cond [(eq_attr "alternative" "0")
15796               (symbol_ref "true")]
15797            (symbol_ref "false")))
15798    (set (attr "length_immediate")
15799      (if_then_else
15800        (and (eq_attr "type" "rotate")
15801             (and (match_operand 2 "const1_operand")
15802                  (ior (match_test "TARGET_SHIFT1")
15803                       (match_test "optimize_function_for_size_p (cfun)"))))
15804        (const_string "0")
15805        (const_string "*")))
15806    (set_attr "mode" "SI")])
15808 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15809 (define_split
15810   [(set (match_operand:DI 0 "register_operand")
15811         (zero_extend:DI
15812           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
15813                      (match_operand:QI 2 "const_int_operand"))))
15814    (clobber (reg:CC FLAGS_REG))]
15815   "TARGET_64BIT && TARGET_BMI2 && reload_completed
15816    && !optimize_function_for_size_p (cfun)"
15817   [(set (match_dup 0)
15818         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
15820   int bitsize = GET_MODE_BITSIZE (SImode);
15822   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15825 (define_split
15826   [(set (match_operand:DI 0 "register_operand")
15827         (zero_extend:DI
15828           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
15829                        (match_operand:QI 2 "const_int_operand"))))
15830    (clobber (reg:CC FLAGS_REG))]
15831   "TARGET_64BIT && TARGET_BMI2 && reload_completed
15832    && !optimize_function_for_size_p (cfun)"
15833   [(set (match_dup 0)
15834         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
15836 (define_insn "*<insn><mode>3_1"
15837   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
15838         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
15839                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
15840    (clobber (reg:CC FLAGS_REG))]
15841   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15843   if (operands[2] == const1_rtx
15844       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15845     return "<rotate>{<imodesuffix>}\t%0";
15846   else
15847     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15849   [(set_attr "type" "rotate")
15850    (set (attr "length_immediate")
15851      (if_then_else
15852        (and (match_operand 2 "const1_operand")
15853             (ior (match_test "TARGET_SHIFT1")
15854                  (match_test "optimize_function_for_size_p (cfun)")))
15855        (const_string "0")
15856        (const_string "*")))
15857    (set_attr "mode" "<MODE>")])
15859 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15860 (define_insn_and_split "*<insn><mode>3_1_slp"
15861   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15862         (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15863                           (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15864    (clobber (reg:CC FLAGS_REG))]
15865   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15867   if (which_alternative)
15868     return "#";
15870   if (operands[2] == const1_rtx
15871       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15872     return "<rotate>{<imodesuffix>}\t%0";
15873   else
15874     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15876   "&& reload_completed"
15877   [(set (strict_low_part (match_dup 0)) (match_dup 1))
15878    (parallel
15879      [(set (strict_low_part (match_dup 0))
15880            (any_rotate:SWI12 (match_dup 0) (match_dup 2)))
15881       (clobber (reg:CC FLAGS_REG))])]
15882   ""
15883   [(set_attr "type" "rotate")
15884    (set (attr "length_immediate")
15885      (if_then_else
15886        (and (match_operand 2 "const1_operand")
15887             (ior (match_test "TARGET_SHIFT1")
15888                  (match_test "optimize_function_for_size_p (cfun)")))
15889        (const_string "0")
15890        (const_string "*")))
15891    (set_attr "mode" "<MODE>")])
15893 (define_split
15894  [(set (match_operand:HI 0 "QIreg_operand")
15895        (any_rotate:HI (match_dup 0) (const_int 8)))
15896   (clobber (reg:CC FLAGS_REG))]
15897  "reload_completed
15898   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
15899  [(parallel [(set (strict_low_part (match_dup 0))
15900                   (bswap:HI (match_dup 0)))
15901              (clobber (reg:CC FLAGS_REG))])])
15903 ;; Rotations through carry flag
15904 (define_insn "rcrsi2"
15905   [(set (match_operand:SI 0 "register_operand" "=r")
15906         (plus:SI
15907           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
15908                        (const_int 1))
15909           (ashift:SI (ltu:SI (reg:CCC FLAGS_REG) (const_int 0))
15910                      (const_int 31))))
15911    (clobber (reg:CC FLAGS_REG))]
15912   ""
15913   "rcr{l}\t%0"
15914   [(set_attr "type" "ishift1")
15915    (set_attr "memory" "none")
15916    (set_attr "length_immediate" "0")
15917    (set_attr "mode" "SI")])
15919 (define_insn "rcrdi2"
15920   [(set (match_operand:DI 0 "register_operand" "=r")
15921         (plus:DI
15922           (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
15923                        (const_int 1))
15924           (ashift:DI (ltu:DI (reg:CCC FLAGS_REG) (const_int 0))
15925                      (const_int 63))))
15926    (clobber (reg:CC FLAGS_REG))]
15927   "TARGET_64BIT"
15928   "rcr{q}\t%0"
15929   [(set_attr "type" "ishift1")
15930    (set_attr "length_immediate" "0")
15931    (set_attr "mode" "DI")])
15933 ;; Versions of sar and shr that set the carry flag.
15934 (define_insn "<insn><mode>3_carry"
15935   [(set (reg:CCC FLAGS_REG)
15936         (unspec:CCC [(and:SWI48 (match_operand:SWI48 1 "register_operand" "0")
15937                                 (const_int 1))
15938                      (const_int 0)] UNSPEC_CC_NE))
15939    (set (match_operand:SWI48 0 "register_operand" "=r")
15940         (any_shiftrt:SWI48 (match_dup 1) (const_int 1)))]
15941   ""
15943   if (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
15944     return "<shift>{<imodesuffix>}\t%0";
15945   return "<shift>{<imodesuffix>}\t{1, %0|%0, 1}";
15947   [(set_attr "type" "ishift1")
15948    (set (attr "length_immediate")
15949      (if_then_else
15950        (ior (match_test "TARGET_SHIFT1")
15951             (match_test "optimize_function_for_size_p (cfun)"))
15952        (const_string "0")
15953        (const_string "*")))
15954    (set_attr "mode" "<MODE>")])
15956 ;; Bit set / bit test instructions
15958 ;; %%% bts, btr, btc
15960 ;; These instructions are *slow* when applied to memory.
15962 (define_code_attr btsc [(ior "bts") (xor "btc")])
15964 (define_insn "*<btsc><mode>"
15965   [(set (match_operand:SWI48 0 "register_operand" "=r")
15966         (any_or:SWI48
15967           (ashift:SWI48 (const_int 1)
15968                         (match_operand:QI 2 "register_operand" "r"))
15969           (match_operand:SWI48 1 "register_operand" "0")))
15970    (clobber (reg:CC FLAGS_REG))]
15971   "TARGET_USE_BT"
15972   "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
15973   [(set_attr "type" "alu1")
15974    (set_attr "prefix_0f" "1")
15975    (set_attr "znver1_decode" "double")
15976    (set_attr "mode" "<MODE>")])
15978 ;; Avoid useless masking of count operand.
15979 (define_insn_and_split "*<btsc><mode>_mask"
15980   [(set (match_operand:SWI48 0 "register_operand")
15981         (any_or:SWI48
15982           (ashift:SWI48
15983             (const_int 1)
15984             (subreg:QI
15985               (and
15986                 (match_operand 1 "int248_register_operand")
15987                 (match_operand 2 "const_int_operand")) 0))
15988           (match_operand:SWI48 3 "register_operand")))
15989    (clobber (reg:CC FLAGS_REG))]
15990   "TARGET_USE_BT
15991    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15992       == GET_MODE_BITSIZE (<MODE>mode)-1
15993    && ix86_pre_reload_split ()"
15994   "#"
15995   "&& 1"
15996   [(parallel
15997      [(set (match_dup 0)
15998            (any_or:SWI48
15999              (ashift:SWI48 (const_int 1)
16000                            (match_dup 1))
16001              (match_dup 3)))
16002       (clobber (reg:CC FLAGS_REG))])]
16004   operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
16005   operands[1] = gen_lowpart (QImode, operands[1]);
16008 (define_insn_and_split "*<btsc><mode>_mask_1"
16009   [(set (match_operand:SWI48 0 "register_operand")
16010         (any_or:SWI48
16011           (ashift:SWI48
16012             (const_int 1)
16013             (and:QI
16014               (match_operand:QI 1 "register_operand")
16015               (match_operand:QI 2 "const_int_operand")))
16016           (match_operand:SWI48 3 "register_operand")))
16017    (clobber (reg:CC FLAGS_REG))]
16018   "TARGET_USE_BT
16019    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16020       == GET_MODE_BITSIZE (<MODE>mode)-1
16021    && ix86_pre_reload_split ()"
16022   "#"
16023   "&& 1"
16024   [(parallel
16025      [(set (match_dup 0)
16026            (any_or:SWI48
16027              (ashift:SWI48 (const_int 1)
16028                            (match_dup 1))
16029              (match_dup 3)))
16030       (clobber (reg:CC FLAGS_REG))])])
16032 (define_insn "*btr<mode>"
16033   [(set (match_operand:SWI48 0 "register_operand" "=r")
16034         (and:SWI48
16035           (rotate:SWI48 (const_int -2)
16036                         (match_operand:QI 2 "register_operand" "r"))
16037         (match_operand:SWI48 1 "register_operand" "0")))
16038    (clobber (reg:CC FLAGS_REG))]
16039   "TARGET_USE_BT"
16040   "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
16041   [(set_attr "type" "alu1")
16042    (set_attr "prefix_0f" "1")
16043    (set_attr "znver1_decode" "double")
16044    (set_attr "mode" "<MODE>")])
16046 ;; Avoid useless masking of count operand.
16047 (define_insn_and_split "*btr<mode>_mask"
16048   [(set (match_operand:SWI48 0 "register_operand")
16049         (and:SWI48
16050           (rotate:SWI48
16051             (const_int -2)
16052             (subreg:QI
16053               (and
16054                 (match_operand 1 "int248_register_operand")
16055                 (match_operand 2 "const_int_operand")) 0))
16056           (match_operand:SWI48 3 "register_operand")))
16057    (clobber (reg:CC FLAGS_REG))]
16058   "TARGET_USE_BT
16059    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16060       == GET_MODE_BITSIZE (<MODE>mode)-1
16061    && ix86_pre_reload_split ()"
16062   "#"
16063   "&& 1"
16064   [(parallel
16065      [(set (match_dup 0)
16066            (and:SWI48
16067              (rotate:SWI48 (const_int -2)
16068                            (match_dup 1))
16069              (match_dup 3)))
16070       (clobber (reg:CC FLAGS_REG))])]
16072   operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
16073   operands[1] = gen_lowpart (QImode, operands[1]);
16076 (define_insn_and_split "*btr<mode>_mask_1"
16077   [(set (match_operand:SWI48 0 "register_operand")
16078         (and:SWI48
16079           (rotate:SWI48
16080             (const_int -2)
16081             (and:QI
16082               (match_operand:QI 1 "register_operand")
16083               (match_operand:QI 2 "const_int_operand")))
16084           (match_operand:SWI48 3 "register_operand")))
16085    (clobber (reg:CC FLAGS_REG))]
16086   "TARGET_USE_BT
16087    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16088       == GET_MODE_BITSIZE (<MODE>mode)-1
16089    && ix86_pre_reload_split ()"
16090   "#"
16091   "&& 1"
16092   [(parallel
16093      [(set (match_dup 0)
16094            (and:SWI48
16095              (rotate:SWI48 (const_int -2)
16096                            (match_dup 1))
16097              (match_dup 3)))
16098       (clobber (reg:CC FLAGS_REG))])])
16100 (define_insn_and_split "*btr<mode>_1"
16101   [(set (match_operand:SWI12 0 "register_operand")
16102         (and:SWI12
16103           (subreg:SWI12
16104             (rotate:SI (const_int -2)
16105                        (match_operand:QI 2 "register_operand")) 0)
16106           (match_operand:SWI12 1 "nonimmediate_operand")))
16107    (clobber (reg:CC FLAGS_REG))]
16108   "TARGET_USE_BT && ix86_pre_reload_split ()"
16109   "#"
16110   "&& 1"
16111   [(parallel
16112      [(set (match_dup 0)
16113            (and:SI (rotate:SI (const_int -2) (match_dup 2))
16114                    (match_dup 1)))
16115       (clobber (reg:CC FLAGS_REG))])]
16117   operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16118   operands[1] = force_reg (<MODE>mode, operands[1]);
16119   operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
16122 (define_insn_and_split "*btr<mode>_2"
16123   [(set (zero_extract:HI
16124           (match_operand:SWI12 0 "nonimmediate_operand")
16125           (const_int 1)
16126           (match_operand:QI 1 "register_operand"))
16127         (const_int 0))
16128    (clobber (reg:CC FLAGS_REG))]
16129   "TARGET_USE_BT && ix86_pre_reload_split ()"
16130   "#"
16131   "&& MEM_P (operands[0])"
16132   [(set (match_dup 2) (match_dup 0))
16133    (parallel
16134      [(set (match_dup 3)
16135            (and:SI (rotate:SI (const_int -2) (match_dup 1))
16136                    (match_dup 4)))
16137       (clobber (reg:CC FLAGS_REG))])
16138    (set (match_dup 0) (match_dup 5))]
16140   operands[2] = gen_reg_rtx (<MODE>mode);
16141   operands[5] = gen_reg_rtx (<MODE>mode);
16142   operands[3] = lowpart_subreg (SImode, operands[5], <MODE>mode);
16143   operands[4] = lowpart_subreg (SImode, operands[2], <MODE>mode);
16146 (define_split
16147   [(set (zero_extract:HI
16148           (match_operand:SWI12 0 "register_operand")
16149           (const_int 1)
16150           (match_operand:QI 1 "register_operand"))
16151         (const_int 0))
16152    (clobber (reg:CC FLAGS_REG))]
16153   "TARGET_USE_BT && ix86_pre_reload_split ()"
16154   [(parallel
16155      [(set (match_dup 0)
16156            (and:SI (rotate:SI (const_int -2) (match_dup 1))
16157                    (match_dup 2)))
16158       (clobber (reg:CC FLAGS_REG))])]
16160   operands[2] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16161   operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16164 ;; These instructions are never faster than the corresponding
16165 ;; and/ior/xor operations when using immediate operand, so with
16166 ;; 32-bit there's no point.  But in 64-bit, we can't hold the
16167 ;; relevant immediates within the instruction itself, so operating
16168 ;; on bits in the high 32-bits of a register becomes easier.
16170 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
16171 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
16172 ;; negdf respectively, so they can never be disabled entirely.
16174 (define_insn "*btsq_imm"
16175   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16176                          (const_int 1)
16177                          (match_operand:QI 1 "const_0_to_63_operand"))
16178         (const_int 1))
16179    (clobber (reg:CC FLAGS_REG))]
16180   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16181   "bts{q}\t{%1, %0|%0, %1}"
16182   [(set_attr "type" "alu1")
16183    (set_attr "prefix_0f" "1")
16184    (set_attr "znver1_decode" "double")
16185    (set_attr "mode" "DI")])
16187 (define_insn "*btrq_imm"
16188   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16189                          (const_int 1)
16190                          (match_operand:QI 1 "const_0_to_63_operand"))
16191         (const_int 0))
16192    (clobber (reg:CC FLAGS_REG))]
16193   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16194   "btr{q}\t{%1, %0|%0, %1}"
16195   [(set_attr "type" "alu1")
16196    (set_attr "prefix_0f" "1")
16197    (set_attr "znver1_decode" "double")
16198    (set_attr "mode" "DI")])
16200 (define_insn "*btcq_imm"
16201   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16202                          (const_int 1)
16203                          (match_operand:QI 1 "const_0_to_63_operand"))
16204         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
16205    (clobber (reg:CC FLAGS_REG))]
16206   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16207   "btc{q}\t{%1, %0|%0, %1}"
16208   [(set_attr "type" "alu1")
16209    (set_attr "prefix_0f" "1")
16210    (set_attr "znver1_decode" "double")
16211    (set_attr "mode" "DI")])
16213 ;; Allow Nocona to avoid these instructions if a register is available.
16215 (define_peephole2
16216   [(match_scratch:DI 2 "r")
16217    (parallel [(set (zero_extract:DI
16218                      (match_operand:DI 0 "nonimmediate_operand")
16219                      (const_int 1)
16220                      (match_operand:QI 1 "const_0_to_63_operand"))
16221                    (const_int 1))
16222               (clobber (reg:CC FLAGS_REG))])]
16223   "TARGET_64BIT && !TARGET_USE_BT"
16224   [(parallel [(set (match_dup 0)
16225                    (ior:DI (match_dup 0) (match_dup 3)))
16226               (clobber (reg:CC FLAGS_REG))])]
16228   int i = INTVAL (operands[1]);
16230   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16232   if (!x86_64_immediate_operand (operands[3], DImode))
16233     {
16234       emit_move_insn (operands[2], operands[3]);
16235       operands[3] = operands[2];
16236     }
16239 (define_peephole2
16240   [(match_scratch:DI 2 "r")
16241    (parallel [(set (zero_extract:DI
16242                      (match_operand:DI 0 "nonimmediate_operand")
16243                      (const_int 1)
16244                      (match_operand:QI 1 "const_0_to_63_operand"))
16245                    (const_int 0))
16246               (clobber (reg:CC FLAGS_REG))])]
16247   "TARGET_64BIT && !TARGET_USE_BT"
16248   [(parallel [(set (match_dup 0)
16249                    (and:DI (match_dup 0) (match_dup 3)))
16250               (clobber (reg:CC FLAGS_REG))])]
16252   int i = INTVAL (operands[1]);
16254   operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
16256   if (!x86_64_immediate_operand (operands[3], DImode))
16257     {
16258       emit_move_insn (operands[2], operands[3]);
16259       operands[3] = operands[2];
16260     }
16263 (define_peephole2
16264   [(match_scratch:DI 2 "r")
16265    (parallel [(set (zero_extract:DI
16266                      (match_operand:DI 0 "nonimmediate_operand")
16267                      (const_int 1)
16268                      (match_operand:QI 1 "const_0_to_63_operand"))
16269               (not:DI (zero_extract:DI
16270                         (match_dup 0) (const_int 1) (match_dup 1))))
16271               (clobber (reg:CC FLAGS_REG))])]
16272   "TARGET_64BIT && !TARGET_USE_BT"
16273   [(parallel [(set (match_dup 0)
16274                    (xor:DI (match_dup 0) (match_dup 3)))
16275               (clobber (reg:CC FLAGS_REG))])]
16277   int i = INTVAL (operands[1]);
16279   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16281   if (!x86_64_immediate_operand (operands[3], DImode))
16282     {
16283       emit_move_insn (operands[2], operands[3]);
16284       operands[3] = operands[2];
16285     }
16288 ;; %%% bt
16290 (define_insn "*bt<mode>"
16291   [(set (reg:CCC FLAGS_REG)
16292         (compare:CCC
16293           (zero_extract:SWI48
16294             (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
16295             (const_int 1)
16296             (match_operand:QI 1 "nonmemory_operand" "q<S>,<S>"))
16297           (const_int 0)))]
16298   ""
16300   switch (get_attr_mode (insn))
16301     {
16302     case MODE_SI:
16303       return "bt{l}\t{%k1, %k0|%k0, %k1}";
16305     case MODE_DI:
16306       return "bt{q}\t{%q1, %0|%0, %q1}";
16308     default:
16309       gcc_unreachable ();
16310     }
16312   [(set_attr "type" "alu1")
16313    (set_attr "prefix_0f" "1")
16314    (set (attr "mode")
16315         (if_then_else
16316           (and (match_test "CONST_INT_P (operands[1])")
16317                (match_test "INTVAL (operands[1]) < 32"))
16318           (const_string "SI")
16319           (const_string "<MODE>")))])
16321 (define_insn_and_split "*bt<SWI48:mode>_mask"
16322   [(set (reg:CCC FLAGS_REG)
16323         (compare:CCC
16324           (zero_extract:SWI48
16325             (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
16326             (const_int 1)
16327             (subreg:QI
16328               (and:SWI248
16329                 (match_operand:SWI248 1 "register_operand")
16330                 (match_operand 2 "const_int_operand")) 0))
16331           (const_int 0)))]
16332   "TARGET_USE_BT
16333    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
16334       == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
16335    && ix86_pre_reload_split ()"
16336   "#"
16337   "&& 1"
16338   [(set (reg:CCC FLAGS_REG)
16339         (compare:CCC
16340          (zero_extract:SWI48 (match_dup 0) (const_int 1) (match_dup 1))
16341          (const_int 0)))]
16342   "operands[1] = gen_lowpart (QImode, operands[1]);")
16344 (define_insn_and_split "*jcc_bt<mode>"
16345   [(set (pc)
16346         (if_then_else (match_operator 0 "bt_comparison_operator"
16347                         [(zero_extract:SWI48
16348                            (match_operand:SWI48 1 "nonimmediate_operand")
16349                            (const_int 1)
16350                            (match_operand:QI 2 "nonmemory_operand"))
16351                          (const_int 0)])
16352                       (label_ref (match_operand 3))
16353                       (pc)))
16354    (clobber (reg:CC FLAGS_REG))]
16355   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16356    && (CONST_INT_P (operands[2])
16357        ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
16358           && INTVAL (operands[2])
16359                >= (optimize_function_for_size_p (cfun) ? 8 : 32))
16360        : !memory_operand (operands[1], <MODE>mode))
16361    && ix86_pre_reload_split ()"
16362   "#"
16363   "&& 1"
16364   [(set (reg:CCC FLAGS_REG)
16365         (compare:CCC
16366           (zero_extract:SWI48
16367             (match_dup 1)
16368             (const_int 1)
16369             (match_dup 2))
16370           (const_int 0)))
16371    (set (pc)
16372         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16373                       (label_ref (match_dup 3))
16374                       (pc)))]
16376   operands[0] = shallow_copy_rtx (operands[0]);
16377   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16380 ;; Avoid useless masking of bit offset operand.
16381 (define_insn_and_split "*jcc_bt<mode>_mask"
16382   [(set (pc)
16383         (if_then_else (match_operator 0 "bt_comparison_operator"
16384                         [(zero_extract:SWI48
16385                            (match_operand:SWI48 1 "register_operand")
16386                            (const_int 1)
16387                            (and:QI
16388                              (match_operand:QI 2 "register_operand")
16389                              (match_operand 3 "const_int_operand")))])
16390                       (label_ref (match_operand 4))
16391                       (pc)))
16392    (clobber (reg:CC FLAGS_REG))]
16393   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16394    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16395       == GET_MODE_BITSIZE (<MODE>mode)-1
16396    && ix86_pre_reload_split ()"
16397   "#"
16398   "&& 1"
16399   [(set (reg:CCC FLAGS_REG)
16400         (compare:CCC
16401           (zero_extract:SWI48
16402             (match_dup 1)
16403             (const_int 1)
16404             (match_dup 2))
16405           (const_int 0)))
16406    (set (pc)
16407         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16408                       (label_ref (match_dup 4))
16409                       (pc)))]
16411   operands[0] = shallow_copy_rtx (operands[0]);
16412   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16415 ;; Avoid useless masking of bit offset operand.
16416 (define_insn_and_split "*jcc_bt<SWI48:mode>_mask_1"
16417   [(set (pc)
16418         (if_then_else (match_operator 0 "bt_comparison_operator"
16419                         [(zero_extract:SWI48
16420                            (match_operand:SWI48 1 "register_operand")
16421                            (const_int 1)
16422                            (subreg:QI
16423                              (and:SWI248
16424                                (match_operand:SWI248 2 "register_operand")
16425                                (match_operand 3 "const_int_operand")) 0))])
16426                       (label_ref (match_operand 4))
16427                       (pc)))
16428    (clobber (reg:CC FLAGS_REG))]
16429   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16430    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
16431       == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
16432    && ix86_pre_reload_split ()"
16433   "#"
16434   "&& 1"
16435   [(set (reg:CCC FLAGS_REG)
16436         (compare:CCC
16437           (zero_extract:SWI48
16438             (match_dup 1)
16439             (const_int 1)
16440             (match_dup 2))
16441           (const_int 0)))
16442    (set (pc)
16443         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16444                       (label_ref (match_dup 4))
16445                       (pc)))]
16447   operands[0] = shallow_copy_rtx (operands[0]);
16448   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16449   operands[2] = gen_lowpart (QImode, operands[2]);
16452 ;; Help combine recognize bt followed by cmov
16453 (define_split
16454   [(set (match_operand:SWI248 0 "register_operand")
16455         (if_then_else:SWI248
16456          (match_operator 5 "bt_comparison_operator"
16457           [(zero_extract:SWI48
16458             (match_operand:SWI48 1 "register_operand")
16459             (const_int 1)
16460             (match_operand:QI 2 "register_operand"))
16461            (const_int 0)])
16462          (match_operand:SWI248 3 "nonimmediate_operand")
16463          (match_operand:SWI248 4 "nonimmediate_operand")))]
16464   "TARGET_USE_BT && TARGET_CMOVE
16465    && !(MEM_P (operands[3]) && MEM_P (operands[4]))
16466    && ix86_pre_reload_split ()"
16467   [(set (reg:CCC FLAGS_REG)
16468         (compare:CCC
16469          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16470          (const_int 0)))
16471    (set (match_dup 0)
16472         (if_then_else:SWI248 (eq (reg:CCC FLAGS_REG) (const_int 0))
16473                              (match_dup 3)
16474                              (match_dup 4)))]
16476   if (GET_CODE (operands[5]) == EQ)
16477     std::swap (operands[3], operands[4]);
16480 ;; Help combine recognize bt followed by setc
16481 (define_insn_and_split "*bt<mode>_setcqi"
16482   [(set (subreg:SWI48 (match_operand:QI 0 "register_operand") 0)
16483         (zero_extract:SWI48
16484          (match_operand:SWI48 1 "register_operand")
16485          (const_int 1)
16486          (match_operand:QI 2 "register_operand")))
16487    (clobber (reg:CC FLAGS_REG))]
16488   "TARGET_USE_BT && ix86_pre_reload_split ()"
16489   "#"
16490   "&& 1"
16491   [(set (reg:CCC FLAGS_REG)
16492         (compare:CCC
16493          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16494          (const_int 0)))
16495    (set (match_dup 0)
16496         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16498 ;; Help combine recognize bt followed by setnc
16499 (define_insn_and_split "*bt<mode>_setncqi"
16500   [(set (match_operand:QI 0 "register_operand")
16501         (and:QI
16502          (not:QI
16503           (subreg:QI
16504            (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16505                            (match_operand:QI 2 "register_operand")) 0))
16506          (const_int 1)))
16507    (clobber (reg:CC FLAGS_REG))]
16508   "TARGET_USE_BT && ix86_pre_reload_split ()"
16509   "#"
16510   "&& 1"
16511   [(set (reg:CCC FLAGS_REG)
16512         (compare:CCC
16513          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16514          (const_int 0)))
16515    (set (match_dup 0)
16516         (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16518 (define_insn_and_split "*bt<mode>_setnc<mode>"
16519   [(set (match_operand:SWI48 0 "register_operand")
16520         (and:SWI48
16521          (not:SWI48
16522           (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16523                           (match_operand:QI 2 "register_operand")))
16524          (const_int 1)))
16525    (clobber (reg:CC FLAGS_REG))]
16526   "TARGET_USE_BT && ix86_pre_reload_split ()"
16527   "#"
16528   "&& 1"
16529   [(set (reg:CCC FLAGS_REG)
16530         (compare:CCC
16531          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16532          (const_int 0)))
16533    (set (match_dup 3)
16534         (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
16535    (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16536   "operands[3] = gen_reg_rtx (QImode);")
16538 ;; Help combine recognize bt followed by setnc (PR target/110588)
16539 (define_insn_and_split "*bt<mode>_setncqi_2"
16540   [(set (match_operand:QI 0 "register_operand")
16541         (eq:QI
16542           (zero_extract:SWI48
16543             (match_operand:SWI48 1 "register_operand")
16544             (const_int 1)
16545             (match_operand:QI 2 "register_operand"))
16546           (const_int 0)))
16547    (clobber (reg:CC FLAGS_REG))]
16548   "TARGET_USE_BT && ix86_pre_reload_split ()"
16549   "#"
16550   "&& 1"
16551   [(set (reg:CCC FLAGS_REG)
16552         (compare:CCC
16553          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16554          (const_int 0)))
16555    (set (match_dup 0)
16556         (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16558 ;; Help combine recognize bt followed by setc
16559 (define_insn_and_split "*bt<mode>_setc<mode>_mask"
16560   [(set (match_operand:SWI48 0 "register_operand")
16561         (zero_extract:SWI48
16562           (match_operand:SWI48 1 "register_operand")
16563           (const_int 1)
16564           (subreg:QI
16565             (and:SWI48
16566               (match_operand:SWI48 2 "register_operand")
16567               (match_operand 3 "const_int_operand")) 0)))
16568    (clobber (reg:CC FLAGS_REG))]
16569   "TARGET_USE_BT
16570    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16571       == GET_MODE_BITSIZE (<MODE>mode)-1
16572    && ix86_pre_reload_split ()"
16573   "#"
16574   "&& 1"
16575   [(set (reg:CCC FLAGS_REG)
16576         (compare:CCC
16577          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16578          (const_int 0)))
16579    (set (match_dup 3)
16580         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))
16581    (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16583   operands[2] = gen_lowpart (QImode, operands[2]);
16584   operands[3] = gen_reg_rtx (QImode);
16587 ;; Store-flag instructions.
16589 (define_split
16590   [(set (match_operand:QI 0 "nonimmediate_operand")
16591         (match_operator:QI 1 "add_comparison_operator"
16592           [(not:SWI (match_operand:SWI 2 "register_operand"))
16593            (match_operand:SWI 3 "nonimmediate_operand")]))]
16594   ""
16595   [(set (reg:CCC FLAGS_REG)
16596         (compare:CCC
16597           (plus:SWI (match_dup 2) (match_dup 3))
16598           (match_dup 2)))
16599    (set (match_dup 0)
16600         (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))])
16602 (define_split
16603   [(set (match_operand:QI 0 "nonimmediate_operand")
16604         (match_operator:QI 1 "shr_comparison_operator"
16605           [(match_operand:DI 2 "register_operand")
16606            (match_operand 3 "const_int_operand")]))]
16607   "TARGET_64BIT
16608    && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16609   [(set (reg:CCZ FLAGS_REG)
16610         (compare:CCZ
16611           (lshiftrt:DI (match_dup 2) (match_dup 4))
16612           (const_int 0)))
16613    (set (match_dup 0)
16614         (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))]
16616   enum rtx_code new_code;
16618   operands[1] = shallow_copy_rtx (operands[1]);
16619   switch (GET_CODE (operands[1]))
16620     {
16621     case GTU: new_code = NE; break;
16622     case LEU: new_code = EQ; break;
16623     default: gcc_unreachable ();
16624     }
16625   PUT_CODE (operands[1], new_code);
16627   operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16630 ;; For all sCOND expanders, also expand the compare or test insn that
16631 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
16633 (define_insn_and_split "*setcc_di_1"
16634   [(set (match_operand:DI 0 "register_operand" "=q")
16635         (match_operator:DI 1 "ix86_comparison_operator"
16636           [(reg FLAGS_REG) (const_int 0)]))]
16637   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
16638   "#"
16639   "&& reload_completed"
16640   [(set (match_dup 2) (match_dup 1))
16641    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
16643   operands[1] = shallow_copy_rtx (operands[1]);
16644   PUT_MODE (operands[1], QImode);
16645   operands[2] = gen_lowpart (QImode, operands[0]);
16648 (define_insn_and_split "*setcc_<mode>_1_and"
16649   [(set (match_operand:SWI24 0 "register_operand" "=q")
16650         (match_operator:SWI24 1 "ix86_comparison_operator"
16651           [(reg FLAGS_REG) (const_int 0)]))
16652    (clobber (reg:CC FLAGS_REG))]
16653   "!TARGET_PARTIAL_REG_STALL
16654    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
16655   "#"
16656   "&& reload_completed"
16657   [(set (match_dup 2) (match_dup 1))
16658    (parallel [(set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))
16659               (clobber (reg:CC FLAGS_REG))])]
16661   operands[1] = shallow_copy_rtx (operands[1]);
16662   PUT_MODE (operands[1], QImode);
16663   operands[2] = gen_lowpart (QImode, operands[0]);
16666 (define_insn_and_split "*setcc_<mode>_1_movzbl"
16667   [(set (match_operand:SWI24 0 "register_operand" "=q")
16668         (match_operator:SWI24 1 "ix86_comparison_operator"
16669           [(reg FLAGS_REG) (const_int 0)]))]
16670   "!TARGET_PARTIAL_REG_STALL
16671    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
16672   "#"
16673   "&& reload_completed"
16674   [(set (match_dup 2) (match_dup 1))
16675    (set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))]
16677   operands[1] = shallow_copy_rtx (operands[1]);
16678   PUT_MODE (operands[1], QImode);
16679   operands[2] = gen_lowpart (QImode, operands[0]);
16682 (define_insn "*setcc_qi"
16683   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
16684         (match_operator:QI 1 "ix86_comparison_operator"
16685           [(reg FLAGS_REG) (const_int 0)]))]
16686   ""
16687   "set%C1\t%0"
16688   [(set_attr "type" "setcc")
16689    (set_attr "mode" "QI")])
16691 (define_insn "*setcc_qi_slp"
16692   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
16693         (match_operator:QI 1 "ix86_comparison_operator"
16694           [(reg FLAGS_REG) (const_int 0)]))]
16695   ""
16696   "set%C1\t%0"
16697   [(set_attr "type" "setcc")
16698    (set_attr "mode" "QI")])
16700 ;; In general it is not safe to assume too much about CCmode registers,
16701 ;; so simplify-rtx stops when it sees a second one.  Under certain
16702 ;; conditions this is safe on x86, so help combine not create
16704 ;;      seta    %al
16705 ;;      testb   %al, %al
16706 ;;      sete    %al
16708 (define_split
16709   [(set (match_operand:QI 0 "nonimmediate_operand")
16710         (ne:QI (match_operator 1 "ix86_comparison_operator"
16711                  [(reg FLAGS_REG) (const_int 0)])
16712             (const_int 0)))]
16713   ""
16714   [(set (match_dup 0) (match_dup 1))]
16716   operands[1] = shallow_copy_rtx (operands[1]);
16717   PUT_MODE (operands[1], QImode);
16720 (define_split
16721   [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16722         (ne:QI (match_operator 1 "ix86_comparison_operator"
16723                  [(reg FLAGS_REG) (const_int 0)])
16724             (const_int 0)))]
16725   ""
16726   [(set (match_dup 0) (match_dup 1))]
16728   operands[1] = shallow_copy_rtx (operands[1]);
16729   PUT_MODE (operands[1], QImode);
16732 (define_split
16733   [(set (match_operand:QI 0 "nonimmediate_operand")
16734         (eq:QI (match_operator 1 "ix86_comparison_operator"
16735                  [(reg FLAGS_REG) (const_int 0)])
16736             (const_int 0)))]
16737   ""
16738   [(set (match_dup 0) (match_dup 1))]
16740   operands[1] = shallow_copy_rtx (operands[1]);
16741   PUT_MODE (operands[1], QImode);
16742   PUT_CODE (operands[1],
16743             ix86_reverse_condition (GET_CODE (operands[1]),
16744                                     GET_MODE (XEXP (operands[1], 0))));
16746   /* Make sure that (a) the CCmode we have for the flags is strong
16747      enough for the reversed compare or (b) we have a valid FP compare.  */
16748   if (! ix86_comparison_operator (operands[1], VOIDmode))
16749     FAIL;
16752 (define_split
16753   [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16754         (eq:QI (match_operator 1 "ix86_comparison_operator"
16755                  [(reg FLAGS_REG) (const_int 0)])
16756             (const_int 0)))]
16757   ""
16758   [(set (match_dup 0) (match_dup 1))]
16760   operands[1] = shallow_copy_rtx (operands[1]);
16761   PUT_MODE (operands[1], QImode);
16762   PUT_CODE (operands[1],
16763             ix86_reverse_condition (GET_CODE (operands[1]),
16764                                     GET_MODE (XEXP (operands[1], 0))));
16766   /* Make sure that (a) the CCmode we have for the flags is strong
16767      enough for the reversed compare or (b) we have a valid FP compare.  */
16768   if (! ix86_comparison_operator (operands[1], VOIDmode))
16769     FAIL;
16772 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
16773 ;; subsequent logical operations are used to imitate conditional moves.
16774 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
16775 ;; it directly.
16777 (define_insn "setcc_<mode>_sse"
16778   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16779         (match_operator:MODEF 3 "sse_comparison_operator"
16780           [(match_operand:MODEF 1 "register_operand" "0,x")
16781            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xjm")]))]
16782   "SSE_FLOAT_MODE_P (<MODE>mode)"
16783   "@
16784    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
16785    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16786   [(set_attr "isa" "noavx,avx")
16787    (set_attr "addr" "*,gpr16")
16788    (set_attr "type" "ssecmp")
16789    (set_attr "length_immediate" "1")
16790    (set_attr "prefix" "orig,vex")
16791    (set_attr "mode" "<MODE>")])
16793 (define_insn "setcc_hf_mask"
16794   [(set (match_operand:QI 0 "register_operand" "=k")
16795         (unspec:QI
16796           [(match_operand:HF 1 "register_operand" "v")
16797            (match_operand:HF 2 "nonimmediate_operand" "vm")
16798            (match_operand:SI 3 "const_0_to_31_operand")]
16799           UNSPEC_PCMP))]
16800   "TARGET_AVX512FP16"
16801   "vcmpsh\t{%3, %2, %1, %0|%0, %1, %2, %3}"
16802   [(set_attr "type" "ssecmp")
16803    (set_attr "prefix" "evex")
16804    (set_attr "mode" "HF")])
16807 ;; Basic conditional jump instructions.
16809 (define_split
16810   [(set (pc)
16811         (if_then_else
16812           (match_operator 1 "add_comparison_operator"
16813             [(not:SWI (match_operand:SWI 2 "register_operand"))
16814              (match_operand:SWI 3 "nonimmediate_operand")])
16815           (label_ref (match_operand 0))
16816           (pc)))]
16817   ""
16818   [(set (reg:CCC FLAGS_REG)
16819         (compare:CCC
16820           (plus:SWI (match_dup 2) (match_dup 3))
16821           (match_dup 2)))
16822    (set (pc)
16823         (if_then_else (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)])
16824                       (label_ref (match_operand 0))
16825                       (pc)))])
16827 (define_split
16828   [(set (pc)
16829         (if_then_else
16830           (match_operator 1 "shr_comparison_operator"
16831             [(match_operand:DI 2 "register_operand")
16832              (match_operand 3 "const_int_operand")])
16833           (label_ref (match_operand 0))
16834           (pc)))]
16835   "TARGET_64BIT
16836    && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16837   [(set (reg:CCZ FLAGS_REG)
16838         (compare:CCZ
16839           (lshiftrt:DI (match_dup 2) (match_dup 4))
16840           (const_int 0)))
16841    (set (pc)
16842         (if_then_else (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)])
16843                       (label_ref (match_operand 0))
16844                       (pc)))]
16846   enum rtx_code new_code;
16848   operands[1] = shallow_copy_rtx (operands[1]);
16849   switch (GET_CODE (operands[1]))
16850     {
16851     case GTU: new_code = NE; break;
16852     case LEU: new_code = EQ; break;
16853     default: gcc_unreachable ();
16854     }
16855   PUT_CODE (operands[1], new_code);
16857   operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16860 ;; We ignore the overflow flag for signed branch instructions.
16862 (define_insn "*jcc"
16863   [(set (pc)
16864         (if_then_else (match_operator 1 "ix86_comparison_operator"
16865                                       [(reg FLAGS_REG) (const_int 0)])
16866                       (label_ref (match_operand 0))
16867                       (pc)))]
16868   ""
16869   "%!%+j%C1\t%l0"
16870   [(set_attr "type" "ibr")
16871    (set_attr "modrm" "0")
16872    (set (attr "length")
16873         (if_then_else
16874           (and (ge (minus (match_dup 0) (pc))
16875                    (const_int -126))
16876                (lt (minus (match_dup 0) (pc))
16877                    (const_int 128)))
16878           (const_int 2)
16879           (const_int 6)))])
16881 ;; In general it is not safe to assume too much about CCmode registers,
16882 ;; so simplify-rtx stops when it sees a second one.  Under certain
16883 ;; conditions this is safe on x86, so help combine not create
16885 ;;      seta    %al
16886 ;;      testb   %al, %al
16887 ;;      je      Lfoo
16889 (define_split
16890   [(set (pc)
16891         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
16892                                       [(reg FLAGS_REG) (const_int 0)])
16893                           (const_int 0))
16894                       (label_ref (match_operand 1))
16895                       (pc)))]
16896   ""
16897   [(set (pc)
16898         (if_then_else (match_dup 0)
16899                       (label_ref (match_dup 1))
16900                       (pc)))]
16902   operands[0] = shallow_copy_rtx (operands[0]);
16903   PUT_MODE (operands[0], VOIDmode);
16906 (define_split
16907   [(set (pc)
16908         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
16909                                       [(reg FLAGS_REG) (const_int 0)])
16910                           (const_int 0))
16911                       (label_ref (match_operand 1))
16912                       (pc)))]
16913   ""
16914   [(set (pc)
16915         (if_then_else (match_dup 0)
16916                       (label_ref (match_dup 1))
16917                       (pc)))]
16919   operands[0] = shallow_copy_rtx (operands[0]);
16920   PUT_MODE (operands[0], VOIDmode);
16921   PUT_CODE (operands[0],
16922             ix86_reverse_condition (GET_CODE (operands[0]),
16923                                     GET_MODE (XEXP (operands[0], 0))));
16925   /* Make sure that (a) the CCmode we have for the flags is strong
16926      enough for the reversed compare or (b) we have a valid FP compare.  */
16927   if (! ix86_comparison_operator (operands[0], VOIDmode))
16928     FAIL;
16931 ;; Unconditional and other jump instructions
16933 (define_insn "jump"
16934   [(set (pc)
16935         (label_ref (match_operand 0)))]
16936   ""
16937   "%!jmp\t%l0"
16938   [(set_attr "type" "ibr")
16939    (set_attr "modrm" "0")
16940    (set (attr "length")
16941         (if_then_else
16942           (and (ge (minus (match_dup 0) (pc))
16943                    (const_int -126))
16944                (lt (minus (match_dup 0) (pc))
16945                    (const_int 128)))
16946           (const_int 2)
16947           (const_int 5)))])
16949 (define_expand "indirect_jump"
16950   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
16951   ""
16953   if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
16954     operands[0] = convert_memory_address (word_mode, operands[0]);
16955   cfun->machine->has_local_indirect_jump = true;
16958 (define_insn "*indirect_jump"
16959   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
16960   ""
16961   "* return ix86_output_indirect_jmp (operands[0]);"
16962   [(set (attr "type")
16963      (if_then_else (match_test "(cfun->machine->indirect_branch_type
16964                                  != indirect_branch_keep)")
16965         (const_string "multi")
16966         (const_string "ibr")))
16967    (set_attr "length_immediate" "0")])
16969 (define_expand "tablejump"
16970   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
16971               (use (label_ref (match_operand 1)))])]
16972   ""
16974   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
16975      relative.  Convert the relative address to an absolute address.  */
16976   if (flag_pic)
16977     {
16978       rtx op0, op1;
16979       enum rtx_code code;
16981       /* We can't use @GOTOFF for text labels on VxWorks;
16982          see gotoff_operand.  */
16983       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
16984         {
16985           code = PLUS;
16986           op0 = operands[0];
16987           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
16988         }
16989       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
16990         {
16991           code = PLUS;
16992           op0 = operands[0];
16993           op1 = pic_offset_table_rtx;
16994         }
16995       else
16996         {
16997           code = MINUS;
16998           op0 = pic_offset_table_rtx;
16999           op1 = operands[0];
17000         }
17002       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
17003                                          OPTAB_DIRECT);
17004     }
17006   if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
17007     operands[0] = convert_memory_address (word_mode, operands[0]);
17008   cfun->machine->has_local_indirect_jump = true;
17011 (define_insn "*tablejump_1"
17012   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
17013    (use (label_ref (match_operand 1)))]
17014   ""
17015   "* return ix86_output_indirect_jmp (operands[0]);"
17016   [(set (attr "type")
17017      (if_then_else (match_test "(cfun->machine->indirect_branch_type
17018                                  != indirect_branch_keep)")
17019         (const_string "multi")
17020         (const_string "ibr")))
17021    (set_attr "length_immediate" "0")])
17023 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
17025 (define_peephole2
17026   [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
17027    (set (match_operand:QI 1 "register_operand")
17028         (match_operator:QI 2 "ix86_comparison_operator"
17029           [(reg FLAGS_REG) (const_int 0)]))
17030    (set (match_operand 3 "any_QIreg_operand")
17031         (zero_extend (match_dup 1)))]
17032   "(peep2_reg_dead_p (3, operands[1])
17033     || operands_match_p (operands[1], operands[3]))
17034    && ! reg_overlap_mentioned_p (operands[3], operands[0])
17035    && peep2_regno_dead_p (0, FLAGS_REG)"
17036   [(set (match_dup 4) (match_dup 0))
17037    (set (strict_low_part (match_dup 5))
17038         (match_dup 2))]
17040   operands[5] = gen_lowpart (QImode, operands[3]);
17041   ix86_expand_clear (operands[3]);
17044 (define_peephole2
17045   [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
17046               (match_operand 4)])
17047    (set (match_operand:QI 1 "register_operand")
17048         (match_operator:QI 2 "ix86_comparison_operator"
17049           [(reg FLAGS_REG) (const_int 0)]))
17050    (set (match_operand 3 "any_QIreg_operand")
17051         (zero_extend (match_dup 1)))]
17052   "(peep2_reg_dead_p (3, operands[1])
17053     || operands_match_p (operands[1], operands[3]))
17054    && ! reg_overlap_mentioned_p (operands[3], operands[0])
17055    && ! reg_overlap_mentioned_p (operands[3], operands[4])
17056    && ! reg_set_p (operands[3], operands[4])
17057    && peep2_regno_dead_p (0, FLAGS_REG)"
17058   [(parallel [(set (match_dup 5) (match_dup 0))
17059               (match_dup 4)])
17060    (set (strict_low_part (match_dup 6))
17061         (match_dup 2))]
17063   operands[6] = gen_lowpart (QImode, operands[3]);
17064   ix86_expand_clear (operands[3]);
17067 (define_peephole2
17068   [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
17069    (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
17070               (match_operand 5)])
17071    (set (match_operand:QI 2 "register_operand")
17072         (match_operator:QI 3 "ix86_comparison_operator"
17073           [(reg FLAGS_REG) (const_int 0)]))
17074    (set (match_operand 4 "any_QIreg_operand")
17075         (zero_extend (match_dup 2)))]
17076   "(peep2_reg_dead_p (4, operands[2])
17077     || operands_match_p (operands[2], operands[4]))
17078    && ! reg_overlap_mentioned_p (operands[4], operands[0])
17079    && ! reg_overlap_mentioned_p (operands[4], operands[1])
17080    && ! reg_overlap_mentioned_p (operands[4], operands[5])
17081    && ! reg_set_p (operands[4], operands[5])
17082    && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
17083    && peep2_regno_dead_p (0, FLAGS_REG)"
17084   [(set (match_dup 6) (match_dup 0))
17085    (parallel [(set (match_dup 7) (match_dup 1))
17086               (match_dup 5)])
17087    (set (strict_low_part (match_dup 8))
17088         (match_dup 3))]
17090   operands[8] = gen_lowpart (QImode, operands[4]);
17091   ix86_expand_clear (operands[4]);
17094 ;; Similar, but match zero extend with andsi3.
17096 (define_peephole2
17097   [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
17098    (set (match_operand:QI 1 "register_operand")
17099         (match_operator:QI 2 "ix86_comparison_operator"
17100           [(reg FLAGS_REG) (const_int 0)]))
17101    (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
17102                    (and:SI (match_dup 3) (const_int 255)))
17103               (clobber (reg:CC FLAGS_REG))])]
17104   "REGNO (operands[1]) == REGNO (operands[3])
17105    && ! reg_overlap_mentioned_p (operands[3], operands[0])
17106    && peep2_regno_dead_p (0, FLAGS_REG)"
17107   [(set (match_dup 4) (match_dup 0))
17108    (set (strict_low_part (match_dup 5))
17109         (match_dup 2))]
17111   operands[5] = gen_lowpart (QImode, operands[3]);
17112   ix86_expand_clear (operands[3]);
17115 (define_peephole2
17116   [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
17117               (match_operand 4)])
17118    (set (match_operand:QI 1 "register_operand")
17119         (match_operator:QI 2 "ix86_comparison_operator"
17120           [(reg FLAGS_REG) (const_int 0)]))
17121    (parallel [(set (match_operand 3 "any_QIreg_operand")
17122                    (zero_extend (match_dup 1)))
17123               (clobber (reg:CC FLAGS_REG))])]
17124   "(peep2_reg_dead_p (3, operands[1])
17125     || operands_match_p (operands[1], operands[3]))
17126    && ! reg_overlap_mentioned_p (operands[3], operands[0])
17127    && ! reg_overlap_mentioned_p (operands[3], operands[4])
17128    && ! reg_set_p (operands[3], operands[4])
17129    && peep2_regno_dead_p (0, FLAGS_REG)"
17130   [(parallel [(set (match_dup 5) (match_dup 0))
17131               (match_dup 4)])
17132    (set (strict_low_part (match_dup 6))
17133         (match_dup 2))]
17135   operands[6] = gen_lowpart (QImode, operands[3]);
17136   ix86_expand_clear (operands[3]);
17139 (define_peephole2
17140   [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
17141    (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
17142               (match_operand 5)])
17143    (set (match_operand:QI 2 "register_operand")
17144         (match_operator:QI 3 "ix86_comparison_operator"
17145           [(reg FLAGS_REG) (const_int 0)]))
17146    (parallel [(set (match_operand 4 "any_QIreg_operand")
17147                    (zero_extend (match_dup 2)))
17148               (clobber (reg:CC FLAGS_REG))])]
17149   "(peep2_reg_dead_p (4, operands[2])
17150     || operands_match_p (operands[2], operands[4]))
17151    && ! reg_overlap_mentioned_p (operands[4], operands[0])
17152    && ! reg_overlap_mentioned_p (operands[4], operands[1])
17153    && ! reg_overlap_mentioned_p (operands[4], operands[5])
17154    && ! reg_set_p (operands[4], operands[5])
17155    && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
17156    && peep2_regno_dead_p (0, FLAGS_REG)"
17157   [(set (match_dup 6) (match_dup 0))
17158    (parallel [(set (match_dup 7) (match_dup 1))
17159               (match_dup 5)])
17160    (set (strict_low_part (match_dup 8))
17161         (match_dup 3))]
17163   operands[8] = gen_lowpart (QImode, operands[4]);
17164   ix86_expand_clear (operands[4]);
17167 ;; Call instructions.
17169 ;; The predicates normally associated with named expanders are not properly
17170 ;; checked for calls.  This is a bug in the generic code, but it isn't that
17171 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
17173 ;; P6 processors will jump to the address after the decrement when %esp
17174 ;; is used as a call operand, so they will execute return address as a code.
17175 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
17177 ;; Register constraint for call instruction.
17178 (define_mode_attr c [(SI "l") (DI "r")])
17180 ;; Call subroutine returning no value.
17182 (define_expand "call"
17183   [(call (match_operand:QI 0)
17184          (match_operand 1))
17185    (use (match_operand 2))]
17186   ""
17188   ix86_expand_call (NULL, operands[0], operands[1],
17189                     operands[2], NULL, false);
17190   DONE;
17193 (define_expand "sibcall"
17194   [(call (match_operand:QI 0)
17195          (match_operand 1))
17196    (use (match_operand 2))]
17197   ""
17199   ix86_expand_call (NULL, operands[0], operands[1],
17200                     operands[2], NULL, true);
17201   DONE;
17204 (define_insn "*call"
17205   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
17206          (match_operand 1))]
17207   "!SIBLING_CALL_P (insn)"
17208   "* return ix86_output_call_insn (insn, operands[0]);"
17209   [(set_attr "type" "call")])
17211 ;; This covers both call and sibcall since only GOT slot is allowed.
17212 (define_insn "*call_got_x32"
17213   [(call (mem:QI (zero_extend:DI
17214                    (match_operand:SI 0 "GOT_memory_operand" "Bg")))
17215          (match_operand 1))]
17216   "TARGET_X32"
17218   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
17219   return ix86_output_call_insn (insn, fnaddr);
17221   [(set_attr "type" "call")])
17223 ;; Since sibcall never returns, we can only use call-clobbered register
17224 ;; as GOT base.
17225 (define_insn "*sibcall_GOT_32"
17226   [(call (mem:QI
17227            (mem:SI (plus:SI
17228                      (match_operand:SI 0 "register_no_elim_operand" "U")
17229                      (match_operand:SI 1 "GOT32_symbol_operand"))))
17230          (match_operand 2))]
17231   "!TARGET_MACHO
17232   && !TARGET_64BIT
17233   && !TARGET_INDIRECT_BRANCH_REGISTER
17234   && SIBLING_CALL_P (insn)"
17236   rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
17237   fnaddr = gen_const_mem (SImode, fnaddr);
17238   return ix86_output_call_insn (insn, fnaddr);
17240   [(set_attr "type" "call")])
17242 (define_insn "*sibcall"
17243   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
17244          (match_operand 1))]
17245   "SIBLING_CALL_P (insn)"
17246   "* return ix86_output_call_insn (insn, operands[0]);"
17247   [(set_attr "type" "call")])
17249 (define_insn "*sibcall_memory"
17250   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
17251          (match_operand 1))
17252    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17253   "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17254   "* return ix86_output_call_insn (insn, operands[0]);"
17255   [(set_attr "type" "call")])
17257 (define_peephole2
17258   [(set (match_operand:W 0 "register_operand")
17259         (match_operand:W 1 "memory_operand"))
17260    (call (mem:QI (match_dup 0))
17261          (match_operand 3))]
17262   "!TARGET_X32
17263    && !TARGET_INDIRECT_BRANCH_REGISTER
17264    && SIBLING_CALL_P (peep2_next_insn (1))
17265    && !reg_mentioned_p (operands[0],
17266                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17267   [(parallel [(call (mem:QI (match_dup 1))
17268                     (match_dup 3))
17269               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17271 (define_peephole2
17272   [(set (match_operand:W 0 "register_operand")
17273         (match_operand:W 1 "memory_operand"))
17274    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17275    (call (mem:QI (match_dup 0))
17276          (match_operand 3))]
17277   "!TARGET_X32
17278    && !TARGET_INDIRECT_BRANCH_REGISTER
17279    && SIBLING_CALL_P (peep2_next_insn (2))
17280    && !reg_mentioned_p (operands[0],
17281                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17282   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17283    (parallel [(call (mem:QI (match_dup 1))
17284                     (match_dup 3))
17285               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17287 (define_expand "call_pop"
17288   [(parallel [(call (match_operand:QI 0)
17289                     (match_operand:SI 1))
17290               (set (reg:SI SP_REG)
17291                    (plus:SI (reg:SI SP_REG)
17292                             (match_operand:SI 3)))])]
17293   "!TARGET_64BIT"
17295   ix86_expand_call (NULL, operands[0], operands[1],
17296                     operands[2], operands[3], false);
17297   DONE;
17300 (define_insn "*call_pop"
17301   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
17302          (match_operand 1))
17303    (set (reg:SI SP_REG)
17304         (plus:SI (reg:SI SP_REG)
17305                  (match_operand:SI 2 "immediate_operand" "i")))]
17306   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17307   "* return ix86_output_call_insn (insn, operands[0]);"
17308   [(set_attr "type" "call")])
17310 (define_insn "*sibcall_pop"
17311   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
17312          (match_operand 1))
17313    (set (reg:SI SP_REG)
17314         (plus:SI (reg:SI SP_REG)
17315                  (match_operand:SI 2 "immediate_operand" "i")))]
17316   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17317   "* return ix86_output_call_insn (insn, operands[0]);"
17318   [(set_attr "type" "call")])
17320 (define_insn "*sibcall_pop_memory"
17321   [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
17322          (match_operand 1))
17323    (set (reg:SI SP_REG)
17324         (plus:SI (reg:SI SP_REG)
17325                  (match_operand:SI 2 "immediate_operand" "i")))
17326    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17327   "!TARGET_64BIT"
17328   "* return ix86_output_call_insn (insn, operands[0]);"
17329   [(set_attr "type" "call")])
17331 (define_peephole2
17332   [(set (match_operand:SI 0 "register_operand")
17333         (match_operand:SI 1 "memory_operand"))
17334    (parallel [(call (mem:QI (match_dup 0))
17335                     (match_operand 3))
17336               (set (reg:SI SP_REG)
17337                    (plus:SI (reg:SI SP_REG)
17338                             (match_operand:SI 4 "immediate_operand")))])]
17339   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17340    && !reg_mentioned_p (operands[0],
17341                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17342   [(parallel [(call (mem:QI (match_dup 1))
17343                     (match_dup 3))
17344               (set (reg:SI SP_REG)
17345                    (plus:SI (reg:SI SP_REG)
17346                             (match_dup 4)))
17347               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17349 (define_peephole2
17350   [(set (match_operand:SI 0 "register_operand")
17351         (match_operand:SI 1 "memory_operand"))
17352    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17353    (parallel [(call (mem:QI (match_dup 0))
17354                     (match_operand 3))
17355               (set (reg:SI SP_REG)
17356                    (plus:SI (reg:SI SP_REG)
17357                             (match_operand:SI 4 "immediate_operand")))])]
17358   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17359    && !reg_mentioned_p (operands[0],
17360                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17361   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17362    (parallel [(call (mem:QI (match_dup 1))
17363                     (match_dup 3))
17364               (set (reg:SI SP_REG)
17365                    (plus:SI (reg:SI SP_REG)
17366                             (match_dup 4)))
17367               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17369 ;; Combining simple memory jump instruction
17371 (define_peephole2
17372   [(set (match_operand:W 0 "register_operand")
17373         (match_operand:W 1 "memory_operand"))
17374    (set (pc) (match_dup 0))]
17375   "!TARGET_X32
17376    && !TARGET_INDIRECT_BRANCH_REGISTER
17377    && peep2_reg_dead_p (2, operands[0])"
17378   [(set (pc) (match_dup 1))])
17380 ;; Call subroutine, returning value in operand 0
17382 (define_expand "call_value"
17383   [(set (match_operand 0)
17384         (call (match_operand:QI 1)
17385               (match_operand 2)))
17386    (use (match_operand 3))]
17387   ""
17389   ix86_expand_call (operands[0], operands[1], operands[2],
17390                     operands[3], NULL, false);
17391   DONE;
17394 (define_expand "sibcall_value"
17395   [(set (match_operand 0)
17396         (call (match_operand:QI 1)
17397               (match_operand 2)))
17398    (use (match_operand 3))]
17399   ""
17401   ix86_expand_call (operands[0], operands[1], operands[2],
17402                     operands[3], NULL, true);
17403   DONE;
17406 (define_insn "*call_value"
17407   [(set (match_operand 0)
17408         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
17409               (match_operand 2)))]
17410   "!SIBLING_CALL_P (insn)"
17411   "* return ix86_output_call_insn (insn, operands[1]);"
17412   [(set_attr "type" "callv")])
17414 ;; This covers both call and sibcall since only GOT slot is allowed.
17415 (define_insn "*call_value_got_x32"
17416   [(set (match_operand 0)
17417         (call (mem:QI
17418                 (zero_extend:DI
17419                   (match_operand:SI 1 "GOT_memory_operand" "Bg")))
17420               (match_operand 2)))]
17421   "TARGET_X32"
17423   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
17424   return ix86_output_call_insn (insn, fnaddr);
17426   [(set_attr "type" "callv")])
17428 ;; Since sibcall never returns, we can only use call-clobbered register
17429 ;; as GOT base.
17430 (define_insn "*sibcall_value_GOT_32"
17431   [(set (match_operand 0)
17432         (call (mem:QI
17433                 (mem:SI (plus:SI
17434                           (match_operand:SI 1 "register_no_elim_operand" "U")
17435                           (match_operand:SI 2 "GOT32_symbol_operand"))))
17436          (match_operand 3)))]
17437   "!TARGET_MACHO
17438    && !TARGET_64BIT
17439    && !TARGET_INDIRECT_BRANCH_REGISTER
17440    && SIBLING_CALL_P (insn)"
17442   rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
17443   fnaddr = gen_const_mem (SImode, fnaddr);
17444   return ix86_output_call_insn (insn, fnaddr);
17446   [(set_attr "type" "callv")])
17448 (define_insn "*sibcall_value"
17449   [(set (match_operand 0)
17450         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
17451               (match_operand 2)))]
17452   "SIBLING_CALL_P (insn)"
17453   "* return ix86_output_call_insn (insn, operands[1]);"
17454   [(set_attr "type" "callv")])
17456 (define_insn "*sibcall_value_memory"
17457   [(set (match_operand 0)
17458         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
17459               (match_operand 2)))
17460    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17461   "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17462   "* return ix86_output_call_insn (insn, operands[1]);"
17463   [(set_attr "type" "callv")])
17465 (define_peephole2
17466   [(set (match_operand:W 0 "register_operand")
17467         (match_operand:W 1 "memory_operand"))
17468    (set (match_operand 2)
17469    (call (mem:QI (match_dup 0))
17470                  (match_operand 3)))]
17471   "!TARGET_X32
17472    && !TARGET_INDIRECT_BRANCH_REGISTER
17473    && SIBLING_CALL_P (peep2_next_insn (1))
17474    && !reg_mentioned_p (operands[0],
17475                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17476   [(parallel [(set (match_dup 2)
17477                    (call (mem:QI (match_dup 1))
17478                          (match_dup 3)))
17479               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17481 (define_peephole2
17482   [(set (match_operand:W 0 "register_operand")
17483         (match_operand:W 1 "memory_operand"))
17484    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17485    (set (match_operand 2)
17486         (call (mem:QI (match_dup 0))
17487               (match_operand 3)))]
17488   "!TARGET_X32
17489    && !TARGET_INDIRECT_BRANCH_REGISTER
17490    && SIBLING_CALL_P (peep2_next_insn (2))
17491    && !reg_mentioned_p (operands[0],
17492                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17493   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17494    (parallel [(set (match_dup 2)
17495                    (call (mem:QI (match_dup 1))
17496                          (match_dup 3)))
17497               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17499 (define_expand "call_value_pop"
17500   [(parallel [(set (match_operand 0)
17501                    (call (match_operand:QI 1)
17502                          (match_operand:SI 2)))
17503               (set (reg:SI SP_REG)
17504                    (plus:SI (reg:SI SP_REG)
17505                             (match_operand:SI 4)))])]
17506   "!TARGET_64BIT"
17508   ix86_expand_call (operands[0], operands[1], operands[2],
17509                     operands[3], operands[4], false);
17510   DONE;
17513 (define_insn "*call_value_pop"
17514   [(set (match_operand 0)
17515         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
17516               (match_operand 2)))
17517    (set (reg:SI SP_REG)
17518         (plus:SI (reg:SI SP_REG)
17519                  (match_operand:SI 3 "immediate_operand" "i")))]
17520   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17521   "* return ix86_output_call_insn (insn, operands[1]);"
17522   [(set_attr "type" "callv")])
17524 (define_insn "*sibcall_value_pop"
17525   [(set (match_operand 0)
17526         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
17527               (match_operand 2)))
17528    (set (reg:SI SP_REG)
17529         (plus:SI (reg:SI SP_REG)
17530                  (match_operand:SI 3 "immediate_operand" "i")))]
17531   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17532   "* return ix86_output_call_insn (insn, operands[1]);"
17533   [(set_attr "type" "callv")])
17535 (define_insn "*sibcall_value_pop_memory"
17536   [(set (match_operand 0)
17537         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
17538               (match_operand 2)))
17539    (set (reg:SI SP_REG)
17540         (plus:SI (reg:SI SP_REG)
17541                  (match_operand:SI 3 "immediate_operand" "i")))
17542    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17543   "!TARGET_64BIT"
17544   "* return ix86_output_call_insn (insn, operands[1]);"
17545   [(set_attr "type" "callv")])
17547 (define_peephole2
17548   [(set (match_operand:SI 0 "register_operand")
17549         (match_operand:SI 1 "memory_operand"))
17550    (parallel [(set (match_operand 2)
17551                    (call (mem:QI (match_dup 0))
17552                          (match_operand 3)))
17553               (set (reg:SI SP_REG)
17554                    (plus:SI (reg:SI SP_REG)
17555                             (match_operand:SI 4 "immediate_operand")))])]
17556   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17557    && !reg_mentioned_p (operands[0],
17558                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17559   [(parallel [(set (match_dup 2)
17560                    (call (mem:QI (match_dup 1))
17561                          (match_dup 3)))
17562               (set (reg:SI SP_REG)
17563                    (plus:SI (reg:SI SP_REG)
17564                             (match_dup 4)))
17565               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17567 (define_peephole2
17568   [(set (match_operand:SI 0 "register_operand")
17569         (match_operand:SI 1 "memory_operand"))
17570    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17571    (parallel [(set (match_operand 2)
17572                    (call (mem:QI (match_dup 0))
17573                          (match_operand 3)))
17574               (set (reg:SI SP_REG)
17575                    (plus:SI (reg:SI SP_REG)
17576                             (match_operand:SI 4 "immediate_operand")))])]
17577   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17578    && !reg_mentioned_p (operands[0],
17579                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17580   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17581    (parallel [(set (match_dup 2)
17582                    (call (mem:QI (match_dup 1))
17583                          (match_dup 3)))
17584               (set (reg:SI SP_REG)
17585                    (plus:SI (reg:SI SP_REG)
17586                             (match_dup 4)))
17587               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17589 ;; Call subroutine returning any type.
17591 (define_expand "untyped_call"
17592   [(parallel [(call (match_operand 0)
17593                     (const_int 0))
17594               (match_operand 1)
17595               (match_operand 2)])]
17596   ""
17598   int i;
17600   /* In order to give reg-stack an easier job in validating two
17601      coprocessor registers as containing a possible return value,
17602      simply pretend the untyped call returns a complex long double
17603      value. 
17605      We can't use SSE_REGPARM_MAX here since callee is unprototyped
17606      and should have the default ABI.  */
17608   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
17609                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
17610                     operands[0], const0_rtx,
17611                     GEN_INT ((TARGET_64BIT
17612                               ? (ix86_abi == SYSV_ABI
17613                                  ? X86_64_SSE_REGPARM_MAX
17614                                  : X86_64_MS_SSE_REGPARM_MAX)
17615                               : X86_32_SSE_REGPARM_MAX)
17616                              - 1),
17617                     NULL, false);
17619   for (i = 0; i < XVECLEN (operands[2], 0); i++)
17620     {
17621       rtx set = XVECEXP (operands[2], 0, i);
17622       emit_move_insn (SET_DEST (set), SET_SRC (set));
17623     }
17625   /* The optimizer does not know that the call sets the function value
17626      registers we stored in the result block.  We avoid problems by
17627      claiming that all hard registers are used and clobbered at this
17628      point.  */
17629   emit_insn (gen_blockage ());
17631   DONE;
17634 ;; Prologue and epilogue instructions
17636 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
17637 ;; all of memory.  This blocks insns from being moved across this point.
17639 (define_insn "blockage"
17640   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
17641   ""
17642   ""
17643   [(set_attr "length" "0")])
17645 ;; Do not schedule instructions accessing memory across this point.
17647 (define_expand "memory_blockage"
17648   [(set (match_dup 0)
17649         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17650   ""
17652   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17653   MEM_VOLATILE_P (operands[0]) = 1;
17656 (define_insn "*memory_blockage"
17657   [(set (match_operand:BLK 0)
17658         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17659   ""
17660   ""
17661   [(set_attr "length" "0")])
17663 ;; As USE insns aren't meaningful after reload, this is used instead
17664 ;; to prevent deleting instructions setting registers for PIC code
17665 (define_insn "prologue_use"
17666   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
17667   ""
17668   ""
17669   [(set_attr "length" "0")])
17671 ;; Insn emitted into the body of a function to return from a function.
17672 ;; This is only done if the function's epilogue is known to be simple.
17673 ;; See comments for ix86_can_use_return_insn_p in i386.cc.
17675 (define_expand "return"
17676   [(simple_return)]
17677   "ix86_can_use_return_insn_p ()"
17679   if (crtl->args.pops_args)
17680     {
17681       rtx popc = GEN_INT (crtl->args.pops_args);
17682       emit_jump_insn (gen_simple_return_pop_internal (popc));
17683       DONE;
17684     }
17687 ;; We need to disable this for TARGET_SEH, as otherwise
17688 ;; shrink-wrapped prologue gets enabled too.  This might exceed
17689 ;; the maximum size of prologue in unwind information.
17690 ;; Also disallow shrink-wrapping if using stack slot to pass the
17691 ;; static chain pointer - the first instruction has to be pushl %esi
17692 ;; and it can't be moved around, as we use alternate entry points
17693 ;; in that case.
17694 ;; Also disallow for ms_hook_prologue functions which have frame
17695 ;; pointer set up in function label which is correctly handled in
17696 ;; ix86_expand_{prologue|epligoue}() only.
17698 (define_expand "simple_return"
17699   [(simple_return)]
17700   "!TARGET_SEH && !ix86_static_chain_on_stack && !ix86_function_ms_hook_prologue (cfun->decl)"
17702   if (crtl->args.pops_args)
17703     {
17704       rtx popc = GEN_INT (crtl->args.pops_args);
17705       emit_jump_insn (gen_simple_return_pop_internal (popc));
17706       DONE;
17707     }
17710 (define_insn "simple_return_internal"
17711   [(simple_return)]
17712   "reload_completed"
17713   "* return ix86_output_function_return (false);"
17714   [(set_attr "length" "1")
17715    (set_attr "atom_unit" "jeu")
17716    (set_attr "length_immediate" "0")
17717    (set_attr "modrm" "0")])
17719 (define_insn "interrupt_return"
17720   [(simple_return)
17721    (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
17722   "reload_completed"
17724   return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret";
17727 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
17728 ;; instruction Athlon and K8 have.
17730 (define_insn "simple_return_internal_long"
17731   [(simple_return)
17732    (unspec [(const_int 0)] UNSPEC_REP)]
17733   "reload_completed"
17734   "* return ix86_output_function_return (true);"
17735   [(set_attr "length" "2")
17736    (set_attr "atom_unit" "jeu")
17737    (set_attr "length_immediate" "0")
17738    (set_attr "prefix_rep" "1")
17739    (set_attr "modrm" "0")])
17741 (define_insn_and_split "simple_return_pop_internal"
17742   [(simple_return)
17743    (use (match_operand:SI 0 "const_int_operand"))]
17744   "reload_completed"
17745   "ret\t%0"
17746   "&& cfun->machine->function_return_type != indirect_branch_keep"
17747   [(const_int 0)]
17748   "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
17749   [(set_attr "length" "3")
17750    (set_attr "atom_unit" "jeu")
17751    (set_attr "length_immediate" "2")
17752    (set_attr "modrm" "0")])
17754 (define_expand "simple_return_indirect_internal"
17755   [(parallel
17756      [(simple_return)
17757       (use (match_operand 0 "register_operand"))])])
17759 (define_insn "*simple_return_indirect_internal<mode>"
17760   [(simple_return)
17761    (use (match_operand:W 0 "register_operand" "r"))]
17762   "reload_completed"
17763   "* return ix86_output_indirect_function_return (operands[0]);"
17764   [(set (attr "type")
17765      (if_then_else (match_test "(cfun->machine->indirect_branch_type
17766                                  != indirect_branch_keep)")
17767         (const_string "multi")
17768         (const_string "ibr")))
17769    (set_attr "length_immediate" "0")])
17771 (define_insn "nop"
17772   [(const_int 0)]
17773   ""
17774   "nop"
17775   [(set_attr "length" "1")
17776    (set_attr "length_immediate" "0")
17777    (set_attr "modrm" "0")])
17779 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
17780 (define_insn "nops"
17781   [(unspec_volatile [(match_operand 0 "const_int_operand")]
17782                     UNSPECV_NOPS)]
17783   "reload_completed"
17785   int num = INTVAL (operands[0]);
17787   gcc_assert (IN_RANGE (num, 1, 8));
17789   while (num--)
17790     fputs ("\tnop\n", asm_out_file);
17792   return "";
17794   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
17795    (set_attr "length_immediate" "0")
17796    (set_attr "modrm" "0")])
17798 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
17799 ;; branch prediction penalty for the third jump in a 16-byte
17800 ;; block on K8.
17802 (define_insn "pad"
17803   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
17804   ""
17806 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
17807   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
17808 #else
17809   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
17810      The align insn is used to avoid 3 jump instructions in the row to improve
17811      branch prediction and the benefits hardly outweigh the cost of extra 8
17812      nops on the average inserted by full alignment pseudo operation.  */
17813 #endif
17814   return "";
17816   [(set_attr "length" "16")])
17818 (define_expand "prologue"
17819   [(const_int 0)]
17820   ""
17821   "ix86_expand_prologue (); DONE;")
17823 (define_expand "set_got"
17824   [(parallel
17825      [(set (match_operand:SI 0 "register_operand")
17826            (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
17827       (clobber (reg:CC FLAGS_REG))])]
17828   "!TARGET_64BIT"
17830   if (flag_pic && !TARGET_VXWORKS_RTP)
17831     ix86_pc_thunk_call_expanded = true;
17834 (define_insn "*set_got"
17835   [(set (match_operand:SI 0 "register_operand" "=r")
17836         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
17837    (clobber (reg:CC FLAGS_REG))]
17838   "!TARGET_64BIT"
17839   "* return output_set_got (operands[0], NULL_RTX);"
17840   [(set_attr "type" "multi")
17841    (set_attr "length" "12")])
17843 (define_expand "set_got_labelled"
17844   [(parallel
17845      [(set (match_operand:SI 0 "register_operand")
17846            (unspec:SI [(label_ref (match_operand 1))]
17847                       UNSPEC_SET_GOT))
17848       (clobber (reg:CC FLAGS_REG))])]
17849   "!TARGET_64BIT"
17851   if (flag_pic && !TARGET_VXWORKS_RTP)
17852     ix86_pc_thunk_call_expanded = true;
17855 (define_insn "*set_got_labelled"
17856   [(set (match_operand:SI 0 "register_operand" "=r")
17857         (unspec:SI [(label_ref (match_operand 1))]
17858          UNSPEC_SET_GOT))
17859    (clobber (reg:CC FLAGS_REG))]
17860   "!TARGET_64BIT"
17861   "* return output_set_got (operands[0], operands[1]);"
17862   [(set_attr "type" "multi")
17863    (set_attr "length" "12")])
17865 (define_insn "set_got_rex64"
17866   [(set (match_operand:DI 0 "register_operand" "=r")
17867         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
17868   "TARGET_64BIT"
17869   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
17870   [(set_attr "type" "lea")
17871    (set_attr "length_address" "4")
17872    (set_attr "mode" "DI")])
17874 (define_insn "set_rip_rex64"
17875   [(set (match_operand:DI 0 "register_operand" "=r")
17876         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
17877   "TARGET_64BIT"
17878   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
17879   [(set_attr "type" "lea")
17880    (set_attr "length_address" "4")
17881    (set_attr "mode" "DI")])
17883 (define_insn "set_got_offset_rex64"
17884   [(set (match_operand:DI 0 "register_operand" "=r")
17885         (unspec:DI
17886           [(label_ref (match_operand 1))]
17887           UNSPEC_SET_GOT_OFFSET))]
17888   "TARGET_LP64"
17889   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
17890   [(set_attr "type" "imov")
17891    (set_attr "length_immediate" "0")
17892    (set_attr "length_address" "8")
17893    (set_attr "mode" "DI")])
17895 (define_expand "epilogue"
17896   [(const_int 0)]
17897   ""
17898   "ix86_expand_epilogue (1); DONE;")
17900 (define_expand "sibcall_epilogue"
17901   [(const_int 0)]
17902   ""
17903   "ix86_expand_epilogue (0); DONE;")
17905 (define_expand "eh_return"
17906   [(use (match_operand 0 "register_operand"))]
17907   ""
17909   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
17911   /* Tricky bit: we write the address of the handler to which we will
17912      be returning into someone else's stack frame, one word below the
17913      stack address we wish to restore.  */
17914   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
17915   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
17916   /* Return address is always in word_mode.  */
17917   tmp = gen_rtx_MEM (word_mode, tmp);
17918   if (GET_MODE (ra) != word_mode)
17919     ra = convert_to_mode (word_mode, ra, 1);
17920   emit_move_insn (tmp, ra);
17922   emit_jump_insn (gen_eh_return_internal ());
17923   emit_barrier ();
17924   DONE;
17927 (define_insn_and_split "eh_return_internal"
17928   [(eh_return)]
17929   ""
17930   "#"
17931   "epilogue_completed"
17932   [(const_int 0)]
17933   "ix86_expand_epilogue (2); DONE;")
17935 (define_expand "@leave_<mode>"
17936   [(parallel
17937     [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
17938      (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
17939      (clobber (mem:BLK (scratch)))])]
17940   ""
17941   "operands[0] = GEN_INT (<MODE_SIZE>);")
17943 (define_insn "*leave"
17944   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
17945    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
17946    (clobber (mem:BLK (scratch)))]
17947   "!TARGET_64BIT"
17948   "leave"
17949   [(set_attr "type" "leave")])
17951 (define_insn "*leave_rex64"
17952   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
17953    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
17954    (clobber (mem:BLK (scratch)))]
17955   "TARGET_64BIT"
17956   "leave"
17957   [(set_attr "type" "leave")])
17959 ;; Handle -fsplit-stack.
17961 (define_expand "split_stack_prologue"
17962   [(const_int 0)]
17963   ""
17965   ix86_expand_split_stack_prologue ();
17966   DONE;
17969 ;; In order to support the call/return predictor, we use a return
17970 ;; instruction which the middle-end doesn't see.
17971 (define_insn "split_stack_return"
17972   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
17973                      UNSPECV_SPLIT_STACK_RETURN)]
17974   ""
17976   if (operands[0] == const0_rtx)
17977     return "ret";
17978   else
17979     return "ret\t%0";
17981   [(set_attr "atom_unit" "jeu")
17982    (set_attr "modrm" "0")
17983    (set (attr "length")
17984         (if_then_else (match_operand:SI 0 "const0_operand")
17985                       (const_int 1)
17986                       (const_int 3)))
17987    (set (attr "length_immediate")
17988         (if_then_else (match_operand:SI 0 "const0_operand")
17989                       (const_int 0)
17990                       (const_int 2)))])
17992 ;; If there are operand 0 bytes available on the stack, jump to
17993 ;; operand 1.
17995 (define_expand "split_stack_space_check"
17996   [(set (pc) (if_then_else
17997               (ltu (minus (reg SP_REG)
17998                           (match_operand 0 "register_operand"))
17999                    (match_dup 2))
18000               (label_ref (match_operand 1))
18001               (pc)))]
18002   ""
18004   rtx reg = gen_reg_rtx (Pmode);
18006   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
18008   operands[2] = ix86_split_stack_guard ();
18009   ix86_expand_branch (GEU, reg, operands[2], operands[1]);
18011   DONE;
18014 ;; Bit manipulation instructions.
18016 (define_expand "ffs<mode>2"
18017   [(set (match_dup 2) (const_int -1))
18018    (parallel [(set (match_dup 3) (match_dup 4))
18019               (set (match_operand:SWI48 0 "register_operand")
18020                    (ctz:SWI48
18021                      (match_operand:SWI48 1 "nonimmediate_operand")))])
18022    (set (match_dup 0) (if_then_else:SWI48
18023                         (eq (match_dup 3) (const_int 0))
18024                         (match_dup 2)
18025                         (match_dup 0)))
18026    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
18027               (clobber (reg:CC FLAGS_REG))])]
18028   ""
18030   machine_mode flags_mode;
18032   if (<MODE>mode == SImode && !TARGET_CMOVE)
18033     {
18034       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
18035       DONE;
18036     }
18038   flags_mode = TARGET_BMI ? CCCmode : CCZmode;
18040   operands[2] = gen_reg_rtx (<MODE>mode);
18041   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
18042   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
18045 (define_insn_and_split "ffssi2_no_cmove"
18046   [(set (match_operand:SI 0 "register_operand" "=r")
18047         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
18048    (clobber (match_scratch:SI 2 "=&q"))
18049    (clobber (reg:CC FLAGS_REG))]
18050   "!TARGET_CMOVE"
18051   "#"
18052   "&& reload_completed"
18053   [(parallel [(set (match_dup 4) (match_dup 5))
18054               (set (match_dup 0) (ctz:SI (match_dup 1)))])
18055    (set (strict_low_part (match_dup 3))
18056         (eq:QI (match_dup 4) (const_int 0)))
18057    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
18058               (clobber (reg:CC FLAGS_REG))])
18059    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
18060               (clobber (reg:CC FLAGS_REG))])
18061    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
18062               (clobber (reg:CC FLAGS_REG))])]
18064   machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
18066   operands[3] = gen_lowpart (QImode, operands[2]);
18067   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
18068   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
18070   ix86_expand_clear (operands[2]);
18073 (define_insn_and_split "*tzcnt<mode>_1"
18074   [(set (reg:CCC FLAGS_REG)
18075         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18076                      (const_int 0)))
18077    (set (match_operand:SWI48 0 "register_operand" "=r")
18078         (ctz:SWI48 (match_dup 1)))]
18079   "TARGET_BMI"
18080   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18081   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18082    && optimize_function_for_speed_p (cfun)
18083    && !reg_mentioned_p (operands[0], operands[1])"
18084   [(parallel
18085     [(set (reg:CCC FLAGS_REG)
18086           (compare:CCC (match_dup 1) (const_int 0)))
18087      (set (match_dup 0)
18088           (ctz:SWI48 (match_dup 1)))
18089      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
18090   "ix86_expand_clear (operands[0]);"
18091   [(set_attr "type" "alu1")
18092    (set_attr "prefix_0f" "1")
18093    (set_attr "prefix_rep" "1")
18094    (set_attr "btver2_decode" "double")
18095    (set_attr "mode" "<MODE>")])
18097 ; False dependency happens when destination is only updated by tzcnt,
18098 ; lzcnt or popcnt.  There is no false dependency when destination is
18099 ; also used in source.
18100 (define_insn "*tzcnt<mode>_1_falsedep"
18101   [(set (reg:CCC FLAGS_REG)
18102         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18103                      (const_int 0)))
18104    (set (match_operand:SWI48 0 "register_operand" "=r")
18105         (ctz:SWI48 (match_dup 1)))
18106    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18107            UNSPEC_INSN_FALSE_DEP)]
18108   "TARGET_BMI"
18109   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18110   [(set_attr "type" "alu1")
18111    (set_attr "prefix_0f" "1")
18112    (set_attr "prefix_rep" "1")
18113    (set_attr "btver2_decode" "double")
18114    (set_attr "mode" "<MODE>")])
18116 (define_insn "*bsf<mode>_1"
18117   [(set (reg:CCZ FLAGS_REG)
18118         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18119                      (const_int 0)))
18120    (set (match_operand:SWI48 0 "register_operand" "=r")
18121         (ctz:SWI48 (match_dup 1)))]
18122   ""
18123   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
18124   [(set_attr "type" "alu1")
18125    (set_attr "prefix_0f" "1")
18126    (set_attr "btver2_decode" "double")
18127    (set_attr "znver1_decode" "vector")
18128    (set_attr "mode" "<MODE>")])
18130 (define_insn_and_split "ctz<mode>2"
18131   [(set (match_operand:SWI48 0 "register_operand" "=r")
18132         (ctz:SWI48
18133           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18134    (clobber (reg:CC FLAGS_REG))]
18135   ""
18137   if (TARGET_BMI)
18138     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18139   else if (optimize_function_for_size_p (cfun))
18140     ;
18141   else if (TARGET_CPU_P (GENERIC))
18142     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
18143     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18145   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18147   "(TARGET_BMI || TARGET_CPU_P (GENERIC))
18148    && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18149    && optimize_function_for_speed_p (cfun)
18150    && !reg_mentioned_p (operands[0], operands[1])"
18151   [(parallel
18152     [(set (match_dup 0)
18153           (ctz:SWI48 (match_dup 1)))
18154      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18155      (clobber (reg:CC FLAGS_REG))])]
18156   "ix86_expand_clear (operands[0]);"
18157   [(set_attr "type" "alu1")
18158    (set_attr "prefix_0f" "1")
18159    (set (attr "prefix_rep")
18160      (if_then_else
18161        (ior (match_test "TARGET_BMI")
18162             (and (not (match_test "optimize_function_for_size_p (cfun)"))
18163                  (match_test "TARGET_CPU_P (GENERIC)")))
18164        (const_string "1")
18165        (const_string "0")))
18166    (set_attr "mode" "<MODE>")])
18168 ; False dependency happens when destination is only updated by tzcnt,
18169 ; lzcnt or popcnt.  There is no false dependency when destination is
18170 ; also used in source.
18171 (define_insn "*ctz<mode>2_falsedep"
18172   [(set (match_operand:SWI48 0 "register_operand" "=r")
18173         (ctz:SWI48
18174           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18175    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18176            UNSPEC_INSN_FALSE_DEP)
18177    (clobber (reg:CC FLAGS_REG))]
18178   ""
18180   if (TARGET_BMI)
18181     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18182   else if (TARGET_CPU_P (GENERIC))
18183     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
18184     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18185   else
18186     gcc_unreachable ();
18188   [(set_attr "type" "alu1")
18189    (set_attr "prefix_0f" "1")
18190    (set_attr "prefix_rep" "1")
18191    (set_attr "mode" "<MODE>")])
18193 (define_insn_and_split "*ctzsi2_zext"
18194   [(set (match_operand:DI 0 "register_operand" "=r")
18195         (and:DI
18196           (subreg:DI
18197             (ctz:SI
18198               (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18199           (const_int 63)))
18200    (clobber (reg:CC FLAGS_REG))]
18201   "TARGET_BMI && TARGET_64BIT"
18202   "tzcnt{l}\t{%1, %k0|%k0, %1}"
18203   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18204    && optimize_function_for_speed_p (cfun)
18205    && !reg_mentioned_p (operands[0], operands[1])"
18206   [(parallel
18207     [(set (match_dup 0)
18208           (and:DI (subreg:DI (ctz:SI (match_dup 1)) 0) (const_int 63)))
18209      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18210      (clobber (reg:CC FLAGS_REG))])]
18211   "ix86_expand_clear (operands[0]);"
18212   [(set_attr "type" "alu1")
18213    (set_attr "prefix_0f" "1")
18214    (set_attr "prefix_rep" "1")
18215    (set_attr "mode" "SI")])
18217 ; False dependency happens when destination is only updated by tzcnt,
18218 ; lzcnt or popcnt.  There is no false dependency when destination is
18219 ; also used in source.
18220 (define_insn "*ctzsi2_zext_falsedep"
18221   [(set (match_operand:DI 0 "register_operand" "=r")
18222         (and:DI
18223           (subreg:DI
18224             (ctz:SI
18225               (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18226           (const_int 63)))
18227    (unspec [(match_operand:DI 2 "register_operand" "0")]
18228            UNSPEC_INSN_FALSE_DEP)
18229    (clobber (reg:CC FLAGS_REG))]
18230   "TARGET_BMI && TARGET_64BIT"
18231   "tzcnt{l}\t{%1, %k0|%k0, %1}"
18232   [(set_attr "type" "alu1")
18233    (set_attr "prefix_0f" "1")
18234    (set_attr "prefix_rep" "1")
18235    (set_attr "mode" "SI")])
18237 (define_insn_and_split "*ctzsidi2_<s>ext"
18238   [(set (match_operand:DI 0 "register_operand" "=r")
18239         (any_extend:DI
18240           (ctz:SI
18241             (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18242    (clobber (reg:CC FLAGS_REG))]
18243   "TARGET_64BIT"
18245   if (TARGET_BMI)
18246     return "tzcnt{l}\t{%1, %k0|%k0, %1}";
18247   else if (TARGET_CPU_P (GENERIC)
18248            && !optimize_function_for_size_p (cfun))
18249     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
18250     return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
18251   return "bsf{l}\t{%1, %k0|%k0, %1}";
18253   "(TARGET_BMI || TARGET_CPU_P (GENERIC))
18254    && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18255    && optimize_function_for_speed_p (cfun)
18256    && !reg_mentioned_p (operands[0], operands[1])"
18257   [(parallel
18258     [(set (match_dup 0)
18259           (any_extend:DI (ctz:SI (match_dup 1))))
18260      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18261      (clobber (reg:CC FLAGS_REG))])]
18262   "ix86_expand_clear (operands[0]);"
18263   [(set_attr "type" "alu1")
18264    (set_attr "prefix_0f" "1")
18265    (set (attr "prefix_rep")
18266      (if_then_else
18267        (ior (match_test "TARGET_BMI")
18268             (and (not (match_test "optimize_function_for_size_p (cfun)"))
18269                  (match_test "TARGET_CPU_P (GENERIC)")))
18270        (const_string "1")
18271        (const_string "0")))
18272    (set_attr "mode" "SI")])
18274 (define_insn "*ctzsidi2_<s>ext_falsedep"
18275   [(set (match_operand:DI 0 "register_operand" "=r")
18276         (any_extend:DI
18277           (ctz:SI
18278             (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18279    (unspec [(match_operand:DI 2 "register_operand" "0")]
18280            UNSPEC_INSN_FALSE_DEP)
18281    (clobber (reg:CC FLAGS_REG))]
18282   "TARGET_64BIT"
18284   if (TARGET_BMI)
18285     return "tzcnt{l}\t{%1, %k0|%k0, %1}";
18286   else if (TARGET_CPU_P (GENERIC))
18287     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
18288     return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
18289   else
18290     gcc_unreachable ();
18292   [(set_attr "type" "alu1")
18293    (set_attr "prefix_0f" "1")
18294    (set_attr "prefix_rep" "1")
18295    (set_attr "mode" "SI")])
18297 (define_insn "bsr_rex64"
18298   [(set (reg:CCZ FLAGS_REG)
18299         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
18300                      (const_int 0)))
18301    (set (match_operand:DI 0 "register_operand" "=r")
18302         (minus:DI (const_int 63)
18303                   (clz:DI (match_dup 1))))]
18304   "TARGET_64BIT"
18305   "bsr{q}\t{%1, %0|%0, %1}"
18306   [(set_attr "type" "alu1")
18307    (set_attr "prefix_0f" "1")
18308    (set_attr "znver1_decode" "vector")
18309    (set_attr "mode" "DI")])
18311 (define_insn "bsr_rex64_1"
18312   [(set (match_operand:DI 0 "register_operand" "=r")
18313         (minus:DI (const_int 63)
18314                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
18315    (clobber (reg:CC FLAGS_REG))]
18316   "!TARGET_LZCNT && TARGET_64BIT"
18317   "bsr{q}\t{%1, %0|%0, %1}"
18318   [(set_attr "type" "alu1")
18319    (set_attr "prefix_0f" "1")
18320    (set_attr "znver1_decode" "vector")
18321    (set_attr "mode" "DI")])
18323 (define_insn "bsr_rex64_1_zext"
18324   [(set (match_operand:DI 0 "register_operand" "=r")
18325         (zero_extend:DI
18326           (minus:SI (const_int 63)
18327                     (subreg:SI
18328                       (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
18329                       0))))
18330    (clobber (reg:CC FLAGS_REG))]
18331   "!TARGET_LZCNT && TARGET_64BIT"
18332   "bsr{q}\t{%1, %0|%0, %1}"
18333   [(set_attr "type" "alu1")
18334    (set_attr "prefix_0f" "1")
18335    (set_attr "znver1_decode" "vector")
18336    (set_attr "mode" "DI")])
18338 (define_insn "bsr"
18339   [(set (reg:CCZ FLAGS_REG)
18340         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
18341                      (const_int 0)))
18342    (set (match_operand:SI 0 "register_operand" "=r")
18343         (minus:SI (const_int 31)
18344                   (clz:SI (match_dup 1))))]
18345   ""
18346   "bsr{l}\t{%1, %0|%0, %1}"
18347   [(set_attr "type" "alu1")
18348    (set_attr "prefix_0f" "1")
18349    (set_attr "znver1_decode" "vector")
18350    (set_attr "mode" "SI")])
18352 (define_insn "bsr_1"
18353   [(set (match_operand:SI 0 "register_operand" "=r")
18354         (minus:SI (const_int 31)
18355                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18356    (clobber (reg:CC FLAGS_REG))]
18357   "!TARGET_LZCNT"
18358   "bsr{l}\t{%1, %0|%0, %1}"
18359   [(set_attr "type" "alu1")
18360    (set_attr "prefix_0f" "1")
18361    (set_attr "znver1_decode" "vector")
18362    (set_attr "mode" "SI")])
18364 (define_insn "bsr_zext_1"
18365   [(set (match_operand:DI 0 "register_operand" "=r")
18366         (zero_extend:DI
18367           (minus:SI
18368             (const_int 31)
18369             (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))))
18370    (clobber (reg:CC FLAGS_REG))]
18371   "!TARGET_LZCNT && TARGET_64BIT"
18372   "bsr{l}\t{%1, %k0|%k0, %1}"
18373   [(set_attr "type" "alu1")
18374    (set_attr "prefix_0f" "1")
18375    (set_attr "znver1_decode" "vector")
18376    (set_attr "mode" "SI")])
18378 ; As bsr is undefined behavior on zero and for other input
18379 ; values it is in range 0 to 63, we can optimize away sign-extends.
18380 (define_insn_and_split "*bsr_rex64_2"
18381   [(set (match_operand:DI 0 "register_operand")
18382         (xor:DI
18383           (sign_extend:DI
18384             (minus:SI
18385               (const_int 63)
18386               (subreg:SI (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18387                          0)))
18388           (const_int 63)))
18389     (clobber (reg:CC FLAGS_REG))]
18390   "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18391   "#"
18392   "&& 1"
18393   [(parallel [(set (reg:CCZ FLAGS_REG)
18394                    (compare:CCZ (match_dup 1) (const_int 0)))
18395               (set (match_dup 2)
18396                    (minus:DI (const_int 63) (clz:DI (match_dup 1))))])
18397    (parallel [(set (match_dup 0)
18398                    (zero_extend:DI (xor:SI (match_dup 3) (const_int 63))))
18399               (clobber (reg:CC FLAGS_REG))])]
18401   operands[2] = gen_reg_rtx (DImode);
18402   operands[3] = lowpart_subreg (SImode, operands[2], DImode);
18405 (define_insn_and_split "*bsr_2"
18406   [(set (match_operand:DI 0 "register_operand")
18407         (sign_extend:DI
18408           (xor:SI
18409             (minus:SI
18410               (const_int 31)
18411               (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18412             (const_int 31))))
18413    (clobber (reg:CC FLAGS_REG))]
18414   "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18415   "#"
18416   "&& 1"
18417   [(parallel [(set (reg:CCZ FLAGS_REG)
18418                    (compare:CCZ (match_dup 1) (const_int 0)))
18419               (set (match_dup 2)
18420                    (minus:SI (const_int 31) (clz:SI (match_dup 1))))])
18421    (parallel [(set (match_dup 0)
18422                    (zero_extend:DI (xor:SI (match_dup 2) (const_int 31))))
18423               (clobber (reg:CC FLAGS_REG))])]
18424   "operands[2] = gen_reg_rtx (SImode);")
18426 ; Splitters to optimize 64 - __builtin_clzl (x) or 32 - __builtin_clz (x).
18427 ; Again, as for !TARGET_LZCNT CLZ is UB at zero, CLZ is guaranteed to be
18428 ; in [0, 63] or [0, 31] range.
18429 (define_split
18430   [(set (match_operand:SI 0 "register_operand")
18431         (minus:SI
18432           (match_operand:SI 2 "const_int_operand")
18433           (xor:SI
18434             (minus:SI (const_int 63)
18435                       (subreg:SI
18436                         (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18437                         0))
18438             (const_int 63))))]
18439   "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18440   [(set (match_dup 3)
18441         (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18442    (set (match_dup 0)
18443         (plus:SI (match_dup 5) (match_dup 4)))]
18445   operands[3] = gen_reg_rtx (DImode);
18446   operands[5] = lowpart_subreg (SImode, operands[3], DImode);
18447   if (INTVAL (operands[2]) == 63)
18448     {
18449       emit_insn (gen_bsr_rex64_1_zext (operands[3], operands[1]));
18450       emit_move_insn (operands[0], operands[5]);
18451       DONE;
18452     }
18453   operands[4] = gen_int_mode (UINTVAL (operands[2]) - 63, SImode);
18456 (define_split
18457   [(set (match_operand:SI 0 "register_operand")
18458         (minus:SI
18459           (match_operand:SI 2 "const_int_operand")
18460           (xor:SI
18461             (minus:SI (const_int 31)
18462                       (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18463             (const_int 31))))]
18464   "!TARGET_LZCNT && ix86_pre_reload_split ()"
18465   [(set (match_dup 3)
18466         (minus:SI (const_int 31) (clz:SI (match_dup 1))))
18467    (set (match_dup 0)
18468         (plus:SI (match_dup 3) (match_dup 4)))]
18470   if (INTVAL (operands[2]) == 31)
18471     {
18472       emit_insn (gen_bsr_1 (operands[0], operands[1]));
18473       DONE;
18474     }
18475   operands[3] = gen_reg_rtx (SImode);
18476   operands[4] = gen_int_mode (UINTVAL (operands[2]) - 31, SImode);
18479 (define_split
18480   [(set (match_operand:DI 0 "register_operand")
18481         (minus:DI
18482           (match_operand:DI 2 "const_int_operand")
18483           (xor:DI
18484             (sign_extend:DI
18485               (minus:SI (const_int 63)
18486                         (subreg:SI
18487                           (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18488                           0)))
18489             (const_int 63))))]
18490   "!TARGET_LZCNT
18491    && TARGET_64BIT
18492    && ix86_pre_reload_split ()
18493    && ((unsigned HOST_WIDE_INT)
18494        trunc_int_for_mode (UINTVAL (operands[2]) - 63, SImode)
18495        == UINTVAL (operands[2]) - 63)"
18496   [(set (match_dup 3)
18497         (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18498    (set (match_dup 0)
18499         (plus:DI (match_dup 3) (match_dup 4)))]
18501   if (INTVAL (operands[2]) == 63)
18502     {
18503       emit_insn (gen_bsr_rex64_1 (operands[0], operands[1]));
18504       DONE;
18505     }
18506   operands[3] = gen_reg_rtx (DImode);
18507   operands[4] = GEN_INT (UINTVAL (operands[2]) - 63);
18510 (define_split
18511   [(set (match_operand:DI 0 "register_operand")
18512         (minus:DI
18513           (match_operand:DI 2 "const_int_operand")
18514           (sign_extend:DI
18515             (xor:SI
18516               (minus:SI (const_int 31)
18517                         (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18518               (const_int 31)))))]
18519   "!TARGET_LZCNT
18520    && TARGET_64BIT
18521    && ix86_pre_reload_split ()
18522    && ((unsigned HOST_WIDE_INT)
18523        trunc_int_for_mode (UINTVAL (operands[2]) - 31, SImode)
18524        == UINTVAL (operands[2]) - 31)"
18525   [(set (match_dup 3)
18526         (zero_extend:DI (minus:SI (const_int 31) (clz:SI (match_dup 1)))))
18527    (set (match_dup 0)
18528         (plus:DI (match_dup 3) (match_dup 4)))]
18530   if (INTVAL (operands[2]) == 31)
18531     {
18532       emit_insn (gen_bsr_zext_1 (operands[0], operands[1]));
18533       DONE;
18534     }
18535   operands[3] = gen_reg_rtx (DImode);
18536   operands[4] = GEN_INT (UINTVAL (operands[2]) - 31);
18539 (define_expand "clz<mode>2"
18540   [(parallel
18541      [(set (reg:CCZ FLAGS_REG)
18542         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18543                      (const_int 0)))
18544       (set (match_dup 3) (minus:SWI48
18545                            (match_dup 2)
18546                            (clz:SWI48 (match_dup 1))))])
18547    (parallel
18548      [(set (match_operand:SWI48 0 "register_operand")
18549            (xor:SWI48 (match_dup 3) (match_dup 2)))
18550       (clobber (reg:CC FLAGS_REG))])]
18551   ""
18553   if (TARGET_LZCNT)
18554     {
18555       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
18556       DONE;
18557     }
18558   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
18559   operands[3] = gen_reg_rtx (<MODE>mode);
18562 (define_insn_and_split "clz<mode>2_lzcnt"
18563   [(set (match_operand:SWI48 0 "register_operand" "=r")
18564         (clz:SWI48
18565           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18566    (clobber (reg:CC FLAGS_REG))]
18567   "TARGET_LZCNT"
18568   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18569   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18570    && optimize_function_for_speed_p (cfun)
18571    && !reg_mentioned_p (operands[0], operands[1])"
18572   [(parallel
18573     [(set (match_dup 0)
18574           (clz:SWI48 (match_dup 1)))
18575      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18576      (clobber (reg:CC FLAGS_REG))])]
18577   "ix86_expand_clear (operands[0]);"
18578   [(set_attr "prefix_rep" "1")
18579    (set_attr "type" "bitmanip")
18580    (set_attr "mode" "<MODE>")])
18582 ; False dependency happens when destination is only updated by tzcnt,
18583 ; lzcnt or popcnt.  There is no false dependency when destination is
18584 ; also used in source.
18585 (define_insn "*clz<mode>2_lzcnt_falsedep"
18586   [(set (match_operand:SWI48 0 "register_operand" "=r")
18587         (clz:SWI48
18588           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18589    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18590            UNSPEC_INSN_FALSE_DEP)
18591    (clobber (reg:CC FLAGS_REG))]
18592   "TARGET_LZCNT"
18593   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18594   [(set_attr "prefix_rep" "1")
18595    (set_attr "type" "bitmanip")
18596    (set_attr "mode" "<MODE>")])
18598 (define_insn_and_split "*clzsi2_lzcnt_zext"
18599   [(set (match_operand:DI 0 "register_operand" "=r")
18600         (and:DI
18601           (subreg:DI
18602             (clz:SI
18603               (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18604           (const_int 63)))
18605    (clobber (reg:CC FLAGS_REG))]
18606   "TARGET_LZCNT && TARGET_64BIT"
18607   "lzcnt{l}\t{%1, %k0|%k0, %1}"
18608   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18609    && optimize_function_for_speed_p (cfun)
18610    && !reg_mentioned_p (operands[0], operands[1])"
18611   [(parallel
18612     [(set (match_dup 0)
18613           (and:DI (subreg:DI (clz:SI (match_dup 1)) 0) (const_int 63)))
18614      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18615      (clobber (reg:CC FLAGS_REG))])]
18616   "ix86_expand_clear (operands[0]);"
18617   [(set_attr "prefix_rep" "1")
18618    (set_attr "type" "bitmanip")
18619    (set_attr "mode" "SI")])
18621 ; False dependency happens when destination is only updated by tzcnt,
18622 ; lzcnt or popcnt.  There is no false dependency when destination is
18623 ; also used in source.
18624 (define_insn "*clzsi2_lzcnt_zext_falsedep"
18625   [(set (match_operand:DI 0 "register_operand" "=r")
18626         (and:DI
18627           (subreg:DI
18628             (clz:SI
18629               (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 0)
18630           (const_int 63)))
18631    (unspec [(match_operand:DI 2 "register_operand" "0")]
18632            UNSPEC_INSN_FALSE_DEP)
18633    (clobber (reg:CC FLAGS_REG))]
18634   "TARGET_LZCNT"
18635   "lzcnt{l}\t{%1, %k0|%k0, %1}"
18636   [(set_attr "prefix_rep" "1")
18637    (set_attr "type" "bitmanip")
18638    (set_attr "mode" "SI")])
18640 (define_insn_and_split "*clzsi2_lzcnt_zext_2"
18641   [(set (match_operand:DI 0 "register_operand" "=r")
18642         (zero_extend:DI
18643           (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18644    (clobber (reg:CC FLAGS_REG))]
18645   "TARGET_LZCNT && TARGET_64BIT"
18646   "lzcnt{l}\t{%1, %k0|%k0, %1}"
18647   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18648    && optimize_function_for_speed_p (cfun)
18649    && !reg_mentioned_p (operands[0], operands[1])"
18650   [(parallel
18651     [(set (match_dup 0)
18652           (zero_extend:DI (clz:SI (match_dup 1))))
18653      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18654      (clobber (reg:CC FLAGS_REG))])]
18655   "ix86_expand_clear (operands[0]);"
18656   [(set_attr "prefix_rep" "1")
18657    (set_attr "type" "bitmanip")
18658    (set_attr "mode" "SI")])
18660 ; False dependency happens when destination is only updated by tzcnt,
18661 ; lzcnt or popcnt.  There is no false dependency when destination is
18662 ; also used in source.
18663 (define_insn "*clzsi2_lzcnt_zext_2_falsedep"
18664   [(set (match_operand:DI 0 "register_operand" "=r")
18665         (zero_extend:DI
18666           (clz:SI (match_operand:SWI48 1 "nonimmediate_operand" "rm"))))
18667    (unspec [(match_operand:DI 2 "register_operand" "0")]
18668            UNSPEC_INSN_FALSE_DEP)
18669    (clobber (reg:CC FLAGS_REG))]
18670   "TARGET_LZCNT"
18671   "lzcnt{l}\t{%1, %k0|%k0, %1}"
18672   [(set_attr "prefix_rep" "1")
18673    (set_attr "type" "bitmanip")
18674    (set_attr "mode" "SI")])
18676 (define_int_iterator LT_ZCNT
18677         [(UNSPEC_TZCNT "TARGET_BMI")
18678          (UNSPEC_LZCNT "TARGET_LZCNT")])
18680 (define_int_attr lt_zcnt
18681         [(UNSPEC_TZCNT "tzcnt")
18682          (UNSPEC_LZCNT "lzcnt")])
18684 (define_int_attr lt_zcnt_type
18685         [(UNSPEC_TZCNT "alu1")
18686          (UNSPEC_LZCNT "bitmanip")])
18688 ;; Version of lzcnt/tzcnt that is expanded from intrinsics.  This version
18689 ;; provides operand size as output when source operand is zero. 
18691 (define_insn_and_split "<lt_zcnt>_<mode>"
18692   [(set (match_operand:SWI48 0 "register_operand" "=r")
18693         (unspec:SWI48
18694           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18695    (clobber (reg:CC FLAGS_REG))]
18696   ""
18697   "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18698   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18699    && optimize_function_for_speed_p (cfun)
18700    && !reg_mentioned_p (operands[0], operands[1])"
18701   [(parallel
18702     [(set (match_dup 0)
18703           (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
18704      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18705      (clobber (reg:CC FLAGS_REG))])]
18706   "ix86_expand_clear (operands[0]);"
18707   [(set_attr "type" "<lt_zcnt_type>")
18708    (set_attr "prefix_0f" "1")
18709    (set_attr "prefix_rep" "1")
18710    (set_attr "mode" "<MODE>")])
18712 ; False dependency happens when destination is only updated by tzcnt,
18713 ; lzcnt or popcnt.  There is no false dependency when destination is
18714 ; also used in source.
18715 (define_insn "*<lt_zcnt>_<mode>_falsedep"
18716   [(set (match_operand:SWI48 0 "register_operand" "=r")
18717         (unspec:SWI48
18718           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18719    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18720            UNSPEC_INSN_FALSE_DEP)
18721    (clobber (reg:CC FLAGS_REG))]
18722   ""
18723   "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18724   [(set_attr "type" "<lt_zcnt_type>")
18725    (set_attr "prefix_0f" "1")
18726    (set_attr "prefix_rep" "1")
18727    (set_attr "mode" "<MODE>")])
18729 (define_insn "<lt_zcnt>_hi"
18730   [(set (match_operand:HI 0 "register_operand" "=r")
18731         (unspec:HI
18732           [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18733    (clobber (reg:CC FLAGS_REG))]
18734   ""
18735   "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
18736   [(set_attr "type" "<lt_zcnt_type>")
18737    (set_attr "prefix_0f" "1")
18738    (set_attr "prefix_rep" "1")
18739    (set_attr "mode" "HI")])
18741 ;; BMI instructions.
18743 (define_insn "bmi_bextr_<mode>"
18744   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
18745         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18746                        (match_operand:SWI48 2 "register_operand" "r,r")]
18747                       UNSPEC_BEXTR))
18748    (clobber (reg:CC FLAGS_REG))]
18749   "TARGET_BMI"
18750   "bextr\t{%2, %1, %0|%0, %1, %2}"
18751   [(set_attr "type" "bitmanip")
18752    (set_attr "btver2_decode" "direct, double")
18753    (set_attr "mode" "<MODE>")])
18755 (define_insn "*bmi_bextr_<mode>_ccz"
18756   [(set (reg:CCZ FLAGS_REG)
18757         (compare:CCZ
18758           (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18759                          (match_operand:SWI48 2 "register_operand" "r,r")]
18760                         UNSPEC_BEXTR)
18761           (const_int 0)))
18762    (clobber (match_scratch:SWI48 0 "=r,r"))]
18763   "TARGET_BMI"
18764   "bextr\t{%2, %1, %0|%0, %1, %2}"
18765   [(set_attr "type" "bitmanip")
18766    (set_attr "btver2_decode" "direct, double")
18767    (set_attr "mode" "<MODE>")])
18769 (define_insn "*bmi_blsi_<mode>"
18770   [(set (match_operand:SWI48 0 "register_operand" "=r")
18771         (and:SWI48
18772           (neg:SWI48
18773             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18774           (match_dup 1)))
18775    (clobber (reg:CC FLAGS_REG))]
18776   "TARGET_BMI"
18777   "blsi\t{%1, %0|%0, %1}"
18778   [(set_attr "type" "bitmanip")
18779    (set_attr "btver2_decode" "double")
18780    (set_attr "mode" "<MODE>")])
18782 (define_insn "*bmi_blsi_<mode>_cmp"
18783   [(set (reg FLAGS_REG)
18784         (compare
18785           (and:SWI48
18786             (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18787             (match_dup 1))
18788           (const_int 0)))
18789    (set (match_operand:SWI48 0 "register_operand" "=r")
18790         (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))]
18791    "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
18792    "blsi\t{%1, %0|%0, %1}"
18793   [(set_attr "type" "bitmanip")
18794    (set_attr "btver2_decode" "double")
18795    (set_attr "mode" "<MODE>")])
18797 (define_insn "*bmi_blsi_<mode>_ccno"
18798   [(set (reg FLAGS_REG)
18799         (compare
18800           (and:SWI48
18801             (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18802             (match_dup 1))
18803           (const_int 0)))
18804    (clobber (match_scratch:SWI48 0 "=r"))]
18805    "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
18806    "blsi\t{%1, %0|%0, %1}"
18807   [(set_attr "type" "bitmanip")
18808    (set_attr "btver2_decode" "double")
18809    (set_attr "mode" "<MODE>")])
18811 (define_insn "*bmi_blsmsk_<mode>"
18812   [(set (match_operand:SWI48 0 "register_operand" "=r")
18813         (xor:SWI48
18814           (plus:SWI48
18815             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18816             (const_int -1))
18817           (match_dup 1)))
18818    (clobber (reg:CC FLAGS_REG))]
18819   "TARGET_BMI"
18820   "blsmsk\t{%1, %0|%0, %1}"
18821   [(set_attr "type" "bitmanip")
18822    (set_attr "btver2_decode" "double")
18823    (set_attr "mode" "<MODE>")])
18825 (define_insn "*bmi_blsr_<mode>"
18826   [(set (match_operand:SWI48 0 "register_operand" "=r")
18827         (and:SWI48
18828           (plus:SWI48
18829             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18830             (const_int -1))
18831           (match_dup 1)))
18832    (clobber (reg:CC FLAGS_REG))]
18833    "TARGET_BMI"
18834    "blsr\t{%1, %0|%0, %1}"
18835   [(set_attr "type" "bitmanip")
18836    (set_attr "btver2_decode" "double")
18837    (set_attr "mode" "<MODE>")])
18839 (define_insn "*bmi_blsr_<mode>_cmp"
18840   [(set (reg:CCZ FLAGS_REG)
18841         (compare:CCZ
18842           (and:SWI48
18843             (plus:SWI48
18844               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18845               (const_int -1))
18846             (match_dup 1))
18847           (const_int 0)))
18848    (set (match_operand:SWI48 0 "register_operand" "=r")
18849         (and:SWI48
18850           (plus:SWI48
18851             (match_dup 1)
18852             (const_int -1))
18853           (match_dup 1)))]
18854    "TARGET_BMI"
18855    "blsr\t{%1, %0|%0, %1}"
18856   [(set_attr "type" "bitmanip")
18857    (set_attr "btver2_decode" "double")
18858    (set_attr "mode" "<MODE>")])
18860 (define_insn "*bmi_blsr_<mode>_ccz"
18861   [(set (reg:CCZ FLAGS_REG)
18862         (compare:CCZ
18863           (and:SWI48
18864             (plus:SWI48
18865               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18866               (const_int -1))
18867             (match_dup 1))
18868           (const_int 0)))
18869    (clobber (match_scratch:SWI48 0 "=r"))]
18870    "TARGET_BMI"
18871    "blsr\t{%1, %0|%0, %1}"
18872   [(set_attr "type" "bitmanip")
18873    (set_attr "btver2_decode" "double")
18874    (set_attr "mode" "<MODE>")])
18876 ;; BMI2 instructions.
18877 (define_expand "bmi2_bzhi_<mode>3"
18878   [(parallel
18879     [(set (match_operand:SWI48 0 "register_operand")
18880           (if_then_else:SWI48
18881             (ne:QI (match_operand:QI 2 "register_operand")
18882                    (const_int 0))
18883             (zero_extract:SWI48
18884               (match_operand:SWI48 1 "nonimmediate_operand")
18885               (umin:QI (match_dup 2) (match_dup 3))
18886               (const_int 0))
18887             (const_int 0)))
18888      (clobber (reg:CC FLAGS_REG))])]
18889   "TARGET_BMI2"
18891   operands[2] = gen_lowpart (QImode, operands[2]);
18892   operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
18895 (define_insn "*bmi2_bzhi_<mode>3"
18896   [(set (match_operand:SWI48 0 "register_operand" "=r")
18897         (if_then_else:SWI48
18898           (ne:QI (match_operand:QI 2 "register_operand" "q")
18899                  (const_int 0))
18900           (zero_extract:SWI48
18901             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18902             (umin:QI (match_dup 2)
18903                      (match_operand:QI 3 "const_int_operand"))
18904             (const_int 0))
18905           (const_int 0)))
18906    (clobber (reg:CC FLAGS_REG))]
18907   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
18908   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18909   [(set_attr "type" "bitmanip")
18910    (set_attr "prefix" "vex")
18911    (set_attr "mode" "<MODE>")])
18913 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
18914   [(set (reg:CCZ FLAGS_REG)
18915         (compare:CCZ
18916           (if_then_else:SWI48
18917             (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
18918             (zero_extract:SWI48
18919               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18920               (umin:QI (match_dup 2)
18921                        (match_operand:QI 3 "const_int_operand"))
18922               (const_int 0))
18923             (const_int 0))
18924         (const_int 0)))
18925    (clobber (match_scratch:SWI48 0 "=r"))]
18926   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
18927   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18928   [(set_attr "type" "bitmanip")
18929    (set_attr "prefix" "vex")
18930    (set_attr "mode" "<MODE>")])
18932 (define_insn "*bmi2_bzhi_<mode>3_2"
18933   [(set (match_operand:SWI48 0 "register_operand" "=r")
18934         (and:SWI48
18935           (plus:SWI48
18936             (ashift:SWI48 (const_int 1)
18937                           (match_operand:QI 2 "register_operand" "r"))
18938             (const_int -1))
18939           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18940    (clobber (reg:CC FLAGS_REG))]
18941   "TARGET_BMI2"
18942   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18943   [(set_attr "type" "bitmanip")
18944    (set_attr "prefix" "vex")
18945    (set_attr "mode" "<MODE>")])
18947 (define_insn "*bmi2_bzhi_<mode>3_3"
18948   [(set (match_operand:SWI48 0 "register_operand" "=r")
18949         (and:SWI48
18950           (not:SWI48
18951             (ashift:SWI48 (const_int -1)
18952                           (match_operand:QI 2 "register_operand" "r")))
18953           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18954    (clobber (reg:CC FLAGS_REG))]
18955   "TARGET_BMI2"
18956   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18957   [(set_attr "type" "bitmanip")
18958    (set_attr "prefix" "vex")
18959    (set_attr "mode" "<MODE>")])
18961 (define_insn "*bmi2_bzhi_zero_extendsidi_4"
18962   [(set (match_operand:DI 0 "register_operand" "=r")
18963         (zero_extend:DI
18964           (and:SI
18965             (plus:SI
18966               (ashift:SI (const_int 1)
18967                          (match_operand:QI 2 "register_operand" "r"))
18968               (const_int -1))
18969             (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18970    (clobber (reg:CC FLAGS_REG))]
18971   "TARGET_64BIT && TARGET_BMI2"
18972   "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
18973   [(set_attr "type" "bitmanip")
18974    (set_attr "prefix" "vex")
18975    (set_attr "mode" "DI")])
18977 (define_insn "*bmi2_bzhi_zero_extendsidi_5"
18978   [(set (match_operand:DI 0 "register_operand" "=r")
18979         (and:DI
18980           (zero_extend:DI
18981             (plus:SI
18982               (ashift:SI (const_int 1)
18983                          (match_operand:QI 2 "register_operand" "r"))
18984               (const_int -1)))
18985           (match_operand:DI 1 "nonimmediate_operand" "rm")))
18986    (clobber (reg:CC FLAGS_REG))]
18987   "TARGET_64BIT && TARGET_BMI2"
18988   "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
18989   [(set_attr "type" "bitmanip")
18990    (set_attr "prefix" "vex")
18991    (set_attr "mode" "DI")])
18993 (define_insn "bmi2_pdep_<mode>3"
18994   [(set (match_operand:SWI48 0 "register_operand" "=r")
18995         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
18996                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
18997                        UNSPEC_PDEP))]
18998   "TARGET_BMI2"
18999   "pdep\t{%2, %1, %0|%0, %1, %2}"
19000   [(set_attr "type" "bitmanip")
19001    (set_attr "prefix" "vex")
19002    (set_attr "mode" "<MODE>")])
19004 (define_insn "bmi2_pext_<mode>3"
19005   [(set (match_operand:SWI48 0 "register_operand" "=r")
19006         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
19007                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
19008                        UNSPEC_PEXT))]
19009   "TARGET_BMI2"
19010   "pext\t{%2, %1, %0|%0, %1, %2}"
19011   [(set_attr "type" "bitmanip")
19012    (set_attr "prefix" "vex")
19013    (set_attr "mode" "<MODE>")])
19015 ;; TBM instructions.
19016 (define_insn "@tbm_bextri_<mode>"
19017   [(set (match_operand:SWI48 0 "register_operand" "=r")
19018         (zero_extract:SWI48
19019           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19020           (match_operand:QI 2 "const_0_to_255_operand")
19021           (match_operand:QI 3 "const_0_to_255_operand")))
19022    (clobber (reg:CC FLAGS_REG))]
19023    "TARGET_TBM"
19025   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
19026   return "bextr\t{%2, %1, %0|%0, %1, %2}";
19028   [(set_attr "type" "bitmanip")
19029    (set_attr "mode" "<MODE>")])
19031 (define_insn "*tbm_blcfill_<mode>"
19032   [(set (match_operand:SWI48 0 "register_operand" "=r")
19033         (and:SWI48
19034           (plus:SWI48
19035             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19036             (const_int 1))
19037           (match_dup 1)))
19038    (clobber (reg:CC FLAGS_REG))]
19039    "TARGET_TBM"
19040    "blcfill\t{%1, %0|%0, %1}"
19041   [(set_attr "type" "bitmanip")
19042    (set_attr "mode" "<MODE>")])
19044 (define_insn "*tbm_blci_<mode>"
19045   [(set (match_operand:SWI48 0 "register_operand" "=r")
19046         (ior:SWI48
19047           (not:SWI48
19048             (plus:SWI48
19049               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19050               (const_int 1)))
19051           (match_dup 1)))
19052    (clobber (reg:CC FLAGS_REG))]
19053    "TARGET_TBM"
19054    "blci\t{%1, %0|%0, %1}"
19055   [(set_attr "type" "bitmanip")
19056    (set_attr "mode" "<MODE>")])
19058 (define_insn "*tbm_blcic_<mode>"
19059   [(set (match_operand:SWI48 0 "register_operand" "=r")
19060         (and:SWI48
19061           (plus:SWI48
19062             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19063             (const_int 1))
19064           (not:SWI48
19065             (match_dup 1))))
19066    (clobber (reg:CC FLAGS_REG))]
19067    "TARGET_TBM"
19068    "blcic\t{%1, %0|%0, %1}"
19069   [(set_attr "type" "bitmanip")
19070    (set_attr "mode" "<MODE>")])
19072 (define_insn "*tbm_blcmsk_<mode>"
19073   [(set (match_operand:SWI48 0 "register_operand" "=r")
19074         (xor:SWI48
19075           (plus:SWI48
19076             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19077             (const_int 1))
19078           (match_dup 1)))
19079    (clobber (reg:CC FLAGS_REG))]
19080    "TARGET_TBM"
19081    "blcmsk\t{%1, %0|%0, %1}"
19082   [(set_attr "type" "bitmanip")
19083    (set_attr "mode" "<MODE>")])
19085 (define_insn "*tbm_blcs_<mode>"
19086   [(set (match_operand:SWI48 0 "register_operand" "=r")
19087         (ior:SWI48
19088           (plus:SWI48
19089             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19090             (const_int 1))
19091           (match_dup 1)))
19092    (clobber (reg:CC FLAGS_REG))]
19093    "TARGET_TBM"
19094    "blcs\t{%1, %0|%0, %1}"
19095   [(set_attr "type" "bitmanip")
19096    (set_attr "mode" "<MODE>")])
19098 (define_insn "*tbm_blsfill_<mode>"
19099   [(set (match_operand:SWI48 0 "register_operand" "=r")
19100         (ior:SWI48
19101           (plus:SWI48
19102             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19103             (const_int -1))
19104           (match_dup 1)))
19105    (clobber (reg:CC FLAGS_REG))]
19106    "TARGET_TBM"
19107    "blsfill\t{%1, %0|%0, %1}"
19108   [(set_attr "type" "bitmanip")
19109    (set_attr "mode" "<MODE>")])
19111 (define_insn "*tbm_blsic_<mode>"
19112   [(set (match_operand:SWI48 0 "register_operand" "=r")
19113         (ior:SWI48
19114           (plus:SWI48
19115             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19116             (const_int -1))
19117           (not:SWI48
19118             (match_dup 1))))
19119    (clobber (reg:CC FLAGS_REG))]
19120    "TARGET_TBM"
19121    "blsic\t{%1, %0|%0, %1}"
19122   [(set_attr "type" "bitmanip")
19123    (set_attr "mode" "<MODE>")])
19125 (define_insn "*tbm_t1mskc_<mode>"
19126   [(set (match_operand:SWI48 0 "register_operand" "=r")
19127         (ior:SWI48
19128           (plus:SWI48
19129             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19130             (const_int 1))
19131           (not:SWI48
19132             (match_dup 1))))
19133    (clobber (reg:CC FLAGS_REG))]
19134    "TARGET_TBM"
19135    "t1mskc\t{%1, %0|%0, %1}"
19136   [(set_attr "type" "bitmanip")
19137    (set_attr "mode" "<MODE>")])
19139 (define_insn "*tbm_tzmsk_<mode>"
19140   [(set (match_operand:SWI48 0 "register_operand" "=r")
19141         (and:SWI48
19142           (plus:SWI48
19143             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19144             (const_int -1))
19145           (not:SWI48
19146             (match_dup 1))))
19147    (clobber (reg:CC FLAGS_REG))]
19148    "TARGET_TBM"
19149    "tzmsk\t{%1, %0|%0, %1}"
19150   [(set_attr "type" "bitmanip")
19151    (set_attr "mode" "<MODE>")])
19153 (define_insn_and_split "popcount<mode>2"
19154   [(set (match_operand:SWI48 0 "register_operand" "=r")
19155         (popcount:SWI48
19156           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19157    (clobber (reg:CC FLAGS_REG))]
19158   "TARGET_POPCNT"
19160 #if TARGET_MACHO
19161   return "popcnt\t{%1, %0|%0, %1}";
19162 #else
19163   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19164 #endif
19166   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19167    && optimize_function_for_speed_p (cfun)
19168    && !reg_mentioned_p (operands[0], operands[1])"
19169   [(parallel
19170     [(set (match_dup 0)
19171           (popcount:SWI48 (match_dup 1)))
19172      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19173      (clobber (reg:CC FLAGS_REG))])]
19174   "ix86_expand_clear (operands[0]);"
19175   [(set_attr "prefix_rep" "1")
19176    (set_attr "type" "bitmanip")
19177    (set_attr "mode" "<MODE>")])
19179 ; False dependency happens when destination is only updated by tzcnt,
19180 ; lzcnt or popcnt.  There is no false dependency when destination is
19181 ; also used in source.
19182 (define_insn "*popcount<mode>2_falsedep"
19183   [(set (match_operand:SWI48 0 "register_operand" "=r")
19184         (popcount:SWI48
19185           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19186    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
19187            UNSPEC_INSN_FALSE_DEP)
19188    (clobber (reg:CC FLAGS_REG))]
19189   "TARGET_POPCNT"
19191 #if TARGET_MACHO
19192   return "popcnt\t{%1, %0|%0, %1}";
19193 #else
19194   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19195 #endif
19197   [(set_attr "prefix_rep" "1")
19198    (set_attr "type" "bitmanip")
19199    (set_attr "mode" "<MODE>")])
19201 (define_insn_and_split "*popcountsi2_zext"
19202   [(set (match_operand:DI 0 "register_operand" "=r")
19203         (and:DI
19204           (subreg:DI
19205             (popcount:SI
19206               (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19207           (const_int 63)))
19208    (clobber (reg:CC FLAGS_REG))]
19209   "TARGET_POPCNT && TARGET_64BIT"
19211 #if TARGET_MACHO
19212   return "popcnt\t{%1, %k0|%k0, %1}";
19213 #else
19214   return "popcnt{l}\t{%1, %k0|%k0, %1}";
19215 #endif
19217   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19218    && optimize_function_for_speed_p (cfun)
19219    && !reg_mentioned_p (operands[0], operands[1])"
19220   [(parallel
19221     [(set (match_dup 0)
19222           (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63)))
19223      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19224      (clobber (reg:CC FLAGS_REG))])]
19225   "ix86_expand_clear (operands[0]);"
19226   [(set_attr "prefix_rep" "1")
19227    (set_attr "type" "bitmanip")
19228    (set_attr "mode" "SI")])
19230 ; False dependency happens when destination is only updated by tzcnt,
19231 ; lzcnt or popcnt.  There is no false dependency when destination is
19232 ; also used in source.
19233 (define_insn "*popcountsi2_zext_falsedep"
19234   [(set (match_operand:DI 0 "register_operand" "=r")
19235         (and:DI
19236           (subreg:DI
19237             (popcount:SI
19238               (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19239           (const_int 63)))
19240    (unspec [(match_operand:DI 2 "register_operand" "0")]
19241            UNSPEC_INSN_FALSE_DEP)
19242    (clobber (reg:CC FLAGS_REG))]
19243   "TARGET_POPCNT && TARGET_64BIT"
19245 #if TARGET_MACHO
19246   return "popcnt\t{%1, %k0|%k0, %1}";
19247 #else
19248   return "popcnt{l}\t{%1, %k0|%k0, %1}";
19249 #endif
19251   [(set_attr "prefix_rep" "1")
19252    (set_attr "type" "bitmanip")
19253    (set_attr "mode" "SI")])
19255 (define_insn_and_split "*popcountsi2_zext_2"
19256   [(set (match_operand:DI 0 "register_operand" "=r")
19257         (zero_extend:DI
19258           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19259    (clobber (reg:CC FLAGS_REG))]
19260   "TARGET_POPCNT && TARGET_64BIT"
19262 #if TARGET_MACHO
19263   return "popcnt\t{%1, %k0|%k0, %1}";
19264 #else
19265   return "popcnt{l}\t{%1, %k0|%k0, %1}";
19266 #endif
19268   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19269    && optimize_function_for_speed_p (cfun)
19270    && !reg_mentioned_p (operands[0], operands[1])"
19271   [(parallel
19272     [(set (match_dup 0)
19273           (zero_extend:DI (popcount:SI (match_dup 1))))
19274      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19275      (clobber (reg:CC FLAGS_REG))])]
19276   "ix86_expand_clear (operands[0]);"
19277   [(set_attr "prefix_rep" "1")
19278    (set_attr "type" "bitmanip")
19279    (set_attr "mode" "SI")])
19281 ; False dependency happens when destination is only updated by tzcnt,
19282 ; lzcnt or popcnt.  There is no false dependency when destination is
19283 ; also used in source.
19284 (define_insn "*popcountsi2_zext_2_falsedep"
19285   [(set (match_operand:DI 0 "register_operand" "=r")
19286         (zero_extend:DI
19287           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19288    (unspec [(match_operand:DI 2 "register_operand" "0")]
19289            UNSPEC_INSN_FALSE_DEP)
19290    (clobber (reg:CC FLAGS_REG))]
19291   "TARGET_POPCNT && TARGET_64BIT"
19293 #if TARGET_MACHO
19294   return "popcnt\t{%1, %k0|%k0, %1}";
19295 #else
19296   return "popcnt{l}\t{%1, %k0|%k0, %1}";
19297 #endif
19299   [(set_attr "prefix_rep" "1")
19300    (set_attr "type" "bitmanip")
19301    (set_attr "mode" "SI")])
19303 (define_insn_and_split "*popcounthi2_1"
19304   [(set (match_operand:SI 0 "register_operand")
19305         (popcount:SI
19306           (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
19307    (clobber (reg:CC FLAGS_REG))]
19308   "TARGET_POPCNT
19309    && ix86_pre_reload_split ()"
19310   "#"
19311   "&& 1"
19312   [(const_int 0)]
19314   rtx tmp = gen_reg_rtx (HImode);
19316   emit_insn (gen_popcounthi2 (tmp, operands[1]));
19317   emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19318   DONE;
19321 (define_insn_and_split "*popcounthi2_2"
19322   [(set (match_operand:SI 0 "register_operand")
19323         (zero_extend:SI
19324           (popcount:HI (match_operand:HI 1 "nonimmediate_operand"))))
19325    (clobber (reg:CC FLAGS_REG))]
19326   "TARGET_POPCNT
19327    && ix86_pre_reload_split ()"
19328   "#"
19329   "&& 1"
19330   [(const_int 0)]
19332   rtx tmp = gen_reg_rtx (HImode);
19334   emit_insn (gen_popcounthi2 (tmp, operands[1]));
19335   emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19336   DONE;
19339 (define_insn "popcounthi2"
19340   [(set (match_operand:HI 0 "register_operand" "=r")
19341         (popcount:HI
19342           (match_operand:HI 1 "nonimmediate_operand" "rm")))
19343    (clobber (reg:CC FLAGS_REG))]
19344   "TARGET_POPCNT"
19346 #if TARGET_MACHO
19347   return "popcnt\t{%1, %0|%0, %1}";
19348 #else
19349   return "popcnt{w}\t{%1, %0|%0, %1}";
19350 #endif
19352   [(set_attr "prefix_rep" "1")
19353    (set_attr "type" "bitmanip")
19354    (set_attr "mode" "HI")])
19356 (define_expand "bswapdi2"
19357   [(set (match_operand:DI 0 "register_operand")
19358         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
19359   "TARGET_64BIT"
19361   if (!TARGET_MOVBE)
19362     operands[1] = force_reg (DImode, operands[1]);
19365 (define_expand "bswapsi2"
19366   [(set (match_operand:SI 0 "register_operand")
19367         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
19368   ""
19370   if (TARGET_MOVBE)
19371     ;
19372   else if (TARGET_BSWAP)
19373     operands[1] = force_reg (SImode, operands[1]);
19374   else
19375     {
19376       rtx x = operands[0];
19378       emit_move_insn (x, operands[1]);
19379       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19380       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
19381       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19382       DONE;
19383     }
19386 (define_insn "*bswap<mode>2_movbe"
19387   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
19388         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
19389   "TARGET_MOVBE
19390    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19391   "@
19392     bswap\t%0
19393     movbe{<imodesuffix>}\t{%1, %0|%0, %1}
19394     movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
19395   [(set_attr "type" "bitmanip,imov,imov")
19396    (set_attr "modrm" "0,1,1")
19397    (set_attr "prefix_0f" "*,1,1")
19398    (set_attr "prefix_extra" "*,1,1")
19399    (set_attr "mode" "<MODE>")])
19401 (define_insn "*bswap<mode>2"
19402   [(set (match_operand:SWI48 0 "register_operand" "=r")
19403         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
19404   "TARGET_BSWAP"
19405   "bswap\t%0"
19406   [(set_attr "type" "bitmanip")
19407    (set_attr "modrm" "0")
19408    (set_attr "mode" "<MODE>")])
19410 (define_expand "bswaphi2"
19411   [(set (match_operand:HI 0 "register_operand")
19412         (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
19413   "TARGET_MOVBE")
19415 (define_insn "*bswaphi2_movbe"
19416   [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
19417         (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
19418   "TARGET_MOVBE
19419    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19420   "@
19421     xchg{b}\t{%h0, %b0|%b0, %h0}
19422     movbe{w}\t{%1, %0|%0, %1}
19423     movbe{w}\t{%1, %0|%0, %1}"
19424   [(set_attr "type" "imov")
19425    (set_attr "modrm" "*,1,1")
19426    (set_attr "prefix_0f" "*,1,1")
19427    (set_attr "prefix_extra" "*,1,1")
19428    (set_attr "pent_pair" "np,*,*")
19429    (set_attr "athlon_decode" "vector,*,*")
19430    (set_attr "amdfam10_decode" "double,*,*")
19431    (set_attr "bdver1_decode" "double,*,*")
19432    (set_attr "mode" "QI,HI,HI")])
19434 (define_peephole2
19435   [(set (match_operand:HI 0 "general_reg_operand")
19436         (bswap:HI (match_dup 0)))]
19437   "TARGET_MOVBE
19438    && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
19439    && peep2_regno_dead_p (0, FLAGS_REG)"
19440   [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
19441               (clobber (reg:CC FLAGS_REG))])])
19443 (define_insn "bswaphi_lowpart"
19444   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
19445         (bswap:HI (match_dup 0)))
19446    (clobber (reg:CC FLAGS_REG))]
19447   ""
19448   "@
19449     xchg{b}\t{%h0, %b0|%b0, %h0}
19450     rol{w}\t{$8, %0|%0, 8}"
19451   [(set (attr "preferred_for_size")
19452      (cond [(eq_attr "alternative" "0")
19453               (symbol_ref "true")]
19454            (symbol_ref "false")))
19455    (set (attr "preferred_for_speed")
19456      (cond [(eq_attr "alternative" "0")
19457               (symbol_ref "TARGET_USE_XCHGB")]
19458            (symbol_ref "!TARGET_USE_XCHGB")))
19459    (set_attr "length" "2,4")
19460    (set_attr "mode" "QI,HI")])
19462 (define_expand "paritydi2"
19463   [(set (match_operand:DI 0 "register_operand")
19464         (parity:DI (match_operand:DI 1 "register_operand")))]
19465   "! TARGET_POPCNT"
19467   rtx scratch = gen_reg_rtx (QImode);
19468   rtx hipart1 = gen_reg_rtx (SImode);
19469   rtx lopart1 = gen_reg_rtx (SImode);
19470   rtx xor1 = gen_reg_rtx (SImode);
19471   rtx shift2 = gen_reg_rtx (SImode);
19472   rtx hipart2 = gen_reg_rtx (HImode);
19473   rtx lopart2 = gen_reg_rtx (HImode);
19474   rtx xor2 = gen_reg_rtx (HImode);
19476   if (TARGET_64BIT)
19477     {
19478       rtx shift1 = gen_reg_rtx (DImode);
19479       emit_insn (gen_lshrdi3 (shift1, operands[1], GEN_INT (32)));
19480       emit_move_insn (hipart1, gen_lowpart (SImode, shift1));
19481     }
19482   else
19483     emit_move_insn (hipart1, gen_highpart (SImode, operands[1]));
19485   emit_move_insn (lopart1, gen_lowpart (SImode, operands[1]));
19486   emit_insn (gen_xorsi3 (xor1, hipart1, lopart1));
19488   emit_insn (gen_lshrsi3 (shift2, xor1, GEN_INT (16)));
19489   emit_move_insn (hipart2, gen_lowpart (HImode, shift2));
19490   emit_move_insn (lopart2, gen_lowpart (HImode, xor1));
19491   emit_insn (gen_xorhi3 (xor2, hipart2, lopart2));
19493   emit_insn (gen_parityhi2_cmp (xor2));
19495   ix86_expand_setcc (scratch, ORDERED,
19496                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19498   if (TARGET_64BIT)
19499     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
19500   else
19501     {
19502       rtx tmp = gen_reg_rtx (SImode);
19504       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
19505       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
19506     }
19507   DONE;
19510 (define_expand "paritysi2"
19511   [(set (match_operand:SI 0 "register_operand")
19512         (parity:SI (match_operand:SI 1 "register_operand")))]
19513   "! TARGET_POPCNT"
19515   rtx scratch = gen_reg_rtx (QImode);
19516   rtx shift = gen_reg_rtx (SImode);
19517   rtx hipart = gen_reg_rtx (HImode);
19518   rtx lopart = gen_reg_rtx (HImode);
19519   rtx tmp = gen_reg_rtx (HImode);
19521   emit_insn (gen_lshrsi3 (shift, operands[1], GEN_INT (16)));
19522   emit_move_insn (hipart, gen_lowpart (HImode, shift));
19523   emit_move_insn (lopart, gen_lowpart (HImode, operands[1]));
19524   emit_insn (gen_xorhi3 (tmp, hipart, lopart));
19526   emit_insn (gen_parityhi2_cmp (tmp));
19528   ix86_expand_setcc (scratch, ORDERED,
19529                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19531   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
19532   DONE;
19535 (define_expand "parityhi2"
19536   [(set (match_operand:HI 0 "register_operand")
19537         (parity:HI (match_operand:HI 1 "register_operand")))]
19538   "! TARGET_POPCNT"
19540   rtx scratch = gen_reg_rtx (QImode);
19542   emit_insn (gen_parityhi2_cmp (operands[1]));
19544   ix86_expand_setcc (scratch, ORDERED,
19545                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19547   emit_insn (gen_zero_extendqihi2 (operands[0], scratch));
19548   DONE;
19551 (define_expand "parityqi2"
19552   [(set (match_operand:QI 0 "register_operand")
19553         (parity:QI (match_operand:QI 1 "register_operand")))]
19554   "! TARGET_POPCNT"
19556   emit_insn (gen_parityqi2_cmp (operands[1]));
19558   ix86_expand_setcc (operands[0], ORDERED,
19559                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19560   DONE;
19563 (define_insn "parityhi2_cmp"
19564   [(set (reg:CC FLAGS_REG)
19565         (unspec:CC [(match_operand:HI 0 "register_operand" "+Q")]
19566                    UNSPEC_PARITY))
19567    (clobber (match_dup 0))]
19568   ""
19569   "xor{b}\t{%h0, %b0|%b0, %h0}"
19570   [(set_attr "length" "2")
19571    (set_attr "mode" "QI")])
19573 (define_insn "parityqi2_cmp"
19574   [(set (reg:CC FLAGS_REG)
19575         (unspec:CC [(match_operand:QI 0 "register_operand" "q")]
19576                    UNSPEC_PARITY))]
19577   ""
19578   "test{b}\t%0, %0"
19579   [(set_attr "mode" "QI")])
19581 ;; Replace zero_extend:HI followed by parityhi2_cmp with parityqi2_cmp
19582 (define_peephole2
19583   [(set (match_operand:HI 0 "register_operand")
19584         (zero_extend:HI (match_operand:QI 1 "general_reg_operand")))
19585    (parallel [(set (reg:CC FLAGS_REG)
19586                    (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19587               (clobber (match_dup 0))])]
19588   ""
19589   [(set (reg:CC FLAGS_REG)
19590         (unspec:CC [(match_dup 1)] UNSPEC_PARITY))])
19592 ;; Eliminate QImode popcount&1 using parity flag
19593 (define_peephole2
19594   [(set (match_operand:SI 0 "register_operand")
19595         (zero_extend:SI (match_operand:QI 1 "general_reg_operand")))
19596    (parallel [(set (match_operand:SI 2 "register_operand")
19597                    (popcount:SI (match_dup 0)))
19598               (clobber (reg:CC FLAGS_REG))])
19599    (set (reg:CCZ FLAGS_REG)
19600         (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19601                              (const_int 1))
19602                      (const_int 0)))
19603    (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19604                             [(reg:CCZ FLAGS_REG)
19605                              (const_int 0)])
19606                            (label_ref (match_operand 5))
19607                            (pc)))]
19608   "REGNO (operands[2]) == REGNO (operands[3])
19609    && peep2_reg_dead_p (3, operands[0])
19610    && peep2_reg_dead_p (3, operands[2])
19611    && peep2_regno_dead_p (4, FLAGS_REG)"
19612   [(set (reg:CC FLAGS_REG)
19613         (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
19614    (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19615                                             (const_int 0)])
19616                            (label_ref (match_dup 5))
19617                            (pc)))]
19619   operands[4] = shallow_copy_rtx (operands[4]);
19620   PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19623 ;; Eliminate HImode popcount&1 using parity flag
19624 (define_peephole2
19625   [(match_scratch:HI 0 "Q")
19626    (parallel [(set (match_operand:HI 1 "register_operand")
19627                    (popcount:HI
19628                     (match_operand:HI 2 "nonimmediate_operand")))
19629               (clobber (reg:CC FLAGS_REG))])
19630    (set (match_operand 3 "register_operand")
19631         (zero_extend (match_dup 1)))
19632    (set (reg:CCZ FLAGS_REG)
19633         (compare:CCZ (and:QI (match_operand:QI 4 "register_operand")
19634                              (const_int 1))
19635                      (const_int 0)))
19636    (set (pc) (if_then_else (match_operator 5 "bt_comparison_operator"
19637                             [(reg:CCZ FLAGS_REG)
19638                              (const_int 0)])
19639                            (label_ref (match_operand 6))
19640                            (pc)))]
19641   "REGNO (operands[3]) == REGNO (operands[4])
19642    && peep2_reg_dead_p (3, operands[1])
19643    && peep2_reg_dead_p (3, operands[3])
19644    && peep2_regno_dead_p (4, FLAGS_REG)"
19645   [(set (match_dup 0) (match_dup 2))
19646    (parallel [(set (reg:CC FLAGS_REG)
19647                    (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19648               (clobber (match_dup 0))])
19649    (set (pc) (if_then_else (match_op_dup 5 [(reg:CC FLAGS_REG)
19650                                             (const_int 0)])
19651                            (label_ref (match_dup 6))
19652                            (pc)))]
19654   operands[5] = shallow_copy_rtx (operands[5]);
19655   PUT_CODE (operands[5], GET_CODE (operands[5]) == EQ ? UNORDERED : ORDERED);
19658 ;; Eliminate HImode popcount&1 using parity flag (variant 2)
19659 (define_peephole2
19660   [(match_scratch:HI 0 "Q")
19661    (parallel [(set (match_operand:HI 1 "register_operand")
19662                    (popcount:HI
19663                     (match_operand:HI 2 "nonimmediate_operand")))
19664               (clobber (reg:CC FLAGS_REG))])
19665    (set (reg:CCZ FLAGS_REG)
19666         (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19667                              (const_int 1))
19668                      (const_int 0)))
19669    (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19670                             [(reg:CCZ FLAGS_REG)
19671                              (const_int 0)])
19672                            (label_ref (match_operand 5))
19673                            (pc)))]
19674   "REGNO (operands[1]) == REGNO (operands[3])
19675    && peep2_reg_dead_p (2, operands[1])
19676    && peep2_reg_dead_p (2, operands[3])
19677    && peep2_regno_dead_p (3, FLAGS_REG)"
19678   [(set (match_dup 0) (match_dup 2))
19679    (parallel [(set (reg:CC FLAGS_REG)
19680                    (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19681               (clobber (match_dup 0))])
19682    (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19683                                             (const_int 0)])
19684                            (label_ref (match_dup 5))
19685                            (pc)))]
19687   operands[4] = shallow_copy_rtx (operands[4]);
19688   PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19692 ;; Thread-local storage patterns for ELF.
19694 ;; Note that these code sequences must appear exactly as shown
19695 ;; in order to allow linker relaxation.
19697 (define_insn "*tls_global_dynamic_32_gnu"
19698   [(set (match_operand:SI 0 "register_operand" "=a")
19699         (unspec:SI
19700          [(match_operand:SI 1 "register_operand" "Yb")
19701           (match_operand 2 "tls_symbolic_operand")
19702           (match_operand 3 "constant_call_address_operand" "Bz")
19703           (reg:SI SP_REG)]
19704          UNSPEC_TLS_GD))
19705    (clobber (match_scratch:SI 4 "=d"))
19706    (clobber (match_scratch:SI 5 "=c"))
19707    (clobber (reg:CC FLAGS_REG))]
19708   "!TARGET_64BIT && TARGET_GNU_TLS"
19710   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19711     output_asm_insn
19712       ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
19713   else
19714     output_asm_insn
19715       ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
19716   if (TARGET_SUN_TLS)
19717 #ifdef HAVE_AS_IX86_TLSGDPLT
19718     return "call\t%a2@tlsgdplt";
19719 #else
19720     return "call\t%p3@plt";
19721 #endif
19722   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19723     return "call\t%P3";
19724   return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
19726   [(set_attr "type" "multi")
19727    (set_attr "length" "12")])
19729 (define_expand "tls_global_dynamic_32"
19730   [(parallel
19731     [(set (match_operand:SI 0 "register_operand")
19732           (unspec:SI [(match_operand:SI 2 "register_operand")
19733                       (match_operand 1 "tls_symbolic_operand")
19734                       (match_operand 3 "constant_call_address_operand")
19735                       (reg:SI SP_REG)]
19736                      UNSPEC_TLS_GD))
19737      (clobber (scratch:SI))
19738      (clobber (scratch:SI))
19739      (clobber (reg:CC FLAGS_REG))])]
19740   ""
19741   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19743 (define_insn "*tls_global_dynamic_64_<mode>"
19744   [(set (match_operand:P 0 "register_operand" "=a")
19745         (call:P
19746          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
19747          (match_operand 3)))
19748    (unspec:P [(match_operand 1 "tls_symbolic_operand")
19749               (reg:P SP_REG)]
19750              UNSPEC_TLS_GD)]
19751   "TARGET_64BIT"
19753   if (!TARGET_X32)
19754     /* The .loc directive has effect for 'the immediately following assembly
19755        instruction'.  So for a sequence:
19756          .loc f l
19757          .byte x
19758          insn1
19759        the 'immediately following assembly instruction' is insn1.
19760        We want to emit an insn prefix here, but if we use .byte (as shown in
19761        'ELF Handling For Thread-Local Storage'), a preceding .loc will point
19762        inside the insn sequence, rather than to the start.  After relaxation
19763        of the sequence by the linker, the .loc might point inside an insn.
19764        Use data16 prefix instead, which doesn't have this problem.  */
19765     fputs ("\tdata16", asm_out_file);
19766   output_asm_insn
19767     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
19768   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19769     fputs (ASM_SHORT "0x6666\n", asm_out_file);
19770   else
19771     fputs (ASM_BYTE "0x66\n", asm_out_file);
19772   fputs ("\trex64\n", asm_out_file);
19773   if (TARGET_SUN_TLS)
19774     return "call\t%p2@plt";
19775   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19776     return "call\t%P2";
19777   return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
19779   [(set_attr "type" "multi")
19780    (set (attr "length")
19781         (symbol_ref "TARGET_X32 ? 15 : 16"))])
19783 (define_insn "*tls_global_dynamic_64_largepic"
19784   [(set (match_operand:DI 0 "register_operand" "=a")
19785         (call:DI
19786          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
19787                           (match_operand:DI 3 "immediate_operand" "i")))
19788          (match_operand 4)))
19789    (unspec:DI [(match_operand 1 "tls_symbolic_operand")
19790                (reg:DI SP_REG)]
19791               UNSPEC_TLS_GD)]
19792   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
19793    && GET_CODE (operands[3]) == CONST
19794    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
19795    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
19797   output_asm_insn
19798     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
19799   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
19800   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
19801   return "call\t{*%%rax|rax}";
19803   [(set_attr "type" "multi")
19804    (set_attr "length" "22")])
19806 (define_expand "@tls_global_dynamic_64_<mode>"
19807   [(parallel
19808     [(set (match_operand:P 0 "register_operand")
19809           (call:P
19810            (mem:QI (match_operand 2))
19811            (const_int 0)))
19812      (unspec:P [(match_operand 1 "tls_symbolic_operand")
19813                 (reg:P SP_REG)]
19814                UNSPEC_TLS_GD)])]
19815   "TARGET_64BIT"
19816   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19818 (define_insn "*tls_local_dynamic_base_32_gnu"
19819   [(set (match_operand:SI 0 "register_operand" "=a")
19820         (unspec:SI
19821          [(match_operand:SI 1 "register_operand" "Yb")
19822           (match_operand 2 "constant_call_address_operand" "Bz")
19823           (reg:SI SP_REG)]
19824          UNSPEC_TLS_LD_BASE))
19825    (clobber (match_scratch:SI 3 "=d"))
19826    (clobber (match_scratch:SI 4 "=c"))
19827    (clobber (reg:CC FLAGS_REG))]
19828   "!TARGET_64BIT && TARGET_GNU_TLS"
19830   output_asm_insn
19831     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
19832   if (TARGET_SUN_TLS)
19833     {
19834       if (HAVE_AS_IX86_TLSLDMPLT)
19835         return "call\t%&@tlsldmplt";
19836       else
19837         return "call\t%p2@plt";
19838     }
19839   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19840     return "call\t%P2";
19841   return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
19843   [(set_attr "type" "multi")
19844    (set_attr "length" "11")])
19846 (define_expand "tls_local_dynamic_base_32"
19847   [(parallel
19848      [(set (match_operand:SI 0 "register_operand")
19849            (unspec:SI
19850             [(match_operand:SI 1 "register_operand")
19851              (match_operand 2 "constant_call_address_operand")
19852              (reg:SI SP_REG)]
19853             UNSPEC_TLS_LD_BASE))
19854       (clobber (scratch:SI))
19855       (clobber (scratch:SI))
19856       (clobber (reg:CC FLAGS_REG))])]
19857   ""
19858   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19860 (define_insn "*tls_local_dynamic_base_64_<mode>"
19861   [(set (match_operand:P 0 "register_operand" "=a")
19862         (call:P
19863          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
19864          (match_operand 2)))
19865    (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
19866   "TARGET_64BIT"
19868   output_asm_insn
19869     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
19870   if (TARGET_SUN_TLS)
19871     return "call\t%p1@plt";
19872   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19873     return "call\t%P1";
19874   return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
19876   [(set_attr "type" "multi")
19877    (set_attr "length" "12")])
19879 (define_insn "*tls_local_dynamic_base_64_largepic"
19880   [(set (match_operand:DI 0 "register_operand" "=a")
19881         (call:DI
19882          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
19883                           (match_operand:DI 2 "immediate_operand" "i")))
19884          (match_operand 3)))
19885    (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
19886   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
19887    && GET_CODE (operands[2]) == CONST
19888    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
19889    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
19891   output_asm_insn
19892     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
19893   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
19894   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
19895   return "call\t{*%%rax|rax}";
19897   [(set_attr "type" "multi")
19898    (set_attr "length" "22")])
19900 (define_expand "@tls_local_dynamic_base_64_<mode>"
19901   [(parallel
19902      [(set (match_operand:P 0 "register_operand")
19903            (call:P
19904             (mem:QI (match_operand 1))
19905             (const_int 0)))
19906       (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
19907   "TARGET_64BIT"
19908   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19910 ;; Local dynamic of a single variable is a lose.  Show combine how
19911 ;; to convert that back to global dynamic.
19913 (define_insn_and_split "*tls_local_dynamic_32_once"
19914   [(set (match_operand:SI 0 "register_operand" "=a")
19915         (plus:SI
19916          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
19917                      (match_operand 2 "constant_call_address_operand" "Bz")
19918                      (reg:SI SP_REG)]
19919                     UNSPEC_TLS_LD_BASE)
19920          (const:SI (unspec:SI
19921                     [(match_operand 3 "tls_symbolic_operand")]
19922                     UNSPEC_DTPOFF))))
19923    (clobber (match_scratch:SI 4 "=d"))
19924    (clobber (match_scratch:SI 5 "=c"))
19925    (clobber (reg:CC FLAGS_REG))]
19926   ""
19927   "#"
19928   ""
19929   [(parallel
19930      [(set (match_dup 0)
19931            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
19932                        (reg:SI SP_REG)]
19933                       UNSPEC_TLS_GD))
19934       (clobber (match_dup 4))
19935       (clobber (match_dup 5))
19936       (clobber (reg:CC FLAGS_REG))])])
19938 ;; Load and add the thread base pointer from %<tp_seg>:0.
19939 (define_expand "get_thread_pointer<mode>"
19940   [(set (match_operand:PTR 0 "register_operand")
19941         (unspec:PTR [(const_int 0)] UNSPEC_TP))]
19942   ""
19944   /* targetm is not visible in the scope of the condition.  */
19945   if (!targetm.have_tls)
19946     error ("%<__builtin_thread_pointer%> is not supported on this target");
19949 (define_insn_and_split "*load_tp_<mode>"
19950   [(set (match_operand:PTR 0 "register_operand" "=r")
19951         (unspec:PTR [(const_int 0)] UNSPEC_TP))]
19952   ""
19953   "#"
19954   ""
19955   [(set (match_dup 0)
19956         (match_dup 1))]
19958   addr_space_t as = DEFAULT_TLS_SEG_REG;
19960   operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
19961   set_mem_addr_space (operands[1], as);
19964 (define_insn_and_split "*load_tp_x32_zext"
19965   [(set (match_operand:DI 0 "register_operand" "=r")
19966         (zero_extend:DI
19967           (unspec:SI [(const_int 0)] UNSPEC_TP)))]
19968   "TARGET_X32"
19969   "#"
19970   "&& 1"
19971   [(set (match_dup 0)
19972         (zero_extend:DI (match_dup 1)))]
19974   addr_space_t as = DEFAULT_TLS_SEG_REG;
19976   operands[1] = gen_const_mem (SImode, const0_rtx);
19977   set_mem_addr_space (operands[1], as);
19980 (define_insn_and_split "*add_tp_<mode>"
19981   [(set (match_operand:PTR 0 "register_operand" "=r")
19982         (plus:PTR
19983           (unspec:PTR [(const_int 0)] UNSPEC_TP)
19984           (match_operand:PTR 1 "register_operand" "0")))
19985    (clobber (reg:CC FLAGS_REG))]
19986   ""
19987   "#"
19988   ""
19989   [(parallel
19990      [(set (match_dup 0)
19991            (plus:PTR (match_dup 1) (match_dup 2)))
19992       (clobber (reg:CC FLAGS_REG))])]
19994   addr_space_t as = DEFAULT_TLS_SEG_REG;
19996   operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
19997   set_mem_addr_space (operands[2], as);
20000 (define_insn_and_split "*add_tp_x32_zext"
20001   [(set (match_operand:DI 0 "register_operand" "=r")
20002         (zero_extend:DI
20003           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
20004                    (match_operand:SI 1 "register_operand" "0"))))
20005    (clobber (reg:CC FLAGS_REG))]
20006   "TARGET_X32"
20007   "#"
20008   "&& 1"
20009   [(parallel
20010      [(set (match_dup 0)
20011            (zero_extend:DI
20012              (plus:SI (match_dup 1) (match_dup 2))))
20013       (clobber (reg:CC FLAGS_REG))])]
20015   addr_space_t as = DEFAULT_TLS_SEG_REG;
20017   operands[2] = gen_const_mem (SImode, const0_rtx);
20018   set_mem_addr_space (operands[2], as);
20021 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
20022 ;; %rax as destination of the initial executable code sequence.
20023 (define_insn "tls_initial_exec_64_sun"
20024   [(set (match_operand:DI 0 "register_operand" "=a")
20025         (unspec:DI
20026          [(match_operand 1 "tls_symbolic_operand")]
20027          UNSPEC_TLS_IE_SUN))
20028    (clobber (reg:CC FLAGS_REG))]
20029   "TARGET_64BIT && TARGET_SUN_TLS"
20031   output_asm_insn
20032     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
20033   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
20035   [(set_attr "type" "multi")])
20037 ;; GNU2 TLS patterns can be split.
20039 (define_expand "tls_dynamic_gnu2_32"
20040   [(set (match_dup 3)
20041         (plus:SI (match_operand:SI 2 "register_operand")
20042                  (const:SI
20043                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
20044                              UNSPEC_TLSDESC))))
20045    (parallel
20046     [(set (match_operand:SI 0 "register_operand")
20047           (unspec:SI [(match_dup 1) (match_dup 3)
20048                       (match_dup 2) (reg:SI SP_REG)]
20049                       UNSPEC_TLSDESC))
20050      (clobber (reg:CC FLAGS_REG))])]
20051   "!TARGET_64BIT && TARGET_GNU2_TLS"
20053   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
20054   ix86_tls_descriptor_calls_expanded_in_cfun = true;
20057 (define_insn "*tls_dynamic_gnu2_lea_32"
20058   [(set (match_operand:SI 0 "register_operand" "=r")
20059         (plus:SI (match_operand:SI 1 "register_operand" "b")
20060                  (const:SI
20061                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
20062                               UNSPEC_TLSDESC))))]
20063   "!TARGET_64BIT && TARGET_GNU2_TLS"
20064   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
20065   [(set_attr "type" "lea")
20066    (set_attr "mode" "SI")
20067    (set_attr "length" "6")
20068    (set_attr "length_address" "4")])
20070 (define_insn "*tls_dynamic_gnu2_call_32"
20071   [(set (match_operand:SI 0 "register_operand" "=a")
20072         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
20073                     (match_operand:SI 2 "register_operand" "0")
20074                     ;; we have to make sure %ebx still points to the GOT
20075                     (match_operand:SI 3 "register_operand" "b")
20076                     (reg:SI SP_REG)]
20077                    UNSPEC_TLSDESC))
20078    (clobber (reg:CC FLAGS_REG))]
20079   "!TARGET_64BIT && TARGET_GNU2_TLS"
20080   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
20081   [(set_attr "type" "call")
20082    (set_attr "length" "2")
20083    (set_attr "length_address" "0")])
20085 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
20086   [(set (match_operand:SI 0 "register_operand" "=&a")
20087         (plus:SI
20088          (unspec:SI [(match_operand 3 "tls_modbase_operand")
20089                      (match_operand:SI 4)
20090                      (match_operand:SI 2 "register_operand" "b")
20091                      (reg:SI SP_REG)]
20092                     UNSPEC_TLSDESC)
20093          (const:SI (unspec:SI
20094                     [(match_operand 1 "tls_symbolic_operand")]
20095                     UNSPEC_DTPOFF))))
20096    (clobber (reg:CC FLAGS_REG))]
20097   "!TARGET_64BIT && TARGET_GNU2_TLS"
20098   "#"
20099   "&& 1"
20100   [(set (match_dup 0) (match_dup 5))]
20102   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
20103   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
20106 (define_expand "@tls_dynamic_gnu2_64_<mode>"
20107   [(set (match_dup 2)
20108         (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
20109                     UNSPEC_TLSDESC))
20110    (parallel
20111     [(set (match_operand:PTR 0 "register_operand")
20112           (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)]
20113                       UNSPEC_TLSDESC))
20114      (clobber (reg:CC FLAGS_REG))])]
20115   "TARGET_64BIT && TARGET_GNU2_TLS"
20117   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
20118   ix86_tls_descriptor_calls_expanded_in_cfun = true;
20121 (define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
20122   [(set (match_operand:PTR 0 "register_operand" "=r")
20123         (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
20124                     UNSPEC_TLSDESC))]
20125   "TARGET_64BIT && TARGET_GNU2_TLS"
20126   "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
20127   [(set_attr "type" "lea")
20128    (set_attr "mode" "<MODE>")
20129    (set_attr "length" "7")
20130    (set_attr "length_address" "4")])
20132 (define_insn "*tls_dynamic_gnu2_call_64_<mode>"
20133   [(set (match_operand:PTR 0 "register_operand" "=a")
20134         (unspec:PTR [(match_operand 1 "tls_symbolic_operand")
20135                    (match_operand:PTR 2 "register_operand" "0")
20136                    (reg:PTR SP_REG)]
20137                   UNSPEC_TLSDESC))
20138    (clobber (reg:CC FLAGS_REG))]
20139   "TARGET_64BIT && TARGET_GNU2_TLS"
20140   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
20141   [(set_attr "type" "call")
20142    (set_attr "length" "2")
20143    (set_attr "length_address" "0")])
20145 (define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
20146   [(set (match_operand:PTR 0 "register_operand" "=&a")
20147         (plus:PTR
20148          (unspec:PTR [(match_operand 2 "tls_modbase_operand")
20149                       (match_operand:PTR 3)
20150                       (reg:PTR SP_REG)]
20151                      UNSPEC_TLSDESC)
20152          (const:PTR (unspec:PTR
20153                      [(match_operand 1 "tls_symbolic_operand")]
20154                      UNSPEC_DTPOFF))))
20155    (clobber (reg:CC FLAGS_REG))]
20156   "TARGET_64BIT && TARGET_GNU2_TLS"
20157   "#"
20158   "&& 1"
20159   [(set (match_dup 0) (match_dup 4))]
20161   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
20162   emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1]));
20165 (define_split
20166   [(match_operand 0 "tls_address_pattern")]
20167   "TARGET_TLS_DIRECT_SEG_REFS"
20168   [(match_dup 0)]
20169   "operands[0] = ix86_rewrite_tls_address (operands[0]);")
20172 ;; These patterns match the binary 387 instructions for addM3, subM3,
20173 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
20174 ;; SFmode.  The first is the normal insn, the second the same insn but
20175 ;; with one operand a conversion, and the third the same insn but with
20176 ;; the other operand a conversion.  The conversion may be SFmode or
20177 ;; SImode if the target mode DFmode, but only SImode if the target mode
20178 ;; is SFmode.
20180 ;; Gcc is slightly more smart about handling normal two address instructions
20181 ;; so use special patterns for add and mull.
20183 (define_insn "*fop_xf_comm_i387"
20184   [(set (match_operand:XF 0 "register_operand" "=f")
20185         (match_operator:XF 3 "binary_fp_operator"
20186                         [(match_operand:XF 1 "register_operand" "%0")
20187                          (match_operand:XF 2 "register_operand" "f")]))]
20188   "TARGET_80387
20189    && COMMUTATIVE_ARITH_P (operands[3])"
20190   "* return output_387_binary_op (insn, operands);"
20191   [(set (attr "type")
20192         (if_then_else (match_operand:XF 3 "mult_operator")
20193            (const_string "fmul")
20194            (const_string "fop")))
20195    (set_attr "mode" "XF")])
20197 (define_insn "*fop_<mode>_comm"
20198   [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
20199         (match_operator:MODEF 3 "binary_fp_operator"
20200           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
20201            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
20202   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20203     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20204    && COMMUTATIVE_ARITH_P (operands[3])
20205    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20206   "* return output_387_binary_op (insn, operands);"
20207   [(set (attr "type")
20208         (if_then_else (eq_attr "alternative" "1,2")
20209            (if_then_else (match_operand:MODEF 3 "mult_operator")
20210               (const_string "ssemul")
20211               (const_string "sseadd"))
20212            (if_then_else (match_operand:MODEF 3 "mult_operator")
20213               (const_string "fmul")
20214               (const_string "fop"))))
20215    (set_attr "isa" "*,noavx,avx")
20216    (set_attr "prefix" "orig,orig,vex")
20217    (set_attr "mode" "<MODE>")
20218    (set (attr "enabled")
20219      (if_then_else
20220        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20221        (if_then_else
20222          (eq_attr "alternative" "0")
20223          (symbol_ref "TARGET_MIX_SSE_I387
20224                       && X87_ENABLE_ARITH (<MODE>mode)")
20225          (const_string "*"))
20226        (if_then_else
20227          (eq_attr "alternative" "0")
20228          (symbol_ref "true")
20229          (symbol_ref "false"))))])
20231 (define_insn "*<insn>hf"
20232   [(set (match_operand:HF 0 "register_operand" "=v")
20233         (plusminusmultdiv:HF
20234           (match_operand:HF 1 "nonimmediate_operand" "<comm>v")
20235           (match_operand:HF 2 "nonimmediate_operand" "vm")))]
20236   "TARGET_AVX512FP16
20237    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20238   "v<insn>sh\t{%2, %1, %0|%0, %1, %2}"
20239   [(set_attr "prefix" "evex")
20240    (set_attr "mode" "HF")])
20242 (define_insn "*rcpsf2_sse"
20243   [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
20244         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
20245                    UNSPEC_RCP))]
20246   "TARGET_SSE && TARGET_SSE_MATH"
20247   "@
20248    %vrcpss\t{%d1, %0|%0, %d1}
20249    %vrcpss\t{%d1, %0|%0, %d1}
20250    rcpss\t{%1, %d0|%d0, %1}
20251    vrcpss\t{%1, %d0|%d0, %1}"
20252   [(set_attr "isa" "*,*,noavx,avx")
20253    (set_attr "addr" "*,*,*,gpr16")
20254    (set_attr "type" "sse")
20255    (set_attr "atom_sse_attr" "rcp")
20256    (set_attr "btver2_sse_attr" "rcp")
20257    (set_attr "prefix" "maybe_vex")
20258    (set_attr "mode" "SF")
20259    (set_attr "avx_partial_xmm_update" "false,false,true,true")
20260    (set (attr "preferred_for_speed")
20261       (cond [(match_test "TARGET_AVX")
20262                (symbol_ref "true")
20263              (eq_attr "alternative" "1,2,3")
20264                (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20265             ]
20266             (symbol_ref "true")))])
20268 (define_insn "rcphf2"
20269   [(set (match_operand:HF 0 "register_operand" "=v,v")
20270         (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20271                    UNSPEC_RCP))]
20272   "TARGET_AVX512FP16"
20273   "@
20274    vrcpsh\t{%d1, %0|%0, %d1}
20275    vrcpsh\t{%1, %d0|%d0, %1}"
20276   [(set_attr "type" "sse")
20277    (set_attr "prefix" "evex")
20278    (set_attr "mode" "HF")
20279    (set_attr "avx_partial_xmm_update" "false,true")])
20281 (define_insn "*fop_xf_1_i387"
20282   [(set (match_operand:XF 0 "register_operand" "=f,f")
20283         (match_operator:XF 3 "binary_fp_operator"
20284                         [(match_operand:XF 1 "register_operand" "0,f")
20285                          (match_operand:XF 2 "register_operand" "f,0")]))]
20286   "TARGET_80387
20287    && !COMMUTATIVE_ARITH_P (operands[3])"
20288   "* return output_387_binary_op (insn, operands);"
20289   [(set (attr "type")
20290         (if_then_else (match_operand:XF 3 "div_operator")
20291            (const_string "fdiv")
20292            (const_string "fop")))
20293    (set_attr "mode" "XF")])
20295 (define_insn "*fop_<mode>_1"
20296   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
20297         (match_operator:MODEF 3 "binary_fp_operator"
20298           [(match_operand:MODEF 1
20299              "x87nonimm_ssenomem_operand" "0,fm,0,v")
20300            (match_operand:MODEF 2
20301              "nonimmediate_operand"       "fm,0,xm,vm")]))]
20302   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20303     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20304    && !COMMUTATIVE_ARITH_P (operands[3])
20305    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20306   "* return output_387_binary_op (insn, operands);"
20307   [(set (attr "type")
20308         (if_then_else (eq_attr "alternative" "2,3")
20309            (if_then_else (match_operand:MODEF 3 "div_operator")
20310               (const_string "ssediv")
20311               (const_string "sseadd"))
20312            (if_then_else (match_operand:MODEF 3 "div_operator")
20313               (const_string "fdiv")
20314               (const_string "fop"))))
20315    (set_attr "isa" "*,*,noavx,avx")
20316    (set_attr "prefix" "orig,orig,orig,vex")
20317    (set_attr "mode" "<MODE>")
20318    (set (attr "enabled")
20319      (if_then_else
20320        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20321        (if_then_else
20322          (eq_attr "alternative" "0,1")
20323          (symbol_ref "TARGET_MIX_SSE_I387
20324                       && X87_ENABLE_ARITH (<MODE>mode)")
20325          (const_string "*"))
20326        (if_then_else
20327          (eq_attr "alternative" "0,1")
20328          (symbol_ref "true")
20329          (symbol_ref "false"))))])
20331 (define_insn "*fop_<X87MODEF:mode>_2_i387"
20332   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20333         (match_operator:X87MODEF 3 "binary_fp_operator"
20334           [(float:X87MODEF
20335              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
20336            (match_operand:X87MODEF 2 "register_operand" "0")]))]
20337   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20338    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20339    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20340        || optimize_function_for_size_p (cfun))"
20341   "* return output_387_binary_op (insn, operands);"
20342   [(set (attr "type")
20343         (cond [(match_operand:X87MODEF 3 "mult_operator")
20344                  (const_string "fmul")
20345                (match_operand:X87MODEF 3 "div_operator")
20346                  (const_string "fdiv")
20347               ]
20348               (const_string "fop")))
20349    (set_attr "fp_int_src" "true")
20350    (set_attr "mode" "<SWI24:MODE>")])
20352 (define_insn "*fop_<X87MODEF:mode>_3_i387"
20353   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20354         (match_operator:X87MODEF 3 "binary_fp_operator"
20355           [(match_operand:X87MODEF 1 "register_operand" "0")
20356            (float:X87MODEF
20357              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
20358   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20359    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20360    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20361        || optimize_function_for_size_p (cfun))"
20362   "* return output_387_binary_op (insn, operands);"
20363   [(set (attr "type")
20364         (cond [(match_operand:X87MODEF 3 "mult_operator")
20365                  (const_string "fmul")
20366                (match_operand:X87MODEF 3 "div_operator")
20367                  (const_string "fdiv")
20368               ]
20369               (const_string "fop")))
20370    (set_attr "fp_int_src" "true")
20371    (set_attr "mode" "<SWI24:MODE>")])
20373 (define_insn "*fop_xf_4_i387"
20374   [(set (match_operand:XF 0 "register_operand" "=f,f")
20375         (match_operator:XF 3 "binary_fp_operator"
20376            [(float_extend:XF
20377               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
20378             (match_operand:XF 2 "register_operand" "0,f")]))]
20379   "TARGET_80387"
20380   "* return output_387_binary_op (insn, operands);"
20381   [(set (attr "type")
20382         (cond [(match_operand:XF 3 "mult_operator")
20383                  (const_string "fmul")
20384                (match_operand:XF 3 "div_operator")
20385                  (const_string "fdiv")
20386               ]
20387               (const_string "fop")))
20388    (set_attr "mode" "<MODE>")])
20390 (define_insn "*fop_df_4_i387"
20391   [(set (match_operand:DF 0 "register_operand" "=f,f")
20392         (match_operator:DF 3 "binary_fp_operator"
20393            [(float_extend:DF
20394              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
20395             (match_operand:DF 2 "register_operand" "0,f")]))]
20396   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20397    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20398   "* return output_387_binary_op (insn, operands);"
20399   [(set (attr "type")
20400         (cond [(match_operand:DF 3 "mult_operator")
20401                  (const_string "fmul")
20402                (match_operand:DF 3 "div_operator")
20403                  (const_string "fdiv")
20404               ]
20405               (const_string "fop")))
20406    (set_attr "mode" "SF")])
20408 (define_insn "*fop_xf_5_i387"
20409   [(set (match_operand:XF 0 "register_operand" "=f,f")
20410         (match_operator:XF 3 "binary_fp_operator"
20411           [(match_operand:XF 1 "register_operand" "0,f")
20412            (float_extend:XF
20413              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20414   "TARGET_80387"
20415   "* return output_387_binary_op (insn, operands);"
20416   [(set (attr "type")
20417         (cond [(match_operand:XF 3 "mult_operator")
20418                  (const_string "fmul")
20419                (match_operand:XF 3 "div_operator")
20420                  (const_string "fdiv")
20421               ]
20422               (const_string "fop")))
20423    (set_attr "mode" "<MODE>")])
20425 (define_insn "*fop_df_5_i387"
20426   [(set (match_operand:DF 0 "register_operand" "=f,f")
20427         (match_operator:DF 3 "binary_fp_operator"
20428           [(match_operand:DF 1 "register_operand" "0,f")
20429            (float_extend:DF
20430             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20431   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20432    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20433   "* return output_387_binary_op (insn, operands);"
20434   [(set (attr "type")
20435         (cond [(match_operand:DF 3 "mult_operator")
20436                  (const_string "fmul")
20437                (match_operand:DF 3 "div_operator")
20438                  (const_string "fdiv")
20439               ]
20440               (const_string "fop")))
20441    (set_attr "mode" "SF")])
20443 (define_insn "*fop_xf_6_i387"
20444   [(set (match_operand:XF 0 "register_operand" "=f,f")
20445         (match_operator:XF 3 "binary_fp_operator"
20446           [(float_extend:XF
20447              (match_operand:MODEF 1 "register_operand" "0,f"))
20448            (float_extend:XF
20449              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20450   "TARGET_80387"
20451   "* return output_387_binary_op (insn, operands);"
20452   [(set (attr "type")
20453         (cond [(match_operand:XF 3 "mult_operator")
20454                  (const_string "fmul")
20455                (match_operand:XF 3 "div_operator")
20456                  (const_string "fdiv")
20457               ]
20458               (const_string "fop")))
20459    (set_attr "mode" "<MODE>")])
20461 (define_insn "*fop_df_6_i387"
20462   [(set (match_operand:DF 0 "register_operand" "=f,f")
20463         (match_operator:DF 3 "binary_fp_operator"
20464           [(float_extend:DF
20465             (match_operand:SF 1 "register_operand" "0,f"))
20466            (float_extend:DF
20467             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20468   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20469    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20470   "* return output_387_binary_op (insn, operands);"
20471   [(set (attr "type")
20472         (cond [(match_operand:DF 3 "mult_operator")
20473                  (const_string "fmul")
20474                (match_operand:DF 3 "div_operator")
20475                  (const_string "fdiv")
20476               ]
20477               (const_string "fop")))
20478    (set_attr "mode" "SF")])
20480 ;; FPU special functions.
20482 ;; This pattern implements a no-op XFmode truncation for
20483 ;; all fancy i386 XFmode math functions.
20485 (define_insn "truncxf<mode>2_i387_noop_unspec"
20486   [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
20487         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
20488         UNSPEC_TRUNC_NOOP))]
20489   "TARGET_USE_FANCY_MATH_387"
20490   "* return output_387_reg_move (insn, operands);"
20491   [(set_attr "type" "fmov")
20492    (set_attr "mode" "<MODE>")])
20494 (define_insn "sqrtxf2"
20495   [(set (match_operand:XF 0 "register_operand" "=f")
20496         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
20497   "TARGET_USE_FANCY_MATH_387"
20498   "fsqrt"
20499   [(set_attr "type" "fpspc")
20500    (set_attr "mode" "XF")
20501    (set_attr "athlon_decode" "direct")
20502    (set_attr "amdfam10_decode" "direct")
20503    (set_attr "bdver1_decode" "direct")])
20505 (define_insn "*rsqrtsf2_sse"
20506   [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
20507         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
20508                    UNSPEC_RSQRT))]
20509   "TARGET_SSE && TARGET_SSE_MATH"
20510   "@
20511    %vrsqrtss\t{%d1, %0|%0, %d1}
20512    %vrsqrtss\t{%d1, %0|%0, %d1}
20513    rsqrtss\t{%1, %d0|%d0, %1}
20514    vrsqrtss\t{%1, %d0|%d0, %1}"
20515   [(set_attr "isa" "*,*,noavx,avx")
20516    (set_attr "addr" "*,*,*,gpr16")
20517    (set_attr "type" "sse")
20518    (set_attr "atom_sse_attr" "rcp")
20519    (set_attr "btver2_sse_attr" "rcp")
20520    (set_attr "prefix" "maybe_vex")
20521    (set_attr "mode" "SF")
20522    (set_attr "avx_partial_xmm_update" "false,false,true,true")
20523    (set (attr "preferred_for_speed")
20524       (cond [(match_test "TARGET_AVX")
20525                (symbol_ref "true")
20526              (eq_attr "alternative" "1,2,3")
20527                (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20528             ]
20529             (symbol_ref "true")))])
20531 (define_expand "rsqrtsf2"
20532   [(set (match_operand:SF 0 "register_operand")
20533         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
20534                    UNSPEC_RSQRT))]
20535   "TARGET_SSE && TARGET_SSE_MATH"
20537   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
20538   DONE;
20541 (define_insn "rsqrthf2"
20542   [(set (match_operand:HF 0 "register_operand" "=v,v")
20543         (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20544                    UNSPEC_RSQRT))]
20545   "TARGET_AVX512FP16"
20546   "@
20547    vrsqrtsh\t{%d1, %0|%0, %d1}
20548    vrsqrtsh\t{%1, %d0|%d0, %1}"
20549   [(set_attr "type" "sse")
20550    (set_attr "prefix" "evex")
20551    (set_attr "avx_partial_xmm_update" "false,true")
20552    (set_attr "mode" "HF")])
20554 (define_insn "sqrthf2"
20555   [(set (match_operand:HF 0 "register_operand" "=v,v")
20556         (sqrt:HF
20557           (match_operand:HF 1 "nonimmediate_operand" "v,m")))]
20558   "TARGET_AVX512FP16"
20559   "@
20560    vsqrtsh\t{%d1, %0|%0, %d1}
20561    vsqrtsh\t{%1, %d0|%d0, %1}"
20562   [(set_attr "type" "sse")
20563    (set_attr "prefix" "evex")
20564    (set_attr "avx_partial_xmm_update" "false,true")
20565    (set_attr "mode" "HF")])
20567 (define_insn "*sqrt<mode>2_sse"
20568   [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
20569         (sqrt:MODEF
20570           (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
20571   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20572   "@
20573    %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20574    %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20575    %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
20576   [(set_attr "type" "sse")
20577    (set_attr "atom_sse_attr" "sqrt")
20578    (set_attr "btver2_sse_attr" "sqrt")
20579    (set_attr "prefix" "maybe_vex")
20580    (set_attr "avx_partial_xmm_update" "false,false,true")
20581    (set_attr "mode" "<MODE>")
20582    (set (attr "preferred_for_speed")
20583       (cond [(match_test "TARGET_AVX")
20584                (symbol_ref "true")
20585              (eq_attr "alternative" "1,2")
20586                (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20587             ]
20588             (symbol_ref "true")))])
20590 (define_expand "sqrt<mode>2"
20591   [(set (match_operand:MODEF 0 "register_operand")
20592         (sqrt:MODEF
20593           (match_operand:MODEF 1 "nonimmediate_operand")))]
20594   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
20595    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20597   if (<MODE>mode == SFmode
20598       && TARGET_SSE && TARGET_SSE_MATH
20599       && TARGET_RECIP_SQRT
20600       && !optimize_function_for_size_p (cfun)
20601       && flag_finite_math_only && !flag_trapping_math
20602       && flag_unsafe_math_optimizations)
20603     {
20604       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
20605       DONE;
20606     }
20608   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
20609     {
20610       rtx op0 = gen_reg_rtx (XFmode);
20611       rtx op1 = gen_reg_rtx (XFmode);
20613       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20614       emit_insn (gen_sqrtxf2 (op0, op1));
20615       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
20616       DONE;
20617    }
20620 (define_expand "hypot<mode>3"
20621   [(use (match_operand:MODEF 0 "register_operand"))
20622    (use (match_operand:MODEF 1 "general_operand"))
20623    (use (match_operand:MODEF 2 "general_operand"))]
20624   "TARGET_USE_FANCY_MATH_387
20625    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20626        || TARGET_MIX_SSE_I387)
20627    && flag_finite_math_only
20628    && flag_unsafe_math_optimizations"
20630   rtx op0 = gen_reg_rtx (XFmode);
20631   rtx op1 = gen_reg_rtx (XFmode);
20632   rtx op2 = gen_reg_rtx (XFmode);
20634   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20635   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20637   emit_insn (gen_mulxf3 (op1, op1, op1));
20638   emit_insn (gen_mulxf3 (op2, op2, op2));
20639   emit_insn (gen_addxf3 (op0, op2, op1));
20640   emit_insn (gen_sqrtxf2 (op0, op0));
20642   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20643   DONE;
20646 (define_insn "x86_fnstsw_1"
20647   [(set (match_operand:HI 0 "register_operand" "=a")
20648         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
20649   "TARGET_80387"
20650   "fnstsw\t%0"
20651   [(set_attr "length" "2")
20652    (set_attr "mode" "SI")
20653    (set_attr "unit" "i387")])
20655 (define_insn "fpremxf4_i387"
20656   [(set (match_operand:XF 0 "register_operand" "=f")
20657         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20658                     (match_operand:XF 3 "register_operand" "1")]
20659                    UNSPEC_FPREM_F))
20660    (set (match_operand:XF 1 "register_operand" "=f")
20661         (unspec:XF [(match_dup 2) (match_dup 3)]
20662                    UNSPEC_FPREM_U))
20663    (set (reg:CCFP FPSR_REG)
20664         (unspec:CCFP [(match_dup 2) (match_dup 3)]
20665                      UNSPEC_C2_FLAG))]
20666   "TARGET_USE_FANCY_MATH_387"
20667   "fprem"
20668   [(set_attr "type" "fpspc")
20669    (set_attr "znver1_decode" "vector")
20670    (set_attr "mode" "XF")])
20672 (define_expand "fmodxf3"
20673   [(use (match_operand:XF 0 "register_operand"))
20674    (use (match_operand:XF 1 "general_operand"))
20675    (use (match_operand:XF 2 "general_operand"))]
20676   "TARGET_USE_FANCY_MATH_387"
20678   rtx_code_label *label = gen_label_rtx ();
20680   rtx op1 = gen_reg_rtx (XFmode);
20681   rtx op2 = gen_reg_rtx (XFmode);
20683   emit_move_insn (op2, operands[2]);
20684   emit_move_insn (op1, operands[1]);
20686   emit_label (label);
20687   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20688   ix86_emit_fp_unordered_jump (label);
20689   LABEL_NUSES (label) = 1;
20691   emit_move_insn (operands[0], op1);
20692   DONE;
20695 (define_expand "fmod<mode>3"
20696   [(use (match_operand:MODEF 0 "register_operand"))
20697    (use (match_operand:MODEF 1 "general_operand"))
20698    (use (match_operand:MODEF 2 "general_operand"))]
20699   "TARGET_USE_FANCY_MATH_387"
20701   rtx (*gen_truncxf) (rtx, rtx);
20703   rtx_code_label *label = gen_label_rtx ();
20705   rtx op1 = gen_reg_rtx (XFmode);
20706   rtx op2 = gen_reg_rtx (XFmode);
20708   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20709   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20711   emit_label (label);
20712   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20713   ix86_emit_fp_unordered_jump (label);
20714   LABEL_NUSES (label) = 1;
20716   /* Truncate the result properly for strict SSE math.  */
20717   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20718       && !TARGET_MIX_SSE_I387)
20719     gen_truncxf = gen_truncxf<mode>2;
20720   else
20721     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20723   emit_insn (gen_truncxf (operands[0], op1));
20724   DONE;
20727 (define_insn "fprem1xf4_i387"
20728   [(set (match_operand:XF 0 "register_operand" "=f")
20729         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20730                     (match_operand:XF 3 "register_operand" "1")]
20731                    UNSPEC_FPREM1_F))
20732    (set (match_operand:XF 1 "register_operand" "=f")
20733         (unspec:XF [(match_dup 2) (match_dup 3)]
20734                    UNSPEC_FPREM1_U))
20735    (set (reg:CCFP FPSR_REG)
20736         (unspec:CCFP [(match_dup 2) (match_dup 3)]
20737                      UNSPEC_C2_FLAG))]
20738   "TARGET_USE_FANCY_MATH_387"
20739   "fprem1"
20740   [(set_attr "type" "fpspc")
20741    (set_attr "znver1_decode" "vector")
20742    (set_attr "mode" "XF")])
20744 (define_expand "remainderxf3"
20745   [(use (match_operand:XF 0 "register_operand"))
20746    (use (match_operand:XF 1 "general_operand"))
20747    (use (match_operand:XF 2 "general_operand"))]
20748   "TARGET_USE_FANCY_MATH_387"
20750   rtx_code_label *label = gen_label_rtx ();
20752   rtx op1 = gen_reg_rtx (XFmode);
20753   rtx op2 = gen_reg_rtx (XFmode);
20755   emit_move_insn (op2, operands[2]);
20756   emit_move_insn (op1, operands[1]);
20758   emit_label (label);
20759   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20760   ix86_emit_fp_unordered_jump (label);
20761   LABEL_NUSES (label) = 1;
20763   emit_move_insn (operands[0], op1);
20764   DONE;
20767 (define_expand "remainder<mode>3"
20768   [(use (match_operand:MODEF 0 "register_operand"))
20769    (use (match_operand:MODEF 1 "general_operand"))
20770    (use (match_operand:MODEF 2 "general_operand"))]
20771   "TARGET_USE_FANCY_MATH_387"
20773   rtx (*gen_truncxf) (rtx, rtx);
20775   rtx_code_label *label = gen_label_rtx ();
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_label (label);
20785   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20786   ix86_emit_fp_unordered_jump (label);
20787   LABEL_NUSES (label) = 1;
20789   /* Truncate the result properly for strict SSE math.  */
20790   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20791       && !TARGET_MIX_SSE_I387)
20792     gen_truncxf = gen_truncxf<mode>2;
20793   else
20794     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20796   emit_insn (gen_truncxf (operands[0], op1));
20797   DONE;
20800 (define_int_iterator SINCOS
20801         [UNSPEC_SIN
20802          UNSPEC_COS])
20804 (define_int_attr sincos
20805         [(UNSPEC_SIN "sin")
20806          (UNSPEC_COS "cos")])
20808 (define_insn "<sincos>xf2"
20809   [(set (match_operand:XF 0 "register_operand" "=f")
20810         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
20811                    SINCOS))]
20812   "TARGET_USE_FANCY_MATH_387
20813    && flag_unsafe_math_optimizations"
20814   "f<sincos>"
20815   [(set_attr "type" "fpspc")
20816    (set_attr "znver1_decode" "vector")
20817    (set_attr "mode" "XF")])
20819 (define_expand "<sincos><mode>2"
20820   [(set (match_operand:MODEF 0 "register_operand")
20821         (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
20822                       SINCOS))]
20823   "TARGET_USE_FANCY_MATH_387
20824    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20825        || TARGET_MIX_SSE_I387)
20826    && flag_unsafe_math_optimizations"
20828   rtx op0 = gen_reg_rtx (XFmode);
20829   rtx op1 = gen_reg_rtx (XFmode);
20831   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20832   emit_insn (gen_<sincos>xf2 (op0, op1));
20833   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20834   DONE;
20837 (define_insn "sincosxf3"
20838   [(set (match_operand:XF 0 "register_operand" "=f")
20839         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
20840                    UNSPEC_SINCOS_COS))
20841    (set (match_operand:XF 1 "register_operand" "=f")
20842         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
20843   "TARGET_USE_FANCY_MATH_387
20844    && flag_unsafe_math_optimizations"
20845   "fsincos"
20846   [(set_attr "type" "fpspc")
20847    (set_attr "znver1_decode" "vector")
20848    (set_attr "mode" "XF")])
20850 (define_expand "sincos<mode>3"
20851   [(use (match_operand:MODEF 0 "register_operand"))
20852    (use (match_operand:MODEF 1 "register_operand"))
20853    (use (match_operand:MODEF 2 "general_operand"))]
20854   "TARGET_USE_FANCY_MATH_387
20855    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20856        || TARGET_MIX_SSE_I387)
20857    && flag_unsafe_math_optimizations"
20859   rtx op0 = gen_reg_rtx (XFmode);
20860   rtx op1 = gen_reg_rtx (XFmode);
20861   rtx op2 = gen_reg_rtx (XFmode);
20863   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20864   emit_insn (gen_sincosxf3 (op0, op1, op2));
20865   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20866   emit_insn (gen_truncxf<mode>2 (operands[1], op1));
20867   DONE;
20870 (define_insn "fptanxf4_i387"
20871   [(set (match_operand:SF 0 "register_operand" "=f")
20872         (match_operand:SF 3 "const1_operand"))
20873    (set (match_operand:XF 1 "register_operand" "=f")
20874         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
20875                    UNSPEC_TAN))]
20876   "TARGET_USE_FANCY_MATH_387
20877    && flag_unsafe_math_optimizations"
20878   "fptan"
20879   [(set_attr "type" "fpspc")
20880    (set_attr "znver1_decode" "vector")
20881    (set_attr "mode" "XF")])
20883 (define_expand "tanxf2"
20884   [(use (match_operand:XF 0 "register_operand"))
20885    (use (match_operand:XF 1 "register_operand"))]
20886   "TARGET_USE_FANCY_MATH_387
20887    && flag_unsafe_math_optimizations"
20889   rtx one = gen_reg_rtx (SFmode);
20890   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
20891                                 CONST1_RTX (SFmode)));
20892   DONE;
20895 (define_expand "tan<mode>2"
20896   [(use (match_operand:MODEF 0 "register_operand"))
20897    (use (match_operand:MODEF 1 "general_operand"))]
20898   "TARGET_USE_FANCY_MATH_387
20899    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20900        || TARGET_MIX_SSE_I387)
20901    && flag_unsafe_math_optimizations"
20903   rtx op0 = gen_reg_rtx (XFmode);
20904   rtx op1 = gen_reg_rtx (XFmode);
20906   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20907   emit_insn (gen_tanxf2 (op0, op1));
20908   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20909   DONE;
20912 (define_insn "atan2xf3"
20913   [(set (match_operand:XF 0 "register_operand" "=f")
20914         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20915                     (match_operand:XF 1 "register_operand" "f")]
20916                    UNSPEC_FPATAN))
20917    (clobber (match_scratch:XF 3 "=1"))]
20918   "TARGET_USE_FANCY_MATH_387
20919    && flag_unsafe_math_optimizations"
20920   "fpatan"
20921   [(set_attr "type" "fpspc")
20922    (set_attr "znver1_decode" "vector")
20923    (set_attr "mode" "XF")])
20925 (define_expand "atan2<mode>3"
20926   [(use (match_operand:MODEF 0 "register_operand"))
20927    (use (match_operand:MODEF 1 "general_operand"))
20928    (use (match_operand:MODEF 2 "general_operand"))]
20929   "TARGET_USE_FANCY_MATH_387
20930    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20931        || TARGET_MIX_SSE_I387)
20932    && flag_unsafe_math_optimizations"
20934   rtx op0 = gen_reg_rtx (XFmode);
20935   rtx op1 = gen_reg_rtx (XFmode);
20936   rtx op2 = gen_reg_rtx (XFmode);
20938   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20939   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20941   emit_insn (gen_atan2xf3 (op0, op1, op2));
20942   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20943   DONE;
20946 (define_expand "atanxf2"
20947   [(parallel [(set (match_operand:XF 0 "register_operand")
20948                    (unspec:XF [(match_dup 2)
20949                                (match_operand:XF 1 "register_operand")]
20950                               UNSPEC_FPATAN))
20951               (clobber (scratch:XF))])]
20952   "TARGET_USE_FANCY_MATH_387
20953    && flag_unsafe_math_optimizations"
20954   "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
20956 (define_expand "atan<mode>2"
20957   [(use (match_operand:MODEF 0 "register_operand"))
20958    (use (match_operand:MODEF 1 "general_operand"))]
20959   "TARGET_USE_FANCY_MATH_387
20960    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20961        || TARGET_MIX_SSE_I387)
20962    && flag_unsafe_math_optimizations"
20964   rtx op0 = gen_reg_rtx (XFmode);
20965   rtx op1 = gen_reg_rtx (XFmode);
20967   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20968   emit_insn (gen_atanxf2 (op0, op1));
20969   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20970   DONE;
20973 (define_expand "asinxf2"
20974   [(set (match_dup 2)
20975         (mult:XF (match_operand:XF 1 "register_operand")
20976                  (match_dup 1)))
20977    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
20978    (set (match_dup 5) (sqrt:XF (match_dup 4)))
20979    (parallel [(set (match_operand:XF 0 "register_operand")
20980                    (unspec:XF [(match_dup 5) (match_dup 1)]
20981                               UNSPEC_FPATAN))
20982               (clobber (scratch:XF))])]
20983   "TARGET_USE_FANCY_MATH_387
20984    && flag_unsafe_math_optimizations"
20986   int i;
20988   for (i = 2; i < 6; i++)
20989     operands[i] = gen_reg_rtx (XFmode);
20991   emit_move_insn (operands[3], CONST1_RTX (XFmode));
20994 (define_expand "asin<mode>2"
20995   [(use (match_operand:MODEF 0 "register_operand"))
20996    (use (match_operand:MODEF 1 "general_operand"))]
20997   "TARGET_USE_FANCY_MATH_387
20998    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20999        || TARGET_MIX_SSE_I387)
21000    && flag_unsafe_math_optimizations"
21002   rtx op0 = gen_reg_rtx (XFmode);
21003   rtx op1 = gen_reg_rtx (XFmode);
21005   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21006   emit_insn (gen_asinxf2 (op0, op1));
21007   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21008   DONE;
21011 (define_expand "acosxf2"
21012   [(set (match_dup 2)
21013         (mult:XF (match_operand:XF 1 "register_operand")
21014                  (match_dup 1)))
21015    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
21016    (set (match_dup 5) (sqrt:XF (match_dup 4)))
21017    (parallel [(set (match_operand:XF 0 "register_operand")
21018                    (unspec:XF [(match_dup 1) (match_dup 5)]
21019                               UNSPEC_FPATAN))
21020               (clobber (scratch:XF))])]
21021   "TARGET_USE_FANCY_MATH_387
21022    && flag_unsafe_math_optimizations"
21024   int i;
21026   for (i = 2; i < 6; i++)
21027     operands[i] = gen_reg_rtx (XFmode);
21029   emit_move_insn (operands[3], CONST1_RTX (XFmode));
21032 (define_expand "acos<mode>2"
21033   [(use (match_operand:MODEF 0 "register_operand"))
21034    (use (match_operand:MODEF 1 "general_operand"))]
21035   "TARGET_USE_FANCY_MATH_387
21036    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21037        || TARGET_MIX_SSE_I387)
21038    && flag_unsafe_math_optimizations"
21040   rtx op0 = gen_reg_rtx (XFmode);
21041   rtx op1 = gen_reg_rtx (XFmode);
21043   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21044   emit_insn (gen_acosxf2 (op0, op1));
21045   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21046   DONE;
21049 (define_expand "sinhxf2"
21050   [(use (match_operand:XF 0 "register_operand"))
21051    (use (match_operand:XF 1 "register_operand"))]
21052   "TARGET_USE_FANCY_MATH_387
21053    && flag_finite_math_only
21054    && flag_unsafe_math_optimizations"
21056   ix86_emit_i387_sinh (operands[0], operands[1]);
21057   DONE;
21060 (define_expand "sinh<mode>2"
21061   [(use (match_operand:MODEF 0 "register_operand"))
21062    (use (match_operand:MODEF 1 "general_operand"))]
21063   "TARGET_USE_FANCY_MATH_387
21064    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21065        || TARGET_MIX_SSE_I387)
21066    && flag_finite_math_only
21067    && flag_unsafe_math_optimizations"
21069   rtx op0 = gen_reg_rtx (XFmode);
21070   rtx op1 = gen_reg_rtx (XFmode);
21072   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21073   emit_insn (gen_sinhxf2 (op0, op1));
21074   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21075   DONE;
21078 (define_expand "coshxf2"
21079   [(use (match_operand:XF 0 "register_operand"))
21080    (use (match_operand:XF 1 "register_operand"))]
21081   "TARGET_USE_FANCY_MATH_387
21082    && flag_unsafe_math_optimizations"
21084   ix86_emit_i387_cosh (operands[0], operands[1]);
21085   DONE;
21088 (define_expand "cosh<mode>2"
21089   [(use (match_operand:MODEF 0 "register_operand"))
21090    (use (match_operand:MODEF 1 "general_operand"))]
21091   "TARGET_USE_FANCY_MATH_387
21092    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21093        || TARGET_MIX_SSE_I387)
21094    && flag_unsafe_math_optimizations"
21096   rtx op0 = gen_reg_rtx (XFmode);
21097   rtx op1 = gen_reg_rtx (XFmode);
21099   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21100   emit_insn (gen_coshxf2 (op0, op1));
21101   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21102   DONE;
21105 (define_expand "tanhxf2"
21106   [(use (match_operand:XF 0 "register_operand"))
21107    (use (match_operand:XF 1 "register_operand"))]
21108   "TARGET_USE_FANCY_MATH_387
21109    && flag_unsafe_math_optimizations"
21111   ix86_emit_i387_tanh (operands[0], operands[1]);
21112   DONE;
21115 (define_expand "tanh<mode>2"
21116   [(use (match_operand:MODEF 0 "register_operand"))
21117    (use (match_operand:MODEF 1 "general_operand"))]
21118   "TARGET_USE_FANCY_MATH_387
21119    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21120        || TARGET_MIX_SSE_I387)
21121    && flag_unsafe_math_optimizations"
21123   rtx op0 = gen_reg_rtx (XFmode);
21124   rtx op1 = gen_reg_rtx (XFmode);
21126   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21127   emit_insn (gen_tanhxf2 (op0, op1));
21128   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21129   DONE;
21132 (define_expand "asinhxf2"
21133   [(use (match_operand:XF 0 "register_operand"))
21134    (use (match_operand:XF 1 "register_operand"))]
21135   "TARGET_USE_FANCY_MATH_387
21136    && flag_finite_math_only
21137    && flag_unsafe_math_optimizations"
21139   ix86_emit_i387_asinh (operands[0], operands[1]);
21140   DONE;
21143 (define_expand "asinh<mode>2"
21144   [(use (match_operand:MODEF 0 "register_operand"))
21145    (use (match_operand:MODEF 1 "general_operand"))]
21146   "TARGET_USE_FANCY_MATH_387
21147    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21148        || TARGET_MIX_SSE_I387)
21149    && flag_finite_math_only
21150    && flag_unsafe_math_optimizations"
21152   rtx op0 = gen_reg_rtx (XFmode);
21153   rtx op1 = gen_reg_rtx (XFmode);
21155   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21156   emit_insn (gen_asinhxf2 (op0, op1));
21157   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21158   DONE;
21161 (define_expand "acoshxf2"
21162   [(use (match_operand:XF 0 "register_operand"))
21163    (use (match_operand:XF 1 "register_operand"))]
21164   "TARGET_USE_FANCY_MATH_387
21165    && flag_unsafe_math_optimizations"
21167   ix86_emit_i387_acosh (operands[0], operands[1]);
21168   DONE;
21171 (define_expand "acosh<mode>2"
21172   [(use (match_operand:MODEF 0 "register_operand"))
21173    (use (match_operand:MODEF 1 "general_operand"))]
21174   "TARGET_USE_FANCY_MATH_387
21175    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21176        || TARGET_MIX_SSE_I387)
21177    && flag_unsafe_math_optimizations"
21179   rtx op0 = gen_reg_rtx (XFmode);
21180   rtx op1 = gen_reg_rtx (XFmode);
21182   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21183   emit_insn (gen_acoshxf2 (op0, op1));
21184   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21185   DONE;
21188 (define_expand "atanhxf2"
21189   [(use (match_operand:XF 0 "register_operand"))
21190    (use (match_operand:XF 1 "register_operand"))]
21191   "TARGET_USE_FANCY_MATH_387
21192    && flag_unsafe_math_optimizations"
21194   ix86_emit_i387_atanh (operands[0], operands[1]);
21195   DONE;
21198 (define_expand "atanh<mode>2"
21199   [(use (match_operand:MODEF 0 "register_operand"))
21200    (use (match_operand:MODEF 1 "general_operand"))]
21201   "TARGET_USE_FANCY_MATH_387
21202    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21203        || TARGET_MIX_SSE_I387)
21204    && flag_unsafe_math_optimizations"
21206   rtx op0 = gen_reg_rtx (XFmode);
21207   rtx op1 = gen_reg_rtx (XFmode);
21209   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21210   emit_insn (gen_atanhxf2 (op0, op1));
21211   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21212   DONE;
21215 (define_insn "fyl2xxf3_i387"
21216   [(set (match_operand:XF 0 "register_operand" "=f")
21217         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21218                     (match_operand:XF 2 "register_operand" "f")]
21219                    UNSPEC_FYL2X))
21220    (clobber (match_scratch:XF 3 "=2"))]
21221   "TARGET_USE_FANCY_MATH_387
21222    && flag_unsafe_math_optimizations"
21223   "fyl2x"
21224   [(set_attr "type" "fpspc")
21225    (set_attr "znver1_decode" "vector")
21226    (set_attr "mode" "XF")])
21228 (define_expand "logxf2"
21229   [(parallel [(set (match_operand:XF 0 "register_operand")
21230                    (unspec:XF [(match_operand:XF 1 "register_operand")
21231                                (match_dup 2)] UNSPEC_FYL2X))
21232               (clobber (scratch:XF))])]
21233   "TARGET_USE_FANCY_MATH_387
21234    && flag_unsafe_math_optimizations"
21236   operands[2]
21237     = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
21240 (define_expand "log<mode>2"
21241   [(use (match_operand:MODEF 0 "register_operand"))
21242    (use (match_operand:MODEF 1 "general_operand"))]
21243   "TARGET_USE_FANCY_MATH_387
21244    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21245        || TARGET_MIX_SSE_I387)
21246    && flag_unsafe_math_optimizations"
21248   rtx op0 = gen_reg_rtx (XFmode);
21249   rtx op1 = gen_reg_rtx (XFmode);
21251   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21252   emit_insn (gen_logxf2 (op0, op1));
21253   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21254   DONE;
21257 (define_expand "log10xf2"
21258   [(parallel [(set (match_operand:XF 0 "register_operand")
21259                    (unspec:XF [(match_operand:XF 1 "register_operand")
21260                                (match_dup 2)] UNSPEC_FYL2X))
21261               (clobber (scratch:XF))])]
21262   "TARGET_USE_FANCY_MATH_387
21263    && flag_unsafe_math_optimizations"
21265   operands[2]
21266     = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
21269 (define_expand "log10<mode>2"
21270   [(use (match_operand:MODEF 0 "register_operand"))
21271    (use (match_operand:MODEF 1 "general_operand"))]
21272   "TARGET_USE_FANCY_MATH_387
21273    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21274        || TARGET_MIX_SSE_I387)
21275    && flag_unsafe_math_optimizations"
21277   rtx op0 = gen_reg_rtx (XFmode);
21278   rtx op1 = gen_reg_rtx (XFmode);
21280   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21281   emit_insn (gen_log10xf2 (op0, op1));
21282   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21283   DONE;
21286 (define_expand "log2xf2"
21287   [(parallel [(set (match_operand:XF 0 "register_operand")
21288                    (unspec:XF [(match_operand:XF 1 "register_operand")
21289                                (match_dup 2)] UNSPEC_FYL2X))
21290               (clobber (scratch:XF))])]
21291   "TARGET_USE_FANCY_MATH_387
21292    && flag_unsafe_math_optimizations"
21293   "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
21295 (define_expand "log2<mode>2"
21296   [(use (match_operand:MODEF 0 "register_operand"))
21297    (use (match_operand:MODEF 1 "general_operand"))]
21298   "TARGET_USE_FANCY_MATH_387
21299    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21300        || TARGET_MIX_SSE_I387)
21301    && flag_unsafe_math_optimizations"
21303   rtx op0 = gen_reg_rtx (XFmode);
21304   rtx op1 = gen_reg_rtx (XFmode);
21306   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21307   emit_insn (gen_log2xf2 (op0, op1));
21308   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21309   DONE;
21312 (define_insn "fyl2xp1xf3_i387"
21313   [(set (match_operand:XF 0 "register_operand" "=f")
21314         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21315                     (match_operand:XF 2 "register_operand" "f")]
21316                    UNSPEC_FYL2XP1))
21317    (clobber (match_scratch:XF 3 "=2"))]
21318   "TARGET_USE_FANCY_MATH_387
21319    && flag_unsafe_math_optimizations"
21320   "fyl2xp1"
21321   [(set_attr "type" "fpspc")
21322    (set_attr "znver1_decode" "vector")
21323    (set_attr "mode" "XF")])
21325 (define_expand "log1pxf2"
21326   [(use (match_operand:XF 0 "register_operand"))
21327    (use (match_operand:XF 1 "register_operand"))]
21328   "TARGET_USE_FANCY_MATH_387
21329    && flag_unsafe_math_optimizations"
21331   ix86_emit_i387_log1p (operands[0], operands[1]);
21332   DONE;
21335 (define_expand "log1p<mode>2"
21336   [(use (match_operand:MODEF 0 "register_operand"))
21337    (use (match_operand:MODEF 1 "general_operand"))]
21338   "TARGET_USE_FANCY_MATH_387
21339    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21340        || TARGET_MIX_SSE_I387)
21341    && flag_unsafe_math_optimizations"
21343   rtx op0 = gen_reg_rtx (XFmode);
21344   rtx op1 = gen_reg_rtx (XFmode);
21346   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21347   emit_insn (gen_log1pxf2 (op0, op1));
21348   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21349   DONE;
21352 (define_insn "fxtractxf3_i387"
21353   [(set (match_operand:XF 0 "register_operand" "=f")
21354         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21355                    UNSPEC_XTRACT_FRACT))
21356    (set (match_operand:XF 1 "register_operand" "=f")
21357         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
21358   "TARGET_USE_FANCY_MATH_387
21359    && flag_unsafe_math_optimizations"
21360   "fxtract"
21361   [(set_attr "type" "fpspc")
21362    (set_attr "znver1_decode" "vector")
21363    (set_attr "mode" "XF")])
21365 (define_expand "logbxf2"
21366   [(parallel [(set (match_dup 2)
21367                    (unspec:XF [(match_operand:XF 1 "register_operand")]
21368                               UNSPEC_XTRACT_FRACT))
21369               (set (match_operand:XF 0 "register_operand")
21370                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21371   "TARGET_USE_FANCY_MATH_387
21372    && flag_unsafe_math_optimizations"
21373   "operands[2] = gen_reg_rtx (XFmode);")
21375 (define_expand "logb<mode>2"
21376   [(use (match_operand:MODEF 0 "register_operand"))
21377    (use (match_operand:MODEF 1 "general_operand"))]
21378   "TARGET_USE_FANCY_MATH_387
21379    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21380        || TARGET_MIX_SSE_I387)
21381    && flag_unsafe_math_optimizations"
21383   rtx op0 = gen_reg_rtx (XFmode);
21384   rtx op1 = gen_reg_rtx (XFmode);
21386   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21387   emit_insn (gen_logbxf2 (op0, op1));
21388   emit_insn (gen_truncxf<mode>2 (operands[0], op1));
21389   DONE;
21392 (define_expand "ilogbxf2"
21393   [(use (match_operand:SI 0 "register_operand"))
21394    (use (match_operand:XF 1 "register_operand"))]
21395   "TARGET_USE_FANCY_MATH_387
21396    && flag_unsafe_math_optimizations"
21398   rtx op0, op1;
21400   if (optimize_insn_for_size_p ())
21401     FAIL;
21403   op0 = gen_reg_rtx (XFmode);
21404   op1 = gen_reg_rtx (XFmode);
21406   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
21407   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21408   DONE;
21411 (define_expand "ilogb<mode>2"
21412   [(use (match_operand:SI 0 "register_operand"))
21413    (use (match_operand:MODEF 1 "general_operand"))]
21414   "TARGET_USE_FANCY_MATH_387
21415    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21416        || TARGET_MIX_SSE_I387)
21417    && flag_unsafe_math_optimizations"
21419   rtx op0, op1, op2;
21421   if (optimize_insn_for_size_p ())
21422     FAIL;
21424   op0 = gen_reg_rtx (XFmode);
21425   op1 = gen_reg_rtx (XFmode);
21426   op2 = gen_reg_rtx (XFmode);
21428   emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
21429   emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
21430   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21431   DONE;
21434 (define_insn "*f2xm1xf2_i387"
21435   [(set (match_operand:XF 0 "register_operand" "=f")
21436         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21437                    UNSPEC_F2XM1))]
21438   "TARGET_USE_FANCY_MATH_387
21439    && flag_unsafe_math_optimizations"
21440   "f2xm1"
21441   [(set_attr "type" "fpspc")
21442    (set_attr "znver1_decode" "vector")
21443    (set_attr "mode" "XF")])
21445 (define_insn "fscalexf4_i387"
21446   [(set (match_operand:XF 0 "register_operand" "=f")
21447         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21448                     (match_operand:XF 3 "register_operand" "1")]
21449                    UNSPEC_FSCALE_FRACT))
21450    (set (match_operand:XF 1 "register_operand" "=f")
21451         (unspec:XF [(match_dup 2) (match_dup 3)]
21452                    UNSPEC_FSCALE_EXP))]
21453   "TARGET_USE_FANCY_MATH_387
21454    && flag_unsafe_math_optimizations"
21455   "fscale"
21456   [(set_attr "type" "fpspc")
21457    (set_attr "znver1_decode" "vector")
21458    (set_attr "mode" "XF")])
21460 (define_expand "expNcorexf3"
21461   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21462                                (match_operand:XF 2 "register_operand")))
21463    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21464    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21465    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21466    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
21467    (parallel [(set (match_operand:XF 0 "register_operand")
21468                    (unspec:XF [(match_dup 8) (match_dup 4)]
21469                               UNSPEC_FSCALE_FRACT))
21470               (set (match_dup 9)
21471                    (unspec:XF [(match_dup 8) (match_dup 4)]
21472                               UNSPEC_FSCALE_EXP))])]
21473   "TARGET_USE_FANCY_MATH_387
21474    && flag_unsafe_math_optimizations"
21476   int i;
21478   for (i = 3; i < 10; i++)
21479     operands[i] = gen_reg_rtx (XFmode);
21481   emit_move_insn (operands[7], CONST1_RTX (XFmode));
21484 (define_expand "expxf2"
21485   [(use (match_operand:XF 0 "register_operand"))
21486    (use (match_operand:XF 1 "register_operand"))]
21487   "TARGET_USE_FANCY_MATH_387
21488    && flag_unsafe_math_optimizations"
21490   rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
21492   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21493   DONE;
21496 (define_expand "exp<mode>2"
21497   [(use (match_operand:MODEF 0 "register_operand"))
21498    (use (match_operand:MODEF 1 "general_operand"))]
21499   "TARGET_USE_FANCY_MATH_387
21500    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21501        || TARGET_MIX_SSE_I387)
21502    && flag_unsafe_math_optimizations"
21504   rtx op0 = gen_reg_rtx (XFmode);
21505   rtx op1 = gen_reg_rtx (XFmode);
21507   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21508   emit_insn (gen_expxf2 (op0, op1));
21509   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21510   DONE;
21513 (define_expand "exp10xf2"
21514   [(use (match_operand:XF 0 "register_operand"))
21515    (use (match_operand:XF 1 "register_operand"))]
21516   "TARGET_USE_FANCY_MATH_387
21517    && flag_unsafe_math_optimizations"
21519   rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
21521   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21522   DONE;
21525 (define_expand "exp10<mode>2"
21526   [(use (match_operand:MODEF 0 "register_operand"))
21527    (use (match_operand:MODEF 1 "general_operand"))]
21528   "TARGET_USE_FANCY_MATH_387
21529    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21530        || TARGET_MIX_SSE_I387)
21531    && flag_unsafe_math_optimizations"
21533   rtx op0 = gen_reg_rtx (XFmode);
21534   rtx op1 = gen_reg_rtx (XFmode);
21536   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21537   emit_insn (gen_exp10xf2 (op0, op1));
21538   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21539   DONE;
21542 (define_expand "exp2xf2"
21543   [(use (match_operand:XF 0 "register_operand"))
21544    (use (match_operand:XF 1 "register_operand"))]
21545   "TARGET_USE_FANCY_MATH_387
21546    && flag_unsafe_math_optimizations"
21548   rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
21550   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21551   DONE;
21554 (define_expand "exp2<mode>2"
21555   [(use (match_operand:MODEF 0 "register_operand"))
21556    (use (match_operand:MODEF 1 "general_operand"))]
21557   "TARGET_USE_FANCY_MATH_387
21558    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21559        || TARGET_MIX_SSE_I387)
21560    && flag_unsafe_math_optimizations"
21562   rtx op0 = gen_reg_rtx (XFmode);
21563   rtx op1 = gen_reg_rtx (XFmode);
21565   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21566   emit_insn (gen_exp2xf2 (op0, op1));
21567   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21568   DONE;
21571 (define_expand "expm1xf2"
21572   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21573                                (match_dup 2)))
21574    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21575    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21576    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21577    (parallel [(set (match_dup 7)
21578                    (unspec:XF [(match_dup 6) (match_dup 4)]
21579                               UNSPEC_FSCALE_FRACT))
21580               (set (match_dup 8)
21581                    (unspec:XF [(match_dup 6) (match_dup 4)]
21582                               UNSPEC_FSCALE_EXP))])
21583    (parallel [(set (match_dup 10)
21584                    (unspec:XF [(match_dup 9) (match_dup 8)]
21585                               UNSPEC_FSCALE_FRACT))
21586               (set (match_dup 11)
21587                    (unspec:XF [(match_dup 9) (match_dup 8)]
21588                               UNSPEC_FSCALE_EXP))])
21589    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
21590    (set (match_operand:XF 0 "register_operand")
21591         (plus:XF (match_dup 12) (match_dup 7)))]
21592   "TARGET_USE_FANCY_MATH_387
21593    && flag_unsafe_math_optimizations"
21595   int i;
21597   for (i = 2; i < 13; i++)
21598     operands[i] = gen_reg_rtx (XFmode);
21600   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
21601   emit_move_insn (operands[9], CONST1_RTX (XFmode));
21604 (define_expand "expm1<mode>2"
21605   [(use (match_operand:MODEF 0 "register_operand"))
21606    (use (match_operand:MODEF 1 "general_operand"))]
21607   "TARGET_USE_FANCY_MATH_387
21608    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21609        || TARGET_MIX_SSE_I387)
21610    && flag_unsafe_math_optimizations"
21612   rtx op0 = gen_reg_rtx (XFmode);
21613   rtx op1 = gen_reg_rtx (XFmode);
21615   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21616   emit_insn (gen_expm1xf2 (op0, op1));
21617   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21618   DONE;
21621 (define_insn "avx512f_scalef<mode>2"
21622   [(set (match_operand:MODEF 0 "register_operand" "=v")
21623         (unspec:MODEF
21624           [(match_operand:MODEF 1 "register_operand" "v")
21625            (match_operand:MODEF 2 "nonimmediate_operand" "vm")]
21626           UNSPEC_SCALEF))]
21627   "TARGET_AVX512F"
21628   "vscalef<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
21629   [(set_attr "prefix" "evex")
21630    (set_attr "mode"  "<MODE>")])
21632 (define_expand "ldexpxf3"
21633   [(match_operand:XF 0 "register_operand")
21634    (match_operand:XF 1 "register_operand")
21635    (match_operand:SI 2 "register_operand")]
21636   "TARGET_USE_FANCY_MATH_387
21637    && flag_unsafe_math_optimizations"
21639   rtx tmp1 = gen_reg_rtx (XFmode);
21640   rtx tmp2 = gen_reg_rtx (XFmode);
21642   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
21643   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
21644                                  operands[1], tmp1));
21645   DONE;
21648 (define_expand "ldexp<mode>3"
21649   [(use (match_operand:MODEF 0 "register_operand"))
21650    (use (match_operand:MODEF 1 "general_operand"))
21651    (use (match_operand:SI 2 "register_operand"))]
21652   "((TARGET_USE_FANCY_MATH_387
21653      && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21654          || TARGET_MIX_SSE_I387))
21655     || (TARGET_AVX512F && TARGET_SSE_MATH))
21656    && flag_unsafe_math_optimizations"
21658   /* Prefer avx512f version.  */
21659   if (TARGET_AVX512F && TARGET_SSE_MATH)
21660    {
21661      rtx op2 = gen_reg_rtx (<MODE>mode);
21662      operands[1] = force_reg (<MODE>mode, operands[1]);
21664      emit_insn (gen_floatsi<mode>2 (op2, operands[2]));
21665      emit_insn (gen_avx512f_scalef<mode>2 (operands[0], operands[1], op2));
21666    }
21667   else
21668     {
21669       rtx op0 = gen_reg_rtx (XFmode);
21670       rtx op1 = gen_reg_rtx (XFmode);
21672       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21673       emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
21674       emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21675   }
21676   DONE;
21679 (define_expand "scalbxf3"
21680   [(parallel [(set (match_operand:XF 0 " register_operand")
21681                    (unspec:XF [(match_operand:XF 1 "register_operand")
21682                                (match_operand:XF 2 "register_operand")]
21683                               UNSPEC_FSCALE_FRACT))
21684               (set (match_dup 3)
21685                    (unspec:XF [(match_dup 1) (match_dup 2)]
21686                               UNSPEC_FSCALE_EXP))])]
21687   "TARGET_USE_FANCY_MATH_387
21688    && flag_unsafe_math_optimizations"
21689   "operands[3] = gen_reg_rtx (XFmode);")
21691 (define_expand "scalb<mode>3"
21692   [(use (match_operand:MODEF 0 "register_operand"))
21693    (use (match_operand:MODEF 1 "general_operand"))
21694    (use (match_operand:MODEF 2 "general_operand"))]
21695   "TARGET_USE_FANCY_MATH_387
21696    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21697        || TARGET_MIX_SSE_I387)
21698    && flag_unsafe_math_optimizations"
21700   rtx op0 = gen_reg_rtx (XFmode);
21701   rtx op1 = gen_reg_rtx (XFmode);
21702   rtx op2 = gen_reg_rtx (XFmode);
21704   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21705   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21706   emit_insn (gen_scalbxf3 (op0, op1, op2));
21707   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21708   DONE;
21711 (define_expand "significandxf2"
21712   [(parallel [(set (match_operand:XF 0 "register_operand")
21713                    (unspec:XF [(match_operand:XF 1 "register_operand")]
21714                               UNSPEC_XTRACT_FRACT))
21715               (set (match_dup 2)
21716                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21717   "TARGET_USE_FANCY_MATH_387
21718    && flag_unsafe_math_optimizations"
21719   "operands[2] = gen_reg_rtx (XFmode);")
21721 (define_expand "significand<mode>2"
21722   [(use (match_operand:MODEF 0 "register_operand"))
21723    (use (match_operand:MODEF 1 "general_operand"))]
21724   "TARGET_USE_FANCY_MATH_387
21725    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21726        || TARGET_MIX_SSE_I387)
21727    && flag_unsafe_math_optimizations"
21729   rtx op0 = gen_reg_rtx (XFmode);
21730   rtx op1 = gen_reg_rtx (XFmode);
21732   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21733   emit_insn (gen_significandxf2 (op0, op1));
21734   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21735   DONE;
21739 (define_insn "sse4_1_round<mode>2"
21740   [(set (match_operand:MODEFH 0 "register_operand" "=x,x,x,v,v")
21741         (unspec:MODEFH
21742           [(match_operand:MODEFH 1 "nonimmediate_operand" "0,x,jm,v,m")
21743            (match_operand:SI 2 "const_0_to_15_operand")]
21744           UNSPEC_ROUND))]
21745   "TARGET_SSE4_1"
21746   "@
21747    %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21748    %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21749    %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
21750    vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21751    vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
21752   [(set_attr "type" "ssecvt")
21753    (set_attr "prefix_extra" "1,1,1,*,*")
21754    (set_attr "length_immediate" "1")
21755    (set_attr "addr" "*,*,gpr16,*,*")
21756    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
21757    (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
21758    (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
21759    (set_attr "mode" "<MODE>")
21760    (set (attr "preferred_for_speed")
21761       (cond [(match_test "TARGET_AVX")
21762                (symbol_ref "true")
21763              (eq_attr "alternative" "1,2")
21764                (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
21765             ]
21766             (symbol_ref "true")))])
21768 (define_insn "rintxf2"
21769   [(set (match_operand:XF 0 "register_operand" "=f")
21770         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21771                    UNSPEC_FRNDINT))]
21772   "TARGET_USE_FANCY_MATH_387"
21773   "frndint"
21774   [(set_attr "type" "fpspc")
21775    (set_attr "znver1_decode" "vector")
21776    (set_attr "mode" "XF")])
21778 (define_expand "rinthf2"
21779   [(match_operand:HF 0 "register_operand")
21780    (match_operand:HF 1 "nonimmediate_operand")]
21781   "TARGET_AVX512FP16"
21783   emit_insn (gen_sse4_1_roundhf2 (operands[0],
21784                                   operands[1],
21785                                   GEN_INT (ROUND_MXCSR)));
21786   DONE;
21789 (define_expand "rint<mode>2"
21790   [(use (match_operand:MODEF 0 "register_operand"))
21791    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
21792   "TARGET_USE_FANCY_MATH_387
21793    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
21795   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21796     {
21797       if (TARGET_SSE4_1)
21798         emit_insn (gen_sse4_1_round<mode>2
21799                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
21800       else
21801         ix86_expand_rint (operands[0], operands[1]);
21802     }
21803   else
21804     {
21805       rtx op0 = gen_reg_rtx (XFmode);
21806       rtx op1 = gen_reg_rtx (XFmode);
21808       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21809       emit_insn (gen_rintxf2 (op0, op1));
21810       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21811     }
21812   DONE;
21815 (define_expand "nearbyintxf2"
21816   [(set (match_operand:XF 0 "register_operand")
21817         (unspec:XF [(match_operand:XF 1 "register_operand")]
21818                    UNSPEC_FRNDINT))]
21819   "TARGET_USE_FANCY_MATH_387
21820    && !flag_trapping_math")
21822 (define_expand "nearbyinthf2"
21823   [(match_operand:HF 0 "register_operand")
21824    (match_operand:HF 1 "nonimmediate_operand")]
21825   "TARGET_AVX512FP16"
21827   emit_insn (gen_sse4_1_roundhf2 (operands[0],
21828                                   operands[1],
21829                                   GEN_INT (ROUND_MXCSR | ROUND_NO_EXC)));
21830   DONE;
21833 (define_expand "nearbyint<mode>2"
21834   [(use (match_operand:MODEF 0 "register_operand"))
21835    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
21836   "(TARGET_USE_FANCY_MATH_387
21837     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21838           || TARGET_MIX_SSE_I387)
21839     && !flag_trapping_math)
21840    || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
21842   if (TARGET_SSE4_1 && TARGET_SSE_MATH)
21843     emit_insn (gen_sse4_1_round<mode>2
21844                (operands[0], operands[1], GEN_INT (ROUND_MXCSR
21845                                                    | ROUND_NO_EXC)));
21846   else
21847     {
21848       rtx op0 = gen_reg_rtx (XFmode);
21849       rtx op1 = gen_reg_rtx (XFmode);
21851       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21852       emit_insn (gen_nearbyintxf2 (op0, op1));
21853       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21854     }
21855   DONE;
21858 (define_expand "roundhf2"
21859   [(match_operand:HF 0 "register_operand")
21860    (match_operand:HF 1 "register_operand")]
21861   "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
21863   ix86_expand_round_sse4 (operands[0], operands[1]);
21864   DONE;
21867 (define_expand "round<mode>2"
21868   [(match_operand:X87MODEF 0 "register_operand")
21869    (match_operand:X87MODEF 1 "nonimmediate_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
21874     && (flag_fp_int_builtin_inexact || !flag_trapping_math))
21875    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21876        && !flag_trapping_math && !flag_rounding_math)"
21878   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21879       && !flag_trapping_math && !flag_rounding_math)
21880     {
21881       if (TARGET_SSE4_1)
21882         {
21883           operands[1] = force_reg (<MODE>mode, operands[1]);
21884           ix86_expand_round_sse4 (operands[0], operands[1]);
21885         }
21886       else if (TARGET_64BIT || (<MODE>mode != DFmode))
21887         ix86_expand_round (operands[0], operands[1]);
21888       else
21889         ix86_expand_rounddf_32 (operands[0], operands[1]);
21890     }
21891   else
21892     {
21893       operands[1] = force_reg (<MODE>mode, operands[1]);
21894       ix86_emit_i387_round (operands[0], operands[1]);
21895     }
21896   DONE;
21899 (define_insn "lrintxfdi2"
21900   [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
21901         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
21902                    UNSPEC_FIST))
21903    (clobber (match_scratch:XF 2 "=&f"))]
21904   "TARGET_USE_FANCY_MATH_387"
21905   "* return output_fix_trunc (insn, operands, false);"
21906   [(set_attr "type" "fpspc")
21907    (set_attr "mode" "DI")])
21909 (define_insn "lrintxf<mode>2"
21910   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
21911         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
21912                       UNSPEC_FIST))]
21913   "TARGET_USE_FANCY_MATH_387"
21914   "* return output_fix_trunc (insn, operands, false);"
21915   [(set_attr "type" "fpspc")
21916    (set_attr "mode" "<MODE>")])
21918 (define_expand "lroundhf<mode>2"
21919   [(set (match_operand:SWI248 0 "register_operand")
21920      (unspec:SWI248 [(match_operand:HF 1 "nonimmediate_operand")]
21921                    UNSPEC_FIX_NOTRUNC))]
21922   "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
21924   ix86_expand_lround (operands[0], operands[1]);
21925   DONE;
21928 (define_expand "lrinthf<mode>2"
21929   [(set (match_operand:SWI48 0 "register_operand")
21930      (unspec:SWI48 [(match_operand:HF 1 "nonimmediate_operand")]
21931                    UNSPEC_FIX_NOTRUNC))]
21932   "TARGET_AVX512FP16")
21934 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
21935   [(set (match_operand:SWI48 0 "register_operand")
21936      (unspec:SWI48 [(match_operand:MODEF 1 "nonimmediate_operand")]
21937                    UNSPEC_FIX_NOTRUNC))]
21938   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
21940 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
21941   [(match_operand:SWI248x 0 "nonimmediate_operand")
21942    (match_operand:X87MODEF 1 "register_operand")]
21943   "(TARGET_USE_FANCY_MATH_387
21944     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
21945         || TARGET_MIX_SSE_I387)
21946     && flag_unsafe_math_optimizations)
21947    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
21948        && <SWI248x:MODE>mode != HImode 
21949        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
21950        && !flag_trapping_math && !flag_rounding_math)"
21952   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
21953       && <SWI248x:MODE>mode != HImode
21954       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
21955       && !flag_trapping_math && !flag_rounding_math)
21956     ix86_expand_lround (operands[0], operands[1]);
21957   else
21958     ix86_emit_i387_round (operands[0], operands[1]);
21959   DONE;
21962 (define_int_iterator FRNDINT_ROUNDING
21963         [UNSPEC_FRNDINT_ROUNDEVEN
21964          UNSPEC_FRNDINT_FLOOR
21965          UNSPEC_FRNDINT_CEIL
21966          UNSPEC_FRNDINT_TRUNC])
21968 (define_int_iterator FIST_ROUNDING
21969         [UNSPEC_FIST_FLOOR
21970          UNSPEC_FIST_CEIL])
21972 ;; Base name for define_insn
21973 (define_int_attr rounding_insn
21974         [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
21975          (UNSPEC_FRNDINT_FLOOR "floor")
21976          (UNSPEC_FRNDINT_CEIL "ceil")
21977          (UNSPEC_FRNDINT_TRUNC "btrunc")
21978          (UNSPEC_FIST_FLOOR "floor")
21979          (UNSPEC_FIST_CEIL "ceil")])
21981 (define_int_attr rounding
21982         [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
21983          (UNSPEC_FRNDINT_FLOOR "floor")
21984          (UNSPEC_FRNDINT_CEIL "ceil")
21985          (UNSPEC_FRNDINT_TRUNC "trunc")
21986          (UNSPEC_FIST_FLOOR "floor")
21987          (UNSPEC_FIST_CEIL "ceil")])
21989 (define_int_attr ROUNDING
21990         [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
21991          (UNSPEC_FRNDINT_FLOOR "FLOOR")
21992          (UNSPEC_FRNDINT_CEIL "CEIL")
21993          (UNSPEC_FRNDINT_TRUNC "TRUNC")
21994          (UNSPEC_FIST_FLOOR "FLOOR")
21995          (UNSPEC_FIST_CEIL "CEIL")])
21997 ;; Rounding mode control word calculation could clobber FLAGS_REG.
21998 (define_insn_and_split "frndintxf2_<rounding>"
21999   [(set (match_operand:XF 0 "register_operand")
22000         (unspec:XF [(match_operand:XF 1 "register_operand")]
22001                    FRNDINT_ROUNDING))
22002    (clobber (reg:CC FLAGS_REG))]
22003   "TARGET_USE_FANCY_MATH_387
22004    && (flag_fp_int_builtin_inexact || !flag_trapping_math)
22005    && ix86_pre_reload_split ()"
22006   "#"
22007   "&& 1"
22008   [(const_int 0)]
22010   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
22012   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
22013   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
22015   emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
22016                                              operands[2], operands[3]));
22017   DONE;
22019   [(set_attr "type" "frndint")
22020    (set_attr "i387_cw" "<rounding>")
22021    (set_attr "mode" "XF")])
22023 (define_insn "frndintxf2_<rounding>_i387"
22024   [(set (match_operand:XF 0 "register_operand" "=f")
22025         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
22026                    FRNDINT_ROUNDING))
22027    (use (match_operand:HI 2 "memory_operand" "m"))
22028    (use (match_operand:HI 3 "memory_operand" "m"))]
22029   "TARGET_USE_FANCY_MATH_387
22030    && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
22031   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
22032   [(set_attr "type" "frndint")
22033    (set_attr "i387_cw" "<rounding>")
22034    (set_attr "mode" "XF")])
22036 (define_expand "<rounding_insn>xf2"
22037   [(parallel [(set (match_operand:XF 0 "register_operand")
22038                    (unspec:XF [(match_operand:XF 1 "register_operand")]
22039                               FRNDINT_ROUNDING))
22040               (clobber (reg:CC FLAGS_REG))])]
22041   "TARGET_USE_FANCY_MATH_387
22042    && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
22044 (define_expand "<rounding_insn>hf2"
22045   [(parallel [(set (match_operand:HF 0 "register_operand")
22046                    (unspec:HF [(match_operand:HF 1 "register_operand")]
22047                      FRNDINT_ROUNDING))
22048               (clobber (reg:CC FLAGS_REG))])]
22049   "TARGET_AVX512FP16"
22051   emit_insn (gen_sse4_1_roundhf2 (operands[0], operands[1],
22052                                   GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22053   DONE;
22056 (define_expand "<rounding_insn><mode>2"
22057   [(parallel [(set (match_operand:MODEF 0 "register_operand")
22058                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
22059                                  FRNDINT_ROUNDING))
22060               (clobber (reg:CC FLAGS_REG))])]
22061   "(TARGET_USE_FANCY_MATH_387
22062     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22063         || TARGET_MIX_SSE_I387)
22064     && (flag_fp_int_builtin_inexact || !flag_trapping_math))
22065    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22066        && (TARGET_SSE4_1
22067            || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
22068                && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
22070   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22071       && (TARGET_SSE4_1
22072           || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
22073               && (flag_fp_int_builtin_inexact || !flag_trapping_math))))
22074     {
22075       if (TARGET_SSE4_1)
22076         emit_insn (gen_sse4_1_round<mode>2
22077                    (operands[0], operands[1],
22078                     GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22079       else if (TARGET_64BIT || (<MODE>mode != DFmode))
22080         {
22081           if (ROUND_<ROUNDING> == ROUND_FLOOR)
22082             ix86_expand_floorceil (operands[0], operands[1], true);
22083           else if (ROUND_<ROUNDING> == ROUND_CEIL)
22084             ix86_expand_floorceil (operands[0], operands[1], false);
22085           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
22086             ix86_expand_trunc (operands[0], operands[1]);
22087           else
22088             gcc_unreachable ();
22089         }
22090       else
22091         {
22092           if (ROUND_<ROUNDING> == ROUND_FLOOR)
22093             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
22094           else if (ROUND_<ROUNDING> == ROUND_CEIL)
22095             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
22096           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
22097             ix86_expand_truncdf_32 (operands[0], operands[1]);
22098           else
22099             gcc_unreachable ();
22100         }
22101     }
22102   else
22103     {
22104       rtx op0 = gen_reg_rtx (XFmode);
22105       rtx op1 = gen_reg_rtx (XFmode);
22107       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22108       emit_insn (gen_frndintxf2_<rounding> (op0, op1));
22109       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
22110     }
22111   DONE;
22114 ;; Rounding mode control word calculation could clobber FLAGS_REG.
22115 (define_insn_and_split "*fist<mode>2_<rounding>_1"
22116   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
22117         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
22118                         FIST_ROUNDING))
22119    (clobber (reg:CC FLAGS_REG))]
22120   "TARGET_USE_FANCY_MATH_387
22121    && flag_unsafe_math_optimizations
22122    && ix86_pre_reload_split ()"
22123   "#"
22124   "&& 1"
22125   [(const_int 0)]
22127   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
22129   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
22130   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
22132   emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
22133                                          operands[2], operands[3]));
22134   DONE;
22136   [(set_attr "type" "fistp")
22137    (set_attr "i387_cw" "<rounding>")
22138    (set_attr "mode" "<MODE>")])
22140 (define_insn "fistdi2_<rounding>"
22141   [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
22142         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
22143                    FIST_ROUNDING))
22144    (use (match_operand:HI 2 "memory_operand" "m"))
22145    (use (match_operand:HI 3 "memory_operand" "m"))
22146    (clobber (match_scratch:XF 4 "=&f"))]
22147   "TARGET_USE_FANCY_MATH_387
22148    && flag_unsafe_math_optimizations"
22149   "* return output_fix_trunc (insn, operands, false);"
22150   [(set_attr "type" "fistp")
22151    (set_attr "i387_cw" "<rounding>")
22152    (set_attr "mode" "DI")])
22154 (define_insn "fist<mode>2_<rounding>"
22155   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
22156         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
22157                       FIST_ROUNDING))
22158    (use (match_operand:HI 2 "memory_operand" "m"))
22159    (use (match_operand:HI 3 "memory_operand" "m"))]
22160   "TARGET_USE_FANCY_MATH_387
22161    && flag_unsafe_math_optimizations"
22162   "* return output_fix_trunc (insn, operands, false);"
22163   [(set_attr "type" "fistp")
22164    (set_attr "i387_cw" "<rounding>")
22165    (set_attr "mode" "<MODE>")])
22167 (define_expand "l<rounding_insn>xf<mode>2"
22168   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
22169                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
22170                                    FIST_ROUNDING))
22171               (clobber (reg:CC FLAGS_REG))])]
22172   "TARGET_USE_FANCY_MATH_387
22173    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
22174    && flag_unsafe_math_optimizations")
22176 (define_expand "l<rounding_insn>hf<mode>2"
22177   [(set (match_operand:SWI48 0 "nonimmediate_operand")
22178         (unspec:SWI48 [(match_operand:HF 1 "register_operand")]
22179                     FIST_ROUNDING))]
22180   "TARGET_AVX512FP16"
22182   rtx tmp = gen_reg_rtx (HFmode);
22183   emit_insn (gen_sse4_1_roundhf2 (tmp, operands[1],
22184                                  GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22185   emit_insn (gen_fix_trunchf<mode>2 (operands[0], tmp));
22186   DONE;
22189 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
22190   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
22191                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
22192                                  FIST_ROUNDING))
22193               (clobber (reg:CC FLAGS_REG))])]
22194   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
22195    && (TARGET_SSE4_1 || !flag_trapping_math)"
22197   if (TARGET_SSE4_1)
22198     {
22199       rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
22201       emit_insn (gen_sse4_1_round<MODEF:mode>2
22202                  (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
22203                                              | ROUND_NO_EXC)));
22204       emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
22205                  (operands[0], tmp));
22206     }
22207   else if (ROUND_<ROUNDING> == ROUND_FLOOR)
22208     ix86_expand_lfloorceil (operands[0], operands[1], true);
22209   else if (ROUND_<ROUNDING> == ROUND_CEIL)
22210     ix86_expand_lfloorceil (operands[0], operands[1], false);
22211   else
22212     gcc_unreachable ();
22214   DONE;
22217 (define_insn "fxam<mode>2_i387"
22218   [(set (match_operand:HI 0 "register_operand" "=a")
22219         (unspec:HI
22220           [(match_operand:X87MODEF 1 "register_operand" "f")]
22221           UNSPEC_FXAM))]
22222   "TARGET_USE_FANCY_MATH_387"
22223   "fxam\n\tfnstsw\t%0"
22224   [(set_attr "type" "multi")
22225    (set_attr "length" "4")
22226    (set_attr "unit" "i387")
22227    (set_attr "mode" "<MODE>")])
22229 (define_expand "signbittf2"
22230   [(use (match_operand:SI 0 "register_operand"))
22231    (use (match_operand:TF 1 "register_operand"))]
22232   "TARGET_SSE"
22234   if (TARGET_SSE4_1)
22235     {
22236       rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
22237       rtx scratch = gen_reg_rtx (QImode);
22239       emit_insn (gen_ptesttf2 (operands[1], mask));
22240         ix86_expand_setcc (scratch, NE,
22241                            gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
22243       emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
22244     }
22245   else
22246     {
22247       emit_insn (gen_sse_movmskps (operands[0],
22248                                    gen_lowpart (V4SFmode, operands[1])));
22249       emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
22250     }
22251   DONE;
22254 (define_expand "signbitxf2"
22255   [(use (match_operand:SI 0 "register_operand"))
22256    (use (match_operand:XF 1 "register_operand"))]
22257   "TARGET_USE_FANCY_MATH_387"
22259   rtx scratch = gen_reg_rtx (HImode);
22261   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
22262   emit_insn (gen_andsi3 (operands[0],
22263              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22264   DONE;
22267 (define_insn "movmsk_df"
22268   [(set (match_operand:SI 0 "register_operand" "=r,jr")
22269         (unspec:SI
22270           [(match_operand:DF 1 "register_operand" "x,x")]
22271           UNSPEC_MOVMSK))]
22272   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
22273   "%vmovmskpd\t{%1, %0|%0, %1}"
22274   [(set_attr "isa" "noavx,avx")
22275    (set_attr "type" "ssemov")
22276    (set_attr "prefix" "maybe_evex")
22277    (set_attr "mode" "DF")])
22279 ;; Use movmskpd in SSE mode to avoid store forwarding stall
22280 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
22281 (define_expand "signbitdf2"
22282   [(use (match_operand:SI 0 "register_operand"))
22283    (use (match_operand:DF 1 "register_operand"))]
22284   "TARGET_USE_FANCY_MATH_387
22285    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
22287   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
22288     {
22289       emit_insn (gen_movmsk_df (operands[0], operands[1]));
22290       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
22291     }
22292   else
22293     {
22294       rtx scratch = gen_reg_rtx (HImode);
22296       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
22297       emit_insn (gen_andsi3 (operands[0],
22298                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22299     }
22300   DONE;
22303 (define_expand "signbitsf2"
22304   [(use (match_operand:SI 0 "register_operand"))
22305    (use (match_operand:SF 1 "register_operand"))]
22306   "TARGET_USE_FANCY_MATH_387
22307    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
22309   rtx scratch = gen_reg_rtx (HImode);
22311   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
22312   emit_insn (gen_andsi3 (operands[0],
22313              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22314   DONE;
22317 ;; Block operation instructions
22319 (define_insn "cld"
22320   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
22321   ""
22322   "cld"
22323   [(set_attr "length" "1")
22324    (set_attr "length_immediate" "0")
22325    (set_attr "modrm" "0")])
22327 (define_expand "cpymem<mode>"
22328   [(use (match_operand:BLK 0 "memory_operand"))
22329    (use (match_operand:BLK 1 "memory_operand"))
22330    (use (match_operand:SWI48 2 "nonmemory_operand"))
22331    (use (match_operand:SWI48 3 "const_int_operand"))
22332    (use (match_operand:SI 4 "const_int_operand"))
22333    (use (match_operand:SI 5 "const_int_operand"))
22334    (use (match_operand:SI 6 ""))
22335    (use (match_operand:SI 7 ""))
22336    (use (match_operand:SI 8 ""))]
22337   ""
22339  if (ix86_expand_set_or_cpymem (operands[0], operands[1],
22340                                 operands[2], NULL, operands[3],
22341                                 operands[4], operands[5],
22342                                 operands[6], operands[7],
22343                                 operands[8], false))
22344    DONE;
22345  else
22346    FAIL;
22349 ;; Most CPUs don't like single string operations
22350 ;; Handle this case here to simplify previous expander.
22352 (define_expand "strmov"
22353   [(set (match_dup 4) (match_operand 3 "memory_operand"))
22354    (set (match_operand 1 "memory_operand") (match_dup 4))
22355    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
22356               (clobber (reg:CC FLAGS_REG))])
22357    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
22358               (clobber (reg:CC FLAGS_REG))])]
22359   ""
22361   /* Can't use this for non-default address spaces.  */
22362   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
22363     FAIL;
22365   int piece_size = GET_MODE_SIZE (GET_MODE (operands[1]));
22367   /* If .md ever supports :P for Pmode, these can be directly
22368      in the pattern above.  */
22369   operands[5] = plus_constant (Pmode, operands[0], piece_size);
22370   operands[6] = plus_constant (Pmode, operands[2], piece_size);
22372   /* Can't use this if the user has appropriated esi or edi.  */
22373   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22374       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
22375     {
22376       emit_insn (gen_strmov_singleop (operands[0], operands[1],
22377                                       operands[2], operands[3],
22378                                       operands[5], operands[6]));
22379       DONE;
22380     }
22382   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
22385 (define_expand "strmov_singleop"
22386   [(parallel [(set (match_operand 1 "memory_operand")
22387                    (match_operand 3 "memory_operand"))
22388               (set (match_operand 0 "register_operand")
22389                    (match_operand 4))
22390               (set (match_operand 2 "register_operand")
22391                    (match_operand 5))])]
22392   ""
22394   if (TARGET_CLD)
22395     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22398 (define_insn "*strmovdi_rex_1"
22399   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
22400         (mem:DI (match_operand:P 3 "register_operand" "1")))
22401    (set (match_operand:P 0 "register_operand" "=D")
22402         (plus:P (match_dup 2)
22403                 (const_int 8)))
22404    (set (match_operand:P 1 "register_operand" "=S")
22405         (plus:P (match_dup 3)
22406                 (const_int 8)))]
22407   "TARGET_64BIT
22408    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22409    && ix86_check_no_addr_space (insn)"
22410   "%^movsq"
22411   [(set_attr "type" "str")
22412    (set_attr "memory" "both")
22413    (set_attr "mode" "DI")])
22415 (define_insn "*strmovsi_1"
22416   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
22417         (mem:SI (match_operand:P 3 "register_operand" "1")))
22418    (set (match_operand:P 0 "register_operand" "=D")
22419         (plus:P (match_dup 2)
22420                 (const_int 4)))
22421    (set (match_operand:P 1 "register_operand" "=S")
22422         (plus:P (match_dup 3)
22423                 (const_int 4)))]
22424   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22425    && ix86_check_no_addr_space (insn)"
22426   "%^movs{l|d}"
22427   [(set_attr "type" "str")
22428    (set_attr "memory" "both")
22429    (set_attr "mode" "SI")])
22431 (define_insn "*strmovhi_1"
22432   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
22433         (mem:HI (match_operand:P 3 "register_operand" "1")))
22434    (set (match_operand:P 0 "register_operand" "=D")
22435         (plus:P (match_dup 2)
22436                 (const_int 2)))
22437    (set (match_operand:P 1 "register_operand" "=S")
22438         (plus:P (match_dup 3)
22439                 (const_int 2)))]
22440   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22441    && ix86_check_no_addr_space (insn)"
22442   "%^movsw"
22443   [(set_attr "type" "str")
22444    (set_attr "memory" "both")
22445    (set_attr "mode" "HI")])
22447 (define_insn "*strmovqi_1"
22448   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
22449         (mem:QI (match_operand:P 3 "register_operand" "1")))
22450    (set (match_operand:P 0 "register_operand" "=D")
22451         (plus:P (match_dup 2)
22452                 (const_int 1)))
22453    (set (match_operand:P 1 "register_operand" "=S")
22454         (plus:P (match_dup 3)
22455                 (const_int 1)))]
22456   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22457    && ix86_check_no_addr_space (insn)"
22458   "%^movsb"
22459   [(set_attr "type" "str")
22460    (set_attr "memory" "both")
22461    (set (attr "prefix_rex")
22462         (if_then_else
22463           (match_test "<P:MODE>mode == DImode")
22464           (const_string "0")
22465           (const_string "*")))
22466    (set_attr "mode" "QI")])
22468 (define_expand "rep_mov"
22469   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
22470               (set (match_operand 0 "register_operand")
22471                    (match_operand 5))
22472               (set (match_operand 2 "register_operand")
22473                    (match_operand 6))
22474               (set (match_operand 1 "memory_operand")
22475                    (match_operand 3 "memory_operand"))
22476               (use (match_dup 4))])]
22477   ""
22479   if (TARGET_CLD)
22480     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22483 (define_insn "*rep_movdi_rex64"
22484   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22485    (set (match_operand:P 0 "register_operand" "=D")
22486         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22487                           (const_int 3))
22488                 (match_operand:P 3 "register_operand" "0")))
22489    (set (match_operand:P 1 "register_operand" "=S")
22490         (plus:P (ashift:P (match_dup 5) (const_int 3))
22491                 (match_operand:P 4 "register_operand" "1")))
22492    (set (mem:BLK (match_dup 3))
22493         (mem:BLK (match_dup 4)))
22494    (use (match_dup 5))]
22495   "TARGET_64BIT
22496    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22497    && ix86_check_no_addr_space (insn)"
22498   "%^rep{%;} movsq"
22499   [(set_attr "type" "str")
22500    (set_attr "prefix_rep" "1")
22501    (set_attr "memory" "both")
22502    (set_attr "mode" "DI")])
22504 (define_insn "*rep_movsi"
22505   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22506    (set (match_operand:P 0 "register_operand" "=D")
22507         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22508                           (const_int 2))
22509                  (match_operand:P 3 "register_operand" "0")))
22510    (set (match_operand:P 1 "register_operand" "=S")
22511         (plus:P (ashift:P (match_dup 5) (const_int 2))
22512                 (match_operand:P 4 "register_operand" "1")))
22513    (set (mem:BLK (match_dup 3))
22514         (mem:BLK (match_dup 4)))
22515    (use (match_dup 5))]
22516   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22517    && ix86_check_no_addr_space (insn)"
22518   "%^rep{%;} movs{l|d}"
22519   [(set_attr "type" "str")
22520    (set_attr "prefix_rep" "1")
22521    (set_attr "memory" "both")
22522    (set_attr "mode" "SI")])
22524 (define_insn "*rep_movqi"
22525   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22526    (set (match_operand:P 0 "register_operand" "=D")
22527         (plus:P (match_operand:P 3 "register_operand" "0")
22528                 (match_operand:P 5 "register_operand" "2")))
22529    (set (match_operand:P 1 "register_operand" "=S")
22530         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
22531    (set (mem:BLK (match_dup 3))
22532         (mem:BLK (match_dup 4)))
22533    (use (match_dup 5))]
22534   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22535    && ix86_check_no_addr_space (insn)"
22536   "%^rep{%;} movsb"
22537   [(set_attr "type" "str")
22538    (set_attr "prefix_rep" "1")
22539    (set_attr "memory" "both")
22540    (set_attr "mode" "QI")])
22542 (define_expand "setmem<mode>"
22543    [(use (match_operand:BLK 0 "memory_operand"))
22544     (use (match_operand:SWI48 1 "nonmemory_operand"))
22545     (use (match_operand:QI 2 "nonmemory_operand"))
22546     (use (match_operand 3 "const_int_operand"))
22547     (use (match_operand:SI 4 "const_int_operand"))
22548     (use (match_operand:SI 5 "const_int_operand"))
22549     (use (match_operand:SI 6 ""))
22550     (use (match_operand:SI 7 ""))
22551     (use (match_operand:SI 8 ""))]
22552   ""
22554  if (ix86_expand_set_or_cpymem (operands[0], NULL,
22555                                 operands[1], operands[2],
22556                                 operands[3], operands[4],
22557                                 operands[5], operands[6],
22558                                 operands[7], operands[8], true))
22559    DONE;
22560  else
22561    FAIL;
22564 ;; Most CPUs don't like single string operations
22565 ;; Handle this case here to simplify previous expander.
22567 (define_expand "strset"
22568   [(set (match_operand 1 "memory_operand")
22569         (match_operand 2 "register_operand"))
22570    (parallel [(set (match_operand 0 "register_operand")
22571                    (match_dup 3))
22572               (clobber (reg:CC FLAGS_REG))])]
22573   ""
22575   /* Can't use this for non-default address spaces.  */
22576   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
22577     FAIL;
22579   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
22580     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
22582   /* If .md ever supports :P for Pmode, this can be directly
22583      in the pattern above.  */
22584   operands[3] = plus_constant (Pmode, operands[0],
22585                                GET_MODE_SIZE (GET_MODE (operands[2])));
22587   /* Can't use this if the user has appropriated eax or edi.  */
22588   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22589       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
22590     {
22591       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
22592                                       operands[3]));
22593       DONE;
22594     }
22597 (define_expand "strset_singleop"
22598   [(parallel [(set (match_operand 1 "memory_operand")
22599                    (match_operand 2 "register_operand"))
22600               (set (match_operand 0 "register_operand")
22601                    (match_operand 3))
22602               (unspec [(const_int 0)] UNSPEC_STOS)])]
22603   ""
22605   if (TARGET_CLD)
22606     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22609 (define_insn "*strsetdi_rex_1"
22610   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
22611         (match_operand:DI 2 "register_operand" "a"))
22612    (set (match_operand:P 0 "register_operand" "=D")
22613         (plus:P (match_dup 1)
22614                 (const_int 8)))
22615    (unspec [(const_int 0)] UNSPEC_STOS)]
22616   "TARGET_64BIT
22617    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22618    && ix86_check_no_addr_space (insn)"
22619   "%^stosq"
22620   [(set_attr "type" "str")
22621    (set_attr "memory" "store")
22622    (set_attr "mode" "DI")])
22624 (define_insn "*strsetsi_1"
22625   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
22626         (match_operand:SI 2 "register_operand" "a"))
22627    (set (match_operand:P 0 "register_operand" "=D")
22628         (plus:P (match_dup 1)
22629                 (const_int 4)))
22630    (unspec [(const_int 0)] UNSPEC_STOS)]
22631   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22632    && ix86_check_no_addr_space (insn)"
22633   "%^stos{l|d}"
22634   [(set_attr "type" "str")
22635    (set_attr "memory" "store")
22636    (set_attr "mode" "SI")])
22638 (define_insn "*strsethi_1"
22639   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
22640         (match_operand:HI 2 "register_operand" "a"))
22641    (set (match_operand:P 0 "register_operand" "=D")
22642         (plus:P (match_dup 1)
22643                 (const_int 2)))
22644    (unspec [(const_int 0)] UNSPEC_STOS)]
22645   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22646    && ix86_check_no_addr_space (insn)"
22647   "%^stosw"
22648   [(set_attr "type" "str")
22649    (set_attr "memory" "store")
22650    (set_attr "mode" "HI")])
22652 (define_insn "*strsetqi_1"
22653   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
22654         (match_operand:QI 2 "register_operand" "a"))
22655    (set (match_operand:P 0 "register_operand" "=D")
22656         (plus:P (match_dup 1)
22657                 (const_int 1)))
22658    (unspec [(const_int 0)] UNSPEC_STOS)]
22659   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22660    && ix86_check_no_addr_space (insn)"
22661   "%^stosb"
22662   [(set_attr "type" "str")
22663    (set_attr "memory" "store")
22664    (set (attr "prefix_rex")
22665         (if_then_else
22666           (match_test "<P:MODE>mode == DImode")
22667           (const_string "0")
22668           (const_string "*")))
22669    (set_attr "mode" "QI")])
22671 (define_expand "rep_stos"
22672   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
22673               (set (match_operand 0 "register_operand")
22674                    (match_operand 4))
22675               (set (match_operand 2 "memory_operand") (const_int 0))
22676               (use (match_operand 3 "register_operand"))
22677               (use (match_dup 1))])]
22678   ""
22680   if (TARGET_CLD)
22681     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22684 (define_insn "*rep_stosdi_rex64"
22685   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22686    (set (match_operand:P 0 "register_operand" "=D")
22687         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22688                           (const_int 3))
22689                  (match_operand:P 3 "register_operand" "0")))
22690    (set (mem:BLK (match_dup 3))
22691         (const_int 0))
22692    (use (match_operand:DI 2 "register_operand" "a"))
22693    (use (match_dup 4))]
22694   "TARGET_64BIT
22695    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22696    && ix86_check_no_addr_space (insn)"
22697   "%^rep{%;} stosq"
22698   [(set_attr "type" "str")
22699    (set_attr "prefix_rep" "1")
22700    (set_attr "memory" "store")
22701    (set_attr "mode" "DI")])
22703 (define_insn "*rep_stossi"
22704   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22705    (set (match_operand:P 0 "register_operand" "=D")
22706         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22707                           (const_int 2))
22708                  (match_operand:P 3 "register_operand" "0")))
22709    (set (mem:BLK (match_dup 3))
22710         (const_int 0))
22711    (use (match_operand:SI 2 "register_operand" "a"))
22712    (use (match_dup 4))]
22713   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22714    && ix86_check_no_addr_space (insn)"
22715   "%^rep{%;} stos{l|d}"
22716   [(set_attr "type" "str")
22717    (set_attr "prefix_rep" "1")
22718    (set_attr "memory" "store")
22719    (set_attr "mode" "SI")])
22721 (define_insn "*rep_stosqi"
22722   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22723    (set (match_operand:P 0 "register_operand" "=D")
22724         (plus:P (match_operand:P 3 "register_operand" "0")
22725                 (match_operand:P 4 "register_operand" "1")))
22726    (set (mem:BLK (match_dup 3))
22727         (const_int 0))
22728    (use (match_operand:QI 2 "register_operand" "a"))
22729    (use (match_dup 4))]
22730   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22731    && ix86_check_no_addr_space (insn)"
22732   "%^rep{%;} stosb"
22733   [(set_attr "type" "str")
22734    (set_attr "prefix_rep" "1")
22735    (set_attr "memory" "store")
22736    (set (attr "prefix_rex")
22737         (if_then_else
22738           (match_test "<P:MODE>mode == DImode")
22739           (const_string "0")
22740           (const_string "*")))
22741    (set_attr "mode" "QI")])
22743 (define_expand "cmpmemsi"
22744   [(set (match_operand:SI 0 "register_operand" "")
22745         (compare:SI (match_operand:BLK 1 "memory_operand" "")
22746                     (match_operand:BLK 2 "memory_operand" "") ) )
22747    (use (match_operand 3 "general_operand"))
22748    (use (match_operand 4 "immediate_operand"))]
22749   ""
22751   if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22752                                      operands[2], operands[3],
22753                                      operands[4], false))
22754     DONE;
22755   else
22756     FAIL;
22759 (define_expand "cmpstrnsi"
22760   [(set (match_operand:SI 0 "register_operand")
22761         (compare:SI (match_operand:BLK 1 "general_operand")
22762                     (match_operand:BLK 2 "general_operand")))
22763    (use (match_operand 3 "general_operand"))
22764    (use (match_operand 4 "immediate_operand"))]
22765   ""
22767   if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22768                                      operands[2], operands[3],
22769                                      operands[4], true))
22770     DONE;
22771   else
22772     FAIL;
22775 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
22777 (define_expand "cmpintqi"
22778   [(set (match_dup 1)
22779         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22780    (set (match_dup 2)
22781         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22782    (parallel [(set (match_operand:QI 0 "register_operand")
22783                    (minus:QI (match_dup 1)
22784                              (match_dup 2)))
22785               (clobber (reg:CC FLAGS_REG))])]
22786   ""
22788   operands[1] = gen_reg_rtx (QImode);
22789   operands[2] = gen_reg_rtx (QImode);
22792 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
22793 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
22795 (define_expand "cmpstrnqi_nz_1"
22796   [(parallel [(set (reg:CC FLAGS_REG)
22797                    (compare:CC (match_operand 4 "memory_operand")
22798                                (match_operand 5 "memory_operand")))
22799               (use (match_operand 2 "register_operand"))
22800               (use (match_operand:SI 3 "immediate_operand"))
22801               (clobber (match_operand 0 "register_operand"))
22802               (clobber (match_operand 1 "register_operand"))
22803               (clobber (match_dup 2))])]
22804   ""
22806   if (TARGET_CLD)
22807     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22810 (define_insn "*cmpstrnqi_nz_1"
22811   [(set (reg:CC FLAGS_REG)
22812         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
22813                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
22814    (use (match_operand:P 6 "register_operand" "2"))
22815    (use (match_operand:SI 3 "immediate_operand" "i"))
22816    (clobber (match_operand:P 0 "register_operand" "=S"))
22817    (clobber (match_operand:P 1 "register_operand" "=D"))
22818    (clobber (match_operand:P 2 "register_operand" "=c"))]
22819   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22820    && ix86_check_no_addr_space (insn)"
22821   "%^repz{%;} cmpsb"
22822   [(set_attr "type" "str")
22823    (set_attr "mode" "QI")
22824    (set (attr "prefix_rex")
22825         (if_then_else
22826           (match_test "<P:MODE>mode == DImode")
22827           (const_string "0")
22828           (const_string "*")))
22829    (set_attr "prefix_rep" "1")])
22831 ;; The same, but the count is not known to not be zero.
22833 (define_expand "cmpstrnqi_1"
22834   [(parallel [(set (reg:CC FLAGS_REG)
22835                 (if_then_else:CC (ne (match_operand 2 "register_operand")
22836                                      (const_int 0))
22837                   (compare:CC (match_operand 4 "memory_operand")
22838                               (match_operand 5 "memory_operand"))
22839                   (const_int 0)))
22840               (use (match_operand:SI 3 "immediate_operand"))
22841               (use (reg:CC FLAGS_REG))
22842               (clobber (match_operand 0 "register_operand"))
22843               (clobber (match_operand 1 "register_operand"))
22844               (clobber (match_dup 2))])]
22845   ""
22847   if (TARGET_CLD)
22848     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22851 (define_insn "*cmpstrnqi_1"
22852   [(set (reg:CC FLAGS_REG)
22853         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
22854                              (const_int 0))
22855           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
22856                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
22857           (const_int 0)))
22858    (use (match_operand:SI 3 "immediate_operand" "i"))
22859    (use (reg:CC FLAGS_REG))
22860    (clobber (match_operand:P 0 "register_operand" "=S"))
22861    (clobber (match_operand:P 1 "register_operand" "=D"))
22862    (clobber (match_operand:P 2 "register_operand" "=c"))]
22863   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22864    && ix86_check_no_addr_space (insn)"
22865   "%^repz{%;} cmpsb"
22866   [(set_attr "type" "str")
22867    (set_attr "mode" "QI")
22868    (set (attr "prefix_rex")
22869         (if_then_else
22870           (match_test "<P:MODE>mode == DImode")
22871           (const_string "0")
22872           (const_string "*")))
22873    (set_attr "prefix_rep" "1")])
22875 (define_expand "strlen<mode>"
22876   [(set (match_operand:P 0 "register_operand")
22877         (unspec:P [(match_operand:BLK 1 "general_operand")
22878                    (match_operand:QI 2 "immediate_operand")
22879                    (match_operand 3 "immediate_operand")]
22880                   UNSPEC_SCAS))]
22881   ""
22883  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
22884    DONE;
22885  else
22886    FAIL;
22889 (define_expand "strlenqi_1"
22890   [(parallel [(set (match_operand 0 "register_operand")
22891                    (match_operand 2))
22892               (clobber (match_operand 1 "register_operand"))
22893               (clobber (reg:CC FLAGS_REG))])]
22894   ""
22896   if (TARGET_CLD)
22897     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22900 (define_insn "*strlenqi_1"
22901   [(set (match_operand:P 0 "register_operand" "=&c")
22902         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
22903                    (match_operand:QI 2 "register_operand" "a")
22904                    (match_operand:P 3 "immediate_operand" "i")
22905                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
22906    (clobber (match_operand:P 1 "register_operand" "=D"))
22907    (clobber (reg:CC FLAGS_REG))]
22908   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22909    && ix86_check_no_addr_space (insn)"
22910   "%^repnz{%;} scasb"
22911   [(set_attr "type" "str")
22912    (set_attr "mode" "QI")
22913    (set (attr "prefix_rex")
22914         (if_then_else
22915           (match_test "<P:MODE>mode == DImode")
22916           (const_string "0")
22917           (const_string "*")))
22918    (set_attr "prefix_rep" "1")])
22920 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
22921 ;; handled in combine, but it is not currently up to the task.
22922 ;; When used for their truth value, the cmpstrn* expanders generate
22923 ;; code like this:
22925 ;;   repz cmpsb
22926 ;;   seta       %al
22927 ;;   setb       %dl
22928 ;;   cmpb       %al, %dl
22929 ;;   jcc        label
22931 ;; The intermediate three instructions are unnecessary.
22933 ;; This one handles cmpstrn*_nz_1...
22934 (define_peephole2
22935   [(parallel[
22936      (set (reg:CC FLAGS_REG)
22937           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
22938                       (mem:BLK (match_operand 5 "register_operand"))))
22939      (use (match_operand 6 "register_operand"))
22940      (use (match_operand:SI 3 "immediate_operand"))
22941      (clobber (match_operand 0 "register_operand"))
22942      (clobber (match_operand 1 "register_operand"))
22943      (clobber (match_operand 2 "register_operand"))])
22944    (set (match_operand:QI 7 "register_operand")
22945         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22946    (set (match_operand:QI 8 "register_operand")
22947         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22948    (set (reg FLAGS_REG)
22949         (compare (match_dup 7) (match_dup 8)))
22950   ]
22951   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
22952   [(parallel[
22953      (set (reg:CC FLAGS_REG)
22954           (compare:CC (mem:BLK (match_dup 4))
22955                       (mem:BLK (match_dup 5))))
22956      (use (match_dup 6))
22957      (use (match_dup 3))
22958      (clobber (match_dup 0))
22959      (clobber (match_dup 1))
22960      (clobber (match_dup 2))])])
22962 ;; ...and this one handles cmpstrn*_1.
22963 (define_peephole2
22964   [(parallel[
22965      (set (reg:CC FLAGS_REG)
22966           (if_then_else:CC (ne (match_operand 6 "register_operand")
22967                                (const_int 0))
22968             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
22969                         (mem:BLK (match_operand 5 "register_operand")))
22970             (const_int 0)))
22971      (use (match_operand:SI 3 "immediate_operand"))
22972      (use (reg:CC FLAGS_REG))
22973      (clobber (match_operand 0 "register_operand"))
22974      (clobber (match_operand 1 "register_operand"))
22975      (clobber (match_operand 2 "register_operand"))])
22976    (set (match_operand:QI 7 "register_operand")
22977         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22978    (set (match_operand:QI 8 "register_operand")
22979         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22980    (set (reg FLAGS_REG)
22981         (compare (match_dup 7) (match_dup 8)))
22982   ]
22983   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
22984   [(parallel[
22985      (set (reg:CC FLAGS_REG)
22986           (if_then_else:CC (ne (match_dup 6)
22987                                (const_int 0))
22988             (compare:CC (mem:BLK (match_dup 4))
22989                         (mem:BLK (match_dup 5)))
22990             (const_int 0)))
22991      (use (match_dup 3))
22992      (use (reg:CC FLAGS_REG))
22993      (clobber (match_dup 0))
22994      (clobber (match_dup 1))
22995      (clobber (match_dup 2))])])
22997 ;; Conditional move instructions.
22999 (define_expand "mov<mode>cc"
23000   [(set (match_operand:SWIM 0 "register_operand")
23001         (if_then_else:SWIM (match_operand 1 "comparison_operator")
23002                            (match_operand:SWIM 2 "<general_operand>")
23003                            (match_operand:SWIM 3 "<general_operand>")))]
23004   ""
23005   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
23007 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
23008 ;; the register first winds up with `sbbl $0,reg', which is also weird.
23009 ;; So just document what we're doing explicitly.
23011 (define_expand "x86_mov<mode>cc_0_m1"
23012   [(parallel
23013     [(set (match_operand:SWI48 0 "register_operand")
23014           (if_then_else:SWI48
23015             (match_operator:SWI48 2 "ix86_carry_flag_operator"
23016              [(match_operand 1 "flags_reg_operand")
23017               (const_int 0)])
23018             (const_int -1)
23019             (const_int 0)))
23020      (clobber (reg:CC FLAGS_REG))])])
23022 (define_insn "*x86_mov<mode>cc_0_m1"
23023   [(set (match_operand:SWI48 0 "register_operand" "=r")
23024         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
23025                              [(reg FLAGS_REG) (const_int 0)])
23026           (const_int -1)
23027           (const_int 0)))
23028    (clobber (reg:CC FLAGS_REG))]
23029   ""
23030   "sbb{<imodesuffix>}\t%0, %0"
23031   [(set_attr "type" "alu1")
23032    (set_attr "use_carry" "1")
23033    (set_attr "pent_pair" "pu")
23034    (set_attr "mode" "<MODE>")
23035    (set_attr "length_immediate" "0")])
23037 (define_insn "*x86_mov<mode>cc_0_m1_se"
23038   [(set (match_operand:SWI48 0 "register_operand" "=r")
23039         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
23040                              [(reg FLAGS_REG) (const_int 0)])
23041                             (const_int 1)
23042                             (const_int 0)))
23043    (clobber (reg:CC FLAGS_REG))]
23044   ""
23045   "sbb{<imodesuffix>}\t%0, %0"
23046   [(set_attr "type" "alu1")
23047    (set_attr "use_carry" "1")
23048    (set_attr "pent_pair" "pu")
23049    (set_attr "mode" "<MODE>")
23050    (set_attr "length_immediate" "0")])
23052 (define_insn "*x86_mov<mode>cc_0_m1_neg"
23053   [(set (match_operand:SWI 0 "register_operand" "=<r>")
23054         (neg:SWI (match_operator 1 "ix86_carry_flag_operator"
23055                   [(reg FLAGS_REG) (const_int 0)])))
23056    (clobber (reg:CC FLAGS_REG))]
23057   ""
23058   "sbb{<imodesuffix>}\t%0, %0"
23059   [(set_attr "type" "alu1")
23060    (set_attr "use_carry" "1")
23061    (set_attr "pent_pair" "pu")
23062    (set_attr "mode" "<MODE>")
23063    (set_attr "length_immediate" "0")])
23065 (define_expand "x86_mov<mode>cc_0_m1_neg"
23066   [(parallel
23067     [(set (match_operand:SWI48 0 "register_operand")
23068           (neg:SWI48 (ltu:SWI48 (reg:CCC FLAGS_REG) (const_int 0))))
23069      (clobber (reg:CC FLAGS_REG))])])
23071 (define_split
23072   [(set (match_operand:SWI48 0 "register_operand")
23073         (neg:SWI48
23074           (leu:SWI48
23075             (match_operand 1 "int_nonimmediate_operand")
23076             (match_operand 2 "const_int_operand"))))]
23077   "x86_64_immediate_operand (operands[2], VOIDmode)
23078    && INTVAL (operands[2]) != -1
23079    && INTVAL (operands[2]) != 2147483647"
23080   [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
23081    (set (match_dup 0)
23082         (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))]
23083   "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
23085 (define_split
23086   [(set (match_operand:SWI 0 "register_operand")
23087         (neg:SWI
23088           (eq:SWI
23089             (match_operand 1 "int_nonimmediate_operand")
23090             (const_int 0))))]
23091   ""
23092   [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (const_int 1)))
23093    (set (match_dup 0)
23094         (neg:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))])
23096 (define_split
23097   [(set (match_operand:SWI 0 "register_operand")
23098         (neg:SWI
23099           (ne:SWI
23100             (match_operand 1 "int_nonimmediate_operand")
23101             (const_int 0))))]
23102   ""
23103   [(set (reg:CCC FLAGS_REG)
23104         (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
23105    (set (match_dup 0)
23106         (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))])
23108 (define_insn "*mov<mode>cc_noc"
23109   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
23110         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23111                                [(reg FLAGS_REG) (const_int 0)])
23112           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
23113           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
23114   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23115   "@
23116    cmov%O2%C1\t{%2, %0|%0, %2}
23117    cmov%O2%c1\t{%3, %0|%0, %3}"
23118   [(set_attr "type" "icmov")
23119    (set_attr "mode" "<MODE>")])
23121 (define_insn "*movsicc_noc_zext"
23122   [(set (match_operand:DI 0 "register_operand" "=r,r")
23123         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
23124                            [(reg FLAGS_REG) (const_int 0)])
23125           (zero_extend:DI
23126             (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
23127           (zero_extend:DI
23128             (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
23129   "TARGET_64BIT
23130    && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23131   "@
23132    cmov%O2%C1\t{%2, %k0|%k0, %2}
23133    cmov%O2%c1\t{%3, %k0|%k0, %3}"
23134   [(set_attr "type" "icmov")
23135    (set_attr "mode" "SI")])
23137 (define_insn "*movsicc_noc_zext_1"
23138   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r")
23139         (zero_extend:DI
23140           (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
23141                              [(reg FLAGS_REG) (const_int 0)])
23142              (match_operand:SI 2 "nonimmediate_operand" "rm,0")
23143              (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
23144   "TARGET_64BIT
23145    && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23146   "@
23147    cmov%O2%C1\t{%2, %k0|%k0, %2}
23148    cmov%O2%c1\t{%3, %k0|%k0, %3}"
23149   [(set_attr "type" "icmov")
23150    (set_attr "mode" "SI")])
23153 ;; Don't do conditional moves with memory inputs.  This splitter helps
23154 ;; register starved x86_32 by forcing inputs into registers before reload.
23155 (define_split
23156   [(set (match_operand:SWI248 0 "register_operand")
23157         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23158                                [(reg FLAGS_REG) (const_int 0)])
23159           (match_operand:SWI248 2 "nonimmediate_operand")
23160           (match_operand:SWI248 3 "nonimmediate_operand")))]
23161   "!TARGET_64BIT && TARGET_CMOVE
23162    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23163    && (MEM_P (operands[2]) || MEM_P (operands[3]))
23164    && can_create_pseudo_p ()
23165    && optimize_insn_for_speed_p ()"
23166   [(set (match_dup 0)
23167         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
23169   operands[2] = force_reg (<MODE>mode, operands[2]);
23170   operands[3] = force_reg (<MODE>mode, operands[3]);
23173 (define_insn "*movqicc_noc"
23174   [(set (match_operand:QI 0 "register_operand" "=r,r")
23175         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
23176                            [(reg FLAGS_REG) (const_int 0)])
23177                       (match_operand:QI 2 "register_operand" "r,0")
23178                       (match_operand:QI 3 "register_operand" "0,r")))]
23179   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
23180   "#"
23181   [(set_attr "type" "icmov")
23182    (set_attr "mode" "QI")])
23184 (define_split
23185   [(set (match_operand:SWI12 0 "register_operand")
23186         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
23187                               [(reg FLAGS_REG) (const_int 0)])
23188                       (match_operand:SWI12 2 "register_operand")
23189                       (match_operand:SWI12 3 "register_operand")))]
23190   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
23191    && reload_completed"
23192   [(set (match_dup 0)
23193         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
23195   operands[0] = gen_lowpart (SImode, operands[0]);
23196   operands[2] = gen_lowpart (SImode, operands[2]);
23197   operands[3] = gen_lowpart (SImode, operands[3]);
23200 ;; Don't do conditional moves with memory inputs
23201 (define_peephole2
23202   [(match_scratch:SWI248 4 "r")
23203    (set (match_operand:SWI248 0 "register_operand")
23204         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23205                                [(reg FLAGS_REG) (const_int 0)])
23206           (match_operand:SWI248 2 "nonimmediate_operand")
23207           (match_operand:SWI248 3 "nonimmediate_operand")))]
23208   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23209    && (MEM_P (operands[2]) || MEM_P (operands[3]))
23210    && optimize_insn_for_speed_p ()"
23211   [(set (match_dup 4) (match_dup 5))
23212    (set (match_dup 0)
23213         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
23215   if (MEM_P (operands[2]))
23216     {
23217       operands[5] = operands[2];
23218       operands[2] = operands[4];
23219     }
23220   else if (MEM_P (operands[3]))
23221     {
23222       operands[5] = operands[3];
23223       operands[3] = operands[4];
23224     }
23225   else
23226     gcc_unreachable ();
23229 (define_peephole2
23230   [(match_scratch:SI 4 "r")
23231    (set (match_operand:DI 0 "register_operand")
23232         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
23233                            [(reg FLAGS_REG) (const_int 0)])
23234           (zero_extend:DI
23235             (match_operand:SI 2 "nonimmediate_operand"))
23236           (zero_extend:DI
23237             (match_operand:SI 3 "nonimmediate_operand"))))]
23238   "TARGET_64BIT
23239    && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23240    && (MEM_P (operands[2]) || MEM_P (operands[3]))
23241    && optimize_insn_for_speed_p ()"
23242   [(set (match_dup 4) (match_dup 5))
23243    (set (match_dup 0)
23244         (if_then_else:DI (match_dup 1)
23245           (zero_extend:DI (match_dup 2))
23246           (zero_extend:DI (match_dup 3))))]
23248   if (MEM_P (operands[2]))
23249     {
23250       operands[5] = operands[2];
23251       operands[2] = operands[4];
23252     }
23253   else if (MEM_P (operands[3]))
23254     {
23255       operands[5] = operands[3];
23256       operands[3] = operands[4];
23257     }
23258   else
23259     gcc_unreachable ();
23262 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#1).
23263 ;; mov r0,r1; dec r0; mov r2,r3; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
23264 (define_peephole2
23265  [(set (match_operand:SWI248 0 "general_reg_operand")
23266        (match_operand:SWI248 1 "general_reg_operand"))
23267   (parallel [(set (reg FLAGS_REG) (match_operand 5))
23268              (set (match_dup 0) (match_operand:SWI248 6))])
23269   (set (match_operand:SWI248 2 "general_reg_operand")
23270        (match_operand:SWI248 3 "general_gr_operand"))
23271   (set (match_dup 0)
23272        (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
23273                              [(reg FLAGS_REG) (const_int 0)])
23274         (match_dup 0)
23275         (match_dup 2)))]
23276  "TARGET_CMOVE
23277   && REGNO (operands[2]) != REGNO (operands[0])
23278   && REGNO (operands[2]) != REGNO (operands[1])
23279   && peep2_reg_dead_p (1, operands[1])
23280   && peep2_reg_dead_p (4, operands[2])
23281   && !reg_overlap_mentioned_p (operands[0], operands[3])"
23282  [(parallel [(set (match_dup 7) (match_dup 8))
23283              (set (match_dup 1) (match_dup 9))])
23284   (set (match_dup 0) (match_dup 3))
23285   (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23286                                           (match_dup 1)
23287                                           (match_dup 0)))]
23289   operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
23290   operands[8]
23291     = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23292   operands[9]
23293     = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23296 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#2).
23297 ;; mov r2,r3; mov r0,r1; dec r0; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
23298 (define_peephole2
23299  [(set (match_operand:SWI248 2 "general_reg_operand")
23300        (match_operand:SWI248 3 "general_gr_operand"))
23301   (set (match_operand:SWI248 0 "general_reg_operand")
23302        (match_operand:SWI248 1 "general_reg_operand"))
23303   (parallel [(set (reg FLAGS_REG) (match_operand 5))
23304              (set (match_dup 0) (match_operand:SWI248 6))])
23305   (set (match_dup 0)
23306        (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
23307                              [(reg FLAGS_REG) (const_int 0)])
23308         (match_dup 0)
23309         (match_dup 2)))]
23310  "TARGET_CMOVE
23311   && REGNO (operands[2]) != REGNO (operands[0])
23312   && REGNO (operands[2]) != REGNO (operands[1])
23313   && peep2_reg_dead_p (2, operands[1])
23314   && peep2_reg_dead_p (4, operands[2])
23315   && !reg_overlap_mentioned_p (operands[0], operands[3])
23316   && !reg_mentioned_p (operands[2], operands[6])"
23317  [(parallel [(set (match_dup 7) (match_dup 8))
23318              (set (match_dup 1) (match_dup 9))])
23319   (set (match_dup 0) (match_dup 3))
23320   (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23321                                           (match_dup 1)
23322                                           (match_dup 0)))]
23324   operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (2)), 0, 0));
23325   operands[8]
23326     = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23327   operands[9]
23328     = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23331 (define_insn "movhf_mask"
23332   [(set (match_operand:HF 0 "nonimmediate_operand" "=v,m,v")
23333         (unspec:HF
23334           [(match_operand:HF 1 "nonimmediate_operand" "m,v,v")
23335            (match_operand:HF 2 "nonimm_or_0_operand" "0C,0C,0C")
23336            (match_operand:QI 3 "register_operand" "Yk,Yk,Yk")]
23337           UNSPEC_MOVCC_MASK))]
23338   "TARGET_AVX512FP16"
23339   "@
23340    vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23341    vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23342    vmovsh\t{%d1, %0%{%3%}%N2|%0%{%3%}%N2, %d1}"
23343   [(set_attr "type" "ssemov")
23344    (set_attr "prefix" "evex")
23345    (set_attr "mode" "HF")])
23347 (define_expand "movhfcc"
23348   [(set (match_operand:HF 0 "register_operand")
23349         (if_then_else:HF
23350           (match_operand 1 "comparison_operator")
23351           (match_operand:HF 2 "register_operand")
23352           (match_operand:HF 3 "register_operand")))]
23353   "TARGET_AVX512FP16"
23354   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23356 (define_expand "mov<mode>cc"
23357   [(set (match_operand:X87MODEF 0 "register_operand")
23358         (if_then_else:X87MODEF
23359           (match_operand 1 "comparison_operator")
23360           (match_operand:X87MODEF 2 "register_operand")
23361           (match_operand:X87MODEF 3 "register_operand")))]
23362   "(TARGET_80387 && TARGET_CMOVE)
23363    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
23364   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23366 (define_insn "*movxfcc_1"
23367   [(set (match_operand:XF 0 "register_operand" "=f,f")
23368         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
23369                                 [(reg FLAGS_REG) (const_int 0)])
23370                       (match_operand:XF 2 "register_operand" "f,0")
23371                       (match_operand:XF 3 "register_operand" "0,f")))]
23372   "TARGET_80387 && TARGET_CMOVE"
23373   "@
23374    fcmov%F1\t{%2, %0|%0, %2}
23375    fcmov%f1\t{%3, %0|%0, %3}"
23376   [(set_attr "type" "fcmov")
23377    (set_attr "mode" "XF")])
23379 (define_insn "*movdfcc_1"
23380   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
23381         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23382                                 [(reg FLAGS_REG) (const_int 0)])
23383                       (match_operand:DF 2 "nonimmediate_operand"
23384                                                "f ,0,rm,0 ,rm,0")
23385                       (match_operand:DF 3 "nonimmediate_operand"
23386                                                "0 ,f,0 ,rm,0, rm")))]
23387   "TARGET_80387 && TARGET_CMOVE
23388    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23389   "@
23390    fcmov%F1\t{%2, %0|%0, %2}
23391    fcmov%f1\t{%3, %0|%0, %3}
23392    #
23393    #
23394    cmov%O2%C1\t{%2, %0|%0, %2}
23395    cmov%O2%c1\t{%3, %0|%0, %3}"
23396   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
23397    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
23398    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
23400 (define_split
23401   [(set (match_operand:DF 0 "general_reg_operand")
23402         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23403                                 [(reg FLAGS_REG) (const_int 0)])
23404                       (match_operand:DF 2 "nonimmediate_operand")
23405                       (match_operand:DF 3 "nonimmediate_operand")))]
23406   "!TARGET_64BIT && reload_completed"
23407   [(set (match_dup 2)
23408         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
23409    (set (match_dup 3)
23410         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
23412   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
23413   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
23416 (define_insn "*movsfcc_1_387"
23417   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
23418         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
23419                                 [(reg FLAGS_REG) (const_int 0)])
23420                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
23421                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
23422   "TARGET_80387 && TARGET_CMOVE
23423    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23424   "@
23425    fcmov%F1\t{%2, %0|%0, %2}
23426    fcmov%f1\t{%3, %0|%0, %3}
23427    cmov%O2%C1\t{%2, %0|%0, %2}
23428    cmov%O2%c1\t{%3, %0|%0, %3}"
23429   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
23430    (set_attr "mode" "SF,SF,SI,SI")])
23432 ;; Don't do conditional moves with memory inputs.  This splitter helps
23433 ;; register starved x86_32 by forcing inputs into registers before reload.
23434 (define_split
23435   [(set (match_operand:MODEF 0 "register_operand")
23436         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
23437                               [(reg FLAGS_REG) (const_int 0)])
23438           (match_operand:MODEF 2 "nonimmediate_operand")
23439           (match_operand:MODEF 3 "nonimmediate_operand")))]
23440   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
23441    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23442    && (MEM_P (operands[2]) || MEM_P (operands[3]))
23443    && can_create_pseudo_p ()
23444    && optimize_insn_for_speed_p ()"
23445   [(set (match_dup 0)
23446         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23448   operands[2] = force_reg (<MODE>mode, operands[2]);
23449   operands[3] = force_reg (<MODE>mode, operands[3]);
23452 ;; Don't do conditional moves with memory inputs
23453 (define_peephole2
23454   [(match_scratch:MODEF 4 "r")
23455    (set (match_operand:MODEF 0 "general_reg_operand")
23456         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
23457                               [(reg FLAGS_REG) (const_int 0)])
23458           (match_operand:MODEF 2 "nonimmediate_operand")
23459           (match_operand:MODEF 3 "nonimmediate_operand")))]
23460   "(<MODE>mode != DFmode || TARGET_64BIT)
23461    && TARGET_80387 && TARGET_CMOVE
23462    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23463    && (MEM_P (operands[2]) || MEM_P (operands[3]))
23464    && optimize_insn_for_speed_p ()"
23465   [(set (match_dup 4) (match_dup 5))
23466    (set (match_dup 0)
23467         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23469   if (MEM_P (operands[2]))
23470     {
23471       operands[5] = operands[2];
23472       operands[2] = operands[4];
23473     }
23474   else if (MEM_P (operands[3]))
23475     {
23476       operands[5] = operands[3];
23477       operands[3] = operands[4];
23478     }
23479   else
23480     gcc_unreachable ();
23483 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
23484 ;; the scalar versions to have only XMM registers as operands.
23486 ;; XOP conditional move
23487 (define_insn "*xop_pcmov_<mode>"
23488   [(set (match_operand:MODEF 0 "register_operand" "=x")
23489         (if_then_else:MODEF
23490           (match_operand:MODEF 1 "register_operand" "x")
23491           (match_operand:MODEF 2 "register_operand" "x")
23492           (match_operand:MODEF 3 "register_operand" "x")))]
23493   "TARGET_XOP"
23494   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
23495   [(set_attr "type" "sse4arg")
23496    (set_attr "mode" "TI")])
23498 ;; These versions of the min/max patterns are intentionally ignorant of
23499 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
23500 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
23501 ;; are undefined in this condition, we're certain this is correct.
23503 (define_insn "<code><mode>3"
23504   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23505         (smaxmin:MODEF
23506           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
23507           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
23508   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23509   "@
23510    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
23511    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23512   [(set_attr "isa" "noavx,avx")
23513    (set_attr "prefix" "orig,vex")
23514    (set_attr "type" "sseadd")
23515    (set_attr "mode" "<MODE>")])
23517 (define_insn "<code>hf3"
23518   [(set (match_operand:HF 0 "register_operand" "=v")
23519         (smaxmin:HF
23520           (match_operand:HF 1 "nonimmediate_operand" "%v")
23521           (match_operand:HF 2 "nonimmediate_operand" "vm")))]
23522   "TARGET_AVX512FP16"
23523   "v<maxmin_float>sh\t{%2, %1, %0|%0, %1, %2}"
23524   [(set_attr "prefix" "evex")
23525    (set_attr "type" "sseadd")
23526    (set_attr "mode" "HF")])
23528 ;; These versions of the min/max patterns implement exactly the operations
23529 ;;   min = (op1 < op2 ? op1 : op2)
23530 ;;   max = (!(op1 < op2) ? op1 : op2)
23531 ;; Their operands are not commutative, and thus they may be used in the
23532 ;; presence of -0.0 and NaN.
23534 (define_insn "*ieee_s<ieee_maxmin>hf3"
23535   [(set (match_operand:HF 0 "register_operand" "=v")
23536         (unspec:HF
23537           [(match_operand:HF 1 "register_operand" "v")
23538            (match_operand:HF 2 "nonimmediate_operand" "vm")]
23539           IEEE_MAXMIN))]
23540   "TARGET_AVX512FP16"
23541   "v<ieee_maxmin>sh\t{%2, %1, %0|%0, %1, %2}"
23542   [(set_attr "prefix" "evex")
23543    (set_attr "type" "sseadd")
23544    (set_attr "mode" "HF")])
23546 (define_insn "*ieee_s<ieee_maxmin><mode>3"
23547   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23548         (unspec:MODEF
23549           [(match_operand:MODEF 1 "register_operand" "0,v")
23550            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
23551           IEEE_MAXMIN))]
23552   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23553   "@
23554    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
23555    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23556   [(set_attr "isa" "noavx,avx")
23557    (set_attr "prefix" "orig,maybe_evex")
23558    (set_attr "type" "sseadd")
23559    (set_attr "mode" "<MODE>")])
23561 ;; Operands order in min/max instruction matters for signed zero and NANs.
23562 (define_insn_and_split "*ieee_max<mode>3_1"
23563   [(set (match_operand:MODEF 0 "register_operand")
23564         (unspec:MODEF
23565           [(match_operand:MODEF 1 "register_operand")
23566            (match_operand:MODEF 2 "register_operand")
23567            (lt:MODEF
23568              (match_operand:MODEF 3 "register_operand")
23569              (match_operand:MODEF 4 "register_operand"))]
23570           UNSPEC_BLENDV))]
23571   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23572   && (rtx_equal_p (operands[1], operands[3])
23573       && rtx_equal_p (operands[2], operands[4]))
23574   && ix86_pre_reload_split ()"
23575   "#"
23576   "&& 1"
23577   [(set (match_dup 0)
23578         (unspec:MODEF
23579           [(match_dup 2)
23580            (match_dup 1)]
23581          UNSPEC_IEEE_MAX))])
23583 (define_insn_and_split "*ieee_min<mode>3_1"
23584   [(set (match_operand:MODEF 0 "register_operand")
23585         (unspec:MODEF
23586           [(match_operand:MODEF 1 "register_operand")
23587            (match_operand:MODEF 2 "register_operand")
23588            (lt:MODEF
23589              (match_operand:MODEF 3 "register_operand")
23590              (match_operand:MODEF 4 "register_operand"))]
23591           UNSPEC_BLENDV))]
23592   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23593   && (rtx_equal_p (operands[1], operands[4])
23594       && rtx_equal_p (operands[2], operands[3]))
23595   && ix86_pre_reload_split ()"
23596   "#"
23597   "&& 1"
23598   [(set (match_dup 0)
23599         (unspec:MODEF
23600           [(match_dup 2)
23601            (match_dup 1)]
23602          UNSPEC_IEEE_MIN))])
23604 ;; Make two stack loads independent:
23605 ;;   fld aa              fld aa
23606 ;;   fld %st(0)     ->   fld bb
23607 ;;   fmul bb             fmul %st(1), %st
23609 ;; Actually we only match the last two instructions for simplicity.
23611 (define_peephole2
23612   [(set (match_operand 0 "fp_register_operand")
23613         (match_operand 1 "fp_register_operand"))
23614    (set (match_dup 0)
23615         (match_operator 2 "binary_fp_operator"
23616            [(match_dup 0)
23617             (match_operand 3 "memory_operand")]))]
23618   "REGNO (operands[0]) != REGNO (operands[1])"
23619   [(set (match_dup 0) (match_dup 3))
23620    (set (match_dup 0)
23621         (match_op_dup 2
23622           [(match_dup 5) (match_dup 4)]))]
23624   operands[4] = operands[0];
23625   operands[5] = operands[1];
23627   /* The % modifier is not operational anymore in peephole2's, so we have to
23628      swap the operands manually in the case of addition and multiplication. */
23629   if (COMMUTATIVE_ARITH_P (operands[2]))
23630     std::swap (operands[4], operands[5]);
23633 (define_peephole2
23634   [(set (match_operand 0 "fp_register_operand")
23635         (match_operand 1 "fp_register_operand"))
23636    (set (match_dup 0)
23637         (match_operator 2 "binary_fp_operator"
23638            [(match_operand 3 "memory_operand")
23639             (match_dup 0)]))]
23640   "REGNO (operands[0]) != REGNO (operands[1])"
23641   [(set (match_dup 0) (match_dup 3))
23642    (set (match_dup 0)
23643         (match_op_dup 2
23644           [(match_dup 4) (match_dup 5)]))]
23646   operands[4] = operands[0];
23647   operands[5] = operands[1];
23649   /* The % modifier is not operational anymore in peephole2's, so we have to
23650      swap the operands manually in the case of addition and multiplication. */
23651   if (COMMUTATIVE_ARITH_P (operands[2]))
23652     std::swap (operands[4], operands[5]);
23655 ;; Conditional addition patterns
23656 (define_expand "add<mode>cc"
23657   [(match_operand:SWI 0 "register_operand")
23658    (match_operand 1 "ordered_comparison_operator")
23659    (match_operand:SWI 2 "register_operand")
23660    (match_operand:SWI 3 "const_int_operand")]
23661   ""
23662   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
23664 ;; min/max patterns
23666 (define_code_attr maxmin_rel
23667   [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
23669 (define_expand "<code><mode>3"
23670   [(parallel
23671     [(set (match_operand:SDWIM 0 "register_operand")
23672           (maxmin:SDWIM
23673             (match_operand:SDWIM 1 "register_operand")
23674             (match_operand:SDWIM 2 "general_operand")))
23675      (clobber (reg:CC FLAGS_REG))])]
23676   "TARGET_CMOVE
23677    && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)")
23679 (define_insn_and_split "*<code><dwi>3_doubleword"
23680   [(set (match_operand:<DWI> 0 "register_operand")
23681         (maxmin:<DWI>
23682           (match_operand:<DWI> 1 "register_operand")
23683           (match_operand:<DWI> 2 "general_operand")))
23684    (clobber (reg:CC FLAGS_REG))]
23685   "TARGET_CMOVE
23686    && ix86_pre_reload_split ()"
23687   "#"
23688   "&& 1"
23689   [(set (match_dup 0)
23690         (if_then_else:DWIH (match_dup 6)
23691           (match_dup 1)
23692           (match_dup 2)))
23693    (set (match_dup 3)
23694         (if_then_else:DWIH (match_dup 6)
23695           (match_dup 4)
23696           (match_dup 5)))]
23698   operands[2] = force_reg (<DWI>mode, operands[2]);
23700   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
23702   rtx cmplo[2] = { operands[1], operands[2] };
23703   rtx cmphi[2] = { operands[4], operands[5] };
23705   enum rtx_code code = <maxmin_rel>;
23707   switch (code)
23708     {
23709     case LE: case LEU:
23710       std::swap (cmplo[0], cmplo[1]);
23711       std::swap (cmphi[0], cmphi[1]);
23712       code = swap_condition (code);
23713       /* FALLTHRU */
23715     case GE: case GEU:
23716       {
23717         bool uns = (code == GEU);
23718         rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
23719           = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
23721         emit_insn (gen_cmp_1 (<MODE>mode, cmplo[0], cmplo[1]));
23723         rtx tmp = gen_rtx_SCRATCH (<MODE>mode);
23724         emit_insn (sbb_insn (<MODE>mode, tmp, cmphi[0], cmphi[1]));
23726         rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
23727         operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23729         break;
23730       }
23732     default:
23733       gcc_unreachable ();
23734     }
23737 (define_insn_and_split "*<code><mode>3_1"
23738   [(set (match_operand:SWI 0 "register_operand")
23739         (maxmin:SWI
23740           (match_operand:SWI 1 "register_operand")
23741           (match_operand:SWI 2 "general_operand")))
23742    (clobber (reg:CC FLAGS_REG))]
23743   "TARGET_CMOVE
23744    && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
23745    && ix86_pre_reload_split ()"
23746   "#"
23747   "&& 1"
23748   [(set (match_dup 0)
23749         (if_then_else:SWI (match_dup 3)
23750           (match_dup 1)
23751           (match_dup 2)))]
23753   machine_mode mode = <MODE>mode;
23754   rtx cmp_op = operands[2];
23756   operands[2] = force_reg (mode, cmp_op);
23758   enum rtx_code code = <maxmin_rel>;
23760   if (cmp_op == const1_rtx)
23761     {
23762       /* Convert smax (x, 1) into (x > 0 ? x : 1).
23763          Convert umax (x, 1) into (x != 0 ? x : 1).
23764          Convert ?min (x, 1) into (x <= 0 ? x : 1).  */
23765       cmp_op = const0_rtx;
23766       if (code == GE)
23767         code = GT;
23768       else if (code == GEU)
23769         code = NE;
23770     }
23771   /* Convert smin (x, -1) into (x < 0 ? x : -1).  */
23772   else if (cmp_op == constm1_rtx && code == LE)
23773     {
23774       cmp_op = const0_rtx;
23775       code = LT;
23776     }
23777   /* Convert smax (x, -1) into (x >= 0 ? x : -1).  */
23778   else if (cmp_op == constm1_rtx && code == GE)
23779     cmp_op = const0_rtx;
23780   else if (cmp_op != const0_rtx)
23781     cmp_op = operands[2];
23783   machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], cmp_op);
23784   rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
23786   rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], cmp_op);
23787   emit_insn (gen_rtx_SET (flags, tmp));
23789   operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23792 ;; Avoid clearing a register between a flags setting comparison and its use,
23793 ;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
23794 (define_peephole2
23795   [(set (reg FLAGS_REG) (match_operand 0))
23796    (set (match_operand:SWI 1 "general_reg_operand") (const_int 0))]
23797   "peep2_regno_dead_p (0, FLAGS_REG)
23798    && !reg_overlap_mentioned_p (operands[1], operands[0])"
23799    [(set (match_dup 2) (match_dup 0))]
23801   operands[2] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
23802   ix86_expand_clear (operands[1]);
23805 ;; When optimizing for size, zeroing memory should use a register.
23806 (define_peephole2
23807   [(match_scratch:SWI48 0 "r")
23808    (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23809    (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
23810    (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
23811    (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
23812   "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23813   [(const_int 0)]
23815   ix86_expand_clear (operands[0]);
23816   emit_move_insn (operands[1], operands[0]);
23817   emit_move_insn (operands[2], operands[0]);
23818   emit_move_insn (operands[3], operands[0]);
23819   ix86_last_zero_store_uid
23820     = INSN_UID (emit_move_insn (operands[4], operands[0]));
23821   DONE;
23824 (define_peephole2
23825   [(match_scratch:SWI48 0 "r")
23826    (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23827    (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
23828   "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23829   [(const_int 0)]
23831   ix86_expand_clear (operands[0]);
23832   emit_move_insn (operands[1], operands[0]);
23833   ix86_last_zero_store_uid
23834     = INSN_UID (emit_move_insn (operands[2], operands[0]));
23835   DONE;
23838 (define_peephole2
23839   [(match_scratch:SWI48 0 "r")
23840    (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
23841   "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23842   [(const_int 0)]
23844   ix86_expand_clear (operands[0]);
23845   ix86_last_zero_store_uid
23846     = INSN_UID (emit_move_insn (operands[1], operands[0]));
23847   DONE;
23850 (define_peephole2
23851   [(set (match_operand:SWI48 5 "memory_operand")
23852         (match_operand:SWI48 0 "general_reg_operand"))
23853    (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23854    (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
23855    (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
23856    (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
23857   "optimize_insn_for_size_p ()
23858    && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23859   [(const_int 0)]
23861   emit_move_insn (operands[5], operands[0]);
23862   emit_move_insn (operands[1], operands[0]);
23863   emit_move_insn (operands[2], operands[0]);
23864   emit_move_insn (operands[3], operands[0]);
23865   ix86_last_zero_store_uid
23866     = INSN_UID (emit_move_insn (operands[4], operands[0]));
23867   DONE;
23870 (define_peephole2
23871   [(set (match_operand:SWI48 3 "memory_operand")
23872         (match_operand:SWI48 0 "general_reg_operand"))
23873    (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23874    (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
23875   "optimize_insn_for_size_p ()
23876    && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23877   [(const_int 0)]
23879   emit_move_insn (operands[3], operands[0]);
23880   emit_move_insn (operands[1], operands[0]);
23881   ix86_last_zero_store_uid
23882     = INSN_UID (emit_move_insn (operands[2], operands[0]));
23883   DONE;
23886 (define_peephole2
23887   [(set (match_operand:SWI48 2 "memory_operand")
23888         (match_operand:SWI48 0 "general_reg_operand"))
23889    (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
23890   "optimize_insn_for_size_p ()
23891    && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23892   [(const_int 0)]
23894   emit_move_insn (operands[2], operands[0]);
23895   ix86_last_zero_store_uid
23896     = INSN_UID (emit_move_insn (operands[1], operands[0]));
23897   DONE;
23900 ;; Reload dislikes loading constants directly into class_likely_spilled
23901 ;; hard registers.  Try to tidy things up here.
23902 (define_peephole2
23903   [(set (match_operand:SWI 0 "general_reg_operand")
23904         (match_operand:SWI 1 "x86_64_general_operand"))
23905    (set (match_operand:SWI 2 "general_reg_operand")
23906         (match_dup 0))]
23907   "peep2_reg_dead_p (2, operands[0])"
23908   [(set (match_dup 2) (match_dup 1))])
23910 ;; Misc patterns (?)
23912 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
23913 ;; Otherwise there will be nothing to keep
23915 ;; [(set (reg ebp) (reg esp))]
23916 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
23917 ;;  (clobber (eflags)]
23918 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
23920 ;; in proper program order.
23922 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
23923   [(set (match_operand:P 0 "register_operand" "=r,r")
23924         (plus:P (match_operand:P 1 "register_operand" "0,r")
23925                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
23926    (clobber (reg:CC FLAGS_REG))
23927    (clobber (mem:BLK (scratch)))]
23928   ""
23930   switch (get_attr_type (insn))
23931     {
23932     case TYPE_IMOV:
23933       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
23935     case TYPE_ALU:
23936       gcc_assert (rtx_equal_p (operands[0], operands[1]));
23937       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
23938         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
23940       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
23942     default:
23943       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
23944       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
23945     }
23947   [(set (attr "type")
23948         (cond [(and (eq_attr "alternative" "0")
23949                     (not (match_test "TARGET_OPT_AGU")))
23950                  (const_string "alu")
23951                (match_operand:<MODE> 2 "const0_operand")
23952                  (const_string "imov")
23953               ]
23954               (const_string "lea")))
23955    (set (attr "length_immediate")
23956         (cond [(eq_attr "type" "imov")
23957                  (const_string "0")
23958                (and (eq_attr "type" "alu")
23959                     (match_operand 2 "const128_operand"))
23960                  (const_string "1")
23961               ]
23962               (const_string "*")))
23963    (set_attr "mode" "<MODE>")])
23965 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
23966   [(set (match_operand:P 0 "register_operand" "=r")
23967         (minus:P (match_operand:P 1 "register_operand" "0")
23968                  (match_operand:P 2 "register_operand" "r")))
23969    (clobber (reg:CC FLAGS_REG))
23970    (clobber (mem:BLK (scratch)))]
23971   ""
23972   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
23973   [(set_attr "type" "alu")
23974    (set_attr "mode" "<MODE>")])
23976 (define_insn "@allocate_stack_worker_probe_<mode>"
23977   [(set (match_operand:P 0 "register_operand" "=a")
23978         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
23979                             UNSPECV_STACK_PROBE))
23980    (clobber (reg:CC FLAGS_REG))]
23981   "ix86_target_stack_probe ()"
23982   "call\t___chkstk_ms"
23983   [(set_attr "type" "multi")
23984    (set_attr "length" "5")])
23986 (define_expand "allocate_stack"
23987   [(match_operand 0 "register_operand")
23988    (match_operand 1 "general_operand")]
23989   "ix86_target_stack_probe ()"
23991   rtx x;
23993 #ifndef CHECK_STACK_LIMIT
23994 #define CHECK_STACK_LIMIT 0
23995 #endif
23997   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
23998       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
23999     x = operands[1];
24000   else
24001     {
24002       x = copy_to_mode_reg (Pmode, operands[1]);
24004       emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
24005     }
24007   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
24008                            stack_pointer_rtx, 0, OPTAB_DIRECT);
24010   if (x != stack_pointer_rtx)
24011     emit_move_insn (stack_pointer_rtx, x);
24013   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
24014   DONE;
24017 (define_expand "probe_stack"
24018   [(match_operand 0 "memory_operand")]
24019   ""
24021   emit_insn (gen_probe_stack_1
24022              (word_mode, operands[0], const0_rtx));
24023   DONE;
24026 ;; Use OR for stack probes, this is shorter.
24027 (define_insn "@probe_stack_1_<mode>"
24028   [(set (match_operand:W 0 "memory_operand" "=m")
24029         (unspec:W [(match_operand:W 1 "const0_operand")]
24030                   UNSPEC_PROBE_STACK))
24031    (clobber (reg:CC FLAGS_REG))]
24032   ""
24033   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
24034   [(set_attr "type" "alu1")
24035    (set_attr "mode" "<MODE>")
24036    (set_attr "length_immediate" "1")])
24037   
24038 (define_insn "@adjust_stack_and_probe_<mode>"
24039   [(set (match_operand:P 0 "register_operand" "=r")
24040         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
24041                             UNSPECV_PROBE_STACK_RANGE))
24042    (set (reg:P SP_REG)
24043         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand")))
24044    (clobber (reg:CC FLAGS_REG))
24045    (clobber (mem:BLK (scratch)))]
24046   ""
24047   "* return output_adjust_stack_and_probe (operands[0]);"
24048   [(set_attr "type" "multi")])
24050 (define_insn "@probe_stack_range_<mode>"
24051   [(set (match_operand:P 0 "register_operand" "=r")
24052         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
24053                             (match_operand:P 2 "const_int_operand")]
24054                             UNSPECV_PROBE_STACK_RANGE))
24055    (clobber (reg:CC FLAGS_REG))]
24056   ""
24057   "* return output_probe_stack_range (operands[0], operands[2]);"
24058   [(set_attr "type" "multi")])
24060 (define_expand "builtin_setjmp_receiver"
24061   [(label_ref (match_operand 0))]
24062   "!TARGET_64BIT && flag_pic"
24064 #if TARGET_MACHO
24065   if (TARGET_MACHO)
24066     {
24067       rtx xops[3];
24068       rtx_code_label *label_rtx = gen_label_rtx ();
24069       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
24070       xops[0] = xops[1] = pic_offset_table_rtx;
24071       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
24072       ix86_expand_binary_operator (MINUS, SImode, xops);
24073     }
24074   else
24075 #endif
24076     emit_insn (gen_set_got (pic_offset_table_rtx));
24077   DONE;
24080 (define_expand "save_stack_nonlocal"
24081   [(set (match_operand 0 "memory_operand")
24082         (match_operand 1 "register_operand"))]
24083   ""
24085   rtx stack_slot;
24087   if (flag_cf_protection & CF_RETURN)
24088     {
24089       /* Copy shadow stack pointer to the first slot
24090          and stack pointer to the second slot.  */
24091       rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
24092       stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
24094       rtx reg_ssp = force_reg (word_mode, const0_rtx);
24095       emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
24096       emit_move_insn (ssp_slot, reg_ssp);
24097     }
24098   else
24099     stack_slot = adjust_address (operands[0], Pmode, 0);
24100   emit_move_insn (stack_slot, operands[1]);
24101   DONE;
24104 (define_expand "restore_stack_nonlocal"
24105   [(set (match_operand 0 "register_operand" "")
24106         (match_operand 1 "memory_operand" ""))]
24107   ""
24109   rtx stack_slot;
24111   if (flag_cf_protection & CF_RETURN)
24112     {
24113       /* Restore shadow stack pointer from the first slot
24114          and stack pointer from the second slot.  */
24115       rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
24116       stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
24118       /* Get the current shadow stack pointer.  The code below will check if
24119          SHSTK feature is enabled.  If it is not enabled the RDSSP instruction
24120          is a NOP.  */
24121       rtx reg_ssp = force_reg (word_mode, const0_rtx);
24122       emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
24124       /* Compare through subtraction the saved and the current ssp
24125          to decide if ssp has to be adjusted.  */
24126       reg_ssp = expand_simple_binop (word_mode, MINUS,
24127                                      reg_ssp, ssp_slot,
24128                                      reg_ssp, 1, OPTAB_DIRECT);
24130       /* Compare and jump over adjustment code.  */
24131       rtx noadj_label = gen_label_rtx ();
24132       emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
24133                                word_mode, 1, noadj_label);
24135       /* Compute the number of frames to adjust.  */
24136       rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
24137       rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
24138                                             NULL_RTX, 1);
24140       reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
24141                                      GEN_INT (exact_log2 (UNITS_PER_WORD)),
24142                                      reg_adj, 1, OPTAB_DIRECT);
24144       /* Check if number of frames <= 255 so no loop is needed.  */
24145       rtx inc_label = gen_label_rtx ();
24146       emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
24147                                ptr_mode, 1, inc_label);
24149       /* Adjust the ssp in a loop.  */
24150       rtx loop_label = gen_label_rtx ();
24151       emit_label (loop_label);
24152       LABEL_NUSES (loop_label) = 1;
24154       rtx reg_255 = force_reg (word_mode, GEN_INT (255));
24155       emit_insn (gen_incssp (word_mode, reg_255));
24157       reg_adj = expand_simple_binop (ptr_mode, MINUS,
24158                                      reg_adj, GEN_INT (255),
24159                                      reg_adj, 1, OPTAB_DIRECT);
24161       /* Compare and jump to the loop label.  */
24162       emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
24163                                ptr_mode, 1, loop_label);
24165       emit_label (inc_label);
24166       LABEL_NUSES (inc_label) = 1;
24168       emit_insn (gen_incssp (word_mode, reg_ssp));
24170       emit_label (noadj_label);
24171       LABEL_NUSES (noadj_label) = 1;
24172     }
24173   else
24174     stack_slot = adjust_address (operands[1], Pmode, 0);
24175   emit_move_insn (operands[0], stack_slot);
24176   DONE;
24179 (define_expand "stack_protect_set"
24180   [(match_operand 0 "memory_operand")
24181    (match_operand 1 "memory_operand")]
24182   ""
24184   rtx scratch = gen_reg_rtx (word_mode);
24186   emit_insn (gen_stack_protect_set_1
24187              (ptr_mode, word_mode, operands[0], operands[1], scratch));
24188   DONE;
24191 (define_insn "@stack_protect_set_1_<PTR:mode>_<SWI48:mode>"
24192   [(set (match_operand:PTR 0 "memory_operand" "=m")
24193         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
24194                     UNSPEC_SP_SET))
24195    (set (match_operand:SWI48 2 "register_operand" "=&r") (const_int 0))
24196    (clobber (reg:CC FLAGS_REG))]
24197   ""
24199   output_asm_insn ("mov{<PTR:imodesuffix>}\t{%1, %<PTR:k>2|%<PTR:k>2, %1}",
24200                    operands);
24201   output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>2, %0|%0, %<PTR:k>2}",
24202                    operands);
24203   return "xor{l}\t%k2, %k2";
24205   [(set_attr "type" "multi")])
24207 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
24208 ;; immediately followed by *mov{s,d}i_internal, where we can avoid
24209 ;; the xor{l} above.  We don't split this, so that scheduling or
24210 ;; anything else doesn't separate the *stack_protect_set* pattern from
24211 ;; the set of the register that overwrites the register with a new value.
24213 (define_peephole2
24214   [(parallel [(set (match_operand:PTR 0 "memory_operand")
24215                    (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24216                                UNSPEC_SP_SET))
24217               (set (match_operand:W 2 "general_reg_operand") (const_int 0))
24218               (clobber (reg:CC FLAGS_REG))])
24219    (parallel [(set (match_operand:SWI48 3 "general_reg_operand")
24220                    (match_operand:SWI48 4 "const0_operand"))
24221               (clobber (reg:CC FLAGS_REG))])]
24222   "peep2_reg_dead_p (0, operands[3])
24223    && peep2_reg_dead_p (1, operands[2])"
24224   [(parallel [(set (match_dup 0)
24225                    (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24226               (set (match_dup 3) (const_int 0))
24227               (clobber (reg:CC FLAGS_REG))])])
24229 (define_insn "*stack_protect_set_2_<mode>_si"
24230   [(set (match_operand:PTR 0 "memory_operand" "=m")
24231         (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24232                     UNSPEC_SP_SET))
24233    (set (match_operand:SI 1 "register_operand" "=&r")
24234         (match_operand:SI 2 "general_operand" "g"))]
24235   "reload_completed"
24237   output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24238   output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24239   if (pic_32bit_operand (operands[2], SImode)
24240       || ix86_use_lea_for_mov (insn, operands + 1))
24241     return "lea{l}\t{%E2, %1|%1, %E2}";
24242   else
24243     return "mov{l}\t{%2, %1|%1, %2}";
24245   [(set_attr "type" "multi")
24246    (set_attr "length" "24")])
24248 (define_insn "*stack_protect_set_2_<mode>_di"
24249   [(set (match_operand:PTR 0 "memory_operand" "=m,m,m")
24250         (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m,m,m")]
24251                     UNSPEC_SP_SET))
24252    (set (match_operand:DI 1 "register_operand" "=&r,&r,&r")
24253         (match_operand:DI 2 "general_operand" "Z,rem,i"))]
24254   "TARGET_64BIT && reload_completed"
24256   output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24257   output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24258   if (pic_32bit_operand (operands[2], DImode))
24259     return "lea{q}\t{%E2, %1|%1, %E2}";
24260   else if (which_alternative == 0)
24261     return "mov{l}\t{%k2, %k1|%k1, %k2}";
24262   else if (which_alternative == 2)
24263     return "movabs{q}\t{%2, %1|%1, %2}";
24264   else if (ix86_use_lea_for_mov (insn, operands + 1))
24265     return "lea{q}\t{%E2, %1|%1, %E2}";
24266   else
24267     return "mov{q}\t{%2, %1|%1, %2}";
24269   [(set_attr "type" "multi")
24270    (set_attr "length" "24")])
24272 (define_peephole2
24273   [(parallel [(set (match_operand:PTR 0 "memory_operand")
24274                    (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24275                                UNSPEC_SP_SET))
24276               (set (match_operand:W 2 "general_reg_operand") (const_int 0))
24277               (clobber (reg:CC FLAGS_REG))])
24278    (set (match_operand:SWI48 3 "general_reg_operand")
24279         (match_operand:SWI48 4 "general_gr_operand"))]
24280   "peep2_reg_dead_p (0, operands[3])
24281    && peep2_reg_dead_p (1, operands[2])"
24282   [(parallel [(set (match_dup 0)
24283                    (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24284               (set (match_dup 3) (match_dup 4))])])
24286 (define_expand "stack_protect_test"
24287   [(match_operand 0 "memory_operand")
24288    (match_operand 1 "memory_operand")
24289    (match_operand 2)]
24290   ""
24292   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
24294   emit_insn (gen_stack_protect_test_1
24295              (ptr_mode, flags, operands[0], operands[1]));
24297   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
24298                                   flags, const0_rtx, operands[2]));
24299   DONE;
24302 (define_insn "@stack_protect_test_1_<mode>"
24303   [(set (match_operand:CCZ 0 "flags_reg_operand")
24304         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
24305                      (match_operand:PTR 2 "memory_operand" "m")]
24306                     UNSPEC_SP_TEST))
24307    (clobber (match_scratch:PTR 3 "=&r"))]
24308   ""
24310   output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
24311   return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
24313   [(set_attr "type" "multi")])
24315 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
24316 ;; Do not split instructions with mask registers.
24317 (define_split
24318   [(set (match_operand 0 "general_reg_operand")
24319         (match_operator 3 "promotable_binary_operator"
24320            [(match_operand 1 "general_reg_operand")
24321             (match_operand 2 "aligned_operand")]))
24322    (clobber (reg:CC FLAGS_REG))]
24323   "! TARGET_PARTIAL_REG_STALL && reload_completed
24324    && ((GET_MODE (operands[0]) == HImode
24325         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
24326             /* ??? next two lines just !satisfies_constraint_K (...) */
24327             || !CONST_INT_P (operands[2])
24328             || satisfies_constraint_K (operands[2])))
24329        || (GET_MODE (operands[0]) == QImode
24330            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
24331   [(parallel [(set (match_dup 0)
24332                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
24333               (clobber (reg:CC FLAGS_REG))])]
24335   operands[0] = gen_lowpart (SImode, operands[0]);
24336   operands[1] = gen_lowpart (SImode, operands[1]);
24337   if (GET_CODE (operands[3]) != ASHIFT)
24338     operands[2] = gen_lowpart (SImode, operands[2]);
24339   operands[3] = shallow_copy_rtx (operands[3]);
24340   PUT_MODE (operands[3], SImode);
24343 ; Promote the QImode tests, as i386 has encoding of the AND
24344 ; instruction with 32-bit sign-extended immediate and thus the
24345 ; instruction size is unchanged, except in the %eax case for
24346 ; which it is increased by one byte, hence the ! optimize_size.
24347 (define_split
24348   [(set (match_operand 0 "flags_reg_operand")
24349         (match_operator 2 "compare_operator"
24350           [(and (match_operand 3 "aligned_operand")
24351                 (match_operand 4 "const_int_operand"))
24352            (const_int 0)]))
24353    (set (match_operand 1 "register_operand")
24354         (and (match_dup 3) (match_dup 4)))]
24355   "! TARGET_PARTIAL_REG_STALL && reload_completed
24356    && optimize_insn_for_speed_p ()
24357    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
24358        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
24359    /* Ensure that the operand will remain sign-extended immediate.  */
24360    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
24361   [(parallel [(set (match_dup 0)
24362                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
24363                                     (const_int 0)]))
24364               (set (match_dup 1)
24365                    (and:SI (match_dup 3) (match_dup 4)))])]
24367   operands[4]
24368     = gen_int_mode (INTVAL (operands[4])
24369                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
24370   operands[1] = gen_lowpart (SImode, operands[1]);
24371   operands[3] = gen_lowpart (SImode, operands[3]);
24374 ; Don't promote the QImode tests, as i386 doesn't have encoding of
24375 ; the TEST instruction with 32-bit sign-extended immediate and thus
24376 ; the instruction size would at least double, which is not what we
24377 ; want even with ! optimize_size.
24378 (define_split
24379   [(set (match_operand 0 "flags_reg_operand")
24380         (match_operator 1 "compare_operator"
24381           [(and (match_operand:HI 2 "aligned_operand")
24382                 (match_operand:HI 3 "const_int_operand"))
24383            (const_int 0)]))]
24384   "! TARGET_PARTIAL_REG_STALL && reload_completed
24385    && ! TARGET_FAST_PREFIX
24386    && optimize_insn_for_speed_p ()
24387    /* Ensure that the operand will remain sign-extended immediate.  */
24388    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
24389   [(set (match_dup 0)
24390         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24391                          (const_int 0)]))]
24393   operands[3]
24394     = gen_int_mode (INTVAL (operands[3])
24395                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
24396   operands[2] = gen_lowpart (SImode, operands[2]);
24399 (define_split
24400   [(set (match_operand 0 "register_operand")
24401         (neg (match_operand 1 "register_operand")))
24402    (clobber (reg:CC FLAGS_REG))]
24403   "! TARGET_PARTIAL_REG_STALL && reload_completed
24404    && (GET_MODE (operands[0]) == HImode
24405        || (GET_MODE (operands[0]) == QImode
24406            && (TARGET_PROMOTE_QImode
24407                || optimize_insn_for_size_p ())))"
24408   [(parallel [(set (match_dup 0)
24409                    (neg:SI (match_dup 1)))
24410               (clobber (reg:CC FLAGS_REG))])]
24412   operands[0] = gen_lowpart (SImode, operands[0]);
24413   operands[1] = gen_lowpart (SImode, operands[1]);
24416 ;; Do not split instructions with mask regs.
24417 (define_split
24418   [(set (match_operand 0 "general_reg_operand")
24419         (not (match_operand 1 "general_reg_operand")))]
24420   "! TARGET_PARTIAL_REG_STALL && reload_completed
24421    && (GET_MODE (operands[0]) == HImode
24422        || (GET_MODE (operands[0]) == QImode
24423            && (TARGET_PROMOTE_QImode
24424                || optimize_insn_for_size_p ())))"
24425   [(set (match_dup 0)
24426         (not:SI (match_dup 1)))]
24428   operands[0] = gen_lowpart (SImode, operands[0]);
24429   operands[1] = gen_lowpart (SImode, operands[1]);
24432 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
24433 ;; transform a complex memory operation into two memory to register operations.
24435 ;; Don't push memory operands
24436 (define_peephole2
24437   [(set (match_operand:SWI 0 "push_operand")
24438         (match_operand:SWI 1 "memory_operand"))
24439    (match_scratch:SWI 2 "<r>")]
24440   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
24441    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
24442   [(set (match_dup 2) (match_dup 1))
24443    (set (match_dup 0) (match_dup 2))])
24445 ;; We need to handle SFmode only, because DFmode and XFmode are split to
24446 ;; SImode pushes.
24447 (define_peephole2
24448   [(set (match_operand:SF 0 "push_operand")
24449         (match_operand:SF 1 "memory_operand"))
24450    (match_scratch:SF 2 "r")]
24451   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
24452    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
24453   [(set (match_dup 2) (match_dup 1))
24454    (set (match_dup 0) (match_dup 2))])
24456 ;; Don't move an immediate directly to memory when the instruction
24457 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
24458 (define_peephole2
24459   [(match_scratch:SWI124 1 "<r>")
24460    (set (match_operand:SWI124 0 "memory_operand")
24461         (const_int 0))]
24462   "optimize_insn_for_speed_p ()
24463    && ((<MODE>mode == HImode
24464        && TARGET_LCP_STALL)
24465        || (!TARGET_USE_MOV0
24466           && TARGET_SPLIT_LONG_MOVES
24467           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
24468    && peep2_regno_dead_p (0, FLAGS_REG)"
24469   [(parallel [(set (match_dup 2) (const_int 0))
24470               (clobber (reg:CC FLAGS_REG))])
24471    (set (match_dup 0) (match_dup 1))]
24472   "operands[2] = gen_lowpart (SImode, operands[1]);")
24474 (define_peephole2
24475   [(match_scratch:SWI124 2 "<r>")
24476    (set (match_operand:SWI124 0 "memory_operand")
24477         (match_operand:SWI124 1 "immediate_operand"))]
24478   "optimize_insn_for_speed_p ()
24479    && ((<MODE>mode == HImode
24480        && TARGET_LCP_STALL)
24481        || (TARGET_SPLIT_LONG_MOVES
24482           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
24483   [(set (match_dup 2) (match_dup 1))
24484    (set (match_dup 0) (match_dup 2))])
24486 ;; Don't compare memory with zero, load and use a test instead.
24487 (define_peephole2
24488   [(set (match_operand 0 "flags_reg_operand")
24489         (match_operator 1 "compare_operator"
24490           [(match_operand:SI 2 "memory_operand")
24491            (const_int 0)]))
24492    (match_scratch:SI 3 "r")]
24493   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
24494   [(set (match_dup 3) (match_dup 2))
24495    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
24497 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
24498 ;; Don't split NOTs with a displacement operand, because resulting XOR
24499 ;; will not be pairable anyway.
24501 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
24502 ;; represented using a modRM byte.  The XOR replacement is long decoded,
24503 ;; so this split helps here as well.
24505 ;; Note: Can't do this as a regular split because we can't get proper
24506 ;; lifetime information then.
24508 (define_peephole2
24509   [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
24510         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
24511   "optimize_insn_for_speed_p ()
24512    && ((TARGET_NOT_UNPAIRABLE
24513         && (!MEM_P (operands[0])
24514             || !memory_displacement_operand (operands[0], <MODE>mode)))
24515        || (TARGET_NOT_VECTORMODE
24516            && long_memory_operand (operands[0], <MODE>mode)))
24517    && peep2_regno_dead_p (0, FLAGS_REG)"
24518   [(parallel [(set (match_dup 0)
24519                    (xor:SWI124 (match_dup 1) (const_int -1)))
24520               (clobber (reg:CC FLAGS_REG))])])
24522 ;; Non pairable "test imm, reg" instructions can be translated to
24523 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
24524 ;; byte opcode instead of two, have a short form for byte operands),
24525 ;; so do it for other CPUs as well.  Given that the value was dead,
24526 ;; this should not create any new dependencies.  Pass on the sub-word
24527 ;; versions if we're concerned about partial register stalls.
24529 (define_peephole2
24530   [(set (match_operand 0 "flags_reg_operand")
24531         (match_operator 1 "compare_operator"
24532           [(and:SI (match_operand:SI 2 "register_operand")
24533                    (match_operand:SI 3 "immediate_operand"))
24534            (const_int 0)]))]
24535   "ix86_match_ccmode (insn, CCNOmode)
24536    && (REGNO (operands[2]) != AX_REG
24537        || satisfies_constraint_K (operands[3]))
24538    && peep2_reg_dead_p (1, operands[2])"
24539   [(parallel
24540      [(set (match_dup 0)
24541            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24542                             (const_int 0)]))
24543       (set (match_dup 2)
24544            (and:SI (match_dup 2) (match_dup 3)))])])
24546 ;; We don't need to handle HImode case, because it will be promoted to SImode
24547 ;; on ! TARGET_PARTIAL_REG_STALL
24549 (define_peephole2
24550   [(set (match_operand 0 "flags_reg_operand")
24551         (match_operator 1 "compare_operator"
24552           [(and:QI (match_operand:QI 2 "register_operand")
24553                    (match_operand:QI 3 "immediate_operand"))
24554            (const_int 0)]))]
24555   "! TARGET_PARTIAL_REG_STALL
24556    && ix86_match_ccmode (insn, CCNOmode)
24557    && REGNO (operands[2]) != AX_REG
24558    && peep2_reg_dead_p (1, operands[2])"
24559   [(parallel
24560      [(set (match_dup 0)
24561            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
24562                             (const_int 0)]))
24563       (set (match_dup 2)
24564            (and:QI (match_dup 2) (match_dup 3)))])])
24566 (define_peephole2
24567   [(set (match_operand 0 "flags_reg_operand")
24568         (match_operator 1 "compare_operator"
24569           [(and:QI
24570              (subreg:QI
24571                (match_operator:SWI248 4 "extract_operator"
24572                  [(match_operand 2 "int248_register_operand")
24573                   (const_int 8)
24574                   (const_int 8)]) 0)
24575              (match_operand 3 "const_int_operand"))
24576            (const_int 0)]))]
24577   "! TARGET_PARTIAL_REG_STALL
24578    && ix86_match_ccmode (insn, CCNOmode)
24579    && REGNO (operands[2]) != AX_REG
24580    && peep2_reg_dead_p (1, operands[2])"
24581   [(parallel
24582      [(set (match_dup 0)
24583            (match_op_dup 1
24584              [(and:QI
24585                 (subreg:QI
24586                   (match_op_dup 4 [(match_dup 2)
24587                                    (const_int 8)
24588                                    (const_int 8)]) 0)
24589                 (match_dup 3))
24590               (const_int 0)]))
24591       (set (zero_extract:SWI248 (match_dup 2)
24592                                 (const_int 8)
24593                                 (const_int 8))
24594            (subreg:SWI248
24595              (and:QI
24596                (subreg:QI
24597                  (match_op_dup 4 [(match_dup 2)
24598                                   (const_int 8)
24599                                   (const_int 8)]) 0)
24600                (match_dup 3)) 0))])])
24602 ;; Don't do logical operations with memory inputs.
24603 (define_peephole2
24604   [(match_scratch:SWI 2 "<r>")
24605    (parallel [(set (match_operand:SWI 0 "register_operand")
24606                    (match_operator:SWI 3 "arith_or_logical_operator"
24607                      [(match_dup 0)
24608                       (match_operand:SWI 1 "memory_operand")]))
24609               (clobber (reg:CC FLAGS_REG))])]
24610   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24611   [(set (match_dup 2) (match_dup 1))
24612    (parallel [(set (match_dup 0)
24613                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
24614               (clobber (reg:CC FLAGS_REG))])])
24616 (define_peephole2
24617   [(match_scratch:SWI 2 "<r>")
24618    (parallel [(set (match_operand:SWI 0 "register_operand")
24619                    (match_operator:SWI 3 "arith_or_logical_operator"
24620                      [(match_operand:SWI 1 "memory_operand")
24621                       (match_dup 0)]))
24622               (clobber (reg:CC FLAGS_REG))])]
24623   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24624   [(set (match_dup 2) (match_dup 1))
24625    (parallel [(set (match_dup 0)
24626                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
24627               (clobber (reg:CC FLAGS_REG))])])
24629 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when
24630 ;; the memory address refers to the destination of the load!
24632 (define_peephole2
24633   [(set (match_operand:SWI 0 "general_reg_operand")
24634         (match_operand:SWI 1 "general_reg_operand"))
24635    (parallel [(set (match_dup 0)
24636                    (match_operator:SWI 3 "commutative_operator"
24637                      [(match_dup 0)
24638                       (match_operand:SWI 2 "memory_operand")]))
24639               (clobber (reg:CC FLAGS_REG))])]
24640   "REGNO (operands[0]) != REGNO (operands[1])
24641    && (<MODE>mode != QImode
24642        || any_QIreg_operand (operands[1], QImode))"
24643   [(set (match_dup 0) (match_dup 4))
24644    (parallel [(set (match_dup 0)
24645                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
24646               (clobber (reg:CC FLAGS_REG))])]
24648   operands[4]
24649     = ix86_replace_reg_with_reg (operands[2], operands[0], operands[1]);
24652 (define_peephole2
24653   [(set (match_operand 0 "mmx_reg_operand")
24654         (match_operand 1 "mmx_reg_operand"))
24655    (set (match_dup 0)
24656         (match_operator 3 "commutative_operator"
24657           [(match_dup 0)
24658            (match_operand 2 "memory_operand")]))]
24659   "REGNO (operands[0]) != REGNO (operands[1])"
24660   [(set (match_dup 0) (match_dup 2))
24661    (set (match_dup 0)
24662         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
24664 (define_peephole2
24665   [(set (match_operand 0 "sse_reg_operand")
24666         (match_operand 1 "sse_reg_operand"))
24667    (set (match_dup 0)
24668         (match_operator 3 "commutative_operator"
24669           [(match_dup 0)
24670            (match_operand 2 "memory_operand")]))]
24671   "REGNO (operands[0]) != REGNO (operands[1])
24672    /* Punt if operands[1] is %[xy]mm16+ and AVX512BW is not enabled,
24673       as EVEX encoded vpadd[bw], vpmullw, vpmin[su][bw] and vpmax[su][bw]
24674       instructions require AVX512BW and AVX512VL, but with the original
24675       instructions it might require just AVX512VL.
24676       AVX512VL is implied from TARGET_HARD_REGNO_MODE_OK.  */
24677    && (!EXT_REX_SSE_REGNO_P (REGNO (operands[1]))
24678        || TARGET_AVX512BW
24679        || GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (operands[0]))) > 2
24680        || logic_operator (operands[3], VOIDmode))"
24681   [(set (match_dup 0) (match_dup 2))
24682    (set (match_dup 0)
24683         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
24685 ; Don't do logical operations with memory outputs
24687 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
24688 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
24689 ; the same decoder scheduling characteristics as the original.
24691 (define_peephole2
24692   [(match_scratch:SWI 2 "<r>")
24693    (parallel [(set (match_operand:SWI 0 "memory_operand")
24694                    (match_operator:SWI 3 "arith_or_logical_operator"
24695                      [(match_dup 0)
24696                       (match_operand:SWI 1 "<nonmemory_operand>")]))
24697               (clobber (reg:CC FLAGS_REG))])]
24698   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
24699   [(set (match_dup 2) (match_dup 0))
24700    (parallel [(set (match_dup 2)
24701                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
24702               (clobber (reg:CC FLAGS_REG))])
24703    (set (match_dup 0) (match_dup 2))])
24705 (define_peephole2
24706   [(match_scratch:SWI 2 "<r>")
24707    (parallel [(set (match_operand:SWI 0 "memory_operand")
24708                    (match_operator:SWI 3 "arith_or_logical_operator"
24709                      [(match_operand:SWI 1 "<nonmemory_operand>")
24710                       (match_dup 0)]))
24711               (clobber (reg:CC FLAGS_REG))])]
24712   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
24713   [(set (match_dup 2) (match_dup 0))
24714    (parallel [(set (match_dup 2)
24715                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
24716               (clobber (reg:CC FLAGS_REG))])
24717    (set (match_dup 0) (match_dup 2))])
24719 ;; Attempt to use arith or logical operations with memory outputs with
24720 ;; setting of flags.
24721 (define_peephole2
24722   [(set (match_operand:SWI 0 "register_operand")
24723         (match_operand:SWI 1 "memory_operand"))
24724    (parallel [(set (match_dup 0)
24725                    (match_operator:SWI 3 "plusminuslogic_operator"
24726                      [(match_dup 0)
24727                       (match_operand:SWI 2 "<nonmemory_operand>")]))
24728               (clobber (reg:CC FLAGS_REG))])
24729    (set (match_dup 1) (match_dup 0))
24730    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24731   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24732    && peep2_reg_dead_p (4, operands[0])
24733    && !reg_overlap_mentioned_p (operands[0], operands[1])
24734    && !reg_overlap_mentioned_p (operands[0], operands[2])
24735    && (<MODE>mode != QImode
24736        || immediate_operand (operands[2], QImode)
24737        || any_QIreg_operand (operands[2], QImode))
24738    && ix86_match_ccmode (peep2_next_insn (3),
24739                          (GET_CODE (operands[3]) == PLUS
24740                           || GET_CODE (operands[3]) == MINUS)
24741                          ? CCGOCmode : CCNOmode)"
24742   [(parallel [(set (match_dup 4) (match_dup 6))
24743               (set (match_dup 1) (match_dup 5))])]
24745   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
24746   operands[5]
24747     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24748                       copy_rtx (operands[1]),
24749                       operands[2]);
24750   operands[6]
24751     = gen_rtx_COMPARE (GET_MODE (operands[4]),
24752                        copy_rtx (operands[5]),
24753                        const0_rtx);
24756 ;; Likewise for cmpelim optimized pattern.
24757 (define_peephole2
24758   [(set (match_operand:SWI 0 "register_operand")
24759         (match_operand:SWI 1 "memory_operand"))
24760    (parallel [(set (reg FLAGS_REG)
24761                    (compare (match_operator:SWI 3 "plusminuslogic_operator"
24762                               [(match_dup 0)
24763                                (match_operand:SWI 2 "<nonmemory_operand>")])
24764                             (const_int 0)))
24765               (set (match_dup 0) (match_dup 3))])
24766    (set (match_dup 1) (match_dup 0))]
24767   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24768    && peep2_reg_dead_p (3, operands[0])
24769    && !reg_overlap_mentioned_p (operands[0], operands[1])
24770    && !reg_overlap_mentioned_p (operands[0], operands[2])
24771    && ix86_match_ccmode (peep2_next_insn (1),
24772                          (GET_CODE (operands[3]) == PLUS
24773                           || GET_CODE (operands[3]) == MINUS)
24774                          ? CCGOCmode : CCNOmode)"
24775   [(parallel [(set (match_dup 4) (match_dup 6))
24776               (set (match_dup 1) (match_dup 5))])]
24778   operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
24779   operands[5]
24780     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24781                       copy_rtx (operands[1]), operands[2]);
24782   operands[6]
24783     = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
24784                        const0_rtx);
24787 ;; Likewise for instances where we have a lea pattern.
24788 (define_peephole2
24789   [(set (match_operand:SWI 0 "register_operand")
24790         (match_operand:SWI 1 "memory_operand"))
24791    (set (match_operand:<LEAMODE> 3 "register_operand")
24792         (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
24793                         (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
24794    (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
24795    (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
24796   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24797    && REGNO (operands[4]) == REGNO (operands[0])
24798    && REGNO (operands[5]) == REGNO (operands[3])
24799    && peep2_reg_dead_p (4, operands[3])
24800    && ((REGNO (operands[0]) == REGNO (operands[3]))
24801        || peep2_reg_dead_p (2, operands[0]))
24802    && !reg_overlap_mentioned_p (operands[0], operands[1])
24803    && !reg_overlap_mentioned_p (operands[3], operands[1])
24804    && !reg_overlap_mentioned_p (operands[0], operands[2])
24805    && (<MODE>mode != QImode
24806        || immediate_operand (operands[2], QImode)
24807        || any_QIreg_operand (operands[2], QImode))
24808    && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
24809   [(parallel [(set (match_dup 6) (match_dup 8))
24810               (set (match_dup 1) (match_dup 7))])]
24812   operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
24813   operands[7]
24814     = gen_rtx_PLUS (<MODE>mode,
24815                     copy_rtx (operands[1]),
24816                     gen_lowpart (<MODE>mode, operands[2]));
24817   operands[8]
24818     = gen_rtx_COMPARE (GET_MODE (operands[6]),
24819                        copy_rtx (operands[7]),
24820                        const0_rtx);
24823 (define_peephole2
24824   [(parallel [(set (match_operand:SWI 0 "register_operand")
24825                    (match_operator:SWI 2 "plusminuslogic_operator"
24826                      [(match_dup 0)
24827                       (match_operand:SWI 1 "memory_operand")]))
24828               (clobber (reg:CC FLAGS_REG))])
24829    (set (match_dup 1) (match_dup 0))
24830    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24831   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24832    && COMMUTATIVE_ARITH_P (operands[2])
24833    && peep2_reg_dead_p (3, operands[0])
24834    && !reg_overlap_mentioned_p (operands[0], operands[1])
24835    && ix86_match_ccmode (peep2_next_insn (2),
24836                          GET_CODE (operands[2]) == PLUS
24837                          ? CCGOCmode : CCNOmode)"
24838   [(parallel [(set (match_dup 3) (match_dup 5))
24839               (set (match_dup 1) (match_dup 4))])]
24841   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
24842   operands[4]
24843     = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
24844                       copy_rtx (operands[1]),
24845                       operands[0]);
24846   operands[5]
24847     = gen_rtx_COMPARE (GET_MODE (operands[3]),
24848                        copy_rtx (operands[4]),
24849                        const0_rtx);
24852 ;; Likewise for cmpelim optimized pattern.
24853 (define_peephole2
24854   [(parallel [(set (reg FLAGS_REG)
24855                    (compare (match_operator:SWI 2 "plusminuslogic_operator"
24856                               [(match_operand:SWI 0 "register_operand")
24857                                (match_operand:SWI 1 "memory_operand")])
24858                             (const_int 0)))
24859               (set (match_dup 0) (match_dup 2))])
24860    (set (match_dup 1) (match_dup 0))]
24861   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24862    && COMMUTATIVE_ARITH_P (operands[2])
24863    && peep2_reg_dead_p (2, operands[0])
24864    && !reg_overlap_mentioned_p (operands[0], operands[1])
24865    && ix86_match_ccmode (peep2_next_insn (0),
24866                          GET_CODE (operands[2]) == PLUS
24867                          ? CCGOCmode : CCNOmode)"
24868   [(parallel [(set (match_dup 3) (match_dup 5))
24869               (set (match_dup 1) (match_dup 4))])]
24871   operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
24872   operands[4]
24873     = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
24874                       copy_rtx (operands[1]), operands[0]);
24875   operands[5]
24876     = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
24877                        const0_rtx);
24880 (define_peephole2
24881   [(set (match_operand:SWI12 0 "register_operand")
24882         (match_operand:SWI12 1 "memory_operand"))
24883    (parallel [(set (match_operand:SI 4 "register_operand")
24884                    (match_operator:SI 3 "plusminuslogic_operator"
24885                      [(match_dup 4)
24886                       (match_operand:SI 2 "nonmemory_operand")]))
24887               (clobber (reg:CC FLAGS_REG))])
24888    (set (match_dup 1) (match_dup 0))
24889    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24890   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24891    && REGNO (operands[0]) == REGNO (operands[4])
24892    && peep2_reg_dead_p (4, operands[0])
24893    && (<MODE>mode != QImode
24894        || immediate_operand (operands[2], SImode)
24895        || any_QIreg_operand (operands[2], SImode))
24896    && !reg_overlap_mentioned_p (operands[0], operands[1])
24897    && !reg_overlap_mentioned_p (operands[0], operands[2])
24898    && ix86_match_ccmode (peep2_next_insn (3),
24899                          (GET_CODE (operands[3]) == PLUS
24900                           || GET_CODE (operands[3]) == MINUS)
24901                          ? CCGOCmode : CCNOmode)"
24902   [(parallel [(set (match_dup 5) (match_dup 7))
24903               (set (match_dup 1) (match_dup 6))])]
24905   operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
24906   operands[6]
24907     = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
24908                       copy_rtx (operands[1]),
24909                       gen_lowpart (<MODE>mode, operands[2]));
24910   operands[7]
24911     = gen_rtx_COMPARE (GET_MODE (operands[5]),
24912                        copy_rtx (operands[6]),
24913                        const0_rtx);
24916 ;; peephole2 comes before regcprop, so deal also with a case that
24917 ;; would be cleaned up by regcprop.
24918 (define_peephole2
24919   [(set (match_operand:SWI 0 "register_operand")
24920         (match_operand:SWI 1 "memory_operand"))
24921    (parallel [(set (match_dup 0)
24922                    (match_operator:SWI 3 "plusminuslogic_operator"
24923                      [(match_dup 0)
24924                       (match_operand:SWI 2 "<nonmemory_operand>")]))
24925               (clobber (reg:CC FLAGS_REG))])
24926    (set (match_operand:SWI 4 "register_operand") (match_dup 0))
24927    (set (match_dup 1) (match_dup 4))
24928    (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
24929   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24930    && peep2_reg_dead_p (3, operands[0])
24931    && peep2_reg_dead_p (5, operands[4])
24932    && !reg_overlap_mentioned_p (operands[0], operands[1])
24933    && !reg_overlap_mentioned_p (operands[0], operands[2])
24934    && !reg_overlap_mentioned_p (operands[4], operands[1])
24935    && (<MODE>mode != QImode
24936        || immediate_operand (operands[2], QImode)
24937        || any_QIreg_operand (operands[2], QImode))
24938    && ix86_match_ccmode (peep2_next_insn (4),
24939                          (GET_CODE (operands[3]) == PLUS
24940                           || GET_CODE (operands[3]) == MINUS)
24941                          ? CCGOCmode : CCNOmode)"
24942   [(parallel [(set (match_dup 5) (match_dup 7))
24943               (set (match_dup 1) (match_dup 6))])]
24945   operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
24946   operands[6]
24947     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24948                       copy_rtx (operands[1]),
24949                       operands[2]);
24950   operands[7]
24951     = gen_rtx_COMPARE (GET_MODE (operands[5]),
24952                        copy_rtx (operands[6]),
24953                        const0_rtx);
24956 (define_peephole2
24957   [(set (match_operand:SWI12 0 "register_operand")
24958         (match_operand:SWI12 1 "memory_operand"))
24959    (parallel [(set (match_operand:SI 4 "register_operand")
24960                    (match_operator:SI 3 "plusminuslogic_operator"
24961                      [(match_dup 4)
24962                       (match_operand:SI 2 "nonmemory_operand")]))
24963               (clobber (reg:CC FLAGS_REG))])
24964    (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
24965    (set (match_dup 1) (match_dup 5))
24966    (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
24967   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24968    && REGNO (operands[0]) == REGNO (operands[4])
24969    && peep2_reg_dead_p (3, operands[0])
24970    && peep2_reg_dead_p (5, operands[5])
24971    && (<MODE>mode != QImode
24972        || immediate_operand (operands[2], SImode)
24973        || any_QIreg_operand (operands[2], SImode))
24974    && !reg_overlap_mentioned_p (operands[0], operands[1])
24975    && !reg_overlap_mentioned_p (operands[0], operands[2])
24976    && !reg_overlap_mentioned_p (operands[5], operands[1])
24977    && ix86_match_ccmode (peep2_next_insn (4),
24978                          (GET_CODE (operands[3]) == PLUS
24979                           || GET_CODE (operands[3]) == MINUS)
24980                          ? CCGOCmode : CCNOmode)"
24981   [(parallel [(set (match_dup 6) (match_dup 8))
24982               (set (match_dup 1) (match_dup 7))])]
24984   operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
24985   operands[7]
24986     = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
24987                       copy_rtx (operands[1]),
24988                       gen_lowpart (<MODE>mode, operands[2]));
24989   operands[8]
24990     = gen_rtx_COMPARE (GET_MODE (operands[6]),
24991                        copy_rtx (operands[7]),
24992                        const0_rtx);
24995 ;; Likewise for cmpelim optimized pattern.
24996 (define_peephole2
24997   [(set (match_operand:SWI 0 "register_operand")
24998         (match_operand:SWI 1 "memory_operand"))
24999    (parallel [(set (reg FLAGS_REG)
25000                    (compare (match_operator:SWI 3 "plusminuslogic_operator"
25001                               [(match_dup 0)
25002                                (match_operand:SWI 2 "<nonmemory_operand>")])
25003                             (const_int 0)))
25004               (set (match_dup 0) (match_dup 3))])
25005    (set (match_operand:SWI 4 "register_operand") (match_dup 0))
25006    (set (match_dup 1) (match_dup 4))]
25007   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25008    && peep2_reg_dead_p (3, operands[0])
25009    && peep2_reg_dead_p (4, operands[4])
25010    && !reg_overlap_mentioned_p (operands[0], operands[1])
25011    && !reg_overlap_mentioned_p (operands[0], operands[2])
25012    && !reg_overlap_mentioned_p (operands[4], operands[1])
25013    && ix86_match_ccmode (peep2_next_insn (1),
25014                          (GET_CODE (operands[3]) == PLUS
25015                           || GET_CODE (operands[3]) == MINUS)
25016                          ? CCGOCmode : CCNOmode)"
25017   [(parallel [(set (match_dup 5) (match_dup 7))
25018               (set (match_dup 1) (match_dup 6))])]
25020   operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
25021   operands[6]
25022     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25023                       copy_rtx (operands[1]), operands[2]);
25024   operands[7]
25025     = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
25026                        const0_rtx);
25029 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
25030 ;; into x = z; x ^= y; x != z
25031 (define_peephole2
25032   [(set (match_operand:SWI 0 "register_operand")
25033         (match_operand:SWI 1 "memory_operand"))
25034    (set (match_operand:SWI 3 "register_operand") (match_dup 0))
25035    (parallel [(set (match_operand:SWI 4 "register_operand")
25036                    (xor:SWI (match_dup 4)
25037                             (match_operand:SWI 2 "<nonmemory_operand>")))
25038               (clobber (reg:CC FLAGS_REG))])
25039    (set (match_dup 1) (match_dup 4))
25040    (set (reg:CCZ FLAGS_REG)
25041         (compare:CCZ (match_operand:SWI 5 "register_operand")
25042                      (match_operand:SWI 6 "<nonmemory_operand>")))]
25043   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25044    && (REGNO (operands[4]) == REGNO (operands[0])
25045        || REGNO (operands[4]) == REGNO (operands[3]))
25046    && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
25047                              ? 3 : 0], operands[5])
25048        ? rtx_equal_p (operands[2], operands[6])
25049        : rtx_equal_p (operands[2], operands[5])
25050          && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
25051                                   ? 3 : 0], operands[6]))
25052    && peep2_reg_dead_p (4, operands[4])
25053    && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
25054                                     ? 3 : 0])
25055    && !reg_overlap_mentioned_p (operands[0], operands[1])
25056    && !reg_overlap_mentioned_p (operands[0], operands[2])
25057    && !reg_overlap_mentioned_p (operands[3], operands[0])
25058    && !reg_overlap_mentioned_p (operands[3], operands[1])
25059    && !reg_overlap_mentioned_p (operands[3], operands[2])
25060    && (<MODE>mode != QImode
25061        || immediate_operand (operands[2], QImode)
25062        || any_QIreg_operand (operands[2], QImode))"
25063   [(parallel [(set (match_dup 7) (match_dup 9))
25064               (set (match_dup 1) (match_dup 8))])]
25066   operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
25067   operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
25068                              operands[2]);
25069   operands[9]
25070     = gen_rtx_COMPARE (GET_MODE (operands[7]),
25071                        copy_rtx (operands[8]),
25072                        const0_rtx);
25075 (define_peephole2
25076   [(set (match_operand:SWI12 0 "register_operand")
25077         (match_operand:SWI12 1 "memory_operand"))
25078    (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
25079    (parallel [(set (match_operand:SI 4 "register_operand")
25080                    (xor:SI (match_dup 4)
25081                            (match_operand:SI 2 "<nonmemory_operand>")))
25082               (clobber (reg:CC FLAGS_REG))])
25083    (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
25084    (set (reg:CCZ FLAGS_REG)
25085         (compare:CCZ (match_operand:SWI12 6 "register_operand")
25086                      (match_operand:SWI12 7 "<nonmemory_operand>")))]
25087   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25088    && (REGNO (operands[5]) == REGNO (operands[0])
25089        || REGNO (operands[5]) == REGNO (operands[3]))
25090    && REGNO (operands[5]) == REGNO (operands[4])
25091    && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
25092                              ? 3 : 0], operands[6])
25093        ? (REG_P (operands[2])
25094           ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
25095           : rtx_equal_p (operands[2], operands[7]))
25096        : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
25097                                 ? 3 : 0], operands[7])
25098           && REG_P (operands[2])
25099           && REGNO (operands[2]) == REGNO (operands[6])))
25100    && peep2_reg_dead_p (4, operands[5])
25101    && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
25102                                     ? 3 : 0])
25103    && !reg_overlap_mentioned_p (operands[0], operands[1])
25104    && !reg_overlap_mentioned_p (operands[0], operands[2])
25105    && !reg_overlap_mentioned_p (operands[3], operands[0])
25106    && !reg_overlap_mentioned_p (operands[3], operands[1])
25107    && !reg_overlap_mentioned_p (operands[3], operands[2])
25108    && (<MODE>mode != QImode
25109        || immediate_operand (operands[2], SImode)
25110        || any_QIreg_operand (operands[2], SImode))"
25111   [(parallel [(set (match_dup 8) (match_dup 10))
25112               (set (match_dup 1) (match_dup 9))])]
25114   operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
25115   operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
25116                              gen_lowpart (<MODE>mode, operands[2]));
25117   operands[10]
25118     = gen_rtx_COMPARE (GET_MODE (operands[8]),
25119                        copy_rtx (operands[9]),
25120                        const0_rtx);
25123 ;; Attempt to optimize away memory stores of values the memory already
25124 ;; has.  See PR79593.
25125 (define_peephole2
25126   [(set (match_operand 0 "register_operand")
25127         (match_operand 1 "memory_operand"))
25128    (set (match_operand 2 "memory_operand") (match_dup 0))]
25129   "!MEM_VOLATILE_P (operands[1])
25130    && !MEM_VOLATILE_P (operands[2])
25131    && rtx_equal_p (operands[1], operands[2])
25132    && !reg_overlap_mentioned_p (operands[0], operands[2])"
25133   [(set (match_dup 0) (match_dup 1))])
25135 ;; Attempt to always use XOR for zeroing registers (including FP modes).
25136 (define_peephole2
25137   [(set (match_operand 0 "general_reg_operand")
25138         (match_operand 1 "const0_operand"))]
25139   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
25140    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
25141    && peep2_regno_dead_p (0, FLAGS_REG)"
25142   [(parallel [(set (match_dup 0) (const_int 0))
25143               (clobber (reg:CC FLAGS_REG))])]
25144   "operands[0] = gen_lowpart (word_mode, operands[0]);")
25146 (define_peephole2
25147   [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
25148         (const_int 0))]
25149   "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
25150    && peep2_regno_dead_p (0, FLAGS_REG)"
25151   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
25152               (clobber (reg:CC FLAGS_REG))])])
25154 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
25155 (define_peephole2
25156   [(set (match_operand:SWI248 0 "general_reg_operand")
25157         (const_int -1))]
25158   "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
25159    && peep2_regno_dead_p (0, FLAGS_REG)"
25160   [(parallel [(set (match_dup 0) (const_int -1))
25161               (clobber (reg:CC FLAGS_REG))])]
25163   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
25164     operands[0] = gen_lowpart (SImode, operands[0]);
25167 ;; Attempt to convert simple lea to add/shift.
25168 ;; These can be created by move expanders.
25169 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
25170 ;; relevant lea instructions were already split.
25172 (define_peephole2
25173   [(set (match_operand:SWI48 0 "register_operand")
25174         (plus:SWI48 (match_dup 0)
25175                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
25176   "!TARGET_OPT_AGU
25177    && peep2_regno_dead_p (0, FLAGS_REG)"
25178   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
25179               (clobber (reg:CC FLAGS_REG))])])
25181 (define_peephole2
25182   [(set (match_operand:SWI48 0 "register_operand")
25183         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
25184                     (match_dup 0)))]
25185   "!TARGET_OPT_AGU
25186    && peep2_regno_dead_p (0, FLAGS_REG)"
25187   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
25188               (clobber (reg:CC FLAGS_REG))])])
25190 (define_peephole2
25191   [(set (match_operand:DI 0 "register_operand")
25192         (zero_extend:DI
25193           (plus:SI (match_operand:SI 1 "register_operand")
25194                    (match_operand:SI 2 "nonmemory_operand"))))]
25195   "TARGET_64BIT && !TARGET_OPT_AGU
25196    && REGNO (operands[0]) == REGNO (operands[1])
25197    && peep2_regno_dead_p (0, FLAGS_REG)"
25198   [(parallel [(set (match_dup 0)
25199                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
25200               (clobber (reg:CC FLAGS_REG))])])
25202 (define_peephole2
25203   [(set (match_operand:DI 0 "register_operand")
25204         (zero_extend:DI
25205           (plus:SI (match_operand:SI 1 "nonmemory_operand")
25206                    (match_operand:SI 2 "register_operand"))))]
25207   "TARGET_64BIT && !TARGET_OPT_AGU
25208    && REGNO (operands[0]) == REGNO (operands[2])
25209    && peep2_regno_dead_p (0, FLAGS_REG)"
25210   [(parallel [(set (match_dup 0)
25211                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
25212               (clobber (reg:CC FLAGS_REG))])])
25214 (define_peephole2
25215   [(set (match_operand:SWI48 0 "register_operand")
25216         (mult:SWI48 (match_dup 0)
25217                     (match_operand:SWI48 1 "const_int_operand")))]
25218   "pow2p_hwi (INTVAL (operands[1]))
25219    && peep2_regno_dead_p (0, FLAGS_REG)"
25220   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
25221               (clobber (reg:CC FLAGS_REG))])]
25222   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
25224 (define_peephole2
25225   [(set (match_operand:DI 0 "register_operand")
25226         (zero_extend:DI
25227           (mult:SI (match_operand:SI 1 "register_operand")
25228                    (match_operand:SI 2 "const_int_operand"))))]
25229   "TARGET_64BIT
25230    && pow2p_hwi (INTVAL (operands[2]))
25231    && REGNO (operands[0]) == REGNO (operands[1])
25232    && peep2_regno_dead_p (0, FLAGS_REG)"
25233   [(parallel [(set (match_dup 0)
25234                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
25235               (clobber (reg:CC FLAGS_REG))])]
25236   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
25238 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
25239 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
25240 ;; On many CPUs it is also faster, since special hardware to avoid esp
25241 ;; dependencies is present.
25243 ;; While some of these conversions may be done using splitters, we use
25244 ;; peepholes in order to allow combine_stack_adjustments pass to see
25245 ;; nonobfuscated RTL.
25247 ;; Convert prologue esp subtractions to push.
25248 ;; We need register to push.  In order to keep verify_flow_info happy we have
25249 ;; two choices
25250 ;; - use scratch and clobber it in order to avoid dependencies
25251 ;; - use already live register
25252 ;; We can't use the second way right now, since there is no reliable way how to
25253 ;; verify that given register is live.  First choice will also most likely in
25254 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
25255 ;; call clobbered registers are dead.  We may want to use base pointer as an
25256 ;; alternative when no register is available later.
25258 (define_peephole2
25259   [(match_scratch:W 1 "r")
25260    (parallel [(set (reg:P SP_REG)
25261                    (plus:P (reg:P SP_REG)
25262                            (match_operand:P 0 "const_int_operand")))
25263               (clobber (reg:CC FLAGS_REG))
25264               (clobber (mem:BLK (scratch)))])]
25265   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
25266    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
25267    && !ix86_red_zone_used"
25268   [(clobber (match_dup 1))
25269    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25270               (clobber (mem:BLK (scratch)))])])
25272 (define_peephole2
25273   [(match_scratch:W 1 "r")
25274    (parallel [(set (reg:P SP_REG)
25275                    (plus:P (reg:P SP_REG)
25276                            (match_operand:P 0 "const_int_operand")))
25277               (clobber (reg:CC FLAGS_REG))
25278               (clobber (mem:BLK (scratch)))])]
25279   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
25280    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
25281    && !ix86_red_zone_used"
25282   [(clobber (match_dup 1))
25283    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25284    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25285               (clobber (mem:BLK (scratch)))])])
25287 ;; Convert esp subtractions to push.
25288 (define_peephole2
25289   [(match_scratch:W 1 "r")
25290    (parallel [(set (reg:P SP_REG)
25291                    (plus:P (reg:P SP_REG)
25292                            (match_operand:P 0 "const_int_operand")))
25293               (clobber (reg:CC FLAGS_REG))])]
25294   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
25295    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
25296    && !ix86_red_zone_used"
25297   [(clobber (match_dup 1))
25298    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
25300 (define_peephole2
25301   [(match_scratch:W 1 "r")
25302    (parallel [(set (reg:P SP_REG)
25303                    (plus:P (reg:P SP_REG)
25304                            (match_operand:P 0 "const_int_operand")))
25305               (clobber (reg:CC FLAGS_REG))])]
25306   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
25307    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
25308    && !ix86_red_zone_used"
25309   [(clobber (match_dup 1))
25310    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25311    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
25313 ;; Convert epilogue deallocator to pop.
25314 (define_peephole2
25315   [(match_scratch:W 1 "r")
25316    (parallel [(set (reg:P SP_REG)
25317                    (plus:P (reg:P SP_REG)
25318                            (match_operand:P 0 "const_int_operand")))
25319               (clobber (reg:CC FLAGS_REG))
25320               (clobber (mem:BLK (scratch)))])]
25321   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
25322    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
25323   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25324               (clobber (mem:BLK (scratch)))])])
25326 ;; Two pops case is tricky, since pop causes dependency
25327 ;; on destination register.  We use two registers if available.
25328 (define_peephole2
25329   [(match_scratch:W 1 "r")
25330    (match_scratch:W 2 "r")
25331    (parallel [(set (reg:P SP_REG)
25332                    (plus:P (reg:P SP_REG)
25333                            (match_operand:P 0 "const_int_operand")))
25334               (clobber (reg:CC FLAGS_REG))
25335               (clobber (mem:BLK (scratch)))])]
25336   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
25337    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25338   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25339               (clobber (mem:BLK (scratch)))])
25340    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
25342 (define_peephole2
25343   [(match_scratch:W 1 "r")
25344    (parallel [(set (reg:P SP_REG)
25345                    (plus:P (reg:P SP_REG)
25346                            (match_operand:P 0 "const_int_operand")))
25347               (clobber (reg:CC FLAGS_REG))
25348               (clobber (mem:BLK (scratch)))])]
25349   "optimize_insn_for_size_p ()
25350    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25351   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25352               (clobber (mem:BLK (scratch)))])
25353    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25355 ;; Convert esp additions to pop.
25356 (define_peephole2
25357   [(match_scratch:W 1 "r")
25358    (parallel [(set (reg:P SP_REG)
25359                    (plus:P (reg:P SP_REG)
25360                            (match_operand:P 0 "const_int_operand")))
25361               (clobber (reg:CC FLAGS_REG))])]
25362   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
25363   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25365 ;; Two pops case is tricky, since pop causes dependency
25366 ;; on destination register.  We use two registers if available.
25367 (define_peephole2
25368   [(match_scratch:W 1 "r")
25369    (match_scratch:W 2 "r")
25370    (parallel [(set (reg:P SP_REG)
25371                    (plus:P (reg:P SP_REG)
25372                            (match_operand:P 0 "const_int_operand")))
25373               (clobber (reg:CC FLAGS_REG))])]
25374   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25375   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25376    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
25378 (define_peephole2
25379   [(match_scratch:W 1 "r")
25380    (parallel [(set (reg:P SP_REG)
25381                    (plus:P (reg:P SP_REG)
25382                            (match_operand:P 0 "const_int_operand")))
25383               (clobber (reg:CC FLAGS_REG))])]
25384   "optimize_insn_for_size_p ()
25385    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25386   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25387    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25389 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
25390 ;; required and register dies.  Similarly for 128 to -128.
25391 (define_peephole2
25392   [(set (match_operand 0 "flags_reg_operand")
25393         (match_operator 1 "compare_operator"
25394           [(match_operand 2 "register_operand")
25395            (match_operand 3 "const_int_operand")]))]
25396   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
25397      && incdec_operand (operands[3], GET_MODE (operands[3])))
25398     || (!TARGET_FUSE_CMP_AND_BRANCH
25399         && INTVAL (operands[3]) == 128))
25400    && ix86_match_ccmode (insn, CCGCmode)
25401    && peep2_reg_dead_p (1, operands[2])"
25402   [(parallel [(set (match_dup 0)
25403                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
25404               (clobber (match_dup 2))])])
25406 ;; Convert imul by three, five and nine into lea
25407 (define_peephole2
25408   [(parallel
25409     [(set (match_operand:SWI48 0 "register_operand")
25410           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
25411                       (match_operand:SWI48 2 "const359_operand")))
25412      (clobber (reg:CC FLAGS_REG))])]
25413   "!TARGET_PARTIAL_REG_STALL
25414    || <MODE>mode == SImode
25415    || optimize_function_for_size_p (cfun)"
25416   [(set (match_dup 0)
25417         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
25418                     (match_dup 1)))]
25419   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
25421 (define_peephole2
25422   [(parallel
25423     [(set (match_operand:SWI48 0 "register_operand")
25424           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
25425                       (match_operand:SWI48 2 "const359_operand")))
25426      (clobber (reg:CC FLAGS_REG))])]
25427   "optimize_insn_for_speed_p ()
25428    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
25429   [(set (match_dup 0) (match_dup 1))
25430    (set (match_dup 0)
25431         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
25432                     (match_dup 0)))]
25433   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
25435 ;; imul $32bit_imm, mem, reg is vector decoded, while
25436 ;; imul $32bit_imm, reg, reg is direct decoded.
25437 (define_peephole2
25438   [(match_scratch:SWI48 3 "r")
25439    (parallel [(set (match_operand:SWI48 0 "register_operand")
25440                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
25441                                (match_operand:SWI48 2 "immediate_operand")))
25442               (clobber (reg:CC FLAGS_REG))])]
25443   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25444    && !satisfies_constraint_K (operands[2])"
25445   [(set (match_dup 3) (match_dup 1))
25446    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
25447               (clobber (reg:CC FLAGS_REG))])])
25449 (define_peephole2
25450   [(match_scratch:SI 3 "r")
25451    (parallel [(set (match_operand:DI 0 "register_operand")
25452                    (zero_extend:DI
25453                      (mult:SI (match_operand:SI 1 "memory_operand")
25454                               (match_operand:SI 2 "immediate_operand"))))
25455               (clobber (reg:CC FLAGS_REG))])]
25456   "TARGET_64BIT
25457    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25458    && !satisfies_constraint_K (operands[2])"
25459   [(set (match_dup 3) (match_dup 1))
25460    (parallel [(set (match_dup 0)
25461                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
25462               (clobber (reg:CC FLAGS_REG))])])
25464 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
25465 ;; Convert it into imul reg, reg
25466 ;; It would be better to force assembler to encode instruction using long
25467 ;; immediate, but there is apparently no way to do so.
25468 (define_peephole2
25469   [(parallel [(set (match_operand:SWI248 0 "register_operand")
25470                    (mult:SWI248
25471                     (match_operand:SWI248 1 "nonimmediate_operand")
25472                     (match_operand:SWI248 2 "const_int_operand")))
25473               (clobber (reg:CC FLAGS_REG))])
25474    (match_scratch:SWI248 3 "r")]
25475   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
25476    && satisfies_constraint_K (operands[2])"
25477   [(set (match_dup 3) (match_dup 2))
25478    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
25479               (clobber (reg:CC FLAGS_REG))])]
25481   if (!rtx_equal_p (operands[0], operands[1]))
25482     emit_move_insn (operands[0], operands[1]);
25485 ;; After splitting up read-modify operations, array accesses with memory
25486 ;; operands might end up in form:
25487 ;;  sall    $2, %eax
25488 ;;  movl    4(%esp), %edx
25489 ;;  addl    %edx, %eax
25490 ;; instead of pre-splitting:
25491 ;;  sall    $2, %eax
25492 ;;  addl    4(%esp), %eax
25493 ;; Turn it into:
25494 ;;  movl    4(%esp), %edx
25495 ;;  leal    (%edx,%eax,4), %eax
25497 (define_peephole2
25498   [(match_scratch:W 5 "r")
25499    (parallel [(set (match_operand 0 "register_operand")
25500                    (ashift (match_operand 1 "register_operand")
25501                            (match_operand 2 "const_int_operand")))
25502                (clobber (reg:CC FLAGS_REG))])
25503    (parallel [(set (match_operand 3 "register_operand")
25504                    (plus (match_dup 0)
25505                          (match_operand 4 "x86_64_general_operand")))
25506                    (clobber (reg:CC FLAGS_REG))])]
25507   "IN_RANGE (INTVAL (operands[2]), 1, 3)
25508    /* Validate MODE for lea.  */
25509    && ((!TARGET_PARTIAL_REG_STALL
25510         && (GET_MODE (operands[0]) == QImode
25511             || GET_MODE (operands[0]) == HImode))
25512        || GET_MODE (operands[0]) == SImode
25513        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
25514    && (rtx_equal_p (operands[0], operands[3])
25515        || peep2_reg_dead_p (2, operands[0]))
25516    /* We reorder load and the shift.  */
25517    && !reg_overlap_mentioned_p (operands[0], operands[4])"
25518   [(set (match_dup 5) (match_dup 4))
25519    (set (match_dup 0) (match_dup 1))]
25521   machine_mode op1mode = GET_MODE (operands[1]);
25522   machine_mode mode = op1mode == DImode ? DImode : SImode;
25523   int scale = 1 << INTVAL (operands[2]);
25524   rtx index = gen_lowpart (word_mode, operands[1]);
25525   rtx base = gen_lowpart (word_mode, operands[5]);
25526   rtx dest = gen_lowpart (mode, operands[3]);
25528   operands[1] = gen_rtx_PLUS (word_mode, base,
25529                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
25530   if (mode != word_mode)
25531     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
25533   operands[5] = base;
25534   if (op1mode != word_mode)
25535     operands[5] = gen_lowpart (op1mode, operands[5]);
25537   operands[0] = dest;
25540 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
25541 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
25542 ;; caught for use by garbage collectors and the like.  Using an insn that
25543 ;; maps to SIGILL makes it more likely the program will rightfully die.
25544 ;; Keeping with tradition, "6" is in honor of #UD.
25545 (define_insn "trap"
25546   [(trap_if (const_int 1) (const_int 6))]
25547   ""
25549 #ifdef HAVE_AS_IX86_UD2
25550   return "ud2";
25551 #else
25552   return ASM_SHORT "0x0b0f";
25553 #endif
25555   [(set_attr "length" "2")])
25557 (define_insn "ud2"
25558   [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
25559   ""
25561 #ifdef HAVE_AS_IX86_UD2
25562   return "ud2";
25563 #else
25564   return ASM_SHORT "0x0b0f";
25565 #endif
25567   [(set_attr "length" "2")])
25569 (define_expand "prefetch"
25570   [(prefetch (match_operand 0 "address_operand")
25571              (match_operand:SI 1 "const_int_operand")
25572              (match_operand:SI 2 "const_int_operand"))]
25573   "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25575   bool write = operands[1] != const0_rtx;
25576   int locality = INTVAL (operands[2]);
25578   gcc_assert (IN_RANGE (locality, 0, 3));
25580   /* Use 3dNOW prefetch in case we are asking for write prefetch not
25581      supported by SSE counterpart (non-SSE2 athlon machines) or the
25582      SSE prefetch is not available (K6 machines).  Otherwise use SSE
25583      prefetch as it allows specifying of locality.  */
25585   if (write)
25586     {
25587       if (TARGET_PREFETCHWT1)
25588         operands[2] = GEN_INT (MAX (locality, 2)); 
25589       else if (TARGET_PRFCHW)
25590         operands[2] = GEN_INT (3);
25591       else if (TARGET_3DNOW && !TARGET_SSE2)
25592         operands[2] = GEN_INT (3);
25593       else if (TARGET_PREFETCH_SSE)
25594         operands[1] = const0_rtx;
25595       else
25596         {
25597           gcc_assert (TARGET_3DNOW);
25598           operands[2] = GEN_INT (3);
25599         }
25600     }
25601   else
25602     {
25603       if (TARGET_PREFETCH_SSE)
25604         ;
25605       else
25606         {
25607           gcc_assert (TARGET_3DNOW);
25608           operands[2] = GEN_INT (3);
25609         }
25610     }
25613 (define_insn "*prefetch_sse"
25614   [(prefetch (match_operand 0 "address_operand" "p")
25615              (const_int 0)
25616              (match_operand:SI 1 "const_int_operand"))]
25617   "TARGET_PREFETCH_SSE"
25619   static const char * const patterns[4] = {
25620    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
25621   };
25623   int locality = INTVAL (operands[1]);
25624   gcc_assert (IN_RANGE (locality, 0, 3));
25626   return patterns[locality];
25628   [(set_attr "type" "sse")
25629    (set_attr "atom_sse_attr" "prefetch")
25630    (set (attr "length_address")
25631         (symbol_ref "memory_address_length (operands[0], false)"))
25632    (set_attr "memory" "none")])
25634 (define_insn "*prefetch_3dnow"
25635   [(prefetch (match_operand 0 "address_operand" "p")
25636              (match_operand:SI 1 "const_int_operand")
25637              (const_int 3))]
25638   "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25640   if (operands[1] == const0_rtx)
25641     return "prefetch\t%a0";
25642   else
25643     return "prefetchw\t%a0";
25645   [(set_attr "type" "mmx")
25646    (set (attr "length_address")
25647         (symbol_ref "memory_address_length (operands[0], false)"))
25648    (set_attr "memory" "none")])
25650 (define_insn "*prefetch_prefetchwt1"
25651   [(prefetch (match_operand 0 "address_operand" "p")
25652              (const_int 1)
25653              (const_int 2))]
25654   "TARGET_PREFETCHWT1"
25655   "prefetchwt1\t%a0";
25656   [(set_attr "type" "sse")
25657    (set (attr "length_address")
25658         (symbol_ref "memory_address_length (operands[0], false)"))
25659    (set_attr "memory" "none")])
25661 (define_insn "prefetchi"
25662   [(unspec_volatile [(match_operand 0 "local_func_symbolic_operand" "p")
25663                      (match_operand:SI 1 "const_int_operand")]
25664                     UNSPECV_PREFETCHI)]
25665   "TARGET_PREFETCHI && TARGET_64BIT"
25667   static const char * const patterns[2] = {
25668     "prefetchit1\t%0", "prefetchit0\t%0"
25669   };
25671   int locality = INTVAL (operands[1]);
25672   gcc_assert (IN_RANGE (locality, 2, 3));
25674   return patterns[locality - 2];
25676   [(set_attr "type" "sse")
25677    (set (attr "length_address")
25678         (symbol_ref "memory_address_length (operands[0], false)"))
25679    (set_attr "memory" "none")])
25681 (define_insn "sse4_2_crc32<mode>"
25682   [(set (match_operand:SI 0 "register_operand" "=r")
25683         (unspec:SI
25684           [(match_operand:SI 1 "register_operand" "0")
25685            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
25686           UNSPEC_CRC32))]
25687   "TARGET_CRC32"
25688   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
25689   [(set_attr "type" "sselog1")
25690    (set_attr "prefix_rep" "1")
25691    (set_attr "prefix_extra" "1")
25692    (set (attr "prefix_data16")
25693      (if_then_else (match_operand:HI 2)
25694        (const_string "1")
25695        (const_string "*")))
25696    (set (attr "prefix_rex")
25697      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
25698        (const_string "1")
25699        (const_string "*")))
25700    (set_attr "mode" "SI")])
25702 (define_insn "sse4_2_crc32di"
25703   [(set (match_operand:DI 0 "register_operand" "=r")
25704         (zero_extend:DI
25705           (unspec:SI
25706             [(match_operand:SI 1 "register_operand" "0")
25707              (match_operand:DI 2 "nonimmediate_operand" "rm")]
25708           UNSPEC_CRC32)))]
25709   "TARGET_64BIT && TARGET_CRC32"
25710   "crc32{q}\t{%2, %0|%0, %2}"
25711   [(set_attr "type" "sselog1")
25712    (set_attr "prefix_rep" "1")
25713    (set_attr "prefix_extra" "1")
25714    (set_attr "mode" "DI")])
25716 (define_insn "rdpmc"
25717   [(set (match_operand:DI 0 "register_operand" "=A")
25718         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
25719                             UNSPECV_RDPMC))]
25720   "!TARGET_64BIT"
25721   "rdpmc"
25722   [(set_attr "type" "other")
25723    (set_attr "length" "2")])
25725 (define_insn "rdpmc_rex64"
25726   [(set (match_operand:DI 0 "register_operand" "=a")
25727         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
25728                             UNSPECV_RDPMC))
25729    (set (match_operand:DI 1 "register_operand" "=d")
25730         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
25731   "TARGET_64BIT"
25732   "rdpmc"
25733   [(set_attr "type" "other")
25734    (set_attr "length" "2")])
25736 (define_insn "rdtsc"
25737   [(set (match_operand:DI 0 "register_operand" "=A")
25738         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
25739   "!TARGET_64BIT"
25740   "rdtsc"
25741   [(set_attr "type" "other")
25742    (set_attr "length" "2")])
25744 (define_insn "rdtsc_rex64"
25745   [(set (match_operand:DI 0 "register_operand" "=a")
25746         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
25747    (set (match_operand:DI 1 "register_operand" "=d")
25748         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
25749   "TARGET_64BIT"
25750   "rdtsc"
25751   [(set_attr "type" "other")
25752    (set_attr "length" "2")])
25754 (define_insn "rdtscp"
25755   [(set (match_operand:DI 0 "register_operand" "=A")
25756         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25757    (set (match_operand:SI 1 "register_operand" "=c")
25758         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
25759   "!TARGET_64BIT"
25760   "rdtscp"
25761   [(set_attr "type" "other")
25762    (set_attr "length" "3")])
25764 (define_insn "rdtscp_rex64"
25765   [(set (match_operand:DI 0 "register_operand" "=a")
25766         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25767    (set (match_operand:DI 1 "register_operand" "=d")
25768         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25769    (set (match_operand:SI 2 "register_operand" "=c")
25770         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
25771   "TARGET_64BIT"
25772   "rdtscp"
25773   [(set_attr "type" "other")
25774    (set_attr "length" "3")])
25776 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25778 ;; FXSR, XSAVE and XSAVEOPT instructions
25780 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25782 (define_insn "fxsave"
25783   [(set (match_operand:BLK 0 "memory_operand" "=m")
25784         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
25785   "TARGET_FXSR"
25786   "fxsave\t%0"
25787   [(set_attr "type" "other")
25788    (set_attr "memory" "store")
25789    (set (attr "length")
25790         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25792 (define_insn "fxsave64"
25793   [(set (match_operand:BLK 0 "memory_operand" "=jm")
25794         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
25795   "TARGET_64BIT && TARGET_FXSR"
25796   "fxsave64\t%0"
25797   [(set_attr "type" "other")
25798    (set_attr "addr" "gpr16")
25799    (set_attr "memory" "store")
25800    (set (attr "length")
25801         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25803 (define_insn "fxrstor"
25804   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
25805                     UNSPECV_FXRSTOR)]
25806   "TARGET_FXSR"
25807   "fxrstor\t%0"
25808   [(set_attr "type" "other")
25809    (set_attr "memory" "load")
25810    (set (attr "length")
25811         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25813 (define_insn "fxrstor64"
25814   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "jm")]
25815                     UNSPECV_FXRSTOR64)]
25816   "TARGET_64BIT && TARGET_FXSR"
25817   "fxrstor64\t%0"
25818   [(set_attr "type" "other")
25819    (set_attr "addr" "gpr16")
25820    (set_attr "memory" "load")
25821    (set (attr "length")
25822         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25824 (define_int_iterator ANY_XSAVE
25825         [UNSPECV_XSAVE
25826          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
25827          (UNSPECV_XSAVEC "TARGET_XSAVEC")
25828          (UNSPECV_XSAVES "TARGET_XSAVES")])
25830 (define_int_iterator ANY_XSAVE64
25831         [UNSPECV_XSAVE64
25832          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
25833          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
25834          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
25836 (define_int_attr xsave
25837         [(UNSPECV_XSAVE "xsave")
25838          (UNSPECV_XSAVE64 "xsave64")
25839          (UNSPECV_XSAVEOPT "xsaveopt")
25840          (UNSPECV_XSAVEOPT64 "xsaveopt64")
25841          (UNSPECV_XSAVEC "xsavec")
25842          (UNSPECV_XSAVEC64 "xsavec64")
25843          (UNSPECV_XSAVES "xsaves")
25844          (UNSPECV_XSAVES64 "xsaves64")])
25846 (define_int_iterator ANY_XRSTOR
25847         [UNSPECV_XRSTOR
25848          (UNSPECV_XRSTORS "TARGET_XSAVES")])
25850 (define_int_iterator ANY_XRSTOR64
25851         [UNSPECV_XRSTOR64
25852          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
25854 (define_int_attr xrstor
25855         [(UNSPECV_XRSTOR "xrstor")
25856          (UNSPECV_XRSTOR64 "xrstor")
25857          (UNSPECV_XRSTORS "xrstors")
25858          (UNSPECV_XRSTORS64 "xrstors")])
25860 (define_insn "<xsave>"
25861   [(set (match_operand:BLK 0 "memory_operand" "=m")
25862         (unspec_volatile:BLK
25863          [(match_operand:DI 1 "register_operand" "A")]
25864          ANY_XSAVE))]
25865   "!TARGET_64BIT && TARGET_XSAVE"
25866   "<xsave>\t%0"
25867   [(set_attr "type" "other")
25868    (set_attr "memory" "store")
25869    (set (attr "length")
25870         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25872 (define_insn "<xsave>_rex64"
25873   [(set (match_operand:BLK 0 "memory_operand" "=jm")
25874         (unspec_volatile:BLK
25875          [(match_operand:SI 1 "register_operand" "a")
25876           (match_operand:SI 2 "register_operand" "d")]
25877          ANY_XSAVE))]
25878   "TARGET_64BIT && TARGET_XSAVE"
25879   "<xsave>\t%0"
25880   [(set_attr "type" "other")
25881    (set_attr "memory" "store")
25882    (set_attr "addr" "gpr16")
25883    (set (attr "length")
25884         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25886 (define_insn "<xsave>"
25887   [(set (match_operand:BLK 0 "memory_operand" "=jm")
25888         (unspec_volatile:BLK
25889          [(match_operand:SI 1 "register_operand" "a")
25890           (match_operand:SI 2 "register_operand" "d")]
25891          ANY_XSAVE64))]
25892   "TARGET_64BIT && TARGET_XSAVE"
25893   "<xsave>\t%0"
25894   [(set_attr "type" "other")
25895    (set_attr "memory" "store")
25896    (set_attr "addr" "gpr16")
25897    (set (attr "length")
25898         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25900 (define_insn "<xrstor>"
25901    [(unspec_volatile:BLK
25902      [(match_operand:BLK 0 "memory_operand" "m")
25903       (match_operand:DI 1 "register_operand" "A")]
25904      ANY_XRSTOR)]
25905   "!TARGET_64BIT && TARGET_XSAVE"
25906   "<xrstor>\t%0"
25907   [(set_attr "type" "other")
25908    (set_attr "memory" "load")
25909    (set (attr "length")
25910         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25912 (define_insn "<xrstor>_rex64"
25913    [(unspec_volatile:BLK
25914      [(match_operand:BLK 0 "memory_operand" "jm")
25915       (match_operand:SI 1 "register_operand" "a")
25916       (match_operand:SI 2 "register_operand" "d")]
25917      ANY_XRSTOR)]
25918   "TARGET_64BIT && TARGET_XSAVE"
25919   "<xrstor>\t%0"
25920   [(set_attr "type" "other")
25921    (set_attr "memory" "load")
25922    (set_attr "addr" "gpr16")
25923    (set (attr "length")
25924         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25926 (define_insn "<xrstor>64"
25927    [(unspec_volatile:BLK
25928      [(match_operand:BLK 0 "memory_operand" "jm")
25929       (match_operand:SI 1 "register_operand" "a")
25930       (match_operand:SI 2 "register_operand" "d")]
25931      ANY_XRSTOR64)]
25932   "TARGET_64BIT && TARGET_XSAVE"
25933   "<xrstor>64\t%0"
25934   [(set_attr "type" "other")
25935    (set_attr "memory" "load")
25936    (set_attr "addr" "gpr16")
25937    (set (attr "length")
25938         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25940 (define_insn "xsetbv"
25941   [(unspec_volatile:SI
25942          [(match_operand:SI 0 "register_operand" "c")
25943           (match_operand:DI 1 "register_operand" "A")]
25944          UNSPECV_XSETBV)]
25945   "!TARGET_64BIT && TARGET_XSAVE"
25946   "xsetbv"
25947   [(set_attr "type" "other")])
25949 (define_insn "xsetbv_rex64"
25950   [(unspec_volatile:SI
25951          [(match_operand:SI 0 "register_operand" "c")
25952           (match_operand:SI 1 "register_operand" "a")
25953           (match_operand:SI 2 "register_operand" "d")]
25954          UNSPECV_XSETBV)]
25955   "TARGET_64BIT && TARGET_XSAVE"
25956   "xsetbv"
25957   [(set_attr "type" "other")])
25959 (define_insn "xgetbv"
25960   [(set (match_operand:DI 0 "register_operand" "=A")
25961         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
25962                             UNSPECV_XGETBV))]
25963   "!TARGET_64BIT && TARGET_XSAVE"
25964   "xgetbv"
25965   [(set_attr "type" "other")])
25967 (define_insn "xgetbv_rex64"
25968   [(set (match_operand:DI 0 "register_operand" "=a")
25969         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
25970                             UNSPECV_XGETBV))
25971    (set (match_operand:DI 1 "register_operand" "=d")
25972         (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
25973   "TARGET_64BIT && TARGET_XSAVE"
25974   "xgetbv"
25975   [(set_attr "type" "other")])
25977 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25979 ;; Floating-point instructions for atomic compound assignments
25981 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25983 ; Clobber all floating-point registers on environment save and restore
25984 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
25985 (define_insn "fnstenv"
25986   [(set (match_operand:BLK 0 "memory_operand" "=m")
25987         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
25988    (clobber (reg:XF ST0_REG))
25989    (clobber (reg:XF ST1_REG))
25990    (clobber (reg:XF ST2_REG))
25991    (clobber (reg:XF ST3_REG))
25992    (clobber (reg:XF ST4_REG))
25993    (clobber (reg:XF ST5_REG))
25994    (clobber (reg:XF ST6_REG))
25995    (clobber (reg:XF ST7_REG))]
25996   "TARGET_80387"
25997   "fnstenv\t%0"
25998   [(set_attr "type" "other")
25999    (set_attr "memory" "store")
26000    (set (attr "length")
26001         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26003 (define_insn "fldenv"
26004   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
26005                     UNSPECV_FLDENV)
26006    (clobber (reg:XF ST0_REG))
26007    (clobber (reg:XF ST1_REG))
26008    (clobber (reg:XF ST2_REG))
26009    (clobber (reg:XF ST3_REG))
26010    (clobber (reg:XF ST4_REG))
26011    (clobber (reg:XF ST5_REG))
26012    (clobber (reg:XF ST6_REG))
26013    (clobber (reg:XF ST7_REG))]
26014   "TARGET_80387"
26015   "fldenv\t%0"
26016   [(set_attr "type" "other")
26017    (set_attr "memory" "load")
26018    (set (attr "length")
26019         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26021 (define_insn "fnstsw"
26022   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
26023         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
26024   "TARGET_80387"
26025   "fnstsw\t%0"
26026   [(set_attr "type" "other,other")
26027    (set_attr "memory" "none,store")
26028    (set (attr "length")
26029         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26031 (define_insn "fnclex"
26032   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
26033   "TARGET_80387"
26034   "fnclex"
26035   [(set_attr "type" "other")
26036    (set_attr "memory" "none")
26037    (set_attr "length" "2")])
26039 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26041 ;; LWP instructions
26043 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26045 (define_insn "@lwp_llwpcb<mode>"
26046   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26047                     UNSPECV_LLWP_INTRINSIC)]
26048   "TARGET_LWP"
26049   "llwpcb\t%0"
26050   [(set_attr "type" "lwp")
26051    (set_attr "mode" "<MODE>")
26052    (set_attr "length" "5")])
26054 (define_insn "@lwp_slwpcb<mode>"
26055   [(set (match_operand:P 0 "register_operand" "=r")
26056         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
26057   "TARGET_LWP"
26058   "slwpcb\t%0"
26059   [(set_attr "type" "lwp")
26060    (set_attr "mode" "<MODE>")
26061    (set_attr "length" "5")])
26063 (define_insn "@lwp_lwpval<mode>"
26064   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26065                      (match_operand:SI 1 "nonimmediate_operand" "rm")
26066                      (match_operand:SI 2 "const_int_operand")]
26067                     UNSPECV_LWPVAL_INTRINSIC)]
26068   "TARGET_LWP"
26069   "lwpval\t{%2, %1, %0|%0, %1, %2}"
26070   [(set_attr "type" "lwp")
26071    (set_attr "mode" "<MODE>")
26072    (set (attr "length")
26073         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
26075 (define_insn "@lwp_lwpins<mode>"
26076   [(set (reg:CCC FLAGS_REG)
26077         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
26078                               (match_operand:SI 1 "nonimmediate_operand" "rm")
26079                               (match_operand:SI 2 "const_int_operand")]
26080                              UNSPECV_LWPINS_INTRINSIC))]
26081   "TARGET_LWP"
26082   "lwpins\t{%2, %1, %0|%0, %1, %2}"
26083   [(set_attr "type" "lwp")
26084    (set_attr "mode" "<MODE>")
26085    (set (attr "length")
26086         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
26088 (define_int_iterator RDFSGSBASE
26089         [UNSPECV_RDFSBASE
26090          UNSPECV_RDGSBASE])
26092 (define_int_iterator WRFSGSBASE
26093         [UNSPECV_WRFSBASE
26094          UNSPECV_WRGSBASE])
26096 (define_int_attr fsgs
26097         [(UNSPECV_RDFSBASE "fs")
26098          (UNSPECV_RDGSBASE "gs")
26099          (UNSPECV_WRFSBASE "fs")
26100          (UNSPECV_WRGSBASE "gs")])
26102 (define_insn "rd<fsgs>base<mode>"
26103   [(set (match_operand:SWI48 0 "register_operand" "=r")
26104         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
26105   "TARGET_64BIT && TARGET_FSGSBASE"
26106   "rd<fsgs>base\t%0"
26107   [(set_attr "type" "other")
26108    (set_attr "prefix_0f" "1")
26109    (set_attr "prefix_rep" "1")])
26111 (define_insn "wr<fsgs>base<mode>"
26112   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
26113                     WRFSGSBASE)]
26114   "TARGET_64BIT && TARGET_FSGSBASE"
26115   "wr<fsgs>base\t%0"
26116   [(set_attr "type" "other")
26117    (set_attr "prefix_0f" "1")
26118    (set_attr "prefix_rep" "1")])
26120 (define_insn "ptwrite<mode>"
26121   [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
26122                     UNSPECV_PTWRITE)]
26123   "TARGET_PTWRITE"
26124   "ptwrite\t%0"
26125   [(set_attr "type" "other")
26126    (set_attr "prefix_0f" "1")
26127    (set_attr "prefix_rep" "1")])
26129 (define_insn "@rdrand<mode>"
26130   [(set (match_operand:SWI248 0 "register_operand" "=r")
26131         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
26132    (set (reg:CCC FLAGS_REG)
26133         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
26134   "TARGET_RDRND"
26135   "rdrand\t%0"
26136   [(set_attr "type" "other")
26137    (set_attr "prefix_0f" "1")])
26139 (define_insn "@rdseed<mode>"
26140   [(set (match_operand:SWI248 0 "register_operand" "=r")
26141         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
26142    (set (reg:CCC FLAGS_REG)
26143         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
26144   "TARGET_RDSEED"
26145   "rdseed\t%0"
26146   [(set_attr "type" "other")
26147    (set_attr "prefix_0f" "1")])
26149 (define_expand "pause"
26150   [(set (match_dup 0)
26151         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
26152   ""
26154   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
26155   MEM_VOLATILE_P (operands[0]) = 1;
26158 ;; Use "rep; nop", instead of "pause", to support older assemblers.
26159 ;; They have the same encoding.
26160 (define_insn "*pause"
26161   [(set (match_operand:BLK 0)
26162         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
26163   ""
26164   "rep%; nop"
26165   [(set_attr "length" "2")
26166    (set_attr "memory" "unknown")])
26168 ;; CET instructions
26169 (define_insn "@rdssp<mode>"
26170   [(set (match_operand:SWI48 0 "register_operand" "=r")
26171         (unspec_volatile:SWI48 [(match_operand:SWI48 1 "register_operand" "0")]
26172                                UNSPECV_NOP_RDSSP))]
26173   "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
26174   "rdssp<mskmodesuffix>\t%0"
26175   [(set_attr "length" "6")
26176    (set_attr "type" "other")])
26178 (define_insn "@incssp<mode>"
26179   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
26180                     UNSPECV_INCSSP)]
26181   "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
26182   "incssp<mskmodesuffix>\t%0"
26183   [(set_attr "length" "4")
26184    (set_attr "type" "other")])
26186 (define_insn "saveprevssp"
26187   [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
26188   "TARGET_SHSTK"
26189   "saveprevssp"
26190   [(set_attr "length" "5")
26191    (set_attr "type" "other")])
26193 (define_insn "rstorssp"
26194   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
26195                     UNSPECV_RSTORSSP)]
26196   "TARGET_SHSTK"
26197   "rstorssp\t%0"
26198   [(set_attr "length" "5")
26199    (set_attr "type" "other")])
26201 (define_insn "@wrss<mode>"
26202   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26203                      (match_operand:SWI48 1 "memory_operand" "m")]
26204                     UNSPECV_WRSS)]
26205   "TARGET_SHSTK"
26206   "wrss<mskmodesuffix>\t%0, %1"
26207   [(set_attr "length" "3")
26208    (set_attr "type" "other")])
26210 (define_insn "@wruss<mode>"
26211   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26212                      (match_operand:SWI48 1 "memory_operand" "m")]
26213                     UNSPECV_WRUSS)]
26214   "TARGET_SHSTK"
26215   "wruss<mskmodesuffix>\t%0, %1"
26216   [(set_attr "length" "4")
26217    (set_attr "type" "other")])
26219 (define_insn "setssbsy"
26220   [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
26221   "TARGET_SHSTK"
26222   "setssbsy"
26223   [(set_attr "length" "4")
26224    (set_attr "type" "other")])
26226 (define_insn "clrssbsy"
26227   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
26228                     UNSPECV_CLRSSBSY)]
26229   "TARGET_SHSTK"
26230   "clrssbsy\t%0"
26231   [(set_attr "length" "4")
26232    (set_attr "type" "other")])
26234 (define_insn "nop_endbr"
26235   [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
26236   "(flag_cf_protection & CF_BRANCH)"
26238   return TARGET_64BIT ? "endbr64" : "endbr32";
26240   [(set_attr "length" "4")
26241    (set_attr "length_immediate" "0")
26242    (set_attr "modrm" "0")])
26244 ;; For RTM support
26245 (define_expand "xbegin"
26246   [(set (match_operand:SI 0 "register_operand")
26247         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
26248   "TARGET_RTM"
26250   rtx_code_label *label = gen_label_rtx ();
26252   /* xbegin is emitted as jump_insn, so reload won't be able
26253      to reload its operand.  Force the value into AX hard register.  */
26254   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
26255   emit_move_insn (ax_reg, constm1_rtx);
26257   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
26259   emit_label (label);
26260   LABEL_NUSES (label) = 1;
26262   emit_move_insn (operands[0], ax_reg);
26264   DONE;
26267 (define_insn "xbegin_1"
26268   [(set (pc)
26269         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
26270                           (const_int 0))
26271                       (label_ref (match_operand 1))
26272                       (pc)))
26273    (set (match_operand:SI 0 "register_operand" "+a")
26274         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
26275   "TARGET_RTM"
26276   "xbegin\t%l1"
26277   [(set_attr "type" "other")
26278    (set_attr "length" "6")])
26280 (define_insn "xend"
26281   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
26282   "TARGET_RTM"
26283   "xend"
26284   [(set_attr "type" "other")
26285    (set_attr "length" "3")])
26287 (define_insn "xabort"
26288   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand")]
26289                     UNSPECV_XABORT)]
26290   "TARGET_RTM"
26291   "xabort\t%0"
26292   [(set_attr "type" "other")
26293    (set_attr "length" "3")])
26295 (define_expand "xtest"
26296   [(set (match_operand:QI 0 "register_operand")
26297         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
26298   "TARGET_RTM"
26300   emit_insn (gen_xtest_1 ());
26302   ix86_expand_setcc (operands[0], NE,
26303                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
26304   DONE;
26307 (define_insn "xtest_1"
26308   [(set (reg:CCZ FLAGS_REG)
26309         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
26310   "TARGET_RTM"
26311   "xtest"
26312   [(set_attr "type" "other")
26313    (set_attr "length" "3")])
26315 (define_insn "clwb"
26316   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26317                    UNSPECV_CLWB)]
26318   "TARGET_CLWB"
26319   "clwb\t%a0"
26320   [(set_attr "type" "sse")
26321    (set_attr "atom_sse_attr" "fence")
26322    (set_attr "memory" "unknown")])
26324 (define_insn "clflushopt"
26325   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26326                    UNSPECV_CLFLUSHOPT)]
26327   "TARGET_CLFLUSHOPT"
26328   "clflushopt\t%a0"
26329   [(set_attr "type" "sse")
26330    (set_attr "atom_sse_attr" "fence")
26331    (set_attr "memory" "unknown")])
26333 ;; MONITORX and MWAITX
26334 (define_insn "mwaitx"
26335   [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
26336                      (match_operand:SI 1 "register_operand" "a")
26337                      (match_operand:SI 2 "register_operand" "b")]
26338                    UNSPECV_MWAITX)]
26339   "TARGET_MWAITX"
26340 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
26341 ;; Since 32bit register operands are implicitly zero extended to 64bit,
26342 ;; we only need to set up 32bit registers.
26343   "mwaitx"
26344   [(set_attr "length" "3")])
26346 (define_insn "@monitorx_<mode>"
26347   [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
26348                      (match_operand:SI 1 "register_operand" "c")
26349                      (match_operand:SI 2 "register_operand" "d")]
26350                    UNSPECV_MONITORX)]
26351   "TARGET_MWAITX"
26352 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
26353 ;; RCX and RDX are used.  Since 32bit register operands are implicitly
26354 ;; zero extended to 64bit, we only need to set up 32bit registers.
26355   "%^monitorx"
26356   [(set (attr "length")
26357      (symbol_ref ("(Pmode != word_mode) + 3")))])
26359 ;; CLZERO
26360 (define_insn "@clzero_<mode>"
26361   [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
26362                    UNSPECV_CLZERO)]
26363   "TARGET_CLZERO"
26364   "clzero"
26365   [(set_attr "length" "3")
26366   (set_attr "memory" "unknown")])
26368 ;; RDPKRU and WRPKRU
26370 (define_expand "rdpkru"
26371   [(parallel
26372      [(set (match_operand:SI 0 "register_operand")
26373            (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
26374       (set (match_dup 2) (const_int 0))])]
26375   "TARGET_PKU"
26377   operands[1] = force_reg (SImode, const0_rtx);
26378   operands[2] = gen_reg_rtx (SImode);
26381 (define_insn "*rdpkru"
26382   [(set (match_operand:SI 0 "register_operand" "=a")
26383         (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
26384                             UNSPECV_PKU))
26385    (set (match_operand:SI 1 "register_operand" "=d")
26386         (const_int 0))]
26387   "TARGET_PKU"
26388   "rdpkru"
26389   [(set_attr "type" "other")])
26391 (define_expand "wrpkru"
26392   [(unspec_volatile:SI
26393      [(match_operand:SI 0 "register_operand")
26394       (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
26395   "TARGET_PKU"
26397   operands[1] = force_reg (SImode, const0_rtx);
26398   operands[2] = force_reg (SImode, const0_rtx);
26401 (define_insn "*wrpkru"
26402   [(unspec_volatile:SI
26403      [(match_operand:SI 0 "register_operand" "a")
26404       (match_operand:SI 1 "register_operand" "d")
26405       (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
26406   "TARGET_PKU"
26407   "wrpkru"
26408   [(set_attr "type" "other")])
26410 (define_insn "rdpid"
26411   [(set (match_operand:SI 0 "register_operand" "=r")
26412         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
26413   "!TARGET_64BIT && TARGET_RDPID"
26414   "rdpid\t%0"
26415   [(set_attr "type" "other")])
26417 (define_insn "rdpid_rex64"
26418   [(set (match_operand:DI 0 "register_operand" "=r")
26419         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
26420   "TARGET_64BIT && TARGET_RDPID"
26421   "rdpid\t%0"
26422   [(set_attr "type" "other")])
26424 ;; Intirinsics for > i486
26426 (define_insn "wbinvd"
26427   [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
26428   ""
26429   "wbinvd"
26430   [(set_attr "type" "other")])
26432 (define_insn "wbnoinvd"
26433   [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
26434   "TARGET_WBNOINVD"
26435   "wbnoinvd"
26436   [(set_attr "type" "other")])
26438 ;; MOVDIRI and MOVDIR64B
26440 (define_insn "movdiri<mode>"
26441   [(set (match_operand:SWI48 0 "memory_operand" "=m")
26442         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
26443                       UNSPEC_MOVDIRI))]
26444   "TARGET_MOVDIRI"
26445   "movdiri\t{%1, %0|%0, %1}"
26446   [(set_attr "type" "other")])
26448 (define_insn "@movdir64b_<mode>"
26449   [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
26450         (unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
26451                    UNSPEC_MOVDIR64B))]
26452   "TARGET_MOVDIR64B"
26453   "movdir64b\t{%1, %0|%0, %1}"
26454   [(set_attr "type" "other")])
26456 ;; TSXLDTRK
26457 (define_int_iterator TSXLDTRK [UNSPECV_XSUSLDTRK UNSPECV_XRESLDTRK])
26458 (define_int_attr tsxldtrk [(UNSPECV_XSUSLDTRK "xsusldtrk")
26459                  (UNSPECV_XRESLDTRK "xresldtrk")])
26460 (define_insn "<tsxldtrk>"
26461   [(unspec_volatile [(const_int 0)] TSXLDTRK)]
26462   "TARGET_TSXLDTRK"
26463   "<tsxldtrk>"
26464   [(set_attr "type" "other")
26465    (set_attr "length" "4")])
26467 ;; ENQCMD and ENQCMDS
26469 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
26470 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
26472 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
26473   [(set (reg:CCZ FLAGS_REG)
26474         (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
26475                               (match_operand:XI 1 "memory_operand" "m")]
26476                              ENQCMD))]
26477   "TARGET_ENQCMD"
26478   "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
26479   [(set_attr "type" "other")])
26481 ;; UINTR
26482 (define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI])
26483 (define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")])
26485 (define_insn "<uintr>"
26486   [(unspec_volatile [(const_int 0)] UINTR)]
26487   "TARGET_UINTR && TARGET_64BIT"
26488   "<uintr>"
26489   [(set_attr "type" "other")
26490    (set_attr "length" "4")])
26492 (define_insn "testui"
26493   [(set (reg:CCC FLAGS_REG)
26494         (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))]
26495   "TARGET_UINTR && TARGET_64BIT"
26496   "testui"
26497   [(set_attr "type" "other")
26498    (set_attr "length" "4")])
26500 (define_insn "senduipi"
26501   [(unspec_volatile
26502     [(match_operand:DI 0 "register_operand" "r")]
26503     UNSPECV_SENDUIPI)]
26504   "TARGET_UINTR && TARGET_64BIT"
26505   "senduipi\t%0"
26506   [(set_attr "type" "other")
26507    (set_attr "length" "4")])
26509 ;; WAITPKG
26511 (define_insn "umwait"
26512   [(set (reg:CCC FLAGS_REG)
26513         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26514                               (match_operand:DI 1 "register_operand" "A")]
26515                              UNSPECV_UMWAIT))]
26516   "!TARGET_64BIT && TARGET_WAITPKG"
26517   "umwait\t%0"
26518   [(set_attr "length" "3")])
26520 (define_insn "umwait_rex64"
26521   [(set (reg:CCC FLAGS_REG)
26522         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26523                               (match_operand:SI 1 "register_operand" "a")
26524                               (match_operand:SI 2 "register_operand" "d")]
26525                              UNSPECV_UMWAIT))]
26526   "TARGET_64BIT && TARGET_WAITPKG"
26527   "umwait\t%0"
26528   [(set_attr "length" "3")])
26530 (define_insn "@umonitor_<mode>"
26531   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26532                     UNSPECV_UMONITOR)]
26533   "TARGET_WAITPKG"
26534   "umonitor\t%0"
26535   [(set (attr "length")
26536      (symbol_ref ("(Pmode != word_mode) + 3")))])
26538 (define_insn "tpause"
26539   [(set (reg:CCC FLAGS_REG)
26540         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26541                               (match_operand:DI 1 "register_operand" "A")]
26542                              UNSPECV_TPAUSE))]
26543   "!TARGET_64BIT && TARGET_WAITPKG"
26544   "tpause\t%0"
26545   [(set_attr "length" "3")])
26547 (define_insn "tpause_rex64"
26548   [(set (reg:CCC FLAGS_REG)
26549         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26550                               (match_operand:SI 1 "register_operand" "a")
26551                               (match_operand:SI 2 "register_operand" "d")]
26552                              UNSPECV_TPAUSE))]
26553   "TARGET_64BIT && TARGET_WAITPKG"
26554   "tpause\t%0"
26555   [(set_attr "length" "3")])
26557 (define_insn "cldemote"
26558   [(unspec_volatile[(match_operand 0 "address_operand" "p")]
26559                  UNSPECV_CLDEMOTE)]
26560   "TARGET_CLDEMOTE"
26561   "cldemote\t%a0"
26562   [(set_attr "type" "other")
26563    (set_attr "memory" "unknown")])
26565 (define_insn "speculation_barrier"
26566   [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
26567   ""
26568   "lfence"
26569   [(set_attr "type" "other")
26570    (set_attr "length" "3")])
26572 (define_insn "serialize"
26573   [(unspec_volatile [(const_int 0)] UNSPECV_SERIALIZE)]
26574   "TARGET_SERIALIZE"
26575   "serialize"
26576   [(set_attr "type" "other")
26577    (set_attr "length" "3")])
26579 (define_insn "patchable_area"
26580   [(unspec_volatile [(match_operand 0 "const_int_operand")
26581                      (match_operand 1 "const_int_operand")]
26582                     UNSPECV_PATCHABLE_AREA)]
26583   ""
26585   ix86_output_patchable_area (INTVAL (operands[0]),
26586                               INTVAL (operands[1]) != 0);
26587   return "";
26589   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
26590    (set_attr "length_immediate" "0")
26591    (set_attr "modrm" "0")])
26593 (define_insn "hreset"
26594   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")]
26595                      UNSPECV_HRESET)]
26596   "TARGET_HRESET"
26597   "hreset\t{$0|0}"
26598   [(set_attr "type" "other")
26599    (set_attr "length" "4")])
26601 ;; Spaceship optimization
26602 (define_expand "spaceship<mode>3"
26603   [(match_operand:SI 0 "register_operand")
26604    (match_operand:MODEF 1 "cmp_fp_expander_operand")
26605    (match_operand:MODEF 2 "cmp_fp_expander_operand")]
26606   "(TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
26607    && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26609   ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26610   DONE;
26613 (define_expand "spaceshipxf3"
26614   [(match_operand:SI 0 "register_operand")
26615    (match_operand:XF 1 "nonmemory_operand")
26616    (match_operand:XF 2 "nonmemory_operand")]
26617   "TARGET_80387 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26619   ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26620   DONE;
26623 ;; Defined because the generic expand_builtin_issignaling for XFmode
26624 ;; only tests for sNaNs, but i387 treats also pseudo numbers as always
26625 ;; signaling.
26626 (define_expand "issignalingxf2"
26627   [(match_operand:SI 0 "register_operand")
26628    (match_operand:XF 1 "general_operand")]
26629   ""
26631   rtx temp = operands[1];
26632   if (!MEM_P (temp))
26633     {
26634       rtx mem = assign_stack_temp (XFmode, GET_MODE_SIZE (XFmode));
26635       emit_move_insn (mem, temp);
26636       temp = mem;
26637     }
26638   rtx ex = adjust_address (temp, HImode, 8);
26639   rtx hi = adjust_address (temp, SImode, 4);
26640   rtx lo = adjust_address (temp, SImode, 0);
26641   rtx val = GEN_INT (HOST_WIDE_INT_M1U << 30);
26642   rtx mask = GEN_INT (0x7fff);
26643   rtx bit = GEN_INT (HOST_WIDE_INT_1U << 30);
26644   /* Expand to:
26645      ((ex & mask) && (int) hi >= 0)
26646      || ((ex & mask) == mask && ((hi ^ bit) | ((lo | -lo) >> 31)) > val).  */
26647   rtx nlo = expand_unop (SImode, neg_optab, lo, NULL_RTX, 0);
26648   lo = expand_binop (SImode, ior_optab, lo, nlo,
26649                      NULL_RTX, 1, OPTAB_LIB_WIDEN);
26650   lo = expand_shift (RSHIFT_EXPR, SImode, lo, 31, NULL_RTX, 1);
26651   temp = expand_binop (SImode, xor_optab, hi, bit,
26652                        NULL_RTX, 1, OPTAB_LIB_WIDEN);
26653   temp = expand_binop (SImode, ior_optab, temp, lo,
26654                        NULL_RTX, 1, OPTAB_LIB_WIDEN);
26655   temp = emit_store_flag_force (gen_reg_rtx (SImode), GTU, temp, val,
26656                                 SImode, 1, 1);
26657   ex = expand_binop (HImode, and_optab, ex, mask,
26658                      NULL_RTX, 1, OPTAB_LIB_WIDEN);
26659   rtx temp2 = emit_store_flag_force (gen_reg_rtx (SImode), NE,
26660                                      ex, const0_rtx, SImode, 1, 1);
26661   ex = emit_store_flag_force (gen_reg_rtx (SImode), EQ,
26662                               ex, mask, HImode, 1, 1);
26663   temp = expand_binop (SImode, and_optab, temp, ex,
26664                        NULL_RTX, 1, OPTAB_LIB_WIDEN);
26665   rtx temp3 = emit_store_flag_force (gen_reg_rtx (SImode), GE,
26666                                      hi, const0_rtx, SImode, 0, 1);
26667   temp2 = expand_binop (SImode, and_optab, temp2, temp3,
26668                         NULL_RTX, 1, OPTAB_LIB_WIDEN);
26669   temp = expand_binop (SImode, ior_optab, temp, temp2,
26670                        NULL_RTX, 1, OPTAB_LIB_WIDEN);
26671   emit_move_insn (operands[0], temp);
26672   DONE;
26675 (define_insn "urdmsr"
26676   [(set (match_operand:DI 0 "register_operand" "=r")
26677     (unspec_volatile:DI
26678       [(match_operand:DI 1 "x86_64_szext_nonmemory_operand" "reZ")]
26679       UNSPECV_URDMSR))]
26680   "TARGET_USER_MSR && TARGET_64BIT"
26681   "urdmsr\t{%1, %0|%0, %1}"
26682   [(set_attr "prefix" "vex")
26683    (set_attr "type" "other")])
26685 (define_insn "uwrmsr"
26686   [(unspec_volatile
26687     [(match_operand:DI 0 "x86_64_szext_nonmemory_operand" "reZ")
26688       (match_operand:DI 1 "register_operand" "r")]
26689       UNSPECV_UWRMSR)]
26690   "TARGET_USER_MSR && TARGET_64BIT"
26691   "uwrmsr\t{%1, %0|%0, %1}"
26692   [(set_attr "prefix" "vex")
26693    (set_attr "type" "other")])
26695 (include "mmx.md")
26696 (include "sse.md")
26697 (include "sync.md")