make -freg-struct-return visibly a negative alias of -fpcc-struct-return
[official-gcc.git] / gcc / config / i386 / i386.md
blob764bfe20ff2acd5dda17b3a87bd628be10c1c54b
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2024 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
5 ;;
6 ;; This file is part of GCC.
7 ;;
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.  */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
33 ;;      otherwise nothing
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
42 ;;      delimiter.
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;;      %b0 would print %al if operands[0] is reg 0.
45 ;; w --  likewise, print the HImode name of the register.
46 ;; k --  likewise, print the SImode name of the register.
47 ;; q --  likewise, print the DImode name of the register.
48 ;; x --  likewise, print the V4SFmode name of the register.
49 ;; t --  likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
65 ;; ! -- print NOTRACK prefix for jxx/call/ret instructions if required.
67 (define_c_enum "unspec" [
68   ;; Relocation specifiers
69   UNSPEC_GOT
70   UNSPEC_GOTOFF
71   UNSPEC_GOTPCREL
72   UNSPEC_GOTTPOFF
73   UNSPEC_TPOFF
74   UNSPEC_NTPOFF
75   UNSPEC_DTPOFF
76   UNSPEC_GOTNTPOFF
77   UNSPEC_INDNTPOFF
78   UNSPEC_PLTOFF
79   UNSPEC_MACHOPIC_OFFSET
80   UNSPEC_PCREL
81   UNSPEC_SIZEOF
83   ;; Prologue support
84   UNSPEC_STACK_ALLOC
85   UNSPEC_SET_GOT
86   UNSPEC_SET_RIP
87   UNSPEC_SET_GOT_OFFSET
88   UNSPEC_MEMORY_BLOCKAGE
89   UNSPEC_PROBE_STACK
91   ;; TLS support
92   UNSPEC_TP
93   UNSPEC_TLS_GD
94   UNSPEC_TLS_LD_BASE
95   UNSPEC_TLSDESC
96   UNSPEC_TLS_IE_SUN
98   ;; Other random patterns
99   UNSPEC_SCAS
100   UNSPEC_FNSTSW
101   UNSPEC_SAHF
102   UNSPEC_NOTRAP
103   UNSPEC_PARITY
104   UNSPEC_FSTCW
105   UNSPEC_REP
106   UNSPEC_LD_MPIC        ; load_macho_picbase
107   UNSPEC_TRUNC_NOOP
108   UNSPEC_DIV_ALREADY_SPLIT
109   UNSPEC_PAUSE
110   UNSPEC_LEA_ADDR
111   UNSPEC_XBEGIN_ABORT
112   UNSPEC_STOS
113   UNSPEC_PEEPSIB
114   UNSPEC_INSN_FALSE_DEP
115   UNSPEC_SBB
116   UNSPEC_CC_NE
117   UNSPEC_STC
118   UNSPEC_PUSHFL
119   UNSPEC_POPFL
121   ;; For SSE/MMX support:
122   UNSPEC_FIX_NOTRUNC
123   UNSPEC_MASKMOV
124   UNSPEC_MOVCC_MASK
125   UNSPEC_MOVMSK
126   UNSPEC_INSERTPS
127   UNSPEC_BLENDV
128   UNSPEC_PSHUFB
129   UNSPEC_XOP_PERMUTE
130   UNSPEC_RCP
131   UNSPEC_RSQRT
132   UNSPEC_PSADBW
134   ;; Different from generic us_truncate RTX
135   ;; as it does unsigned saturation of signed source.
136   UNSPEC_US_TRUNCATE
138   ;; For AVX/AVX512F support
139   UNSPEC_SCALEF
140   UNSPEC_PCMP
141   UNSPEC_CVTBFSF
143   ;; Generic math support
144   UNSPEC_IEEE_MIN       ; not commutative
145   UNSPEC_IEEE_MAX       ; not commutative
147   ;; x87 Floating point
148   UNSPEC_SIN
149   UNSPEC_COS
150   UNSPEC_FPATAN
151   UNSPEC_FYL2X
152   UNSPEC_FYL2XP1
153   UNSPEC_FRNDINT
154   UNSPEC_FIST
155   UNSPEC_F2XM1
156   UNSPEC_TAN
157   UNSPEC_FXAM
159   ;; x87 Rounding
160   UNSPEC_FRNDINT_ROUNDEVEN
161   UNSPEC_FRNDINT_FLOOR
162   UNSPEC_FRNDINT_CEIL
163   UNSPEC_FRNDINT_TRUNC
164   UNSPEC_FIST_FLOOR
165   UNSPEC_FIST_CEIL
167   ;; x87 Double output FP
168   UNSPEC_SINCOS_COS
169   UNSPEC_SINCOS_SIN
170   UNSPEC_XTRACT_FRACT
171   UNSPEC_XTRACT_EXP
172   UNSPEC_FSCALE_FRACT
173   UNSPEC_FSCALE_EXP
174   UNSPEC_FPREM_F
175   UNSPEC_FPREM_U
176   UNSPEC_FPREM1_F
177   UNSPEC_FPREM1_U
179   UNSPEC_C2_FLAG
180   UNSPEC_FXAM_MEM
182   ;; SSP patterns
183   UNSPEC_SP_SET
184   UNSPEC_SP_TEST
186   ;; For ROUND support
187   UNSPEC_ROUND
189   ;; For CRC32 support
190   UNSPEC_CRC32
192   ;; For LZCNT suppoprt
193   UNSPEC_LZCNT
195   ;; For BMI support
196   UNSPEC_TZCNT
197   UNSPEC_BEXTR
199   ;; For BMI2 support
200   UNSPEC_PDEP
201   UNSPEC_PEXT
203   ;; IRET support
204   UNSPEC_INTERRUPT_RETURN
206   ;; For MOVDIRI and MOVDIR64B support
207   UNSPEC_MOVDIRI
208   UNSPEC_MOVDIR64B
210   ;; For insn_callee_abi:
211   UNSPEC_CALLEE_ABI
213   ;; For APX PUSH2/POP2 support
214   UNSPEC_APXPUSH2
215   UNSPEC_APXPOP2_LOW
216   UNSPEC_APXPOP2_HIGH
218   ;; For APX PPX support
219   UNSPEC_APX_PPX
222 (define_c_enum "unspecv" [
223   UNSPECV_UD2
224   UNSPECV_BLOCKAGE
225   UNSPECV_STACK_PROBE
226   UNSPECV_PROBE_STACK_RANGE
227   UNSPECV_ALIGN
228   UNSPECV_PROLOGUE_USE
229   UNSPECV_SPLIT_STACK_RETURN
230   UNSPECV_CLD
231   UNSPECV_NOPS
232   UNSPECV_RDTSC
233   UNSPECV_RDTSCP
234   UNSPECV_RDPMC
235   UNSPECV_LLWP_INTRINSIC
236   UNSPECV_SLWP_INTRINSIC
237   UNSPECV_LWPVAL_INTRINSIC
238   UNSPECV_LWPINS_INTRINSIC
239   UNSPECV_RDFSBASE
240   UNSPECV_RDGSBASE
241   UNSPECV_WRFSBASE
242   UNSPECV_WRGSBASE
243   UNSPECV_FXSAVE
244   UNSPECV_FXRSTOR
245   UNSPECV_FXSAVE64
246   UNSPECV_FXRSTOR64
247   UNSPECV_XSAVE
248   UNSPECV_XRSTOR
249   UNSPECV_XSAVE64
250   UNSPECV_XRSTOR64
251   UNSPECV_XSAVEOPT
252   UNSPECV_XSAVEOPT64
253   UNSPECV_XSAVES
254   UNSPECV_XRSTORS
255   UNSPECV_XSAVES64
256   UNSPECV_XRSTORS64
257   UNSPECV_XSAVEC
258   UNSPECV_XSAVEC64
259   UNSPECV_XGETBV
260   UNSPECV_XSETBV
261   UNSPECV_WBINVD
262   UNSPECV_WBNOINVD
264   ;; For atomic compound assignments.
265   UNSPECV_FNSTENV
266   UNSPECV_FLDENV
267   UNSPECV_FNSTSW
268   UNSPECV_FNCLEX
270   ;; For RDRAND support
271   UNSPECV_RDRAND
273   ;; For RDSEED support
274   UNSPECV_RDSEED
276   ;; For RTM support
277   UNSPECV_XBEGIN
278   UNSPECV_XEND
279   UNSPECV_XABORT
280   UNSPECV_XTEST
282   UNSPECV_NLGR
284   ;; For CLWB support
285   UNSPECV_CLWB
287   ;; For CLFLUSHOPT support
288   UNSPECV_CLFLUSHOPT
290   ;; For MONITORX and MWAITX support 
291   UNSPECV_MONITORX
292   UNSPECV_MWAITX
294   ;; For CLZERO support
295   UNSPECV_CLZERO
297   ;; For RDPKRU and WRPKRU support
298   UNSPECV_PKU
300   ;; For RDPID support
301   UNSPECV_RDPID
303   ;; For CET support
304   UNSPECV_NOP_ENDBR
305   UNSPECV_NOP_RDSSP
306   UNSPECV_INCSSP
307   UNSPECV_SAVEPREVSSP
308   UNSPECV_RSTORSSP
309   UNSPECV_WRSS
310   UNSPECV_WRUSS
311   UNSPECV_SETSSBSY
312   UNSPECV_CLRSSBSY
314   ;; For TSXLDTRK support
315   UNSPECV_XSUSLDTRK
316   UNSPECV_XRESLDTRK
318   ;; For WAITPKG support
319   UNSPECV_UMWAIT
320   UNSPECV_UMONITOR
321   UNSPECV_TPAUSE
323   ;; For UINTR support
324   UNSPECV_CLUI
325   UNSPECV_STUI
326   UNSPECV_TESTUI
327   UNSPECV_SENDUIPI
329   ;; For CLDEMOTE support
330   UNSPECV_CLDEMOTE
332   ;; For Speculation Barrier support
333   UNSPECV_SPECULATION_BARRIER
335   UNSPECV_PTWRITE
337   ;; For ENQCMD and ENQCMDS support
338   UNSPECV_ENQCMD
339   UNSPECV_ENQCMDS
341   ;; For SERIALIZE support
342   UNSPECV_SERIALIZE
344   ;; For patchable area support
345   UNSPECV_PATCHABLE_AREA
347   ;; For HRESET support
348   UNSPECV_HRESET
350   ;; For PREFETCHI support
351   UNSPECV_PREFETCHI
353   ;; For USER_MSR support
354   UNSPECV_URDMSR
355   UNSPECV_UWRMSR
357   ;; For AMX-TILE
358   UNSPECV_LDTILECFG
359   UNSPECV_STTILECFG
362 ;; Constants to represent rounding modes in the ROUND instruction
363 (define_constants
364   [(ROUND_ROUNDEVEN             0x0)
365    (ROUND_FLOOR                 0x1)
366    (ROUND_CEIL                  0x2)
367    (ROUND_TRUNC                 0x3)
368    (ROUND_MXCSR                 0x4)
369    (ROUND_NO_EXC                0x8)
370   ])
372 ;; Constants to represent AVX512F embeded rounding
373 (define_constants
374   [(ROUND_NEAREST_INT                   0)
375    (ROUND_NEG_INF                       1)
376    (ROUND_POS_INF                       2)
377    (ROUND_ZERO                          3)
378    (NO_ROUND                            4)
379    (ROUND_SAE                           8)
380   ])
382 ;; Constants to represent pcomtrue/pcomfalse variants
383 (define_constants
384   [(PCOM_FALSE                  0)
385    (PCOM_TRUE                   1)
386    (COM_FALSE_S                 2)
387    (COM_FALSE_P                 3)
388    (COM_TRUE_S                  4)
389    (COM_TRUE_P                  5)
390   ])
392 ;; Constants used in the XOP pperm instruction
393 (define_constants
394   [(PPERM_SRC                   0x00)   /* copy source */
395    (PPERM_INVERT                0x20)   /* invert source */
396    (PPERM_REVERSE               0x40)   /* bit reverse source */
397    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
398    (PPERM_ZERO                  0x80)   /* all 0's */
399    (PPERM_ONES                  0xa0)   /* all 1's */
400    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
401    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
402    (PPERM_SRC1                  0x00)   /* use first source byte */
403    (PPERM_SRC2                  0x10)   /* use second source byte */
404    ])
406 ;; Registers by name.
407 (define_constants
408   [(AX_REG                       0)
409    (DX_REG                       1)
410    (CX_REG                       2)
411    (BX_REG                       3)
412    (SI_REG                       4)
413    (DI_REG                       5)
414    (BP_REG                       6)
415    (SP_REG                       7)
416    (ST0_REG                      8)
417    (ST1_REG                      9)
418    (ST2_REG                     10)
419    (ST3_REG                     11)
420    (ST4_REG                     12)
421    (ST5_REG                     13)
422    (ST6_REG                     14)
423    (ST7_REG                     15)
424    (ARGP_REG                    16)
425    (FLAGS_REG                   17)
426    (FPSR_REG                    18)
427    (FRAME_REG                   19)
428    (XMM0_REG                    20)
429    (XMM1_REG                    21)
430    (XMM2_REG                    22)
431    (XMM3_REG                    23)
432    (XMM4_REG                    24)
433    (XMM5_REG                    25)
434    (XMM6_REG                    26)
435    (XMM7_REG                    27)
436    (MM0_REG                     28)
437    (MM1_REG                     29)
438    (MM2_REG                     30)
439    (MM3_REG                     31)
440    (MM4_REG                     32)
441    (MM5_REG                     33)
442    (MM6_REG                     34)
443    (MM7_REG                     35)
444    (R8_REG                      36)
445    (R9_REG                      37)
446    (R10_REG                     38)
447    (R11_REG                     39)
448    (R12_REG                     40)
449    (R13_REG                     41)
450    (R14_REG                     42)
451    (R15_REG                     43)
452    (XMM8_REG                    44)
453    (XMM9_REG                    45)
454    (XMM10_REG                   46)
455    (XMM11_REG                   47)
456    (XMM12_REG                   48)
457    (XMM13_REG                   49)
458    (XMM14_REG                   50)
459    (XMM15_REG                   51)
460    (XMM16_REG                   52)
461    (XMM17_REG                   53)
462    (XMM18_REG                   54)
463    (XMM19_REG                   55)
464    (XMM20_REG                   56)
465    (XMM21_REG                   57)
466    (XMM22_REG                   58)
467    (XMM23_REG                   59)
468    (XMM24_REG                   60)
469    (XMM25_REG                   61)
470    (XMM26_REG                   62)
471    (XMM27_REG                   63)
472    (XMM28_REG                   64)
473    (XMM29_REG                   65)
474    (XMM30_REG                   66)
475    (XMM31_REG                   67)
476    (MASK0_REG                   68)
477    (MASK1_REG                   69)
478    (MASK2_REG                   70)
479    (MASK3_REG                   71)
480    (MASK4_REG                   72)
481    (MASK5_REG                   73)
482    (MASK6_REG                   74)
483    (MASK7_REG                   75)
484    (R16_REG                     76)
485    (R17_REG                     77)
486    (R18_REG                     78)
487    (R19_REG                     79)
488    (R20_REG                     80)
489    (R21_REG                     81)
490    (R22_REG                     82)
491    (R23_REG                     83)
492    (R24_REG                     84)
493    (R25_REG                     85)
494    (R26_REG                     86)
495    (R27_REG                     87)
496    (R28_REG                     88)
497    (R29_REG                     89)
498    (R30_REG                     90)
499    (R31_REG                     91)
500    (FIRST_PSEUDO_REG            92)
501   ])
503 ;; Insn callee abi index.
504 (define_constants
505   [(ABI_DEFAULT         0)
506    (ABI_VZEROUPPER      1)
507    (ABI_UNKNOWN         2)])
509 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
510 ;; from i386.cc.
512 ;; In C guard expressions, put expressions which may be compile-time
513 ;; constants first.  This allows for better optimization.  For
514 ;; example, write "TARGET_64BIT && reload_completed", not
515 ;; "reload_completed && TARGET_64BIT".
518 ;; Processor type.
519 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
520                     atom,slm,glm,haswell,generic,lujiazui,yongfeng,amdfam10,bdver1,
521                     bdver2,bdver3,bdver4,btver2,znver1,znver2,znver3,znver4,
522                     znver5"
523   (const (symbol_ref "ix86_schedule")))
525 ;; A basic instruction type.  Refinements due to arguments to be
526 ;; provided in other attributes.
527 (define_attr "type"
528   "other,multi,
529    alu,alu1,negnot,imov,imovx,lea,
530    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
531    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
532    push,pop,call,callv,leave,
533    str,bitmanip,
534    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
535    fxch,fistp,fisttp,frndint,
536    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
537    ssemul,sseimul,ssediv,sselog,sselog1,
538    sseishft,sseishft1,ssecmp,ssecomi,
539    ssecvt,ssecvt1,sseicvt,sseins,
540    sseshuf,sseshuf1,ssemuladd,sse4arg,
541    lwp,mskmov,msklog,
542    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
543   (const_string "other"))
545 ;; Main data type used by the insn
546 (define_attr "mode"
547   "unknown,none,QI,HI,SI,DI,TI,OI,XI,HF,BF,SF,DF,XF,TF,
548    V32HF,V16HF,V8HF,V4HF,V2HF,V32BF,V16BF,V8BF,V4BF,V2BF,
549    V16SF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,V8DF"
550   (const_string "unknown"))
552 ;; The CPU unit operations uses.
553 (define_attr "unit" "integer,i387,sse,mmx,unknown"
554   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
555                           fxch,fistp,fisttp,frndint")
556            (const_string "i387")
557          (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
558                           ssemul,sseimul,ssediv,sselog,sselog1,
559                           sseishft,sseishft1,ssecmp,ssecomi,
560                           ssecvt,ssecvt1,sseicvt,sseins,
561                           sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
562            (const_string "sse")
563          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
564            (const_string "mmx")
565          (eq_attr "type" "other")
566            (const_string "unknown")]
567          (const_string "integer")))
569 ;; Used to control the "enabled" attribute on a per-instruction basis.
570 (define_attr "isa" "base,x64,nox64,x64_sse2,x64_sse4,x64_sse4_noavx,
571                     x64_avx,x64_avx512bw,x64_avx512dq,apx_ndd,apx_ndd_64,
572                     sse_noavx,sse2,sse2_noavx,sse3,sse3_noavx,sse4,sse4_noavx,
573                     avx,noavx,avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,avx512f_512,
574                     noavx512f,avx512bw,avx512bw_512,noavx512bw,avx512dq,
575                     noavx512dq,fma_or_avx512vl,avx512vl,noavx512vl,avxvnni,
576                     avx512vnnivl,avx512fp16,avxifma,avx512ifmavl,avxneconvert,
577                     avx512bf16vl,vpclmulqdqvl,avx_noavx512f,avx_noavx512vl,
578                     vaes_avx512vl"
579   (const_string "base"))
581 ;; The (bounding maximum) length of an instruction immediate.
582 (define_attr "length_immediate" ""
583   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
584                           bitmanip,imulx,msklog,mskmov")
585            (const_int 0)
586          (ior (eq_attr "type" "sse4arg")
587               (eq_attr "isa" "fma4"))
588            (const_int 1)
589          (eq_attr "unit" "i387,sse,mmx")
590            (const_int 0)
591          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
592                           rotate,rotatex,rotate1,imul,icmp,push,pop")
593            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
594          (eq_attr "type" "imov,test")
595            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
596          (eq_attr "type" "call")
597            (if_then_else (match_operand 0 "constant_call_address_operand")
598              (const_int 4)
599              (const_int 0))
600          (eq_attr "type" "callv")
601            (if_then_else (match_operand 1 "constant_call_address_operand")
602              (const_int 4)
603              (const_int 0))
604          ;; We don't know the size before shorten_branches.  Expect
605          ;; the instruction to fit for better scheduling.
606          (eq_attr "type" "ibr")
607            (const_int 1)
608          ]
609          (symbol_ref "/* Update immediate_length and other attributes! */
610                       gcc_unreachable (),1")))
612 ;; The (bounding maximum) length of an instruction address.
613 (define_attr "length_address" ""
614   (cond [(eq_attr "type" "str,other,multi,fxch")
615            (const_int 0)
616          (and (eq_attr "type" "call")
617               (match_operand 0 "constant_call_address_operand"))
618              (const_int 0)
619          (and (eq_attr "type" "callv")
620               (match_operand 1 "constant_call_address_operand"))
621              (const_int 0)
622          ]
623          (symbol_ref "ix86_attr_length_address_default (insn)")))
625 ;; Set when length prefix is used.
626 (define_attr "prefix_data16" ""
627   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
628            (const_int 0)
629          (eq_attr "mode" "HI")
630            (const_int 1)
631          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
632            (const_int 1)
633         ]
634         (const_int 0)))
636 ;; Set when string REP prefix is used.
637 (define_attr "prefix_rep" ""
638   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
639            (const_int 0)
640          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
641            (const_int 1)
642         ]
643         (const_int 0)))
645 ;; Set when 0f opcode prefix is used.
646 (define_attr "prefix_0f" ""
647   (if_then_else
648     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
649          (eq_attr "unit" "sse,mmx"))
650     (const_int 1)
651     (const_int 0)))
653 ;; Set when REX opcode prefix is used.
654 (define_attr "prefix_rex" ""
655   (cond [(not (match_test "TARGET_64BIT"))
656            (const_int 0)
657          (and (eq_attr "mode" "DI")
658               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
659                    (eq_attr "unit" "!mmx")))
660            (const_int 1)
661          (and (eq_attr "mode" "QI")
662               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
663            (const_int 1)
664          (match_test "x86_extended_reg_mentioned_p (insn)")
665            (const_int 1)
666          (and (eq_attr "type" "imovx")
667               (match_operand:QI 1 "ext_QIreg_operand"))
668            (const_int 1)
669         ]
670         (const_int 0)))
672 ;; There are also additional prefixes in 3DNOW, SSSE3.
673 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
674 ;; While generally inapplicable to VEX/XOP/EVEX encodings, "length_vex" uses
675 ;; the attribute evaluating to zero to know that VEX2 encoding may be usable.
676 (define_attr "prefix_extra" ""
677   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
678            (const_int 1)
679         ]
680         (const_int 0)))
682 ;; Prefix used: original, VEX or maybe VEX.
683 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
684   (cond [(eq_attr "mode" "OI,V8SF,V4DF")
685            (const_string "vex")
686          (eq_attr "mode" "XI,V16SF,V8DF")
687            (const_string "evex")
688          (eq_attr "type" "ssemuladd")
689            (if_then_else (eq_attr "isa" "fma4")
690              (const_string "vex")
691              (const_string "maybe_evex"))
692          (eq_attr "type" "sse4arg")
693            (const_string "vex")
694         ]
695         (const_string "orig")))
697 ;; VEX W bit is used.
698 (define_attr "prefix_vex_w" "" (const_int 0))
700 ;; The length of VEX prefix
701 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
702 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
703 ;; still prefix_0f 1, with prefix_extra 1.
704 (define_attr "length_vex" ""
705   (if_then_else (and (eq_attr "prefix_0f" "1")
706                      (eq_attr "prefix_extra" "0"))
707     (if_then_else (eq_attr "prefix_vex_w" "1")
708       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
709       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
710     (if_then_else (eq_attr "prefix_vex_w" "1")
711       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
712       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
714 ;; 4-bytes evex prefix and 1 byte opcode.
715 (define_attr "length_evex" "" (const_int 5))
717 ;; Set when modrm byte is used.
718 (define_attr "modrm" ""
719   (cond [(eq_attr "type" "str,leave")
720            (const_int 0)
721          (eq_attr "unit" "i387")
722            (const_int 0)
723          (and (eq_attr "type" "incdec")
724               (and (not (match_test "TARGET_64BIT"))
725                    (ior (match_operand:SI 1 "register_operand")
726                         (match_operand:HI 1 "register_operand"))))
727            (const_int 0)
728          (and (eq_attr "type" "push")
729               (not (match_operand 1 "memory_operand")))
730            (const_int 0)
731          (and (eq_attr "type" "pop")
732               (not (match_operand 0 "memory_operand")))
733            (const_int 0)
734          (and (eq_attr "type" "imov")
735               (and (not (eq_attr "mode" "DI"))
736                    (ior (and (match_operand 0 "register_operand")
737                              (match_operand 1 "immediate_operand"))
738                         (ior (and (match_operand 0 "ax_reg_operand")
739                                   (match_operand 1 "memory_displacement_only_operand"))
740                              (and (match_operand 0 "memory_displacement_only_operand")
741                                   (match_operand 1 "ax_reg_operand"))))))
742            (const_int 0)
743          (and (eq_attr "type" "call")
744               (match_operand 0 "constant_call_address_operand"))
745              (const_int 0)
746          (and (eq_attr "type" "callv")
747               (match_operand 1 "constant_call_address_operand"))
748              (const_int 0)
749          (and (eq_attr "type" "alu,alu1,icmp,test")
750               (match_operand 0 "ax_reg_operand"))
751              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
752          ]
753          (const_int 1)))
755 ;; The (bounding maximum) length of an instruction in bytes.
756 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
757 ;; Later we may want to split them and compute proper length as for
758 ;; other insns.
759 (define_attr "length" ""
760   (cond [(eq_attr "type" "other,multi,fistp,frndint")
761            (const_int 16)
762          (eq_attr "type" "fcmp")
763            (const_int 4)
764          (eq_attr "unit" "i387")
765            (plus (const_int 2)
766                  (plus (attr "prefix_data16")
767                        (attr "length_address")))
768          (ior (eq_attr "prefix" "evex")
769               (and (ior (eq_attr "prefix" "maybe_evex")
770                         (eq_attr "prefix" "maybe_vex"))
771                    (match_test "TARGET_AVX512F")))
772            (plus (attr "length_evex")
773                  (plus (attr "length_immediate")
774                        (plus (attr "modrm")
775                              (attr "length_address"))))
776          (ior (eq_attr "prefix" "vex")
777               (and (ior (eq_attr "prefix" "maybe_vex")
778                         (eq_attr "prefix" "maybe_evex"))
779                    (match_test "TARGET_AVX")))
780            (plus (attr "length_vex")
781                  (plus (attr "length_immediate")
782                        (plus (attr "modrm")
783                              (attr "length_address"))))]
784          (plus (plus (attr "modrm")
785                      (plus (attr "prefix_0f")
786                            (plus (attr "prefix_rex")
787                                  (plus (attr "prefix_extra")
788                                        (const_int 1)))))
789                (plus (attr "prefix_rep")
790                      (plus (attr "prefix_data16")
791                            (plus (attr "length_immediate")
792                                  (attr "length_address")))))))
794 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
795 ;; `store' if there is a simple memory reference therein, or `unknown'
796 ;; if the instruction is complex.
798 (define_attr "memory" "none,load,store,both,unknown"
799   (cond [(eq_attr "type" "other,multi,str,lwp")
800            (const_string "unknown")
801          (eq_attr "type" "lea,fcmov,fpspc")
802            (const_string "none")
803          (eq_attr "type" "fistp,leave")
804            (const_string "both")
805          (eq_attr "type" "frndint")
806            (const_string "load")
807          (eq_attr "type" "push")
808            (if_then_else (match_operand 1 "memory_operand")
809              (const_string "both")
810              (const_string "store"))
811          (eq_attr "type" "pop")
812            (if_then_else (match_operand 0 "memory_operand")
813              (const_string "both")
814              (const_string "load"))
815          (eq_attr "type" "setcc")
816            (if_then_else (match_operand 0 "memory_operand")
817              (const_string "store")
818              (const_string "none"))
819          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
820            (if_then_else (ior (match_operand 0 "memory_operand")
821                               (match_operand 1 "memory_operand"))
822              (const_string "load")
823              (const_string "none"))
824          (eq_attr "type" "ibr")
825            (if_then_else (match_operand 0 "memory_operand")
826              (const_string "load")
827              (const_string "none"))
828          (eq_attr "type" "call")
829            (if_then_else (match_operand 0 "constant_call_address_operand")
830              (const_string "none")
831              (const_string "load"))
832          (eq_attr "type" "callv")
833            (if_then_else (match_operand 1 "constant_call_address_operand")
834              (const_string "none")
835              (const_string "load"))
836          (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
837               (match_operand 1 "memory_operand"))
838            (const_string "both")
839          (and (match_operand 0 "memory_operand")
840               (match_operand 1 "memory_operand"))
841            (const_string "both")
842          (match_operand 0 "memory_operand")
843            (const_string "store")
844          (match_operand 1 "memory_operand")
845            (const_string "load")
846          (and (eq_attr "type"
847                  "!alu1,negnot,ishift1,rotate1,
848                    imov,imovx,icmp,test,bitmanip,
849                    fmov,fcmp,fsgn,
850                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
851                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
852                    mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
853               (match_operand 2 "memory_operand"))
854            (const_string "load")
855          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
856               (match_operand 3 "memory_operand"))
857            (const_string "load")
858         ]
859         (const_string "none")))
861 ;; Indicates if an instruction has both an immediate and a displacement.
863 (define_attr "imm_disp" "false,true,unknown"
864   (cond [(eq_attr "type" "other,multi")
865            (const_string "unknown")
866          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
867               (and (match_operand 0 "memory_displacement_operand")
868                    (match_operand 1 "immediate_operand")))
869            (const_string "true")
870          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
871               (and (match_operand 0 "memory_displacement_operand")
872                    (match_operand 2 "immediate_operand")))
873            (const_string "true")
874         ]
875         (const_string "false")))
877 ;; Indicates if an FP operation has an integer source.
879 (define_attr "fp_int_src" "false,true"
880   (const_string "false"))
882 ;; Defines rounding mode of an FP operation.
884 (define_attr "i387_cw" "roundeven,floor,ceil,trunc,uninitialized,any"
885   (const_string "any"))
887 ;; Define attribute to indicate AVX insns with partial XMM register update.
888 (define_attr "avx_partial_xmm_update" "false,true"
889   (const_string "false"))
891 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
892 (define_attr "use_carry" "0,1" (const_string "0"))
894 ;; Define attribute to indicate unaligned ssemov insns
895 (define_attr "movu" "0,1" (const_string "0"))
897 ;; Define attribute to limit memory address register set.
898 (define_attr "addr" "gpr8,gpr16,gpr32" (const_string "gpr32"))
900 ;; Define instruction set of MMX instructions
901 (define_attr "mmx_isa" "base,native,sse,sse_noavx,avx"
902   (const_string "base"))
904 (define_attr "enabled" ""
905   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
906          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
907          (eq_attr "isa" "x64_sse2")
908            (symbol_ref "TARGET_64BIT && TARGET_SSE2")
909          (eq_attr "isa" "x64_sse4")
910            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
911          (eq_attr "isa" "x64_sse4_noavx")
912            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
913          (eq_attr "isa" "x64_avx")
914            (symbol_ref "TARGET_64BIT && TARGET_AVX")
915          (eq_attr "isa" "x64_avx512bw")
916            (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
917          (eq_attr "isa" "x64_avx512dq")
918            (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
919          (eq_attr "isa" "sse_noavx")
920            (symbol_ref "TARGET_SSE && !TARGET_AVX")
921          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
922          (eq_attr "isa" "sse2_noavx")
923            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
924          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
925          (eq_attr "isa" "sse3_noavx")
926            (symbol_ref "TARGET_SSE3 && !TARGET_AVX")
927          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
928          (eq_attr "isa" "sse4_noavx")
929            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
930          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
931          (eq_attr "isa" "avx_noavx512f")
932            (symbol_ref "TARGET_AVX && !TARGET_AVX512F")
933          (eq_attr "isa" "avx_noavx512vl")
934            (symbol_ref "TARGET_AVX && !TARGET_AVX512VL")
935          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
936          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
937          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
938          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
939          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
940          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
941          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
942          (eq_attr "isa" "fma_or_avx512vl")
943            (symbol_ref "TARGET_FMA || TARGET_AVX512VL")
944          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
945          (eq_attr "isa" "avx512f_512")
946            (symbol_ref "TARGET_AVX512F && TARGET_EVEX512")
947          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
948          (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
949          (eq_attr "isa" "avx512bw_512")
950            (symbol_ref "TARGET_AVX512BW && TARGET_EVEX512")
951          (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
952          (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
953          (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
954          (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
955          (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
956          (eq_attr "isa" "avxvnni") (symbol_ref "TARGET_AVXVNNI")
957          (eq_attr "isa" "avx512vnnivl")
958            (symbol_ref "TARGET_AVX512VNNI && TARGET_AVX512VL")
959          (eq_attr "isa" "avx512fp16")
960            (symbol_ref "TARGET_AVX512FP16")
961          (eq_attr "isa" "avxifma") (symbol_ref "TARGET_AVXIFMA")
962          (eq_attr "isa" "avx512ifmavl")
963            (symbol_ref "TARGET_AVX512IFMA && TARGET_AVX512VL")
964          (eq_attr "isa" "avxneconvert") (symbol_ref "TARGET_AVXNECONVERT")
965          (eq_attr "isa" "avx512bf16vl")
966            (symbol_ref "TARGET_AVX512BF16 && TARGET_AVX512VL")
967          (eq_attr "isa" "vpclmulqdqvl")
968            (symbol_ref "TARGET_VPCLMULQDQ && TARGET_AVX512VL")
969          (eq_attr "isa" "apx_ndd")
970            (symbol_ref "TARGET_APX_NDD")
971          (eq_attr "isa" "apx_ndd_64")
972            (symbol_ref "TARGET_APX_NDD && Pmode == DImode")
973          (eq_attr "isa" "vaes_avx512vl")
974            (symbol_ref "TARGET_VAES && TARGET_AVX512VL")
976          (eq_attr "mmx_isa" "native")
977            (symbol_ref "!TARGET_MMX_WITH_SSE")
978          (eq_attr "mmx_isa" "sse")
979            (symbol_ref "TARGET_MMX_WITH_SSE")
980          (eq_attr "mmx_isa" "sse_noavx")
981            (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
982          (eq_attr "mmx_isa" "avx")
983            (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
984         ]
985         (const_int 1)))
987 (define_attr "preferred_for_size" "" (const_int 1))
988 (define_attr "preferred_for_speed" "" (const_int 1))
990 ;; Describe a user's asm statement.
991 (define_asm_attributes
992   [(set_attr "length" "128")
993    (set_attr "type" "multi")])
995 (define_code_iterator plusminus [plus minus])
996 (define_code_iterator plusminusmult [plus minus mult])
997 (define_code_iterator plusminusmultdiv [plus minus mult div])
999 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
1001 ;; Base name for insn mnemonic.
1002 (define_code_attr plusminus_mnemonic
1003   [(plus "add") (ss_plus "adds") (us_plus "addus")
1004    (minus "sub") (ss_minus "subs") (us_minus "subus")])
1006 (define_code_iterator multdiv [mult div])
1008 (define_code_attr multdiv_mnemonic
1009   [(mult "mul") (div "div")])
1011 ;; Mark commutative operators as such in constraints.
1012 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
1013                         (minus "") (ss_minus "") (us_minus "")
1014                         (mult "%") (div "")])
1016 ;; Mapping of max and min
1017 (define_code_iterator maxmin [smax smin umax umin])
1019 ;; Mapping of signed max and min
1020 (define_code_iterator smaxmin [smax smin])
1022 ;; Mapping of unsigned max and min
1023 (define_code_iterator umaxmin [umax umin])
1025 ;; Base name for integer and FP insn mnemonic
1026 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
1027                               (umax "maxu") (umin "minu")])
1028 (define_code_attr maxmin_float [(smax "max") (smin "min")])
1030 (define_int_iterator IEEE_MAXMIN
1031         [UNSPEC_IEEE_MAX
1032          UNSPEC_IEEE_MIN])
1034 (define_int_attr ieee_maxmin
1035         [(UNSPEC_IEEE_MAX "max")
1036          (UNSPEC_IEEE_MIN "min")])
1038 ;; Mapping of logic operators
1039 (define_code_iterator any_logic [and ior xor])
1040 (define_code_iterator any_or [ior xor])
1041 (define_code_iterator fpint_logic [and xor])
1043 ;; Base name for insn mnemonic.
1044 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
1046 ;; Mapping of logic-shift operators
1047 (define_code_iterator any_lshift [ashift lshiftrt])
1049 ;; Mapping of shift-right operators
1050 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
1052 ;; Mapping of all shift operators
1053 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
1055 ;; Base name for insn mnemonic.
1056 (define_code_attr shift [(ashift "sal") (lshiftrt "shr") (ashiftrt "sar")])
1057 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
1059 ;; Mapping of rotate operators
1060 (define_code_iterator any_rotate [rotate rotatert])
1062 ;; Base name for insn mnemonic.
1063 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
1065 ;; Mapping of abs neg operators
1066 (define_code_iterator absneg [abs neg])
1068 ;; Mapping of abs neg operators to logic operation
1069 (define_code_attr absneg_op [(abs "and") (neg "xor")])
1071 ;; Base name for x87 insn mnemonic.
1072 (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
1074 ;; Mapping of extend operators
1075 (define_code_iterator any_extend [sign_extend zero_extend])
1077 ;; Mapping of highpart multiply operators
1078 (define_code_iterator any_mul_highpart [smul_highpart umul_highpart])
1080 ;; Prefix for insn menmonic.
1081 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
1082                              (smul_highpart "i") (umul_highpart "")
1083                              (div "i") (udiv "")])
1084 ;; Prefix for define_insn
1085 (define_code_attr s [(sign_extend "s") (zero_extend "u")
1086                      (smul_highpart "s") (umul_highpart "u")])
1087 (define_code_attr u [(sign_extend "") (zero_extend "u")
1088                      (div "") (udiv "u")])
1089 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")
1090                           (div "false") (udiv "true")])
1092 ;; Used in signed and unsigned truncations.
1093 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
1094 ;; Instruction suffix for truncations.
1095 (define_code_attr trunsuffix
1096   [(ss_truncate "s") (truncate "") (us_truncate "us")])
1098 ;; Instruction suffix for SSE sign and zero extensions.
1099 (define_code_attr extsuffix [(sign_extend "sx") (zero_extend "zx")])
1101 ;; Used in signed and unsigned fix.
1102 (define_code_iterator any_fix [fix unsigned_fix])
1103 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
1104 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
1105 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
1107 ;; Used in signed and unsigned float.
1108 (define_code_iterator any_float [float unsigned_float])
1109 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
1110 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
1111 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
1113 ;; Base name for expression
1114 (define_code_attr insn
1115   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
1116    (minus "sub") (ss_minus "sssub") (us_minus "ussub")
1117    (sign_extend "extend") (zero_extend "zero_extend")
1118    (ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")
1119    (rotate "rotl") (rotatert "rotr")
1120    (mult "mul") (div "div")])
1122 ;; All integer modes.
1123 (define_mode_iterator SWI1248x [QI HI SI DI])
1125 ;; All integer modes without QImode.
1126 (define_mode_iterator SWI248x [HI SI DI])
1128 ;; All integer modes without QImode and HImode.
1129 (define_mode_iterator SWI48x [SI DI])
1131 ;; All integer modes without SImode and DImode.
1132 (define_mode_iterator SWI12 [QI HI])
1134 ;; All integer modes without DImode.
1135 (define_mode_iterator SWI124 [QI HI SI])
1137 ;; All integer modes without QImode and DImode.
1138 (define_mode_iterator SWI24 [HI SI])
1140 ;; Single word integer modes.
1141 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1143 ;; Single word integer modes without QImode.
1144 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1146 ;; Single word integer modes without QImode and HImode.
1147 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1149 ;; All math-dependant single and double word integer modes.
1150 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1151                              (HI "TARGET_HIMODE_MATH")
1152                              SI DI (TI "TARGET_64BIT")])
1154 ;; Math-dependant single word integer modes.
1155 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1156                             (HI "TARGET_HIMODE_MATH")
1157                             SI (DI "TARGET_64BIT")])
1159 ;; Math-dependant integer modes without DImode.
1160 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1161                                (HI "TARGET_HIMODE_MATH")
1162                                SI])
1164 ;; Math-dependant integer modes with DImode.
1165 (define_mode_iterator SWIM1248x
1166         [(QI "TARGET_QIMODE_MATH")
1167          (HI "TARGET_HIMODE_MATH")
1168          SI DI])
1170 ;; Math-dependant single word integer modes without QImode.
1171 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1172                                SI (DI "TARGET_64BIT")])
1174 ;; Double word integer modes.
1175 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1176                            (TI "TARGET_64BIT")])
1178 ;; SWI and DWI together.
1179 (define_mode_iterator SWIDWI [QI HI SI DI (TI "TARGET_64BIT")])
1181 ;; SWI48 and DWI together.
1182 (define_mode_iterator SWI48DWI [SI DI (TI "TARGET_64BIT")])
1184 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
1185 ;; compile time constant, it is faster to use <MODE_SIZE> than
1186 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
1187 ;; command line options just use GET_MODE_SIZE macro.
1188 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8")
1189                              (TI "16") (HF "2") (BF "2") (SF "4") (DF "8")
1190                              (XF "GET_MODE_SIZE (XFmode)")
1191                              (V16QI "16") (V32QI "32") (V64QI "64")
1192                              (V8HI "16") (V16HI "32") (V32HI "64")
1193                              (V4SI "16") (V8SI "32") (V16SI "64")
1194                              (V2DI "16") (V4DI "32") (V8DI "64")
1195                              (V1TI "16") (V2TI "32") (V4TI "64")
1196                              (V2DF "16") (V4DF "32") (V8DF "64")
1197                              (V4SF "16") (V8SF "32") (V16SF "64")
1198                              (V8HF "16") (V16HF "32") (V32HF "64")
1199                              (V4HF "8") (V2HF "4")
1200                              (V8BF "16") (V16BF "32") (V32BF "64")
1201                              (V4BF "8") (V2BF "4")])
1203 ;; Double word integer modes as mode attribute.
1204 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "OI")])
1205 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti") (TI "oi")])
1207 ;; Half sized integer modes.
1208 (define_mode_attr HALF [(TI "DI") (DI "SI")])
1209 (define_mode_attr half [(TI "di") (DI "si")])
1211 ;; LEA mode corresponding to an integer mode
1212 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1214 ;; Half mode for double word integer modes.
1215 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1216                             (DI "TARGET_64BIT")])
1218 ;; Instruction suffix for integer modes.
1219 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1221 ;; Instruction suffix for masks.
1222 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1224 ;; Pointer size prefix for integer modes (Intel asm dialect)
1225 (define_mode_attr iptrsize [(QI "BYTE")
1226                             (HI "WORD")
1227                             (SI "DWORD")
1228                             (DI "QWORD")])
1230 ;; Register class for integer modes.
1231 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1233 ;; Immediate operand constraint for integer modes.
1234 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1236 ;; General operand constraint for word modes.
1237 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1239 ;; Memory operand constraint for word modes.
1240 (define_mode_attr m [(QI "m") (HI "m") (SI "BM") (DI "BM")])
1242 ;; Immediate operand constraint for double integer modes.
1243 (define_mode_attr di [(SI "nF") (DI "Wd")])
1245 ;; Immediate operand constraint for shifts.
1246 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1247 (define_mode_attr KS [(QI "Wb") (HI "Ww") (SI "I") (DI "J")])
1249 ;; Print register name in the specified mode.
1250 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1252 ;; General operand predicate for integer modes.
1253 (define_mode_attr general_operand
1254         [(QI "general_operand")
1255          (HI "general_operand")
1256          (SI "x86_64_general_operand")
1257          (DI "x86_64_general_operand")
1258          (TI "x86_64_general_operand")])
1260 ;; General operand predicate for integer modes, where for TImode
1261 ;; we need both words of the operand to be general operands.
1262 (define_mode_attr general_hilo_operand
1263         [(QI "general_operand")
1264          (HI "general_operand")
1265          (SI "x86_64_general_operand")
1266          (DI "x86_64_general_operand")
1267          (TI "x86_64_hilo_general_operand")])
1269 ;; General sign extend operand predicate for integer modes,
1270 ;; which disallows VOIDmode operands and thus it is suitable
1271 ;; for use inside sign_extend.
1272 (define_mode_attr general_sext_operand
1273         [(QI "sext_operand")
1274          (HI "sext_operand")
1275          (SI "x86_64_sext_operand")
1276          (DI "x86_64_sext_operand")])
1278 ;; General sign/zero extend operand predicate for integer modes.
1279 (define_mode_attr general_szext_operand
1280         [(QI "general_operand")
1281          (HI "general_operand")
1282          (SI "x86_64_szext_general_operand")
1283          (DI "x86_64_szext_general_operand")
1284          (TI "x86_64_hilo_general_operand")])
1286 (define_mode_attr nonmemory_szext_operand
1287         [(QI "nonmemory_operand")
1288          (HI "nonmemory_operand")
1289          (SI "x86_64_szext_nonmemory_operand")
1290          (DI "x86_64_szext_nonmemory_operand")])
1292 ;; Immediate operand predicate for integer modes.
1293 (define_mode_attr immediate_operand
1294         [(QI "immediate_operand")
1295          (HI "immediate_operand")
1296          (SI "x86_64_immediate_operand")
1297          (DI "x86_64_immediate_operand")])
1299 ;; Nonmemory operand predicate for integer modes.
1300 (define_mode_attr nonmemory_operand
1301         [(QI "nonmemory_operand")
1302          (HI "nonmemory_operand")
1303          (SI "x86_64_nonmemory_operand")
1304          (DI "x86_64_nonmemory_operand")])
1306 ;; Operand predicate for shifts.
1307 (define_mode_attr shift_operand
1308         [(QI "nonimmediate_operand")
1309          (HI "nonimmediate_operand")
1310          (SI "nonimmediate_operand")
1311          (DI "shiftdi_operand")
1312          (TI "register_operand")])
1314 ;; Operand predicate for shift argument.
1315 (define_mode_attr shift_immediate_operand
1316         [(QI "const_1_to_31_operand")
1317          (HI "const_1_to_31_operand")
1318          (SI "const_1_to_31_operand")
1319          (DI "const_1_to_63_operand")])
1321 ;; Input operand predicate for arithmetic left shifts.
1322 (define_mode_attr ashl_input_operand
1323         [(QI "nonimmediate_operand")
1324          (HI "nonimmediate_operand")
1325          (SI "nonimmediate_operand")
1326          (DI "ashldi_input_operand")
1327          (TI "reg_or_pm1_operand")])
1329 ;; SSE and x87 SFmode and DFmode floating point modes
1330 (define_mode_iterator MODEF [SF DF])
1332 (define_mode_iterator MODEF248 [BF HF SF (DF "TARGET_SSE2")])
1334 ;; SSE floating point modes
1335 (define_mode_iterator MODEFH [(HF "TARGET_AVX512FP16") SF DF])
1337 ;; All x87 floating point modes
1338 (define_mode_iterator X87MODEF [SF DF XF])
1340 ;; All x87 floating point modes plus HFmode
1341 (define_mode_iterator X87MODEFH [HF SF DF XF BF])
1343 ;; All SSE floating point modes
1344 (define_mode_iterator SSEMODEF [HF SF DF TF])
1345 (define_mode_attr ssevecmodef [(HF "V8HF") (SF "V4SF") (DF "V2DF") (TF "TF")])
1347 ;; SSE instruction suffix for various modes
1348 (define_mode_attr ssemodesuffix
1349   [(HF "sh") (SF "ss") (DF "sd")
1350    (V32HF "ph") (V16SF "ps") (V8DF "pd")
1351    (V16HF "ph") (V16BF "bf") (V8SF "ps") (V4DF "pd")
1352    (V8HF "ph")  (V8BF "bf") (V4SF "ps") (V2DF "pd")
1353    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1354    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1355    (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1357 ;; SSE vector suffix for floating point modes
1358 ;; BF HF use same suffix as SF for logic operations.
1359 (define_mode_attr ssevecmodesuffix [(BF "ps") (HF "ps") (SF "ps") (DF "pd")])
1361 ;; SSE vector mode corresponding to a scalar mode
1362 (define_mode_attr ssevecmode
1363   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (HF "V8HF") (BF "V8BF") (SF "V4SF") (DF "V2DF")])
1364 (define_mode_attr ssevecmodelower
1365   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1367 ;; AVX512F vector mode corresponding to a scalar mode
1368 (define_mode_attr avx512fvecmode
1369   [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI")
1370    (HF "V32HF") (BF "V32BF") (SF "V16SF") (DF "V8DF")])
1372 ;; Instruction suffix for REX 64bit operators.
1373 (define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")])
1374 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1376 ;; This mode iterator allows :P to be used for patterns that operate on
1377 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1378 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1380 ;; This mode iterator allows :W to be used for patterns that operate on
1381 ;; word_mode sized quantities.
1382 (define_mode_iterator W
1383   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1385 ;; This mode iterator allows :PTR to be used for patterns that operate on
1386 ;; ptr_mode sized quantities.
1387 (define_mode_iterator PTR
1388   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1390 ;; Scheduling descriptions
1392 (include "pentium.md")
1393 (include "ppro.md")
1394 (include "k6.md")
1395 (include "athlon.md")
1396 (include "bdver1.md")
1397 (include "bdver3.md")
1398 (include "btver2.md")
1399 (include "znver.md")
1400 (include "zn4zn5.md")
1401 (include "geode.md")
1402 (include "atom.md")
1403 (include "slm.md")
1404 (include "glm.md")
1405 (include "core2.md")
1406 (include "haswell.md")
1407 (include "lujiazui.md")
1408 (include "yongfeng.md")
1411 ;; Operand and operator predicates and constraints
1413 (include "predicates.md")
1414 (include "constraints.md")
1417 ;; Compare and branch/compare and store instructions.
1419 (define_expand "cbranch<mode>4"
1420   [(set (reg:CC FLAGS_REG)
1421         (compare:CC (match_operand:SWIM1248x 1 "nonimmediate_operand")
1422                     (match_operand:SWIM1248x 2 "<general_operand>")))
1423    (set (pc) (if_then_else
1424                (match_operator 0 "ordered_comparison_operator"
1425                 [(reg:CC FLAGS_REG) (const_int 0)])
1426                (label_ref (match_operand 3))
1427                (pc)))]
1428   ""
1430   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1431     operands[1] = force_reg (<MODE>mode, operands[1]);
1432   ix86_expand_branch (GET_CODE (operands[0]),
1433                       operands[1], operands[2], operands[3]);
1434   DONE;
1437 (define_expand "cbranchti4"
1438   [(set (reg:CC FLAGS_REG)
1439         (compare:CC (match_operand:TI 1 "nonimmediate_operand")
1440                     (match_operand:TI 2 "ix86_timode_comparison_operand")))
1441    (set (pc) (if_then_else
1442                (match_operator 0 "ix86_timode_comparison_operator"
1443                 [(reg:CC FLAGS_REG) (const_int 0)])
1444                (label_ref (match_operand 3))
1445                (pc)))]
1446   "TARGET_64BIT || TARGET_SSE4_1"
1448   ix86_expand_branch (GET_CODE (operands[0]),
1449                       operands[1], operands[2], operands[3]);
1450   DONE;
1453 (define_expand "cbranchoi4"
1454   [(set (reg:CC FLAGS_REG)
1455         (compare:CC (match_operand:OI 1 "nonimmediate_operand")
1456                     (match_operand:OI 2 "nonimmediate_operand")))
1457    (set (pc) (if_then_else
1458                (match_operator 0 "bt_comparison_operator"
1459                 [(reg:CC FLAGS_REG) (const_int 0)])
1460                (label_ref (match_operand 3))
1461                (pc)))]
1462   "TARGET_AVX"
1464   ix86_expand_branch (GET_CODE (operands[0]),
1465                       operands[1], operands[2], operands[3]);
1466   DONE;
1469 (define_expand "cbranchxi4"
1470   [(set (reg:CC FLAGS_REG)
1471         (compare:CC (match_operand:XI 1 "nonimmediate_operand")
1472                     (match_operand:XI 2 "nonimmediate_operand")))
1473    (set (pc) (if_then_else
1474                (match_operator 0 "bt_comparison_operator"
1475                 [(reg:CC FLAGS_REG) (const_int 0)])
1476                (label_ref (match_operand 3))
1477                (pc)))]
1478   "TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256"
1480   ix86_expand_branch (GET_CODE (operands[0]),
1481                       operands[1], operands[2], operands[3]);
1482   DONE;
1485 (define_expand "cstore<mode>4"
1486   [(set (reg:CC FLAGS_REG)
1487         (compare:CC (match_operand:SDWIM 2 "nonimmediate_operand")
1488                     (match_operand:SDWIM 3 "<general_operand>")))
1489    (set (match_operand:QI 0 "register_operand")
1490         (match_operator 1 "ordered_comparison_operator"
1491           [(reg:CC FLAGS_REG) (const_int 0)]))]
1492   ""
1494   if (<MODE>mode == (TARGET_64BIT ? TImode : DImode))
1495     {
1496       if (GET_CODE (operands[1]) != EQ
1497           && GET_CODE (operands[1]) != NE)
1498         FAIL;
1499     }
1500   else if (MEM_P (operands[2]) && MEM_P (operands[3]))
1501     operands[2] = force_reg (<MODE>mode, operands[2]);
1502   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1503                      operands[2], operands[3]);
1504   DONE;
1507 (define_expand "@cmp<mode>_1"
1508   [(set (reg:CC FLAGS_REG)
1509         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1510                     (match_operand:SWI48 1 "<general_operand>")))])
1512 (define_mode_iterator SWI1248_AVX512BWDQ_64
1513   [(QI "TARGET_AVX512DQ") HI
1514    (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1516 (define_insn "*cmp<mode>_ccz_1"
1517   [(set (reg FLAGS_REG)
1518         (compare (match_operand:SWI1248_AVX512BWDQ_64 0
1519                         "nonimmediate_operand" "<r>,?m<r>,$k")
1520                  (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))]
1521   "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
1522   "@
1523    test{<imodesuffix>}\t%0, %0
1524    cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1525    kortest<mskmodesuffix>\t%0, %0"
1526   [(set_attr "type" "test,icmp,msklog")
1527    (set_attr "length_immediate" "0,1,*")
1528    (set_attr "prefix" "*,*,vex")
1529    (set_attr "mode" "<MODE>")])
1531 (define_insn "*cmp<mode>_ccno_1"
1532   [(set (reg FLAGS_REG)
1533         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1534                  (match_operand:SWI 1 "const0_operand")))]
1535   "ix86_match_ccmode (insn, CCNOmode)"
1536   "@
1537    test{<imodesuffix>}\t%0, %0
1538    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1539   [(set_attr "type" "test,icmp")
1540    (set_attr "length_immediate" "0,1")
1541    (set_attr "mode" "<MODE>")])
1543 (define_insn "*cmp<mode>_1"
1544   [(set (reg FLAGS_REG)
1545         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1546                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>")))]
1547   "ix86_match_ccmode (insn, CCmode)"
1548   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1549   [(set_attr "type" "icmp")
1550    (set_attr "mode" "<MODE>")])
1552 (define_insn "*cmp<mode>_minus_1"
1553   [(set (reg FLAGS_REG)
1554         (compare
1555           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1556                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>"))
1557           (const_int 0)))]
1558   "ix86_match_ccmode (insn, CCGOCmode)"
1559   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1560   [(set_attr "type" "icmp")
1561    (set_attr "mode" "<MODE>")])
1563 (define_insn "*cmpqi_ext<mode>_1"
1564   [(set (reg FLAGS_REG)
1565         (compare
1566           (match_operand:QI 0 "nonimmediate_operand" "QBn")
1567           (subreg:QI
1568             (match_operator:SWI248 2 "extract_operator"
1569               [(match_operand 1 "int248_register_operand" "Q")
1570                (const_int 8)
1571                (const_int 8)]) 0)))]
1572   "ix86_match_ccmode (insn, CCmode)"
1573   "cmp{b}\t{%h1, %0|%0, %h1}"
1574   [(set_attr "addr" "gpr8")
1575    (set_attr "type" "icmp")
1576    (set_attr "mode" "QI")])
1578 (define_insn "*cmpqi_ext<mode>_2"
1579   [(set (reg FLAGS_REG)
1580         (compare
1581           (subreg:QI
1582             (match_operator:SWI248 2 "extract_operator"
1583               [(match_operand 0 "int248_register_operand" "Q")
1584                (const_int 8)
1585                (const_int 8)]) 0)
1586           (match_operand:QI 1 "const0_operand")))]
1587   "ix86_match_ccmode (insn, CCNOmode)"
1588   "test{b}\t%h0, %h0"
1589   [(set_attr "type" "test")
1590    (set_attr "length_immediate" "0")
1591    (set_attr "mode" "QI")])
1593 (define_expand "cmpqi_ext_3"
1594   [(set (reg:CC FLAGS_REG)
1595         (compare:CC
1596           (subreg:QI
1597             (zero_extract:HI
1598               (match_operand:HI 0 "register_operand")
1599               (const_int 8)
1600               (const_int 8)) 0)
1601           (match_operand:QI 1 "const_int_operand")))])
1603 (define_insn "*cmpqi_ext<mode>_3"
1604   [(set (reg FLAGS_REG)
1605         (compare
1606           (subreg:QI
1607             (match_operator:SWI248 2 "extract_operator"
1608               [(match_operand 0 "int248_register_operand" "Q")
1609                (const_int 8)
1610                (const_int 8)]) 0)
1611           (match_operand:QI 1 "general_operand" "QnBn")))]
1612   "ix86_match_ccmode (insn, CCmode)"
1613   "cmp{b}\t{%1, %h0|%h0, %1}"
1614   [(set_attr "addr" "gpr8")
1615    (set_attr "type" "icmp")
1616    (set_attr "mode" "QI")])
1618 (define_insn "*cmpqi_ext<mode>_4"
1619   [(set (reg FLAGS_REG)
1620         (compare
1621           (subreg:QI
1622             (match_operator:SWI248 2 "extract_operator"
1623               [(match_operand 0 "int248_register_operand" "Q")
1624                (const_int 8)
1625                (const_int 8)]) 0)
1626           (subreg:QI
1627             (match_operator:SWI248 3 "extract_operator"
1628               [(match_operand 1 "int248_register_operand" "Q")
1629                (const_int 8)
1630                (const_int 8)]) 0)))]
1631   "ix86_match_ccmode (insn, CCmode)"
1632   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1633   [(set_attr "type" "icmp")
1634    (set_attr "mode" "QI")])
1636 (define_insn_and_split "*cmp<dwi>_doubleword"
1637   [(set (reg:CCZ FLAGS_REG)
1638         (compare:CCZ (match_operand:<DWI> 0 "nonimmediate_operand")
1639                      (match_operand:<DWI> 1 "general_operand")))]
1640   "ix86_pre_reload_split ()"
1641   "#"
1642   "&& 1"
1643   [(parallel [(set (reg:CCZ FLAGS_REG)
1644                    (compare:CCZ (ior:DWIH (match_dup 4) (match_dup 5))
1645                                 (const_int 0)))
1646               (set (match_dup 4) (ior:DWIH (match_dup 4) (match_dup 5)))])]
1648   split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);
1650   operands[4] = gen_reg_rtx (<MODE>mode);
1652   /* Special case comparisons against -1.  */
1653   if (operands[1] == constm1_rtx && operands[3] == constm1_rtx)
1654     {
1655       emit_insn (gen_and<mode>3 (operands[4], operands[0], operands[2]));
1656       emit_insn (gen_cmp_1 (<MODE>mode, operands[4], constm1_rtx));
1657       DONE;
1658     }
1660   if (operands[1] == const0_rtx)
1661     emit_move_insn (operands[4], operands[0]);
1662   else if (operands[0] == const0_rtx)
1663     emit_move_insn (operands[4], operands[1]);
1664   else if (operands[1] == constm1_rtx)
1665     emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[0]));
1666   else if (operands[0] == constm1_rtx)
1667     emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[1]));
1668   else
1669     {
1670       if (CONST_SCALAR_INT_P (operands[1])
1671           && !x86_64_immediate_operand (operands[1], <MODE>mode))
1672         operands[1] = force_reg (<MODE>mode, operands[1]);
1673       emit_insn (gen_xor<mode>3 (operands[4], operands[0], operands[1]));
1674     }
1676   if (operands[3] == const0_rtx)
1677     operands[5] = operands[2];
1678   else if (operands[2] == const0_rtx)
1679     operands[5] = operands[3];
1680   else
1681     {
1682       operands[5] = gen_reg_rtx (<MODE>mode);
1683       if (operands[3] == constm1_rtx)
1684         emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[2]));
1685       else if (operands[2] == constm1_rtx)
1686         emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[3]));
1687       else
1688         {
1689           if (CONST_SCALAR_INT_P (operands[3])
1690               && !x86_64_immediate_operand (operands[3], <MODE>mode))
1691             operands[3] = force_reg (<MODE>mode, operands[3]);
1692           emit_insn (gen_xor<mode>3 (operands[5], operands[2], operands[3]));
1693         }
1694     }
1697 ;; These implement float point compares.
1698 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1699 ;; which would allow mix and match FP modes on the compares.  Which is what
1700 ;; the old patterns did, but with many more of them.
1702 (define_expand "cbranchxf4"
1703   [(set (reg:CC FLAGS_REG)
1704         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1705                     (match_operand:XF 2 "nonmemory_operand")))
1706    (set (pc) (if_then_else
1707               (match_operator 0 "ix86_fp_comparison_operator"
1708                [(reg:CC FLAGS_REG)
1709                 (const_int 0)])
1710               (label_ref (match_operand 3))
1711               (pc)))]
1712   "TARGET_80387"
1714   ix86_expand_branch (GET_CODE (operands[0]),
1715                       operands[1], operands[2], operands[3]);
1716   DONE;
1719 (define_expand "cstorexf4"
1720   [(set (reg:CC FLAGS_REG)
1721         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1722                     (match_operand:XF 3 "nonmemory_operand")))
1723    (set (match_operand:QI 0 "register_operand")
1724               (match_operator 1 "ix86_fp_comparison_operator"
1725                [(reg:CC FLAGS_REG)
1726                 (const_int 0)]))]
1727   "TARGET_80387"
1729   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1730                      operands[2], operands[3]);
1731   DONE;
1734 (define_expand "cbranchhf4"
1735   [(set (reg:CC FLAGS_REG)
1736         (compare:CC (match_operand:HF 1 "cmp_fp_expander_operand")
1737                     (match_operand:HF 2 "cmp_fp_expander_operand")))
1738    (set (pc) (if_then_else
1739               (match_operator 0 "ix86_fp_comparison_operator"
1740                [(reg:CC FLAGS_REG)
1741                 (const_int 0)])
1742               (label_ref (match_operand 3))
1743               (pc)))]
1744   "TARGET_AVX512FP16"
1746   ix86_expand_branch (GET_CODE (operands[0]),
1747                       operands[1], operands[2], operands[3]);
1748   DONE;
1751 (define_expand "cbranch<mode>4"
1752   [(set (reg:CC FLAGS_REG)
1753         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1754                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1755    (set (pc) (if_then_else
1756               (match_operator 0 "ix86_fp_comparison_operator"
1757                [(reg:CC FLAGS_REG)
1758                 (const_int 0)])
1759               (label_ref (match_operand 3))
1760               (pc)))]
1761   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1763   ix86_expand_branch (GET_CODE (operands[0]),
1764                       operands[1], operands[2], operands[3]);
1765   DONE;
1768 (define_expand "cbranchbf4"
1769   [(set (reg:CC FLAGS_REG)
1770         (compare:CC (match_operand:BF 1 "cmp_fp_expander_operand")
1771                     (match_operand:BF 2 "cmp_fp_expander_operand")))
1772    (set (pc) (if_then_else
1773               (match_operator 0 "comparison_operator"
1774                [(reg:CC FLAGS_REG)
1775                 (const_int 0)])
1776               (label_ref (match_operand 3))
1777               (pc)))]
1778   "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1780   rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[1]);
1781   rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1782   do_compare_rtx_and_jump (op1, op2, GET_CODE (operands[0]), 0,
1783                            SFmode, NULL_RTX, NULL,
1784                            as_a <rtx_code_label *> (operands[3]),
1785                            /* Unfortunately this isn't propagated.  */
1786                            profile_probability::even ());
1787   DONE;
1790 (define_expand "cstorehf4"
1791   [(set (reg:CC FLAGS_REG)
1792         (compare:CC (match_operand:HF 2 "cmp_fp_expander_operand")
1793                     (match_operand:HF 3 "cmp_fp_expander_operand")))
1794    (set (match_operand:QI 0 "register_operand")
1795         (match_operator 1 "ix86_fp_comparison_operator"
1796           [(reg:CC FLAGS_REG)
1797            (const_int 0)]))]
1798   "TARGET_AVX512FP16"
1800   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1801                      operands[2], operands[3]);
1802   DONE;
1805 (define_expand "cstorebf4"
1806   [(set (reg:CC FLAGS_REG)
1807         (compare:CC (match_operand:BF 2 "cmp_fp_expander_operand")
1808                     (match_operand:BF 3 "cmp_fp_expander_operand")))
1809    (set (match_operand:QI 0 "register_operand")
1810         (match_operator 1 "comparison_operator"
1811           [(reg:CC FLAGS_REG)
1812            (const_int 0)]))]
1813   "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1815   rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1816   rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[3]);
1817   rtx res = emit_store_flag_force (operands[0], GET_CODE (operands[1]),
1818                                    op1, op2, SFmode, 0, 1);
1819   if (!rtx_equal_p (res, operands[0]))
1820     emit_move_insn (operands[0], res);
1821   DONE;
1824 (define_expand "cstore<mode>4"
1825   [(set (reg:CC FLAGS_REG)
1826         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1827                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1828    (set (match_operand:QI 0 "register_operand")
1829               (match_operator 1 "ix86_fp_comparison_operator"
1830                [(reg:CC FLAGS_REG)
1831                 (const_int 0)]))]
1832   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1834   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1835                      operands[2], operands[3]);
1836   DONE;
1839 (define_expand "cbranchcc4"
1840   [(set (pc) (if_then_else
1841               (match_operator 0 "comparison_operator"
1842                [(match_operand 1 "flags_reg_operand")
1843                 (match_operand 2 "const0_operand")])
1844               (label_ref (match_operand 3))
1845               (pc)))]
1846   ""
1848   ix86_expand_branch (GET_CODE (operands[0]),
1849                       operands[1], operands[2], operands[3]);
1850   DONE;
1853 (define_expand "cstorecc4"
1854   [(set (match_operand:QI 0 "register_operand")
1855               (match_operator 1 "comparison_operator"
1856                [(match_operand 2 "flags_reg_operand")
1857                 (match_operand 3 "const0_operand")]))]
1858   ""
1860   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1861                      operands[2], operands[3]);
1862   DONE;
1865 ;; FP compares, step 1:
1866 ;; Set the FP condition codes and move fpsr to ax.
1868 ;; We may not use "#" to split and emit these
1869 ;; due to reg-stack pops killing fpsr.
1871 (define_insn "*cmpxf_i387"
1872   [(set (match_operand:HI 0 "register_operand" "=a")
1873         (unspec:HI
1874           [(compare:CCFP
1875              (match_operand:XF 1 "register_operand" "f")
1876              (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1877           UNSPEC_FNSTSW))]
1878   "TARGET_80387"
1879   "* return output_fp_compare (insn, operands, false, false);"
1880   [(set_attr "type" "multi")
1881    (set_attr "unit" "i387")
1882    (set_attr "mode" "XF")])
1884 (define_insn "*cmp<mode>_i387"
1885   [(set (match_operand:HI 0 "register_operand" "=a")
1886         (unspec:HI
1887           [(compare:CCFP
1888              (match_operand:MODEF 1 "register_operand" "f")
1889              (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1890           UNSPEC_FNSTSW))]
1891   "TARGET_80387"
1892   "* return output_fp_compare (insn, operands, false, false);"
1893   [(set_attr "type" "multi")
1894    (set_attr "unit" "i387")
1895    (set_attr "mode" "<MODE>")])
1897 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1898   [(set (match_operand:HI 0 "register_operand" "=a")
1899         (unspec:HI
1900           [(compare:CCFP
1901              (match_operand:X87MODEF 1 "register_operand" "f")
1902              (float:X87MODEF
1903                (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1904           UNSPEC_FNSTSW))]
1905   "TARGET_80387
1906    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1907        || optimize_function_for_size_p (cfun))"
1908   "* return output_fp_compare (insn, operands, false, false);"
1909   [(set_attr "type" "multi")
1910    (set_attr "unit" "i387")
1911    (set_attr "fp_int_src" "true")
1912    (set_attr "mode" "<SWI24:MODE>")])
1914 (define_insn "*cmpu<mode>_i387"
1915   [(set (match_operand:HI 0 "register_operand" "=a")
1916         (unspec:HI
1917           [(unspec:CCFP
1918              [(compare:CCFP
1919                 (match_operand:X87MODEF 1 "register_operand" "f")
1920                 (match_operand:X87MODEF 2 "register_operand" "f"))]
1921              UNSPEC_NOTRAP)]
1922           UNSPEC_FNSTSW))]
1923   "TARGET_80387"
1924   "* return output_fp_compare (insn, operands, false, true);"
1925   [(set_attr "type" "multi")
1926    (set_attr "unit" "i387")
1927    (set_attr "mode" "<MODE>")])
1929 ;; FP compares, step 2:
1930 ;; Get ax into flags, general case.
1932 (define_insn "x86_sahf_1"
1933   [(set (reg:CC FLAGS_REG)
1934         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1935                    UNSPEC_SAHF))]
1936   "TARGET_SAHF"
1938 #ifndef HAVE_AS_IX86_SAHF
1939   if (TARGET_64BIT)
1940     return ASM_BYTE "0x9e";
1941   else
1942 #endif
1943   return "sahf";
1945   [(set_attr "length" "1")
1946    (set_attr "athlon_decode" "vector")
1947    (set_attr "amdfam10_decode" "direct")
1948    (set_attr "bdver1_decode" "direct")
1949    (set_attr "mode" "SI")])
1951 ;; Pentium Pro can do both steps in one go.
1952 ;; (these instructions set flags directly)
1954 (define_subst_attr "unord" "unord_subst" "" "u")
1955 (define_subst_attr "unordered" "unord_subst" "false" "true")
1957 (define_subst "unord_subst"
1958   [(set (match_operand:CCFP 0)
1959         (match_operand:CCFP 1))]
1960   ""
1961   [(set (match_dup 0)
1962         (unspec:CCFP
1963           [(match_dup 1)]
1964           UNSPEC_NOTRAP))])
1966 (define_insn "*cmpi<unord>xf_i387"
1967   [(set (reg:CCFP FLAGS_REG)
1968         (compare:CCFP
1969           (match_operand:XF 0 "register_operand" "f")
1970           (match_operand:XF 1 "register_operand" "f")))]
1971   "TARGET_80387 && TARGET_CMOVE"
1972   "* return output_fp_compare (insn, operands, true, <unordered>);"
1973   [(set_attr "type" "fcmp")
1974    (set_attr "mode" "XF")
1975    (set_attr "athlon_decode" "vector")
1976    (set_attr "amdfam10_decode" "direct")
1977    (set_attr "bdver1_decode" "double")
1978    (set_attr "znver1_decode" "double")])
1980 (define_insn "*cmpi<unord><MODEF:mode>"
1981   [(set (reg:CCFP FLAGS_REG)
1982         (compare:CCFP
1983           (match_operand:MODEF 0 "register_operand" "f,v")
1984           (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1985   "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1986    || (TARGET_80387 && TARGET_CMOVE)"
1987   "@
1988    * return output_fp_compare (insn, operands, true, <unordered>);
1989    %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1990   [(set_attr "type" "fcmp,ssecomi")
1991    (set_attr "prefix" "orig,maybe_vex")
1992    (set_attr "mode" "<MODEF:MODE>")
1993    (set_attr "prefix_rep" "*,0")
1994    (set (attr "prefix_data16")
1995         (cond [(eq_attr "alternative" "0")
1996                  (const_string "*")
1997                (eq_attr "mode" "DF")
1998                  (const_string "1")
1999               ]
2000               (const_string "0")))
2001    (set_attr "athlon_decode" "vector")
2002    (set_attr "amdfam10_decode" "direct")
2003    (set_attr "bdver1_decode" "double")
2004    (set_attr "znver1_decode" "double")
2005    (set (attr "enabled")
2006      (if_then_else
2007        (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
2008        (if_then_else
2009          (eq_attr "alternative" "0")
2010          (symbol_ref "TARGET_MIX_SSE_I387")
2011          (symbol_ref "true"))
2012        (if_then_else
2013          (eq_attr "alternative" "0")
2014          (symbol_ref "true")
2015          (symbol_ref "false"))))])
2017 (define_insn "*cmpi<unord>hf"
2018   [(set (reg:CCFP FLAGS_REG)
2019         (compare:CCFP
2020           (match_operand:HF 0 "register_operand" "v")
2021           (match_operand:HF 1 "nonimmediate_operand" "vm")))]
2022   "TARGET_AVX512FP16"
2023   "v<unord>comish\t{%1, %0|%0, %1}"
2024   [(set_attr "type" "ssecomi")
2025    (set_attr "prefix" "evex")
2026    (set_attr "mode" "HF")])
2028 ;; Set carry flag.
2029 (define_insn "x86_stc"
2030   [(set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2031   ""
2032   "stc"
2033   [(set_attr "length" "1")
2034    (set_attr "length_immediate" "0")
2035    (set_attr "modrm" "0")])
2037 ;; On Pentium 4, set the carry flag using mov $1,%al;addb $-1,%al.
2038 (define_peephole2
2039   [(match_scratch:QI 0 "r")
2040    (set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2041   "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2042   [(set (match_dup 0) (const_int 1))
2043    (parallel
2044      [(set (reg:CCC FLAGS_REG)
2045            (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2046                         (match_dup 0)))
2047       (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2049 ;; Complement carry flag.
2050 (define_insn "*x86_cmc"
2051   [(set (reg:CCC FLAGS_REG)
2052         (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2053                      (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2054   ""
2055   "cmc"
2056   [(set_attr "length" "1")
2057    (set_attr "length_immediate" "0")
2058    (set_attr "use_carry" "1")
2059    (set_attr "modrm" "0")])
2061 ;; On Pentium 4, cmc is replaced with setnc %al;addb $-1,%al.
2062 (define_peephole2
2063   [(match_scratch:QI 0 "r")
2064    (set (reg:CCC FLAGS_REG)
2065         (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2066                      (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2067   "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2068   [(set (match_dup 0) (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
2069    (parallel
2070      [(set (reg:CCC FLAGS_REG)
2071            (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2072                         (match_dup 0)))
2073       (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2075 ;; Push/pop instructions.
2077 (define_insn_and_split "*pushv1ti2"
2078   [(set (match_operand:V1TI 0 "push_operand" "=<")
2079         (match_operand:V1TI 1 "register_operand" "v"))]
2080   "TARGET_64BIT && TARGET_STV"
2081   "#"
2082   "&& reload_completed"
2083   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2084    (set (match_dup 0) (match_dup 1))]
2086   operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (V1TImode)));
2087   /* Preserve memory attributes. */
2088   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2090   [(set_attr "type" "multi")
2091    (set_attr "mode" "TI")])
2093 (define_insn "*push<mode>2"
2094   [(set (match_operand:DWI 0 "push_operand" "=<,<")
2095         (match_operand:DWI 1 "general_no_elim_operand" "riF*o,*v"))]
2096   ""
2097   "#"
2098   [(set_attr "type" "multi")
2099    (set_attr "mode" "<MODE>")])
2101 (define_split
2102   [(set (match_operand:DWI 0 "push_operand")
2103         (match_operand:DWI 1 "general_gr_operand"))]
2104   "reload_completed"
2105   [(const_int 0)]
2106   "ix86_split_long_move (operands); DONE;")
2108 (define_insn "*pushdi2_rex64"
2109   [(set (match_operand:DI 0 "push_operand" "=<,<,!<")
2110         (match_operand:DI 1 "general_no_elim_operand" "re*m,*v,n"))]
2111   "TARGET_64BIT"
2112   "@
2113    push{q}\t%1
2114    #
2115    #"
2116   [(set_attr "type" "push,multi,multi")
2117    (set_attr "mode" "DI")])
2119 ;; Convert impossible pushes of immediate to existing instructions.
2120 ;; First try to get scratch register and go through it.  In case this
2121 ;; fails, push sign extended lower part first and then overwrite
2122 ;; upper part by 32bit move.
2124 (define_peephole2
2125   [(match_scratch:DI 2 "r")
2126    (set (match_operand:DI 0 "push_operand")
2127         (match_operand:DI 1 "immediate_operand"))]
2128   "TARGET_64BIT
2129    && !symbolic_operand (operands[1], DImode)
2130    && !x86_64_immediate_operand (operands[1], DImode)"
2131   [(set (match_dup 2) (match_dup 1))
2132    (set (match_dup 0) (match_dup 2))])
2134 (define_split
2135   [(set (match_operand:DI 0 "push_operand")
2136         (match_operand:DI 1 "immediate_operand"))]
2137   "TARGET_64BIT && epilogue_completed
2138    && !symbolic_operand (operands[1], DImode)
2139    && !x86_64_immediate_operand (operands[1], DImode)"
2140   [(set (match_dup 0) (match_dup 1))
2141    (set (match_dup 2) (match_dup 3))]
2143   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
2145   operands[1] = gen_lowpart (DImode, operands[2]);
2146   operands[2] = gen_rtx_MEM (SImode,
2147                              plus_constant (Pmode, stack_pointer_rtx, 4));
2150 ;; For TARGET_64BIT we always round up to 8 bytes.
2151 (define_insn "*pushsi2_rex64"
2152   [(set (match_operand:SI 0 "push_operand" "=X,X")
2153         (match_operand:SI 1 "nonmemory_no_elim_operand" "re,*v"))]
2154   "TARGET_64BIT"
2155   "@
2156    push{q}\t%q1
2157    #"
2158   [(set_attr "type" "push,multi")
2159    (set_attr "mode" "DI")])
2161 (define_insn "*pushsi2"
2162   [(set (match_operand:SI 0 "push_operand" "=<,<")
2163         (match_operand:SI 1 "general_no_elim_operand" "ri*m,*v"))]
2164   "!TARGET_64BIT"
2165   "@
2166    push{l}\t%1
2167    #"
2168   [(set_attr "type" "push,multi")
2169    (set_attr "mode" "SI")])
2171 (define_split
2172   [(set (match_operand:SWI48DWI 0 "push_operand")
2173         (match_operand:SWI48DWI 1 "sse_reg_operand"))]
2174   "TARGET_SSE && reload_completed"
2175   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2176     (set (match_dup 0) (match_dup 1))]
2178   operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (<SWI48DWI:MODE>mode)));
2179   /* Preserve memory attributes. */
2180   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2183 ;; emit_push_insn when it calls move_by_pieces requires an insn to
2184 ;; "push a byte/word".  But actually we use push{l,q}, which has
2185 ;; the effect of rounding the amount pushed up to a word.
2187 (define_insn "*push<mode>2"
2188   [(set (match_operand:SWI12 0 "push_operand" "=X")
2189         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
2190   ""
2191   "* return TARGET_64BIT ? \"push{q}\t%q1\" : \"push{l}\t%k1\";"
2192   [(set_attr "type" "push")
2193    (set (attr "mode")
2194         (if_then_else (match_test "TARGET_64BIT")
2195           (const_string "DI")
2196           (const_string "SI")))])
2198 (define_insn "*push<mode>2_prologue"
2199   [(set (match_operand:W 0 "push_operand" "=<")
2200         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
2201    (clobber (mem:BLK (scratch)))]
2202   ""
2203   "push{<imodesuffix>}\t%1"
2204   [(set_attr "type" "push")
2205    (set_attr "mode" "<MODE>")])
2207 (define_insn "*pop<mode>1"
2208   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2209         (match_operand:W 1 "pop_operand" ">"))]
2210   ""
2211   "pop{<imodesuffix>}\t%0"
2212   [(set_attr "type" "pop")
2213    (set_attr "mode" "<MODE>")])
2215 (define_insn "*pop<mode>1_epilogue"
2216   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2217         (match_operand:W 1 "pop_operand" ">"))
2218    (clobber (mem:BLK (scratch)))]
2219   ""
2220   "pop{<imodesuffix>}\t%0"
2221   [(set_attr "type" "pop")
2222    (set_attr "mode" "<MODE>")])
2224 (define_insn "@pushfl<mode>2"
2225   [(set (match_operand:W 0 "push_operand" "=<")
2226         (unspec:W [(match_operand 1 "flags_reg_operand")]
2227                   UNSPEC_PUSHFL))]
2228   "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_CC"
2229   "pushf{<imodesuffix>}"
2230   [(set_attr "type" "push")
2231    (set_attr "mode" "<MODE>")])
2233 (define_insn "@popfl<mode>1"
2234   [(set (match_operand:CC 0 "flags_reg_operand")
2235         (unspec:CC [(match_operand:W 1 "pop_operand" ">")]
2236                    UNSPEC_POPFL))]
2237   ""
2238   "popf{<imodesuffix>}"
2239   [(set_attr "type" "pop")
2240    (set_attr "mode" "<MODE>")])
2243 ;; Reload patterns to support multi-word load/store
2244 ;; with non-offsetable address.
2245 (define_expand "reload_noff_store"
2246   [(parallel [(match_operand 0 "memory_operand" "=m")
2247               (match_operand 1 "register_operand" "r")
2248               (match_operand:DI 2 "register_operand" "=&r")])]
2249   "TARGET_64BIT"
2251   rtx mem = operands[0];
2252   rtx addr = XEXP (mem, 0);
2254   emit_move_insn (operands[2], addr);
2255   mem = replace_equiv_address_nv (mem, operands[2]);
2257   emit_insn (gen_rtx_SET (mem, operands[1]));
2258   DONE;
2261 (define_expand "reload_noff_load"
2262   [(parallel [(match_operand 0 "register_operand" "=r")
2263               (match_operand 1 "memory_operand" "m")
2264               (match_operand:DI 2 "register_operand" "=r")])]
2265   "TARGET_64BIT"
2267   rtx mem = operands[1];
2268   rtx addr = XEXP (mem, 0);
2270   emit_move_insn (operands[2], addr);
2271   mem = replace_equiv_address_nv (mem, operands[2]);
2273   emit_insn (gen_rtx_SET (operands[0], mem));
2274   DONE;
2277 ;; Move instructions.
2279 (define_expand "movxi"
2280   [(set (match_operand:XI 0 "nonimmediate_operand")
2281         (match_operand:XI 1 "general_operand"))]
2282   "TARGET_AVX512F && TARGET_EVEX512"
2283   "ix86_expand_vector_move (XImode, operands); DONE;")
2285 (define_expand "movoi"
2286   [(set (match_operand:OI 0 "nonimmediate_operand")
2287         (match_operand:OI 1 "general_operand"))]
2288   "TARGET_AVX"
2289   "ix86_expand_vector_move (OImode, operands); DONE;")
2291 (define_expand "movti"
2292   [(set (match_operand:TI 0 "nonimmediate_operand")
2293         (match_operand:TI 1 "general_operand"))]
2294   "TARGET_64BIT || TARGET_SSE"
2296   if (TARGET_64BIT)
2297     ix86_expand_move (TImode, operands);
2298   else
2299     ix86_expand_vector_move (TImode, operands);
2300   DONE;
2303 ;; This expands to what emit_move_complex would generate if we didn't
2304 ;; have a movti pattern.  Having this avoids problems with reload on
2305 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2306 ;; to have around all the time.
2307 (define_expand "movcdi"
2308   [(set (match_operand:CDI 0 "nonimmediate_operand")
2309         (match_operand:CDI 1 "general_operand"))]
2310   ""
2312   if (push_operand (operands[0], CDImode))
2313     emit_move_complex_push (CDImode, operands[0], operands[1]);
2314   else
2315     emit_move_complex_parts (operands[0], operands[1]);
2316   DONE;
2319 (define_expand "mov<mode>"
2320   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2321         (match_operand:SWI1248x 1 "general_operand"))]
2322   ""
2323   "ix86_expand_move (<MODE>mode, operands); DONE;")
2325 (define_insn "*mov<mode>_xor"
2326   [(set (match_operand:SWI48 0 "register_operand" "=r")
2327         (match_operand:SWI48 1 "const0_operand"))
2328    (clobber (reg:CC FLAGS_REG))]
2329   "reload_completed"
2330   "xor{l}\t%k0, %k0"
2331   [(set_attr "type" "alu1")
2332    (set_attr "mode" "SI")
2333    (set_attr "length_immediate" "0")])
2335 (define_insn "*mov<mode>_and"
2336   [(set (match_operand:SWI248 0 "memory_operand" "=m")
2337         (match_operand:SWI248 1 "const0_operand"))
2338    (clobber (reg:CC FLAGS_REG))]
2339   "reload_completed"
2340   "and{<imodesuffix>}\t{%1, %0|%0, %1}"
2341   [(set_attr "type" "alu1")
2342    (set_attr "mode" "<MODE>")
2343    (set_attr "length_immediate" "1")])
2345 (define_insn "*mov<mode>_or"
2346   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
2347         (match_operand:SWI248 1 "constm1_operand"))
2348    (clobber (reg:CC FLAGS_REG))]
2349   "reload_completed"
2350   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2351   [(set_attr "type" "alu1")
2352    (set_attr "mode" "<MODE>")
2353    (set_attr "length_immediate" "1")])
2355 (define_insn "*movxi_internal_avx512f"
2356   [(set (match_operand:XI 0 "nonimmediate_operand"              "=v,v ,v ,m")
2357         (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2358   "TARGET_AVX512F && TARGET_EVEX512
2359    && (register_operand (operands[0], XImode)
2360        || register_operand (operands[1], XImode))"
2362   switch (get_attr_type (insn))
2363     {
2364     case TYPE_SSELOG1:
2365       return standard_sse_constant_opcode (insn, operands);
2367     case TYPE_SSEMOV:
2368       return ix86_output_ssemov (insn, operands);
2370     default:
2371       gcc_unreachable ();
2372     }
2374   [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2375    (set_attr "prefix" "evex")
2376    (set_attr "mode" "XI")])
2378 (define_insn "*movoi_internal_avx"
2379   [(set (match_operand:OI 0 "nonimmediate_operand"              "=v,v ,v ,m")
2380         (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2381   "TARGET_AVX
2382    && (register_operand (operands[0], OImode)
2383        || register_operand (operands[1], OImode))"
2385   switch (get_attr_type (insn))
2386     {
2387     case TYPE_SSELOG1:
2388       return standard_sse_constant_opcode (insn, operands);
2390     case TYPE_SSEMOV:
2391       return ix86_output_ssemov (insn, operands);
2393     default:
2394       gcc_unreachable ();
2395     }
2397   [(set_attr "isa" "*,avx2,*,*")
2398    (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2399    (set_attr "prefix" "vex")
2400    (set_attr "mode" "OI")])
2402 (define_insn "*movti_internal"
2403   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?jc,?Yd")
2404         (match_operand:TI 1 "general_operand"      "riFo,re,C,BC,vm,v,Yd,jc"))]
2405   "(TARGET_64BIT
2406     && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2407    || (TARGET_SSE
2408        && nonimmediate_or_sse_const_operand (operands[1], TImode)
2409        && (register_operand (operands[0], TImode)
2410            || register_operand (operands[1], TImode)))"
2412   switch (get_attr_type (insn))
2413     {
2414     case TYPE_MULTI:
2415       return "#";
2417     case TYPE_SSELOG1:
2418       return standard_sse_constant_opcode (insn, operands);
2420     case TYPE_SSEMOV:
2421       return ix86_output_ssemov (insn, operands);
2423     default:
2424       gcc_unreachable ();
2425     }
2427   [(set (attr "isa")
2428      (cond [(eq_attr "alternative" "0,1,6,7")
2429               (const_string "x64")
2430             (eq_attr "alternative" "3")
2431               (const_string "sse2")
2432            ]
2433            (const_string "*")))
2434    (set (attr "type")
2435      (cond [(eq_attr "alternative" "0,1,6,7")
2436               (const_string "multi")
2437             (eq_attr "alternative" "2,3")
2438               (const_string "sselog1")
2439            ]
2440            (const_string "ssemov")))
2441    (set (attr "prefix")
2442      (if_then_else (eq_attr "type" "sselog1,ssemov")
2443        (const_string "maybe_vex")
2444        (const_string "orig")))
2445    (set (attr "mode")
2446         (cond [(eq_attr "alternative" "0,1")
2447                  (const_string "DI")
2448                (match_test "TARGET_AVX")
2449                  (const_string "TI")
2450                (ior (not (match_test "TARGET_SSE2"))
2451                     (match_test "optimize_function_for_size_p (cfun)"))
2452                  (const_string "V4SF")
2453                (and (eq_attr "alternative" "5")
2454                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2455                  (const_string "V4SF")
2456                ]
2457                (const_string "TI")))
2458    (set (attr "preferred_for_speed")
2459      (cond [(eq_attr "alternative" "6")
2460               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2461             (eq_attr "alternative" "7")
2462               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2463            ]
2464            (symbol_ref "true")))])
2466 (define_split
2467   [(set (match_operand:TI 0 "sse_reg_operand")
2468         (match_operand:TI 1 "general_reg_operand"))]
2469   "TARGET_64BIT && TARGET_SSE4_1
2470    && reload_completed"
2471   [(set (match_dup 2)
2472         (vec_merge:V2DI
2473           (vec_duplicate:V2DI (match_dup 3))
2474           (match_dup 2)
2475           (const_int 2)))]
2477   operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2478   operands[3] = gen_highpart (DImode, operands[1]);
2480   emit_move_insn (gen_lowpart (DImode, operands[0]),
2481                   gen_lowpart (DImode, operands[1]));
2484 (define_insn "*movdi_internal"
2485   [(set (match_operand:DI 0 "nonimmediate_operand"
2486     "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r,?*y,?Yv,?v,?v,m ,m,?jc,?*Yd,?r,?v,?*y,?*x,*k,*k  ,*r,*m,*k")
2487         (match_operand:DI 1 "general_operand"
2488     "riFo,riF,Z,rem,i,re,C ,*y,Bk ,*y,*y,r  ,C  ,?v,Bk,?v,v,*Yd,jc  ,?v,r  ,*x ,*y ,*r,*kBk,*k,*k,CBC"))]
2489   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2490    && ix86_hardreg_mov_ok (operands[0], operands[1])"
2492   switch (get_attr_type (insn))
2493     {
2494     case TYPE_MSKMOV:
2495       return "kmovq\t{%1, %0|%0, %1}";
2497     case TYPE_MSKLOG:
2498       if (operands[1] == const0_rtx)
2499         return "kxorq\t%0, %0, %0";
2500       else if (operands[1] == constm1_rtx)
2501         return "kxnorq\t%0, %0, %0";
2502       gcc_unreachable ();
2504     case TYPE_MULTI:
2505       return "#";
2507     case TYPE_MMX:
2508       return "pxor\t%0, %0";
2510     case TYPE_MMXMOV:
2511       /* Handle broken assemblers that require movd instead of movq.  */
2512       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2513           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2514         return "movd\t{%1, %0|%0, %1}";
2515       return "movq\t{%1, %0|%0, %1}";
2517     case TYPE_SSELOG1:
2518       return standard_sse_constant_opcode (insn, operands);
2520     case TYPE_SSEMOV:
2521       return ix86_output_ssemov (insn, operands);
2523     case TYPE_SSECVT:
2524       if (SSE_REG_P (operands[0]))
2525         return "movq2dq\t{%1, %0|%0, %1}";
2526       else
2527         return "movdq2q\t{%1, %0|%0, %1}";
2529     case TYPE_LEA:
2530       return "lea{q}\t{%E1, %0|%0, %E1}";
2532     case TYPE_IMOV:
2533       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2534       if (get_attr_mode (insn) == MODE_SI)
2535         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2536       else if (which_alternative == 4)
2537         return "movabs{q}\t{%1, %0|%0, %1}";
2538       else if (ix86_use_lea_for_mov (insn, operands))
2539         return "lea{q}\t{%E1, %0|%0, %E1}";
2540       else
2541         return "mov{q}\t{%1, %0|%0, %1}";
2543     default:
2544       gcc_unreachable ();
2545     }
2547   [(set (attr "isa")
2548      (cond [(eq_attr "alternative" "0,1,17,18")
2549               (const_string "nox64")
2550             (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2551               (const_string "x64")
2552             (eq_attr "alternative" "19,20")
2553               (const_string "x64_sse2")
2554             (eq_attr "alternative" "21,22")
2555               (const_string "sse2")
2556            ]
2557            (const_string "*")))
2558    (set (attr "type")
2559      (cond [(eq_attr "alternative" "0,1,17,18")
2560               (const_string "multi")
2561             (eq_attr "alternative" "6")
2562               (const_string "mmx")
2563             (eq_attr "alternative" "7,8,9,10,11")
2564               (const_string "mmxmov")
2565             (eq_attr "alternative" "12")
2566               (const_string "sselog1")
2567             (eq_attr "alternative" "13,14,15,16,19,20")
2568               (const_string "ssemov")
2569             (eq_attr "alternative" "21,22")
2570               (const_string "ssecvt")
2571             (eq_attr "alternative" "23,24,25,26")
2572               (const_string "mskmov")
2573             (eq_attr "alternative" "27")
2574               (const_string "msklog")
2575             (and (match_operand 0 "register_operand")
2576                  (match_operand 1 "pic_32bit_operand"))
2577               (const_string "lea")
2578            ]
2579            (const_string "imov")))
2580    (set (attr "modrm")
2581      (if_then_else
2582        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2583        (const_string "0")
2584        (const_string "*")))
2585    (set (attr "length_immediate")
2586      (if_then_else
2587        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2588        (const_string "8")
2589        (const_string "*")))
2590    (set (attr "prefix_rex")
2591      (if_then_else
2592        (eq_attr "alternative" "10,11,19,20")
2593        (const_string "1")
2594        (const_string "*")))
2595    (set (attr "prefix")
2596      (if_then_else (eq_attr "type" "sselog1,ssemov")
2597        (const_string "maybe_vex")
2598        (const_string "orig")))
2599    (set (attr "prefix_data16")
2600      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2601        (const_string "1")
2602        (const_string "*")))
2603    (set (attr "mode")
2604      (cond [(eq_attr "alternative" "2")
2605               (const_string "SI")
2606             (eq_attr "alternative" "12")
2607               (cond [(match_test "TARGET_AVX")
2608                        (const_string "TI")
2609                      (ior (not (match_test "TARGET_SSE2"))
2610                           (match_test "optimize_function_for_size_p (cfun)"))
2611                        (const_string "V4SF")
2612                     ]
2613                     (const_string "TI"))
2614             (eq_attr "alternative" "13")
2615               (cond [(match_test "TARGET_AVX512VL")
2616                        (const_string "TI")
2617                      (match_test "TARGET_AVX512F")
2618                        (const_string "DF")
2619                      (match_test "TARGET_AVX")
2620                        (const_string "TI")
2621                      (ior (not (match_test "TARGET_SSE2"))
2622                           (match_test "optimize_function_for_size_p (cfun)"))
2623                        (const_string "V4SF")
2624                     ]
2625                     (const_string "TI"))
2627             (and (eq_attr "alternative" "14,15,16")
2628                  (not (match_test "TARGET_SSE2")))
2629               (const_string "V2SF")
2630            ]
2631            (const_string "DI")))
2632    (set (attr "preferred_for_speed")
2633      (cond [(eq_attr "alternative" "10,17,19")
2634               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2635             (eq_attr "alternative" "11,18,20")
2636               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2637            ]
2638            (symbol_ref "true")))
2639    (set (attr "enabled")
2640      (cond [(eq_attr "alternative" "15")
2641               (if_then_else
2642                 (match_test "TARGET_STV && TARGET_SSE2")
2643                 (symbol_ref "false")
2644                 (const_string "*"))
2645             (eq_attr "alternative" "16")
2646               (if_then_else
2647                 (match_test "TARGET_STV && TARGET_SSE2")
2648                 (symbol_ref "true")
2649                 (symbol_ref "false"))
2650            ]
2651            (const_string "*")))])
2653 (define_split
2654   [(set (match_operand:<DWI> 0 "general_reg_operand")
2655         (match_operand:<DWI> 1 "sse_reg_operand"))]
2656   "TARGET_SSE4_1
2657    && reload_completed"
2658   [(set (match_dup 2)
2659         (vec_select:DWIH
2660           (match_dup 3)
2661           (parallel [(const_int 1)])))]
2663   operands[2] = gen_highpart (<MODE>mode, operands[0]);
2664   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2666   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2667                   gen_lowpart (<MODE>mode, operands[1]));
2670 (define_split
2671   [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2672         (match_operand:DWI 1 "general_gr_operand"))]
2673   "reload_completed"
2674   [(const_int 0)]
2675   "ix86_split_long_move (operands); DONE;")
2677 (define_split
2678   [(set (match_operand:DI 0 "sse_reg_operand")
2679         (match_operand:DI 1 "general_reg_operand"))]
2680   "!TARGET_64BIT && TARGET_SSE4_1
2681    && reload_completed"
2682   [(set (match_dup 2)
2683         (vec_merge:V4SI
2684           (vec_duplicate:V4SI (match_dup 3))
2685           (match_dup 2)
2686           (const_int 2)))]
2688   operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2689   operands[3] = gen_highpart (SImode, operands[1]);
2691   emit_move_insn (gen_lowpart (SImode, operands[0]),
2692                   gen_lowpart (SImode, operands[1]));
2695 ;; movabsq $0x0012345678000000, %rax is longer
2696 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2697 (define_peephole2
2698   [(set (match_operand:DI 0 "register_operand")
2699         (match_operand:DI 1 "const_int_operand"))]
2700   "TARGET_64BIT
2701    && optimize_insn_for_size_p ()
2702    && LEGACY_INT_REG_P (operands[0])
2703    && !x86_64_immediate_operand (operands[1], DImode)
2704    && !x86_64_zext_immediate_operand (operands[1], DImode)
2705    && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2706         & ~HOST_WIDE_INT_C (0xffffffff))
2707    && peep2_regno_dead_p (0, FLAGS_REG)"
2708   [(set (match_dup 0) (match_dup 1))
2709    (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2710               (clobber (reg:CC FLAGS_REG))])]
2712   int shift = ctz_hwi (UINTVAL (operands[1]));
2713   rtx op1 = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2714   if (ix86_endbr_immediate_operand (op1, VOIDmode))
2715     FAIL;
2716   operands[1] = op1;
2717   operands[2] = gen_int_mode (shift, QImode);
2720 (define_insn "*movsi_internal"
2721   [(set (match_operand:SI 0 "nonimmediate_operand"
2722     "=r,m ,*y,*y,?*y,?m,?r,?*y,?Yv,?v,?v,m ,?r,?v,*k,*k  ,*rm,*k")
2723         (match_operand:SI 1 "general_operand"
2724     "g ,re,C ,*y,Bk ,*y,*y,r  ,C  ,?v,Bk,?v,?v,r  ,*r,*kBk,*k ,CBC"))]
2725   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2726    && ix86_hardreg_mov_ok (operands[0], operands[1])"
2728   switch (get_attr_type (insn))
2729     {
2730     case TYPE_SSELOG1:
2731       return standard_sse_constant_opcode (insn, operands);
2733     case TYPE_MSKMOV:
2734       return "kmovd\t{%1, %0|%0, %1}";
2736     case TYPE_MSKLOG:
2737       if (operands[1] == const0_rtx)
2738         return "kxord\t%0, %0, %0";
2739       else if (operands[1] == constm1_rtx)
2740         return "kxnord\t%0, %0, %0";
2741       gcc_unreachable ();
2743     case TYPE_SSEMOV:
2744       return ix86_output_ssemov (insn, operands);
2746     case TYPE_MMX:
2747       return "pxor\t%0, %0";
2749     case TYPE_MMXMOV:
2750       switch (get_attr_mode (insn))
2751         {
2752         case MODE_DI:
2753           return "movq\t{%1, %0|%0, %1}";
2754         case MODE_SI:
2755           return "movd\t{%1, %0|%0, %1}";
2757         default:
2758           gcc_unreachable ();
2759         }
2761     case TYPE_LEA:
2762       return "lea{l}\t{%E1, %0|%0, %E1}";
2764     case TYPE_IMOV:
2765       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2766       if (ix86_use_lea_for_mov (insn, operands))
2767         return "lea{l}\t{%E1, %0|%0, %E1}";
2768       else
2769         return "mov{l}\t{%1, %0|%0, %1}";
2771     default:
2772       gcc_unreachable ();
2773     }
2775   [(set (attr "isa")
2776      (cond [(eq_attr "alternative" "12,13")
2777               (const_string "sse2")
2778            ]
2779            (const_string "*")))
2780    (set (attr "type")
2781      (cond [(eq_attr "alternative" "2")
2782               (const_string "mmx")
2783             (eq_attr "alternative" "3,4,5,6,7")
2784               (const_string "mmxmov")
2785             (eq_attr "alternative" "8")
2786               (const_string "sselog1")
2787             (eq_attr "alternative" "9,10,11,12,13")
2788               (const_string "ssemov")
2789             (eq_attr "alternative" "14,15,16")
2790               (const_string "mskmov")
2791             (eq_attr "alternative" "17")
2792               (const_string "msklog")
2793             (and (match_operand 0 "register_operand")
2794                  (match_operand 1 "pic_32bit_operand"))
2795               (const_string "lea")
2796            ]
2797            (const_string "imov")))
2798    (set (attr "prefix")
2799      (if_then_else (eq_attr "type" "sselog1,ssemov")
2800        (const_string "maybe_vex")
2801        (const_string "orig")))
2802    (set (attr "prefix_data16")
2803      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2804        (const_string "1")
2805        (const_string "*")))
2806    (set (attr "mode")
2807      (cond [(eq_attr "alternative" "2,3")
2808               (const_string "DI")
2809             (eq_attr "alternative" "8")
2810               (cond [(match_test "TARGET_AVX")
2811                        (const_string "TI")
2812                      (ior (not (match_test "TARGET_SSE2"))
2813                           (match_test "optimize_function_for_size_p (cfun)"))
2814                        (const_string "V4SF")
2815                     ]
2816                     (const_string "TI"))
2817             (eq_attr "alternative" "9")
2818               (cond [(match_test "TARGET_AVX512VL")
2819                        (const_string "TI")
2820                      (match_test "TARGET_AVX512F")
2821                        (const_string "SF")
2822                      (match_test "TARGET_AVX")
2823                        (const_string "TI")
2824                      (ior (not (match_test "TARGET_SSE2"))
2825                           (match_test "optimize_function_for_size_p (cfun)"))
2826                        (const_string "V4SF")
2827                     ]
2828                     (const_string "TI"))
2830             (and (eq_attr "alternative" "10,11")
2831                  (not (match_test "TARGET_SSE2")))
2832               (const_string "SF")
2833            ]
2834            (const_string "SI")))
2835    (set (attr "preferred_for_speed")
2836      (cond [(eq_attr "alternative" "6,12")
2837               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2838             (eq_attr "alternative" "7,13")
2839               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2840            ]
2841            (symbol_ref "true")))])
2843 ;; With -Oz, transform mov $imm,reg to the shorter push $imm; pop reg.
2844 (define_peephole2
2845   [(set (match_operand:SWI248 0 "general_reg_operand")
2846         (match_operand:SWI248 1 "const_int_operand"))]
2847   "optimize_insn_for_size_p () && optimize_size > 1
2848    && operands[1] != const0_rtx
2849    && IN_RANGE (INTVAL (operands[1]), -128, 127)
2850    && !ix86_red_zone_used
2851    && REGNO (operands[0]) != SP_REG"
2852   [(set (match_dup 2) (match_dup 1))
2853    (set (match_dup 0) (match_dup 3))]
2855   if (GET_MODE (operands[0]) != word_mode)
2856     operands[0] = gen_rtx_REG (word_mode, REGNO (operands[0]));
2858   operands[2] = gen_rtx_MEM (word_mode,
2859                              gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
2860   operands[3] = gen_rtx_MEM (word_mode,
2861                              gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2864 ;; With -Oz, transform mov $0,mem to the shorter and $0,mem.
2865 ;; Likewise, transform mov $-1,mem to the shorter or $-1,mem.
2866 (define_peephole2
2867   [(set (match_operand:SWI248 0 "memory_operand")
2868         (match_operand:SWI248 1 "const_int_operand"))]
2869   "(operands[1] == const0_rtx || operands[1] == constm1_rtx)
2870    && optimize_insn_for_size_p () && optimize_size > 1
2871    && peep2_regno_dead_p (0, FLAGS_REG)"
2872   [(parallel [(set (match_dup 0) (match_dup 1))
2873               (clobber (reg:CC FLAGS_REG))])])
2875 (define_insn "*movhi_internal"
2876   [(set (match_operand:HI 0 "nonimmediate_operand"
2877     "=r,r,r,m ,*k,*k ,r ,m ,*k ,?r,?*v,*Yv,*v,*v,jm,m")
2878         (match_operand:HI 1 "general_operand"
2879     "r ,n,m,rn,r ,*km,*k,*k,CBC,*v,r  ,C  ,*v,m ,*x,*v"))]
2880   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2881    && ix86_hardreg_mov_ok (operands[0], operands[1])"
2883   switch (get_attr_type (insn))
2884     {
2885     case TYPE_IMOVX:
2886       /* movzwl is faster than movw on p2 due to partial word stalls,
2887          though not as fast as an aligned movl.  */
2888       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2890     case TYPE_MSKMOV:
2891       switch (which_alternative)
2892         {
2893         case 4:
2894           return "kmovw\t{%k1, %0|%0, %k1}";
2895         case 6:
2896           return "kmovw\t{%1, %k0|%k0, %1}";
2897         case 5:
2898         case 7:
2899           return "kmovw\t{%1, %0|%0, %1}";
2900         default:
2901           gcc_unreachable ();
2902         }
2904     case TYPE_SSEMOV:
2905       return ix86_output_ssemov (insn, operands);
2907     case TYPE_SSELOG1:
2908       if (satisfies_constraint_C (operands[1]))
2909         return standard_sse_constant_opcode (insn, operands);
2911       if (SSE_REG_P (operands[0]))
2912         return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
2913       else
2914         return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
2916     case TYPE_MSKLOG:
2917       if (operands[1] == const0_rtx)
2918         return "kxorw\t%0, %0, %0";
2919       else if (operands[1] == constm1_rtx)
2920         return "kxnorw\t%0, %0, %0";
2921       gcc_unreachable ();
2923     default:
2924       if (get_attr_mode (insn) == MODE_SI)
2925         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2926       else
2927         return "mov{w}\t{%1, %0|%0, %1}";
2928     }
2930   [(set (attr "isa")
2931         (cond [(eq_attr "alternative" "9,10,11,12,13")
2932                   (const_string "sse2")
2933                (eq_attr "alternative" "14")
2934                   (const_string "sse4_noavx")
2935                (eq_attr "alternative" "15")
2936                   (const_string "avx")
2937                ]
2938                (const_string "*")))
2939    (set (attr "addr")
2940         (if_then_else (eq_attr "alternative" "14")
2941                       (const_string "gpr16")
2942                       (const_string "*")))
2943    (set (attr "type")
2944      (cond [(eq_attr "alternative" "4,5,6,7")
2945               (const_string "mskmov")
2946             (eq_attr "alternative" "8")
2947               (const_string "msklog")
2948             (eq_attr "alternative" "13,14,15")
2949               (if_then_else (match_test "TARGET_AVX512FP16")
2950                 (const_string "ssemov")
2951                 (const_string "sselog1"))
2952             (eq_attr "alternative" "11")
2953               (const_string "sselog1")
2954             (eq_attr "alternative" "9,10,12")
2955               (const_string "ssemov")
2956             (match_test "optimize_function_for_size_p (cfun)")
2957               (const_string "imov")
2958             (and (eq_attr "alternative" "0")
2959                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2960                       (not (match_test "TARGET_HIMODE_MATH"))))
2961               (const_string "imov")
2962             (and (eq_attr "alternative" "1,2")
2963                  (match_operand:HI 1 "aligned_operand"))
2964               (const_string "imov")
2965             (and (match_test "TARGET_MOVX")
2966                  (eq_attr "alternative" "0,2"))
2967               (const_string "imovx")
2968            ]
2969            (const_string "imov")))
2970    (set (attr "prefix")
2971         (cond [(eq_attr "alternative" "4,5,6,7,8")
2972                  (const_string "vex")
2973                (eq_attr "alternative" "9,10,11,12,13,14,15")
2974                  (const_string "maybe_evex")
2975               ]
2976               (const_string "orig")))
2977    (set (attr "mode")
2978      (cond [(eq_attr "alternative" "9,10")
2979               (if_then_else (match_test "TARGET_AVX512FP16")
2980                 (const_string "HI")
2981                 (const_string "SI"))
2982             (eq_attr "alternative" "13,14,15")
2983               (if_then_else (match_test "TARGET_AVX512FP16")
2984                 (const_string "HI")
2985                 (const_string "TI"))
2986             (eq_attr "alternative" "11")
2987               (cond [(match_test "TARGET_AVX")
2988                        (const_string "TI")
2989                      (ior (not (match_test "TARGET_SSE2"))
2990                           (match_test "optimize_function_for_size_p (cfun)"))
2991                        (const_string "V4SF")
2992                     ]
2993                     (const_string "TI"))
2994             (eq_attr "alternative" "12")
2995               (cond [(match_test "TARGET_AVX512VL")
2996                        (const_string "TI")
2997                      (match_test "TARGET_AVX512FP16")
2998                        (const_string "HF")
2999                      (match_test "TARGET_AVX512F")
3000                        (const_string "SF")
3001                      (match_test "TARGET_AVX")
3002                        (const_string "TI")
3003                      (ior (not (match_test "TARGET_SSE2"))
3004                           (match_test "optimize_function_for_size_p (cfun)"))
3005                        (const_string "V4SF")
3006                     ]
3007                     (const_string "TI"))
3008             (eq_attr "type" "imovx")
3009               (const_string "SI")
3010             (and (eq_attr "alternative" "1,2")
3011                  (match_operand:HI 1 "aligned_operand"))
3012               (const_string "SI")
3013             (and (eq_attr "alternative" "0")
3014                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
3015                       (not (match_test "TARGET_HIMODE_MATH"))))
3016               (const_string "SI")
3017             ]
3018             (const_string "HI")))
3019    (set (attr "preferred_for_speed")
3020      (cond [(eq_attr "alternative" "9")
3021               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3022             (eq_attr "alternative" "10")
3023               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3024            ]
3025            (symbol_ref "true")))])
3027 ;; Situation is quite tricky about when to choose full sized (SImode) move
3028 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
3029 ;; partial register dependency machines (such as AMD Athlon), where QImode
3030 ;; moves issue extra dependency and for partial register stalls machines
3031 ;; that don't use QImode patterns (and QImode move cause stall on the next
3032 ;; instruction).
3034 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
3035 ;; register stall machines with, where we use QImode instructions, since
3036 ;; partial register stall can be caused there.  Then we use movzx.
3038 (define_insn "*movqi_internal"
3039   [(set (match_operand:QI 0 "nonimmediate_operand"
3040                         "=Q,R,r,q,q,r,r ,?r,m ,*k,*k,*r,*m,*k,*k,*k")
3041         (match_operand:QI 1 "general_operand"
3042                         "Q ,R,r,n,m,q,rn, m,qn,*r,*k,*k,*k,*m,C,BC"))]
3043   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3044    && ix86_hardreg_mov_ok (operands[0], operands[1])"
3047   char buf[128];
3048   const char *ops;
3049   const char *suffix;
3051   switch (get_attr_type (insn))
3052     {
3053     case TYPE_IMOVX:
3054       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
3055       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
3057     case TYPE_MSKMOV:
3058       switch (which_alternative)
3059         {
3060         case 9:
3061           ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
3062           break;
3063         case 11:
3064           ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
3065           break;
3066         case 12:
3067         case 13:
3068           gcc_assert (TARGET_AVX512DQ);
3069           /* FALLTHRU */
3070         case 10:
3071           ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
3072           break;
3073         default:
3074           gcc_unreachable ();
3075         }
3077       suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
3079       snprintf (buf, sizeof (buf), ops, suffix);
3080       output_asm_insn (buf, operands);
3081       return "";
3083     case TYPE_MSKLOG:
3084       if (operands[1] == const0_rtx)
3085         {
3086           if (get_attr_mode (insn) == MODE_HI)
3087             return "kxorw\t%0, %0, %0";
3088           else
3089             return "kxorb\t%0, %0, %0";
3090         }
3091       else if (operands[1] == constm1_rtx)
3092         {
3093           gcc_assert (TARGET_AVX512DQ);
3094           return "kxnorb\t%0, %0, %0";
3095         }
3096       gcc_unreachable ();
3098     default:
3099       if (get_attr_mode (insn) == MODE_SI)
3100         return "mov{l}\t{%k1, %k0|%k0, %k1}";
3101       else
3102         return "mov{b}\t{%1, %0|%0, %1}";
3103     }
3105   [(set (attr "isa")
3106      (cond [(eq_attr "alternative" "1,2")
3107               (const_string "x64")
3108             (eq_attr "alternative" "12,13,15")
3109               (const_string "avx512dq")
3110            ]
3111            (const_string "*")))
3112    (set (attr "type")
3113      (cond [(eq_attr "alternative" "9,10,11,12,13")
3114               (const_string "mskmov")
3115             (eq_attr "alternative" "14,15")
3116               (const_string "msklog")
3117             (and (eq_attr "alternative" "7")
3118                  (not (match_operand:QI 1 "aligned_operand")))
3119               (const_string "imovx")
3120             (match_test "optimize_function_for_size_p (cfun)")
3121               (const_string "imov")
3122             (and (eq_attr "alternative" "5")
3123                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
3124                       (not (match_test "TARGET_QIMODE_MATH"))))
3125               (const_string "imov")
3126             (eq_attr "alternative" "5,7")
3127               (const_string "imovx")
3128             (and (match_test "TARGET_MOVX")
3129                  (eq_attr "alternative" "4"))
3130               (const_string "imovx")
3131            ]
3132            (const_string "imov")))
3133    (set (attr "prefix")
3134      (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15")
3135        (const_string "vex")
3136        (const_string "orig")))
3137    (set (attr "mode")
3138       (cond [(eq_attr "alternative" "5,6,7")
3139                (const_string "SI")
3140              (eq_attr "alternative" "8")
3141                (const_string "QI")
3142              (and (eq_attr "alternative" "9,10,11,14")
3143                   (not (match_test "TARGET_AVX512DQ")))
3144                (const_string "HI")
3145              (eq_attr "type" "imovx")
3146                (const_string "SI")
3147              ;; For -Os, 8-bit immediates are always shorter than 32-bit
3148              ;; ones.
3149              (and (eq_attr "type" "imov")
3150                   (and (eq_attr "alternative" "3")
3151                        (match_test "optimize_function_for_size_p (cfun)")))
3152                (const_string "QI")
3153              ;; For -Os, movl where one or both operands are NON_Q_REGS
3154              ;; and both are LEGACY_REGS is shorter than movb.
3155              ;; Otherwise movb and movl sizes are the same, so decide purely
3156              ;; based on speed factors.
3157              (and (eq_attr "type" "imov")
3158                   (and (eq_attr "alternative" "1")
3159                        (match_test "optimize_function_for_size_p (cfun)")))
3160                (const_string "SI")
3161              (and (eq_attr "type" "imov")
3162                   (and (eq_attr "alternative" "0,1,2,3")
3163                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
3164                             (not (match_test "TARGET_PARTIAL_REG_STALL")))))
3165                (const_string "SI")
3166              ;; Avoid partial register stalls when not using QImode arithmetic
3167              (and (eq_attr "type" "imov")
3168                   (and (eq_attr "alternative" "0,1,2,3")
3169                        (and (match_test "TARGET_PARTIAL_REG_STALL")
3170                             (not (match_test "TARGET_QIMODE_MATH")))))
3171                (const_string "SI")
3172            ]
3173            (const_string "QI")))])
3175 /* Reload dislikes loading 0/-1 directly into mask registers.
3176    Try to tidy things up here.  */
3177 (define_peephole2
3178   [(set (match_operand:SWI 0 "general_reg_operand")
3179         (match_operand:SWI 1 "immediate_operand"))
3180    (set (match_operand:SWI 2 "mask_reg_operand")
3181         (match_dup 0))]
3182   "peep2_reg_dead_p (2, operands[0])
3183    && (const0_operand (operands[1], <MODE>mode)
3184        || (constm1_operand (operands[1], <MODE>mode)
3185            && (<MODE_SIZE> > 1 || TARGET_AVX512DQ)))"
3186   [(set (match_dup 2) (match_dup 1))])
3188 ;; Stores and loads of ax to arbitrary constant address.
3189 ;; We fake an second form of instruction to force reload to load address
3190 ;; into register when rax is not available
3191 (define_insn "*movabs<mode>_1"
3192   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
3193         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
3194   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
3196   /* Recover the full memory rtx.  */
3197   operands[0] = SET_DEST (PATTERN (insn));
3198   switch (which_alternative)
3199     {
3200     case 0:
3201       return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
3202     case 1:
3203       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3204     default:
3205       gcc_unreachable ();
3206     }
3208   [(set_attr "type" "imov")
3209    (set_attr "modrm" "0,*")
3210    (set_attr "length_address" "8,0")
3211    (set_attr "length_immediate" "0,*")
3212    (set_attr "memory" "store")
3213    (set_attr "mode" "<MODE>")])
3215 (define_insn "*movabs<mode>_2"
3216   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
3217         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
3218   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
3220   /* Recover the full memory rtx.  */
3221   operands[1] = SET_SRC (PATTERN (insn));
3222   switch (which_alternative)
3223     {
3224     case 0:
3225       return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
3226     case 1:
3227       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3228     default:
3229       gcc_unreachable ();
3230     }
3232   [(set_attr "type" "imov")
3233    (set_attr "modrm" "0,*")
3234    (set_attr "length_address" "8,0")
3235    (set_attr "length_immediate" "0")
3236    (set_attr "memory" "load")
3237    (set_attr "mode" "<MODE>")])
3239 (define_insn "swap<mode>"
3240   [(set (match_operand:SWI48 0 "register_operand" "+r")
3241         (match_operand:SWI48 1 "register_operand" "+r"))
3242    (set (match_dup 1)
3243         (match_dup 0))]
3244   ""
3245   "xchg{<imodesuffix>}\t%1, %0"
3246   [(set_attr "type" "imov")
3247    (set_attr "mode" "<MODE>")
3248    (set_attr "pent_pair" "np")
3249    (set_attr "athlon_decode" "vector")
3250    (set_attr "amdfam10_decode" "double")
3251    (set_attr "bdver1_decode" "double")])
3253 (define_insn "*swap<mode>"
3254   [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
3255         (match_operand:SWI12 1 "register_operand" "+<r>,r"))
3256    (set (match_dup 1)
3257         (match_dup 0))]
3258   ""
3259   "@
3260    xchg{<imodesuffix>}\t%1, %0
3261    xchg{l}\t%k1, %k0"
3262   [(set_attr "type" "imov")
3263    (set_attr "mode" "<MODE>,SI")
3264    (set (attr "preferred_for_size")
3265      (cond [(eq_attr "alternative" "0")
3266               (symbol_ref "false")]
3267            (symbol_ref "true")))
3268    ;; Potential partial reg stall on alternative 1.
3269    (set (attr "preferred_for_speed")
3270      (cond [(eq_attr "alternative" "1")
3271               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
3272            (symbol_ref "true")))
3273    (set_attr "pent_pair" "np")
3274    (set_attr "athlon_decode" "vector")
3275    (set_attr "amdfam10_decode" "double")
3276    (set_attr "bdver1_decode" "double")])
3278 (define_peephole2
3279   [(set (match_operand:SWI 0 "general_reg_operand")
3280         (match_operand:SWI 1 "general_reg_operand"))
3281    (set (match_dup 1)
3282         (match_operand:SWI 2 "general_reg_operand"))
3283    (set (match_dup 2) (match_dup 0))]
3284   "peep2_reg_dead_p (3, operands[0])
3285    && optimize_insn_for_size_p ()"
3286   [(parallel [(set (match_dup 1) (match_dup 2))
3287               (set (match_dup 2) (match_dup 1))])])
3289 ;; Convert xchg with a REG_UNUSED note to a mov (variant #1).
3290 (define_peephole2
3291   [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3292                    (match_operand:SWI 1 "general_reg_operand"))
3293               (set (match_dup 1) (match_dup 0))])]
3294   "((REGNO (operands[0]) != AX_REG
3295      && REGNO (operands[1]) != AX_REG)
3296     || optimize_size < 2
3297     || !optimize_insn_for_size_p ())
3298    && peep2_reg_dead_p (1, operands[0])"
3299   [(set (match_dup 1) (match_dup 0))])
3301 ;; Convert xchg with a REG_UNUSED note to a mov (variant #2).
3302 (define_peephole2
3303   [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3304                    (match_operand:SWI 1 "general_reg_operand"))
3305               (set (match_dup 1) (match_dup 0))])]
3306   "((REGNO (operands[0]) != AX_REG
3307      && REGNO (operands[1]) != AX_REG)
3308     || optimize_size < 2
3309     || !optimize_insn_for_size_p ())
3310    && peep2_reg_dead_p (1, operands[1])"
3311   [(set (match_dup 0) (match_dup 1))])
3313 ;; Convert moves to/from AX_REG into xchg with -Oz.
3314 (define_peephole2
3315   [(set (match_operand:SWI48 0 "general_reg_operand")
3316         (match_operand:SWI48 1 "general_reg_operand"))]
3317  "optimize_size > 1
3318   && ((REGNO (operands[0]) == AX_REG)
3319       != (REGNO (operands[1]) == AX_REG))
3320   && optimize_insn_for_size_p ()
3321   && peep2_reg_dead_p (1, operands[1])"
3322   [(parallel [(set (match_dup 0) (match_dup 1))
3323               (set (match_dup 1) (match_dup 0))])])
3325 (define_expand "movstrict<mode>"
3326   [(set (strict_low_part (match_operand:SWI12 0 "register_operand"))
3327         (match_operand:SWI12 1 "general_operand"))]
3328   ""
3330   gcc_assert (SUBREG_P (operands[0]));
3331   if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
3332       || !VALID_INT_MODE_P (GET_MODE (SUBREG_REG (operands[0]))))
3333     FAIL;
3336 (define_insn "*movstrict<mode>_1"
3337   [(set (strict_low_part
3338           (match_operand:SWI12 0 "register_operand" "+<r>"))
3339         (match_operand:SWI12 1 "general_operand" "<r>mn"))]
3340   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
3341   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
3342   [(set_attr "type" "imov")
3343    (set_attr "mode" "<MODE>")])
3345 (define_insn "*movstrict<mode>_xor"
3346   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
3347         (match_operand:SWI12 1 "const0_operand"))
3348    (clobber (reg:CC FLAGS_REG))]
3349   "reload_completed"
3350   "xor{<imodesuffix>}\t%0, %0"
3351   [(set_attr "type" "alu1")
3352    (set_attr "mode" "<MODE>")
3353    (set_attr "length_immediate" "0")])
3355 (define_insn "*movstrictqi_ext<mode>_1"
3356   [(set (strict_low_part
3357           (match_operand:QI 0 "register_operand" "+Q"))
3358           (subreg:QI
3359             (match_operator:SWI248 2 "extract_operator"
3360               [(match_operand 1 "int248_register_operand" "Q")
3361                (const_int 8)
3362                (const_int 8)]) 0))]
3363   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
3364   "mov{b}\t{%h1, %0|%0, %h1}"
3365   [(set_attr "type" "imov")
3366    (set_attr "mode" "QI")])
3368 (define_expand "extv<mode>"
3369   [(set (match_operand:SWI24 0 "register_operand")
3370         (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
3371                             (match_operand:QI 2 "const_int_operand")
3372                             (match_operand:QI 3 "const_int_operand")))]
3373   ""
3375   /* Handle extractions from %ah et al.  */
3376   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3377     FAIL;
3379   unsigned int regno = reg_or_subregno (operands[1]);
3381   /* Be careful to expand only with registers having upper parts.  */
3382   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3383     operands[1] = copy_to_reg (operands[1]);
3386 (define_insn "*extv<mode>"
3387   [(set (match_operand:SWI24 0 "register_operand" "=R")
3388         (sign_extract:SWI24 (match_operand 1 "int248_register_operand" "Q")
3389                             (const_int 8)
3390                             (const_int 8)))]
3391   ""
3392   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
3393   [(set_attr "type" "imovx")
3394    (set_attr "mode" "SI")])
3396 ;; Split sign-extension of single least significant bit as and x,$1;neg x
3397 (define_insn_and_split "*extv<mode>_1_0"
3398   [(set (match_operand:SWI48 0 "register_operand" "=r")
3399         (sign_extract:SWI48 (match_operand:SWI48 1 "register_operand" "0")
3400                             (const_int 1)
3401                             (const_int 0)))
3402    (clobber (reg:CC FLAGS_REG))]
3403   ""
3404   "#"
3405   ""
3406   [(parallel [(set (match_dup 0) (and:SWI48 (match_dup 1) (const_int 1)))
3407               (clobber (reg:CC FLAGS_REG))])
3408    (parallel [(set (match_dup 0) (neg:SWI48 (match_dup 0)))
3409               (clobber (reg:CC FLAGS_REG))])])
3411 (define_expand "extzv<mode>"
3412   [(set (match_operand:SWI248 0 "register_operand")
3413         (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
3414                              (match_operand:QI 2 "const_int_operand")
3415                              (match_operand:QI 3 "const_int_operand")))]
3416   ""
3418   if (ix86_expand_pextr (operands))
3419     DONE;
3421   /* Handle extractions from %ah et al.  */
3422   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3423     FAIL;
3425   unsigned int regno = reg_or_subregno (operands[1]);
3427   /* Be careful to expand only with registers having upper parts.  */
3428   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3429     operands[1] = copy_to_reg (operands[1]);
3432 (define_insn "*extzv<mode>"
3433   [(set (match_operand:SWI248 0 "register_operand" "=R")
3434         (zero_extract:SWI248 (match_operand 1 "int248_register_operand" "Q")
3435                              (const_int 8)
3436                              (const_int 8)))]
3437   ""
3438   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
3439   [(set_attr "type" "imovx")
3440    (set_attr "mode" "SI")])
3442 (define_insn "*extzvqi"
3443   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn,?R")
3444         (subreg:QI
3445           (match_operator:SWI248 2 "extract_operator"
3446             [(match_operand 1 "int248_register_operand" "Q,Q")
3447              (const_int 8)
3448              (const_int 8)]) 0))]
3449   ""
3451   switch (get_attr_type (insn))
3452     {
3453     case TYPE_IMOVX:
3454       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
3455     default:
3456       return "mov{b}\t{%h1, %0|%0, %h1}";
3457     }
3459   [(set_attr "addr" "gpr8,*")
3460    (set (attr "type")
3461      (if_then_else (and (match_operand:QI 0 "register_operand")
3462                         (ior (not (match_operand:QI 0 "QIreg_operand"))
3463                              (match_test "TARGET_MOVX")))
3464         (const_string "imovx")
3465         (const_string "imov")))
3466    (set (attr "mode")
3467      (if_then_else (eq_attr "type" "imovx")
3468         (const_string "SI")
3469         (const_string "QI")))])
3471 (define_expand "insv<mode>"
3472   [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3473                              (match_operand:QI 1 "const_int_operand")
3474                              (match_operand:QI 2 "const_int_operand"))
3475         (match_operand:SWI248 3 "register_operand"))]
3476   ""
3478   rtx dst;
3480   if (ix86_expand_pinsr (operands))
3481     DONE;
3483   /* Handle insertions to %ah et al.  */
3484   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3485     FAIL;
3487   unsigned int regno = reg_or_subregno (operands[0]);
3489   /* Be careful to expand only with registers having upper parts.  */
3490   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3491     dst = copy_to_reg (operands[0]);
3492   else
3493     dst = operands[0];
3495   emit_insn (gen_insv_1 (<MODE>mode, dst, operands[3]));
3497   /* Fix up the destination if needed.  */
3498   if (dst != operands[0])
3499     emit_move_insn (operands[0], dst);
3501   DONE;
3504 (define_insn "@insv<mode>_1"
3505   [(set (zero_extract:SWI248
3506           (match_operand 0 "int248_register_operand" "+Q")
3507           (const_int 8)
3508           (const_int 8))
3509         (match_operand:SWI248 1 "general_operand" "QnBn"))]
3510   ""
3512   if (CONST_INT_P (operands[1]))
3513     operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3514   return "mov{b}\t{%b1, %h0|%h0, %b1}";
3516   [(set_attr "addr" "gpr8")
3517    (set_attr "type" "imov")
3518    (set_attr "mode" "QI")])
3520 (define_insn "*insvqi_1"
3521   [(set (zero_extract:SWI248
3522           (match_operand 0 "int248_register_operand" "+Q")
3523           (const_int 8)
3524           (const_int 8))
3525         (subreg:SWI248
3526           (match_operand:QI 1 "general_operand" "QnBn") 0))]
3527   ""
3528   "mov{b}\t{%1, %h0|%h0, %1}"
3529   [(set_attr "addr" "gpr8")
3530    (set_attr "type" "imov")
3531    (set_attr "mode" "QI")])
3533 ;; Eliminate redundant insv, e.g. xorl %eax,%eax; movb $0, %ah
3534 (define_peephole2
3535   [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3536                    (const_int 0))
3537               (clobber (reg:CC FLAGS_REG))])
3538    (set (zero_extract:SWI248 (match_operand 1 "int248_register_operand")
3539                              (const_int 8)
3540                              (const_int 8))
3541         (const_int 0))]
3542   "REGNO (operands[0]) == REGNO (operands[1])"
3543   [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3544                    (const_int 0))
3545               (clobber (reg:CC FLAGS_REG))])])
3547 ;; Combine movl followed by movb.
3548 (define_peephole2
3549   [(set (match_operand:SWI48 0 "general_reg_operand")
3550         (match_operand:SWI48 1 "const_int_operand"))
3551    (set (zero_extract:SWI248 (match_operand 2 "int248_register_operand")
3552                              (const_int 8)
3553                              (const_int 8))
3554         (match_operand:SWI248 3 "const_int_operand"))]
3555   "REGNO (operands[0]) == REGNO (operands[2])"
3556   [(set (match_operand:SWI48 0 "general_reg_operand")
3557         (match_dup 4))]
3559   HOST_WIDE_INT tmp = INTVAL (operands[1]) & ~HOST_WIDE_INT_C (0xff00);
3560   tmp |= (INTVAL (operands[3]) & 0xff) << 8;
3561   operands[4] = gen_int_mode (tmp, <SWI48:MODE>mode);
3564 (define_insn "*insvqi_2"
3565   [(set (zero_extract:SWI248
3566           (match_operand 0 "int248_register_operand" "+Q")
3567           (const_int 8)
3568           (const_int 8))
3569         (match_operator:SWI248 2 "extract_operator"
3570           [(match_operand 1 "int248_register_operand" "Q")
3571            (const_int 8)
3572            (const_int 8)]))]
3573   ""
3574   "mov{b}\t{%h1, %h0|%h0, %h1}"
3575   [(set_attr "type" "imov")
3576    (set_attr "mode" "QI")])
3578 (define_insn "*insvqi_3"
3579   [(set (zero_extract:SWI248
3580           (match_operand 0 "int248_register_operand" "+Q")
3581           (const_int 8)
3582           (const_int 8))
3583         (any_shiftrt:SWI248
3584           (match_operand:SWI248 1 "register_operand" "Q")
3585           (const_int 8)))]
3586   ""
3587   "mov{b}\t{%h1, %h0|%h0, %h1}"
3588   [(set_attr "type" "imov")
3589    (set_attr "mode" "QI")])
3591 (define_code_iterator any_or_plus [plus ior xor])
3593 (define_insn_and_split "*insvti_highpart_1"
3594   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3595         (any_or_plus:TI
3596           (and:TI
3597             (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3598             (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3599           (ashift:TI
3600             (zero_extend:TI
3601               (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))
3602             (const_int 64))))]
3603   "TARGET_64BIT
3604    && CONST_WIDE_INT_P (operands[3])
3605    && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3606    && CONST_WIDE_INT_ELT (operands[3], 0) == -1
3607    && CONST_WIDE_INT_ELT (operands[3], 1) == 0"
3608   "#"
3609   "&& reload_completed"
3610   [(const_int 0)]
3612   operands[4] = gen_lowpart (DImode, operands[1]);
3613   split_double_concat (TImode, operands[0], operands[4], operands[2]);
3614   DONE;
3617 (define_insn_and_split "*insvti_lowpart_1"
3618   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3619         (any_or_plus:TI
3620           (and:TI
3621             (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3622             (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3623           (zero_extend:TI
3624             (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))))]
3625   "TARGET_64BIT
3626    && CONST_WIDE_INT_P (operands[3])
3627    && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3628    && CONST_WIDE_INT_ELT (operands[3], 0) == 0
3629    && CONST_WIDE_INT_ELT (operands[3], 1) == -1"
3630   "#"
3631   "&& reload_completed"
3632   [(const_int 0)]
3634   operands[4] = gen_highpart (DImode, operands[1]);
3635   split_double_concat (TImode, operands[0], operands[2], operands[4]);
3636   DONE;
3639 (define_insn_and_split "*insvdi_lowpart_1"
3640   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,r,r,&r")
3641         (any_or_plus:DI
3642           (and:DI
3643             (match_operand:DI 1 "nonimmediate_operand" "r,m,r,m")
3644             (match_operand:DI 3 "const_int_operand" "n,n,n,n"))
3645           (zero_extend:DI
3646             (match_operand:SI 2 "nonimmediate_operand" "r,r,m,m"))))]
3647   "!TARGET_64BIT
3648    && CONST_INT_P (operands[3])
3649    && UINTVAL (operands[3]) == 0xffffffff00000000ll"
3650   "#"
3651   "&& reload_completed"
3652   [(const_int 0)]
3654   operands[4] = gen_highpart (SImode, operands[1]);
3655   split_double_concat (DImode, operands[0], operands[2], operands[4]);
3656   DONE;
3659 ;; Floating point push instructions.
3661 (define_insn "*pushtf"
3662   [(set (match_operand:TF 0 "push_operand" "=<,<")
3663         (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3664   "TARGET_64BIT || TARGET_SSE"
3666   /* This insn should be already split before reg-stack.  */
3667   return "#";
3669   [(set_attr "isa" "*,x64")
3670    (set_attr "type" "multi")
3671    (set_attr "unit" "sse,*")
3672    (set_attr "mode" "TF,DI")])
3674 ;; %%% Kill this when call knows how to work this out.
3675 (define_split
3676   [(set (match_operand:TF 0 "push_operand")
3677         (match_operand:TF 1 "sse_reg_operand"))]
3678   "TARGET_SSE && reload_completed"
3679   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3680    (set (match_dup 0) (match_dup 1))]
3682   /* Preserve memory attributes. */
3683   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3686 (define_insn "*pushxf"
3687   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3688         (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3689   ""
3691   /* This insn should be already split before reg-stack.  */
3692   return "#";
3694   [(set_attr "isa" "*,*,*,nox64,x64")
3695    (set_attr "type" "multi")
3696    (set_attr "unit" "i387,*,*,*,*")
3697    (set (attr "mode")
3698         (cond [(eq_attr "alternative" "1,2,3,4")
3699                  (if_then_else (match_test "TARGET_64BIT")
3700                    (const_string "DI")
3701                    (const_string "SI"))
3702               ]
3703               (const_string "XF")))
3704    (set (attr "preferred_for_size")
3705      (cond [(eq_attr "alternative" "1")
3706               (symbol_ref "false")]
3707            (symbol_ref "true")))])
3709 ;; %%% Kill this when call knows how to work this out.
3710 (define_split
3711   [(set (match_operand:XF 0 "push_operand")
3712         (match_operand:XF 1 "fp_register_operand"))]
3713   "reload_completed"
3714   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3715    (set (match_dup 0) (match_dup 1))]
3717   operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3718   /* Preserve memory attributes. */
3719   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3722 (define_insn "*pushdf"
3723   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3724         (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,v"))]
3725   ""
3727   /* This insn should be already split before reg-stack.  */
3728   return "#";
3730   [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3731    (set_attr "type" "multi")
3732    (set_attr "unit" "i387,*,*,*,*,sse")
3733    (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3734    (set (attr "preferred_for_size")
3735      (cond [(eq_attr "alternative" "1")
3736               (symbol_ref "false")]
3737            (symbol_ref "true")))
3738    (set (attr "preferred_for_speed")
3739      (cond [(eq_attr "alternative" "1")
3740               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3741            (symbol_ref "true")))])
3742    
3743 ;; %%% Kill this when call knows how to work this out.
3744 (define_split
3745   [(set (match_operand:DF 0 "push_operand")
3746         (match_operand:DF 1 "any_fp_register_operand"))]
3747   "reload_completed"
3748   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3749    (set (match_dup 0) (match_dup 1))]
3751   /* Preserve memory attributes. */
3752   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3755 (define_mode_iterator HFBF [HF BF])
3757 (define_insn "*push<mode>_rex64"
3758   [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3759         (match_operand:HFBF 1 "nonmemory_no_elim_operand" "r,x"))]
3760   "TARGET_64BIT"
3762   /* Anything else should be already split before reg-stack.  */
3763   gcc_assert (which_alternative == 0);
3764   return "push{q}\t%q1";
3766   [(set_attr "isa"  "*,sse4")
3767    (set_attr "type" "push,multi")
3768    (set_attr "mode" "DI,TI")])
3770 (define_insn "*push<mode>"
3771   [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3772         (match_operand:HFBF 1 "general_no_elim_operand" "rmF,x"))]
3773   "!TARGET_64BIT"
3775   /* Anything else should be already split before reg-stack.  */
3776   gcc_assert (which_alternative == 0);
3777   return "push{l}\t%k1";
3779   [(set_attr "isa"  "*,sse4")
3780    (set_attr "type" "push,multi")
3781    (set_attr "mode" "SI,TI")])
3783 (define_insn "push2_di"
3784   [(set (match_operand:TI 0 "push_operand" "=<")
3785         (unspec:TI [(match_operand:DI 1 "register_operand" "r")
3786                     (match_operand:DI 2 "register_operand" "r")]
3787                     UNSPEC_APXPUSH2))]
3788   "TARGET_APX_PUSH2POP2"
3789   "push2\t{%2, %1|%1, %2}"
3790   [(set_attr "mode" "TI")
3791    (set_attr "type" "multi")
3792    (set_attr "prefix" "evex")])
3794 (define_insn "pop2_di"
3795   [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3796                    (unspec:DI [(match_operand:TI 1 "pop_operand" ">")]
3797                               UNSPEC_APXPOP2_LOW))
3798               (set (match_operand:DI 2 "register_operand" "=r")
3799                    (unspec:DI [(const_int 0)] UNSPEC_APXPOP2_HIGH))])]
3800   "TARGET_APX_PUSH2POP2"
3801   "pop2\t{%2, %0|%0, %2}"
3802   [(set_attr "mode" "TI")
3803    (set_attr "prefix" "evex")])
3805 (define_insn "pushp_di"
3806   [(set (match_operand:DI 0 "push_operand" "=<")
3807         (match_operand:DI 1 "register_operand" "r"))
3808    (unspec:DI [(const_int 0)] UNSPEC_APX_PPX)]
3809   "TARGET_64BIT"
3810   "pushp\t%1"
3811   [(set_attr "mode" "DI")])
3813 (define_insn "popp_di"
3814   [(set (match_operand:DI 0 "register_operand" "=r")
3815         (match_operand:DI 1 "pop_operand" ">"))
3816    (unspec:DI [(const_int 0)] UNSPEC_APX_PPX)]
3817   "TARGET_APX_PPX"
3818   "popp\t%0"
3819   [(set_attr "mode" "DI")])
3821 (define_insn "push2p_di"
3822   [(set (match_operand:TI 0 "push_operand" "=<")
3823         (unspec:TI [(match_operand:DI 1 "register_operand" "r")
3824                     (match_operand:DI 2 "register_operand" "r")]
3825                     UNSPEC_APXPUSH2))
3826    (unspec:DI [(const_int 0)] UNSPEC_APX_PPX)]
3827   "TARGET_APX_PUSH2POP2 && TARGET_APX_PPX"
3828   "push2p\t{%2, %1|%1, %2}"
3829   [(set_attr "mode" "TI")
3830    (set_attr "type" "multi")
3831    (set_attr "prefix" "evex")])
3833 (define_insn "pop2p_di"
3834   [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3835                    (unspec:DI [(match_operand:TI 1 "pop_operand" ">")]
3836                               UNSPEC_APXPOP2_LOW))
3837               (set (match_operand:DI 2 "register_operand" "=r")
3838                    (unspec:DI [(const_int 0)] UNSPEC_APXPOP2_HIGH))
3839               (unspec:DI [(const_int 0)] UNSPEC_APX_PPX)])]
3840   "TARGET_APX_PUSH2POP2 && TARGET_APX_PPX"
3841   "pop2p\t{%2, %0|%0, %2}"
3842   [(set_attr "mode" "TI")
3843    (set_attr "prefix" "evex")])
3845 (define_insn "*pushsf_rex64"
3846   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3847         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,v"))]
3848   "TARGET_64BIT"
3850   /* Anything else should be already split before reg-stack.  */
3851   if (which_alternative != 1)
3852     return "#";
3853   return "push{q}\t%q1";
3855   [(set_attr "type" "multi,push,multi")
3856    (set_attr "unit" "i387,*,*")
3857    (set_attr "mode" "SF,DI,SF")])
3859 (define_insn "*pushsf"
3860   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3861         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,v"))]
3862   "!TARGET_64BIT"
3864   /* Anything else should be already split before reg-stack.  */
3865   if (which_alternative != 1)
3866     return "#";
3867   return "push{l}\t%1";
3869   [(set_attr "type" "multi,push,multi")
3870    (set_attr "unit" "i387,*,*")
3871    (set_attr "mode" "SF,SI,SF")])
3873 (define_mode_iterator MODESH [SF HF BF])
3874 ;; %%% Kill this when call knows how to work this out.
3875 (define_split
3876   [(set (match_operand:MODESH 0 "push_operand")
3877         (match_operand:MODESH 1 "any_fp_register_operand"))]
3878   "reload_completed"
3879   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3880    (set (match_dup 0) (match_dup 1))]
3882   rtx op = XEXP (operands[0], 0);
3883   if (GET_CODE (op) == PRE_DEC)
3884     {
3885       gcc_assert (!TARGET_64BIT);
3886       op = GEN_INT (-4);
3887     }
3888   else
3889     {
3890       op = XEXP (XEXP (op, 1), 1);
3891       gcc_assert (CONST_INT_P (op));
3892     }
3893   operands[2] = op;
3894   /* Preserve memory attributes. */
3895   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3898 (define_split
3899   [(set (match_operand:SF 0 "push_operand")
3900         (match_operand:SF 1 "memory_operand"))]
3901   "reload_completed
3902    && find_constant_src (insn)"
3903   [(set (match_dup 0) (match_dup 2))]
3904   "operands[2] = find_constant_src (curr_insn);")
3906 (define_split
3907   [(set (match_operand 0 "push_operand")
3908         (match_operand 1 "general_gr_operand"))]
3909   "reload_completed
3910    && (GET_MODE (operands[0]) == TFmode
3911        || GET_MODE (operands[0]) == XFmode
3912        || GET_MODE (operands[0]) == DFmode)"
3913   [(const_int 0)]
3914   "ix86_split_long_move (operands); DONE;")
3916 ;; Floating point move instructions.
3918 (define_expand "movtf"
3919   [(set (match_operand:TF 0 "nonimmediate_operand")
3920         (match_operand:TF 1 "nonimmediate_operand"))]
3921   "TARGET_64BIT || TARGET_SSE"
3922   "ix86_expand_move (TFmode, operands); DONE;")
3924 (define_expand "mov<mode>"
3925   [(set (match_operand:X87MODEFH 0 "nonimmediate_operand")
3926         (match_operand:X87MODEFH 1 "general_operand"))]
3927   ""
3928   "ix86_expand_move (<MODE>mode, operands); DONE;")
3930 (define_insn "*movtf_internal"
3931   [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3932         (match_operand:TF 1 "general_operand"      "C ,vm,v,*roF,*rC"))]
3933   "(TARGET_64BIT || TARGET_SSE)
3934    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3935    && (lra_in_progress || reload_completed
3936        || !CONST_DOUBLE_P (operands[1])
3937        || (standard_sse_constant_p (operands[1], TFmode) == 1
3938            && !memory_operand (operands[0], TFmode))
3939        || (!TARGET_MEMORY_MISMATCH_STALL
3940            && memory_operand (operands[0], TFmode)))"
3942   switch (get_attr_type (insn))
3943     {
3944     case TYPE_SSELOG1:
3945       return standard_sse_constant_opcode (insn, operands);
3947     case TYPE_SSEMOV:
3948       return ix86_output_ssemov (insn, operands);
3950     case TYPE_MULTI:
3951         return "#";
3953     default:
3954       gcc_unreachable ();
3955     }
3957   [(set_attr "isa" "*,*,*,x64,x64")
3958    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3959    (set (attr "prefix")
3960      (if_then_else (eq_attr "type" "sselog1,ssemov")
3961        (const_string "maybe_vex")
3962        (const_string "orig")))
3963    (set (attr "mode")
3964         (cond [(eq_attr "alternative" "3,4")
3965                  (const_string "DI")
3966                (match_test "TARGET_AVX")
3967                  (const_string "TI")
3968                (ior (not (match_test "TARGET_SSE2"))
3969                     (match_test "optimize_function_for_size_p (cfun)"))
3970                  (const_string "V4SF")
3971                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3972                  (const_string "V4SF")
3973                (and (eq_attr "alternative" "2")
3974                     (match_test "TARGET_SSE_TYPELESS_STORES"))
3975                  (const_string "V4SF")
3976                ]
3977                (const_string "TI")))])
3979 (define_split
3980   [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3981         (match_operand:TF 1 "general_gr_operand"))]
3982   "reload_completed"
3983   [(const_int 0)]
3984   "ix86_split_long_move (operands); DONE;")
3986 ;; Possible store forwarding (partial memory) stall
3987 ;; in alternatives 4, 6, 7 and 8.
3988 (define_insn "*movxf_internal"
3989   [(set (match_operand:XF 0 "nonimmediate_operand"
3990          "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r  ,o ,o")
3991         (match_operand:XF 1 "general_operand"
3992          "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3993   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3994    && (lra_in_progress || reload_completed
3995        || !CONST_DOUBLE_P (operands[1])
3996        || ((optimize_function_for_size_p (cfun)
3997             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3998            && standard_80387_constant_p (operands[1]) > 0
3999            && !memory_operand (operands[0], XFmode))
4000        || (!TARGET_MEMORY_MISMATCH_STALL
4001            && memory_operand (operands[0], XFmode))
4002        || !TARGET_HARD_XF_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     default:
4015       gcc_unreachable ();
4016     }
4018   [(set (attr "isa")
4019         (cond [(eq_attr "alternative" "7,10")
4020                  (const_string "nox64")
4021                (eq_attr "alternative" "8,11")
4022                  (const_string "x64")
4023               ]
4024               (const_string "*")))
4025    (set (attr "type")
4026         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
4027                  (const_string "multi")
4028               ]
4029               (const_string "fmov")))
4030    (set (attr "mode")
4031         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
4032                  (if_then_else (match_test "TARGET_64BIT")
4033                    (const_string "DI")
4034                    (const_string "SI"))
4035               ]
4036               (const_string "XF")))
4037    (set (attr "preferred_for_size")
4038      (cond [(eq_attr "alternative" "3,4")
4039               (symbol_ref "false")]
4040            (symbol_ref "true")))
4041    (set (attr "enabled")
4042      (cond [(eq_attr "alternative" "9,10,11")
4043               (if_then_else
4044                 (match_test "TARGET_HARD_XF_REGS")
4045                 (symbol_ref "false")
4046                 (const_string "*"))
4047             (not (match_test "TARGET_HARD_XF_REGS"))
4048               (symbol_ref "false")
4049            ]
4050            (const_string "*")))])
4051    
4052 (define_split
4053   [(set (match_operand:XF 0 "nonimmediate_gr_operand")
4054         (match_operand:XF 1 "general_gr_operand"))]
4055   "reload_completed"
4056   [(const_int 0)]
4057   "ix86_split_long_move (operands); DONE;")
4059 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
4060 (define_insn "*movdf_internal"
4061   [(set (match_operand:DF 0 "nonimmediate_operand"
4062     "=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")
4063         (match_operand:DF 1 "general_operand"
4064     "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"))]
4065   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4066    && (lra_in_progress || reload_completed
4067        || !CONST_DOUBLE_P (operands[1])
4068        || ((optimize_function_for_size_p (cfun)
4069             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4070            && IS_STACK_MODE (DFmode)
4071            && standard_80387_constant_p (operands[1]) > 0
4072            && !memory_operand (operands[0], DFmode))
4073        || (TARGET_SSE2 && TARGET_SSE_MATH
4074            && standard_sse_constant_p (operands[1], DFmode) == 1
4075            && !memory_operand (operands[0], DFmode))
4076        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
4077            && memory_operand (operands[0], DFmode))
4078        || !TARGET_HARD_DF_REGS)"
4080   switch (get_attr_type (insn))
4081     {
4082     case TYPE_FMOV:
4083       if (which_alternative == 2)
4084         return standard_80387_constant_opcode (operands[1]);
4085       return output_387_reg_move (insn, operands);
4087     case TYPE_MULTI:
4088       return "#";
4090     case TYPE_IMOV:
4091       if (get_attr_mode (insn) == MODE_SI)
4092         return "mov{l}\t{%1, %k0|%k0, %1}";
4093       else if (which_alternative == 11)
4094         return "movabs{q}\t{%1, %0|%0, %1}";
4095       else
4096         return "mov{q}\t{%1, %0|%0, %1}";
4098     case TYPE_SSELOG1:
4099       return standard_sse_constant_opcode (insn, operands);
4101     case TYPE_SSEMOV:
4102       return ix86_output_ssemov (insn, operands);
4104     default:
4105       gcc_unreachable ();
4106     }
4108   [(set (attr "isa")
4109         (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
4110                  (const_string "nox64")
4111                (eq_attr "alternative" "8,9,10,11,24,25")
4112                  (const_string "x64")
4113                (eq_attr "alternative" "12,13,14,15")
4114                  (const_string "sse2")
4115                (eq_attr "alternative" "20,21")
4116                  (const_string "x64_sse2")
4117               ]
4118               (const_string "*")))
4119    (set (attr "type")
4120         (cond [(eq_attr "alternative" "0,1,2")
4121                  (const_string "fmov")
4122                (eq_attr "alternative" "3,4,5,6,7,22,23")
4123                  (const_string "multi")
4124                (eq_attr "alternative" "8,9,10,11,24,25")
4125                  (const_string "imov")
4126                (eq_attr "alternative" "12,16")
4127                  (const_string "sselog1")
4128               ]
4129               (const_string "ssemov")))
4130    (set (attr "modrm")
4131      (if_then_else (eq_attr "alternative" "11")
4132        (const_string "0")
4133        (const_string "*")))
4134    (set (attr "length_immediate")
4135      (if_then_else (eq_attr "alternative" "11")
4136        (const_string "8")
4137        (const_string "*")))
4138    (set (attr "prefix")
4139      (if_then_else (eq_attr "type" "sselog1,ssemov")
4140        (const_string "maybe_vex")
4141        (const_string "orig")))
4142    (set (attr "prefix_data16")
4143      (if_then_else
4144        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
4145             (eq_attr "mode" "V1DF"))
4146        (const_string "1")
4147        (const_string "*")))
4148    (set (attr "mode")
4149         (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
4150                  (const_string "SI")
4151                (eq_attr "alternative" "8,9,11,20,21,24,25")
4152                  (const_string "DI")
4154                /* xorps is one byte shorter for non-AVX targets.  */
4155                (eq_attr "alternative" "12,16")
4156                  (cond [(match_test "TARGET_AVX")
4157                           (const_string "V2DF")
4158                         (ior (not (match_test "TARGET_SSE2"))
4159                              (match_test "optimize_function_for_size_p (cfun)"))
4160                           (const_string "V4SF")
4161                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4162                           (const_string "TI")
4163                        ]
4164                        (const_string "V2DF"))
4166                /* For architectures resolving dependencies on
4167                   whole SSE registers use movapd to break dependency
4168                   chains, otherwise use short move to avoid extra work.  */
4170                /* movaps is one byte shorter for non-AVX targets.  */
4171                (eq_attr "alternative" "13,17")
4172                  (cond [(match_test "TARGET_AVX512VL")
4173                           (const_string "V2DF")
4174                         (match_test "TARGET_AVX512F")
4175                           (const_string "DF")
4176                         (match_test "TARGET_AVX")
4177                           (const_string "V2DF")
4178                         (ior (not (match_test "TARGET_SSE2"))
4179                              (match_test "optimize_function_for_size_p (cfun)"))
4180                           (const_string "V4SF")
4181                         (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
4182                           (const_string "V4SF")
4183                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4184                           (const_string "V2DF")
4185                        ]
4186                        (const_string "DF"))
4188                /* For architectures resolving dependencies on register
4189                   parts we may avoid extra work to zero out upper part
4190                   of register.  */
4191                (eq_attr "alternative" "14,18")
4192                  (cond [(not (match_test "TARGET_SSE2"))
4193                           (const_string "V2SF")
4194                         (match_test "TARGET_AVX")
4195                           (const_string "DF")
4196                         (match_test "TARGET_SSE_SPLIT_REGS")
4197                           (const_string "V1DF")
4198                        ]
4199                        (const_string "DF"))
4201                (and (eq_attr "alternative" "15,19")
4202                     (not (match_test "TARGET_SSE2")))
4203                  (const_string "V2SF")
4204               ]
4205               (const_string "DF")))
4206    (set (attr "preferred_for_size")
4207      (cond [(eq_attr "alternative" "3,4")
4208               (symbol_ref "false")]
4209            (symbol_ref "true")))
4210    (set (attr "preferred_for_speed")
4211      (cond [(eq_attr "alternative" "3,4")
4212               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
4213             (eq_attr "alternative" "20")
4214               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4215             (eq_attr "alternative" "21")
4216               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4217            ]
4218            (symbol_ref "true")))
4219    (set (attr "enabled")
4220      (cond [(eq_attr "alternative" "22,23,24,25")
4221               (if_then_else
4222                 (match_test "TARGET_HARD_DF_REGS")
4223                 (symbol_ref "false")
4224                 (const_string "*"))
4225             (not (match_test "TARGET_HARD_DF_REGS"))
4226               (symbol_ref "false")
4227            ]
4228            (const_string "*")))])
4230 (define_split
4231   [(set (match_operand:DF 0 "nonimmediate_gr_operand")
4232         (match_operand:DF 1 "general_gr_operand"))]
4233   "!TARGET_64BIT && reload_completed"
4234   [(const_int 0)]
4235   "ix86_split_long_move (operands); DONE;")
4237 (define_insn "*movsf_internal"
4238   [(set (match_operand:SF 0 "nonimmediate_operand"
4239           "=Yf*f,m   ,Yf*f,?r ,?m,Yv,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r  ,m")
4240         (match_operand:SF 1 "general_operand"
4241           "Yf*fm,Yf*f,G   ,rmF,rF,C ,v,m,v,v ,r ,*y ,m  ,*y,*y,r  ,rmF,rF"))]
4242   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4243    && (lra_in_progress || reload_completed
4244        || !CONST_DOUBLE_P (operands[1])
4245        || ((optimize_function_for_size_p (cfun)
4246             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4247            && IS_STACK_MODE (SFmode)
4248            && standard_80387_constant_p (operands[1]) > 0)
4249        || (TARGET_SSE && TARGET_SSE_MATH
4250            && standard_sse_constant_p (operands[1], SFmode) == 1)
4251        || memory_operand (operands[0], SFmode)
4252        || !TARGET_HARD_SF_REGS)"
4254   switch (get_attr_type (insn))
4255     {
4256     case TYPE_FMOV:
4257       if (which_alternative == 2)
4258         return standard_80387_constant_opcode (operands[1]);
4259       return output_387_reg_move (insn, operands);
4261     case TYPE_IMOV:
4262       return "mov{l}\t{%1, %0|%0, %1}";
4264     case TYPE_SSELOG1:
4265       return standard_sse_constant_opcode (insn, operands);
4267     case TYPE_SSEMOV:
4268       return ix86_output_ssemov (insn, operands);
4270     case TYPE_MMXMOV:
4271       switch (get_attr_mode (insn))
4272         {
4273         case MODE_DI:
4274           return "movq\t{%1, %0|%0, %1}";
4275         case MODE_SI:
4276           return "movd\t{%1, %0|%0, %1}";
4278         default:
4279           gcc_unreachable ();
4280         }
4282     default:
4283       gcc_unreachable ();
4284     }
4286   [(set (attr "isa")
4287      (cond [(eq_attr "alternative" "9,10")
4288               (const_string "sse2")
4289            ]
4290            (const_string "*")))
4291    (set (attr "type")
4292         (cond [(eq_attr "alternative" "0,1,2")
4293                  (const_string "fmov")
4294                (eq_attr "alternative" "3,4,16,17")
4295                  (const_string "imov")
4296                (eq_attr "alternative" "5")
4297                  (const_string "sselog1")
4298                (eq_attr "alternative" "11,12,13,14,15")
4299                  (const_string "mmxmov")
4300               ]
4301               (const_string "ssemov")))
4302    (set (attr "prefix")
4303      (if_then_else (eq_attr "type" "sselog1,ssemov")
4304        (const_string "maybe_vex")
4305        (const_string "orig")))
4306    (set (attr "prefix_data16")
4307      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
4308        (const_string "1")
4309        (const_string "*")))
4310    (set (attr "mode")
4311         (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
4312                  (const_string "SI")
4313                (eq_attr "alternative" "11")
4314                  (const_string "DI")
4315                (eq_attr "alternative" "5")
4316                  (cond [(and (match_test "TARGET_AVX512F && TARGET_EVEX512")
4317                              (not (match_test "TARGET_PREFER_AVX256")))
4318                           (const_string "V16SF")
4319                         (match_test "TARGET_AVX")
4320                           (const_string "V4SF")
4321                         (ior (not (match_test "TARGET_SSE2"))
4322                              (match_test "optimize_function_for_size_p (cfun)"))
4323                           (const_string "V4SF")
4324                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4325                           (const_string "TI")
4326                        ]
4327                        (const_string "V4SF"))
4329                /* For architectures resolving dependencies on
4330                   whole SSE registers use APS move to break dependency
4331                   chains, otherwise use short move to avoid extra work.
4333                   Do the same for architectures resolving dependencies on
4334                   the parts.  While in DF mode it is better to always handle
4335                   just register parts, the SF mode is different due to lack
4336                   of instructions to load just part of the register.  It is
4337                   better to maintain the whole registers in single format
4338                   to avoid problems on using packed logical operations.  */
4339                (eq_attr "alternative" "6")
4340                  (cond [(match_test "TARGET_AVX512VL")
4341                           (const_string "V4SF")
4342                         (match_test "TARGET_AVX512F")
4343                           (const_string "SF")
4344                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4345                              (match_test "TARGET_SSE_SPLIT_REGS"))
4346                           (const_string "V4SF")
4347                        ]
4348                        (const_string "SF"))
4349               ]
4350               (const_string "SF")))
4351    (set (attr "preferred_for_speed")
4352      (cond [(eq_attr "alternative" "9,14")
4353               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4354             (eq_attr "alternative" "10,15")
4355               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4356            ]
4357            (symbol_ref "true")))
4358    (set (attr "enabled")
4359      (cond [(eq_attr "alternative" "16,17")
4360               (if_then_else
4361                 (match_test "TARGET_HARD_SF_REGS")
4362                 (symbol_ref "false")
4363                 (const_string "*"))
4364             (not (match_test "TARGET_HARD_SF_REGS"))
4365               (symbol_ref "false")
4366            ]
4367            (const_string "*")))])
4369 (define_mode_attr hfbfconstf
4370  [(HF "F") (BF "")])
4372 (define_insn "*mov<mode>_internal"
4373  [(set (match_operand:HFBF 0 "nonimmediate_operand"
4374          "=?r,?r,?r,?m           ,Yv,v,?r,jm,m,?v,v")
4375        (match_operand:HFBF 1 "general_operand"
4376          "r  ,F ,m ,r<hfbfconstf>,C ,v, v,v ,v,r ,m"))]
4377  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4378   && (lra_in_progress
4379       || reload_completed
4380       || !CONST_DOUBLE_P (operands[1])
4381       || (TARGET_SSE2
4382           && standard_sse_constant_p (operands[1], <MODE>mode) == 1)
4383       || memory_operand (operands[0], <MODE>mode))"
4385   switch (get_attr_type (insn))
4386     {
4387     case TYPE_IMOVX:
4388       /* movzwl is faster than movw on p2 due to partial word stalls,
4389          though not as fast as an aligned movl.  */
4390       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
4392     case TYPE_SSEMOV:
4393       return ix86_output_ssemov (insn, operands);
4395     case TYPE_SSELOG1:
4396       if (satisfies_constraint_C (operands[1]))
4397         return standard_sse_constant_opcode (insn, operands);
4399       if (SSE_REG_P (operands[0]))
4400         return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
4401       else
4402         return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
4404     default:
4405       if (get_attr_mode (insn) == MODE_SI)
4406         return "mov{l}\t{%k1, %k0|%k0, %k1}";
4407       else
4408         return "mov{w}\t{%1, %0|%0, %1}";
4409     }
4411   [(set (attr "isa")
4412         (cond [(eq_attr "alternative" "4,5,6,9,10")
4413                  (const_string "sse2")
4414                (eq_attr "alternative" "7")
4415                  (const_string "sse4_noavx")
4416                (eq_attr "alternative" "8")
4417                  (const_string "avx")
4418               ]
4419               (const_string "*")))
4420    (set (attr "addr")
4421         (if_then_else (eq_attr "alternative" "7")
4422                       (const_string "gpr16")
4423                       (const_string "*")))
4424    (set (attr "type")
4425         (cond [(eq_attr "alternative" "4")
4426                  (const_string "sselog1")
4427                (eq_attr "alternative" "5,6,9")
4428                  (const_string "ssemov")
4429                (eq_attr "alternative" "7,8,10")
4430                  (if_then_else
4431                    (match_test ("TARGET_AVX512FP16"))
4432                    (const_string "ssemov")
4433                    (const_string "sselog1"))
4434                (match_test "optimize_function_for_size_p (cfun)")
4435                  (const_string "imov")
4436                (and (eq_attr "alternative" "0")
4437                     (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4438                          (not (match_test "TARGET_HIMODE_MATH"))))
4439                  (const_string "imov")
4440                (and (eq_attr "alternative" "1,2")
4441                     (match_operand:HI 1 "aligned_operand"))
4442                  (const_string "imov")
4443                (and (match_test "TARGET_MOVX")
4444                     (eq_attr "alternative" "0,2"))
4445                  (const_string "imovx")
4446                  ]
4447               (const_string "imov")))
4448    (set (attr "prefix")
4449         (cond [(eq_attr "alternative" "4,5,6,7,8,9,10")
4450                  (const_string "maybe_vex")
4451               ]
4452               (const_string "orig")))
4453    (set (attr "mode")
4454         (cond [(eq_attr "alternative" "4")
4455                  (const_string "V4SF")
4456                (eq_attr "alternative" "6,9")
4457                  (if_then_else
4458                    (match_test "TARGET_AVX512FP16")
4459                    (const_string "HI")
4460                    (const_string "SI"))
4461                (eq_attr "alternative" "7,8,10")
4462                  (if_then_else
4463                    (match_test "TARGET_AVX512FP16")
4464                    (const_string "HI")
4465                    (const_string "TI"))
4466                (eq_attr "alternative" "5")
4467                  (cond [(match_test "TARGET_AVX512VL")
4468                         (const_string "V4SF")
4469                         (match_test "TARGET_AVX512FP16")
4470                           (const_string "HF")
4471                         (match_test "TARGET_AVX512F")
4472                           (const_string "SF")
4473                         (match_test "TARGET_AVX")
4474                           (const_string "V4SF")
4475                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4476                              (match_test "TARGET_SSE_SPLIT_REGS"))
4477                           (const_string "V4SF")
4478                        ]
4479                        (const_string "SF"))
4480                (eq_attr "type" "imovx")
4481                  (const_string "SI")
4482                (and (eq_attr "alternative" "1,2")
4483                     (match_operand:HI 1 "aligned_operand"))
4484                  (const_string "SI")
4485                (and (eq_attr "alternative" "0")
4486                     (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4487                          (not (match_test "TARGET_HIMODE_MATH"))))
4488                  (const_string "SI")
4489               ]
4490               (const_string "HI")))
4491    (set (attr "enabled")
4492         (cond [(and (match_test "<MODE>mode == BFmode")
4493                     (eq_attr "alternative" "1"))
4494                 (symbol_ref "false")
4495               ]
4496               (const_string "*")))])
4498 (define_split
4499   [(set (match_operand 0 "any_fp_register_operand")
4500         (match_operand 1 "memory_operand"))]
4501   "reload_completed
4502    && (GET_MODE (operands[0]) == TFmode
4503        || GET_MODE (operands[0]) == XFmode
4504        || GET_MODE (operands[0]) == DFmode
4505        || GET_MODE (operands[0]) == SFmode)
4506    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4507   [(set (match_dup 0) (match_dup 2))]
4508   "operands[2] = find_constant_src (curr_insn);")
4510 (define_split
4511   [(set (match_operand 0 "any_fp_register_operand")
4512         (float_extend (match_operand 1 "memory_operand")))]
4513   "reload_completed
4514    && (GET_MODE (operands[0]) == TFmode
4515        || GET_MODE (operands[0]) == XFmode
4516        || GET_MODE (operands[0]) == DFmode)
4517    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4518   [(set (match_dup 0) (match_dup 2))]
4519   "operands[2] = find_constant_src (curr_insn);")
4521 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
4522 (define_split
4523   [(set (match_operand:X87MODEF 0 "fp_register_operand")
4524         (match_operand:X87MODEF 1 "immediate_operand"))]
4525   "reload_completed
4526    && (standard_80387_constant_p (operands[1]) == 8
4527        || standard_80387_constant_p (operands[1]) == 9)"
4528   [(set (match_dup 0)(match_dup 1))
4529    (set (match_dup 0)
4530         (neg:X87MODEF (match_dup 0)))]
4532   if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
4533     operands[1] = CONST0_RTX (<MODE>mode);
4534   else
4535     operands[1] = CONST1_RTX (<MODE>mode);
4538 (define_insn "*swapxf"
4539   [(set (match_operand:XF 0 "register_operand" "+f")
4540         (match_operand:XF 1 "register_operand" "+f"))
4541    (set (match_dup 1)
4542         (match_dup 0))]
4543   "TARGET_80387"
4545   if (STACK_TOP_P (operands[0]))
4546     return "fxch\t%1";
4547   else
4548     return "fxch\t%0";
4550   [(set_attr "type" "fxch")
4551    (set_attr "mode" "XF")])
4554 ;; Zero extension instructions
4556 (define_insn_and_split "zero_extendditi2"
4557   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4558         (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "rm,r")))]
4559   "TARGET_64BIT"
4560   "#"
4561   "&& reload_completed"
4562   [(set (match_dup 3) (match_dup 1))
4563    (set (match_dup 4) (const_int 0))]
4564   "split_double_mode (TImode, &operands[0], 1, &operands[3], &operands[4]);")
4566 (define_expand "zero_extendsidi2"
4567   [(set (match_operand:DI 0 "nonimmediate_operand")
4568         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
4570 (define_insn "*zero_extendsidi2"
4571   [(set (match_operand:DI 0 "nonimmediate_operand"
4572                 "=r,?r,?o,r   ,o,?*y,?!*y,$r,$v,$x,*x,*v,?r,?k")
4573         (zero_extend:DI
4574          (match_operand:SI 1 "x86_64_zext_operand"
4575                 "0 ,rm,r ,rmWz,0,r  ,m   ,v ,r ,m ,*x,*v,?k,?km")))]
4576   ""
4578   switch (get_attr_type (insn))
4579     {
4580     case TYPE_IMOVX:
4581       if (ix86_use_lea_for_mov (insn, operands))
4582         return "lea{l}\t{%E1, %k0|%k0, %E1}";
4583       else
4584         return "mov{l}\t{%1, %k0|%k0, %1}";
4586     case TYPE_MULTI:
4587       return "#";
4589     case TYPE_MMXMOV:
4590       return "movd\t{%1, %0|%0, %1}";
4592     case TYPE_SSEMOV:
4593       if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
4594         {
4595           if (EXT_REX_SSE_REG_P (operands[0])
4596               || EXT_REX_SSE_REG_P (operands[1]))
4597             return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
4598           else
4599             return "%vpmovzxdq\t{%1, %0|%0, %1}";
4600         }
4602       if (GENERAL_REG_P (operands[0]))
4603         return "%vmovd\t{%1, %k0|%k0, %1}";
4605       return "%vmovd\t{%1, %0|%0, %1}";
4607     case TYPE_MSKMOV:
4608       return "kmovd\t{%1, %k0|%k0, %1}";
4610     default:
4611       gcc_unreachable ();
4612     }
4614   [(set (attr "isa")
4615      (cond [(eq_attr "alternative" "0,1,2")
4616               (const_string "nox64")
4617             (eq_attr "alternative" "3")
4618               (const_string "x64")
4619             (eq_attr "alternative" "7,8,9")
4620               (const_string "sse2")
4621             (eq_attr "alternative" "10")
4622               (const_string "sse4")
4623             (eq_attr "alternative" "11")
4624               (const_string "avx512f")
4625             (eq_attr "alternative" "12")
4626               (const_string "x64_avx512bw")
4627             (eq_attr "alternative" "13")
4628               (const_string "avx512bw")
4629            ]
4630            (const_string "*")))
4631    (set (attr "mmx_isa")
4632      (if_then_else (eq_attr "alternative" "5,6")
4633                    (const_string "native")
4634                    (const_string "*")))
4635    (set (attr "type")
4636      (cond [(eq_attr "alternative" "0,1,2,4")
4637               (const_string "multi")
4638             (eq_attr "alternative" "5,6")
4639               (const_string "mmxmov")
4640             (eq_attr "alternative" "7")
4641               (if_then_else (match_test "TARGET_64BIT")
4642                 (const_string "ssemov")
4643                 (const_string "multi"))
4644             (eq_attr "alternative" "8,9,10,11")
4645               (const_string "ssemov")
4646             (eq_attr "alternative" "12,13")
4647               (const_string "mskmov")
4648            ]
4649            (const_string "imovx")))
4650    (set (attr "prefix_extra")
4651      (if_then_else (eq_attr "alternative" "10,11")
4652        (const_string "1")
4653        (const_string "*")))
4654    (set (attr "prefix")
4655      (if_then_else (eq_attr "type" "ssemov")
4656        (const_string "maybe_vex")
4657        (const_string "orig")))
4658    (set (attr "prefix_0f")
4659      (if_then_else (eq_attr "type" "imovx")
4660        (const_string "0")
4661        (const_string "*")))
4662    (set (attr "mode")
4663      (cond [(eq_attr "alternative" "5,6")
4664               (const_string "DI")
4665             (and (eq_attr "alternative" "7")
4666                  (match_test "TARGET_64BIT"))
4667               (const_string "TI")
4668             (eq_attr "alternative" "8,10,11")
4669               (const_string "TI")
4670            ]
4671            (const_string "SI")))
4672    (set (attr "preferred_for_speed")
4673      (cond [(eq_attr "alternative" "7")
4674               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4675             (eq_attr "alternative" "5,8")
4676               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4677            ]
4678            (symbol_ref "true")))])
4680 (define_split
4681   [(set (match_operand:DI 0 "memory_operand")
4682         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
4683   "reload_completed"
4684   [(set (match_dup 4) (const_int 0))]
4685   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4687 (define_split
4688   [(set (match_operand:DI 0 "general_reg_operand")
4689         (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
4690   "!TARGET_64BIT && reload_completed
4691    && REGNO (operands[0]) == REGNO (operands[1])"
4692   [(set (match_dup 4) (const_int 0))]
4693   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4695 (define_split
4696   [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4697         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4698   "!TARGET_64BIT && reload_completed
4699    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4700   [(set (match_dup 3) (match_dup 1))
4701    (set (match_dup 4) (const_int 0))]
4702   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4704 (define_mode_attr kmov_isa
4705   [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
4707 (define_insn "zero_extend<mode>di2"
4708   [(set (match_operand:DI 0 "register_operand" "=r,?r,?k")
4709         (zero_extend:DI
4710          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,?k,?km")))]
4711   "TARGET_64BIT"
4712   "@
4713    movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4714    kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
4715    kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4716   [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4717    (set_attr "type" "imovx,mskmov,mskmov")
4718    (set_attr "mode" "SI,<MODE>,<MODE>")])
4720 (define_expand "zero_extend<mode>si2"
4721   [(set (match_operand:SI 0 "register_operand")
4722         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4723   ""
4725   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4726     {
4727       operands[1] = force_reg (<MODE>mode, operands[1]);
4728       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4729       DONE;
4730     }
4733 (define_insn_and_split "zero_extend<mode>si2_and"
4734   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4735         (zero_extend:SI
4736           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4737    (clobber (reg:CC FLAGS_REG))]
4738   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4739   "#"
4740   "&& reload_completed"
4741   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4742               (clobber (reg:CC FLAGS_REG))])]
4744   if (!REG_P (operands[1])
4745       || REGNO (operands[0]) != REGNO (operands[1]))
4746     {
4747       ix86_expand_clear (operands[0]);
4749       gcc_assert (!TARGET_PARTIAL_REG_STALL);
4750       emit_insn (gen_rtx_SET
4751                  (gen_rtx_STRICT_LOW_PART
4752                   (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
4753                   operands[1]));
4754       DONE;
4755     }
4757   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4759   [(set_attr "type" "alu1")
4760    (set_attr "mode" "SI")])
4762 (define_insn "*zero_extend<mode>si2"
4763   [(set (match_operand:SI 0 "register_operand" "=r,?r,?k")
4764         (zero_extend:SI
4765           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,?k,?km")))]
4766   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4767   "@
4768    movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4769    kmov<mskmodesuffix>\t{%1, %0|%0, %1}
4770    kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4771   [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4772    (set_attr "type" "imovx,mskmov,mskmov")
4773    (set_attr "mode" "SI,<MODE>,<MODE>")])
4775 (define_expand "zero_extendqihi2"
4776   [(set (match_operand:HI 0 "register_operand")
4777         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4778   ""
4780   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4781     {
4782       operands[1] = force_reg (QImode, operands[1]);
4783       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4784       DONE;
4785     }
4788 (define_insn_and_split "zero_extendqihi2_and"
4789   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4790         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4791    (clobber (reg:CC FLAGS_REG))]
4792   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4793   "#"
4794   "&& reload_completed"
4795   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4796               (clobber (reg:CC FLAGS_REG))])]
4798   if (!REG_P (operands[1])
4799       || REGNO (operands[0]) != REGNO (operands[1]))
4800     {
4801       ix86_expand_clear (operands[0]);
4803       gcc_assert (!TARGET_PARTIAL_REG_STALL);
4804       emit_insn (gen_rtx_SET
4805                  (gen_rtx_STRICT_LOW_PART
4806                   (VOIDmode, gen_lowpart (QImode, operands[0])),
4807                   operands[1]));
4808       DONE;
4809     }
4811   operands[0] = gen_lowpart (SImode, operands[0]);
4813   [(set_attr "type" "alu1")
4814    (set_attr "mode" "SI")])
4816 ; zero extend to SImode to avoid partial register stalls
4817 (define_insn "*zero_extendqihi2"
4818   [(set (match_operand:HI 0 "register_operand" "=r,?r,?k")
4819         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,?k,?km")))]
4820   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4821   "@
4822    movz{bl|x}\t{%1, %k0|%k0, %1}
4823    kmovb\t{%1, %k0|%k0, %1}
4824    kmovb\t{%1, %0|%0, %1}"
4825   [(set_attr "isa" "*,avx512dq,avx512dq")
4826    (set_attr "type" "imovx,mskmov,mskmov")
4827    (set_attr "mode" "SI,QI,QI")])
4829 ;; Transform xorl; mov[bw] (set strict_low_part) into movz[bw]l.
4830 (define_peephole2
4831   [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
4832                    (const_int 0))
4833               (clobber (reg:CC FLAGS_REG))])
4834    (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4835         (match_operand:SWI12 2 "nonimmediate_operand"))]
4836   "REGNO (operands[0]) == REGNO (operands[1])
4837    && (<SWI48:MODE>mode != SImode
4838        || !TARGET_ZERO_EXTEND_WITH_AND
4839        || !optimize_function_for_speed_p (cfun))"
4840   [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4842 ;; Likewise, but preserving FLAGS_REG.
4843 (define_peephole2
4844   [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
4845    (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4846         (match_operand:SWI12 2 "nonimmediate_operand"))]
4847   "REGNO (operands[0]) == REGNO (operands[1])
4848    && (<SWI48:MODE>mode != SImode
4849        || !TARGET_ZERO_EXTEND_WITH_AND
4850        || !optimize_function_for_speed_p (cfun))"
4851   [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4853 ;; Sign extension instructions
4855 (define_expand "extendsidi2"
4856   [(set (match_operand:DI 0 "register_operand")
4857         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4858   ""
4860   if (!TARGET_64BIT)
4861     {
4862       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4863       DONE;
4864     }
4867 (define_insn "*extendsidi2_rex64"
4868   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4869         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4870   "TARGET_64BIT"
4871   "@
4872    {cltq|cdqe}
4873    movs{lq|x}\t{%1, %0|%0, %1}"
4874   [(set_attr "type" "imovx")
4875    (set_attr "mode" "DI")
4876    (set_attr "prefix_0f" "0")
4877    (set_attr "modrm" "0,1")])
4879 (define_insn "extendsidi2_1"
4880   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4881         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4882    (clobber (reg:CC FLAGS_REG))
4883    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4884   "!TARGET_64BIT"
4885   "#")
4887 (define_insn "extendditi2"
4888   [(set (match_operand:TI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4889         (sign_extend:TI (match_operand:DI 1 "register_operand" "0,0,r,r")))
4890    (clobber (reg:CC FLAGS_REG))
4891    (clobber (match_scratch:DI 2 "=X,X,X,&r"))]
4892   "TARGET_64BIT"
4893   "#")
4895 ;; Split the memory case.  If the source register doesn't die, it will stay
4896 ;; this way, if it does die, following peephole2s take care of it.
4897 (define_split
4898   [(set (match_operand:<DWI> 0 "memory_operand")
4899         (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4900    (clobber (reg:CC FLAGS_REG))
4901    (clobber (match_operand:DWIH 2 "register_operand"))]
4902   "reload_completed"
4903   [(const_int 0)]
4905   rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4907   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4909   emit_move_insn (operands[3], operands[1]);
4911   /* Generate a cltd if possible and doing so it profitable.  */
4912   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4913       && REGNO (operands[1]) == AX_REG
4914       && REGNO (operands[2]) == DX_REG)
4915     {
4916       emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[1], bits));
4917     }
4918   else
4919     {
4920       emit_move_insn (operands[2], operands[1]);
4921       emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[2], bits));
4922     }
4923   emit_move_insn (operands[4], operands[2]);
4924   DONE;
4927 ;; Peepholes for the case where the source register does die, after
4928 ;; being split with the above splitter.
4929 (define_peephole2
4930   [(set (match_operand:DWIH 0 "memory_operand")
4931         (match_operand:DWIH 1 "general_reg_operand"))
4932    (set (match_operand:DWIH 2 "general_reg_operand") (match_dup 1))
4933    (parallel [(set (match_dup 2)
4934                    (ashiftrt:DWIH (match_dup 2)
4935                                   (match_operand 4 "const_int_operand")))
4936                (clobber (reg:CC FLAGS_REG))])
4937    (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4938   "REGNO (operands[1]) != REGNO (operands[2])
4939    && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4940    && peep2_reg_dead_p (2, operands[1])
4941    && peep2_reg_dead_p (4, operands[2])
4942    && !reg_mentioned_p (operands[2], operands[3])"
4943   [(set (match_dup 0) (match_dup 1))
4944    (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4945               (clobber (reg:CC FLAGS_REG))])
4946    (set (match_dup 3) (match_dup 1))])
4948 (define_peephole2
4949   [(set (match_operand:DWIH 0 "memory_operand")
4950         (match_operand:DWIH 1 "general_reg_operand"))
4951    (parallel [(set (match_operand:DWIH 2 "general_reg_operand")
4952                    (ashiftrt:DWIH (match_dup 1)
4953                                   (match_operand 4 "const_int_operand")))
4954                (clobber (reg:CC FLAGS_REG))])
4955    (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4956   "/* cltd is shorter than sarl $31, %eax */
4957    !optimize_function_for_size_p (cfun)
4958    && REGNO (operands[1]) == AX_REG
4959    && REGNO (operands[2]) == DX_REG
4960    && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4961    && peep2_reg_dead_p (2, operands[1])
4962    && peep2_reg_dead_p (3, operands[2])
4963    && !reg_mentioned_p (operands[2], operands[3])"
4964   [(set (match_dup 0) (match_dup 1))
4965    (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4966               (clobber (reg:CC FLAGS_REG))])
4967    (set (match_dup 3) (match_dup 1))])
4969 ;; Extend to register case.  Optimize case where source and destination
4970 ;; registers match and cases where we can use cltd.
4971 (define_split
4972   [(set (match_operand:<DWI> 0 "register_operand")
4973         (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4974    (clobber (reg:CC FLAGS_REG))
4975    (clobber (match_scratch:DWIH 2))]
4976   "reload_completed"
4977   [(const_int 0)]
4979   rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4981   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4983   if (REGNO (operands[3]) != REGNO (operands[1]))
4984     emit_move_insn (operands[3], operands[1]);
4986   rtx src = operands[1];
4987   if (REGNO (operands[3]) == AX_REG)
4988     src = operands[3];
4990   /* Generate a cltd if possible and doing so it profitable.  */
4991   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4992       && REGNO (src) == AX_REG
4993       && REGNO (operands[4]) == DX_REG)
4994     {
4995       emit_insn (gen_ashr<mode>3_cvt (operands[4], src, bits));
4996       DONE;
4997     }
4999   if (REGNO (operands[4]) != REGNO (operands[1]))
5000     emit_move_insn (operands[4], operands[1]);
5002   emit_insn (gen_ashr<mode>3_cvt (operands[4], operands[4], bits));
5003   DONE;
5006 (define_insn "extend<mode>di2"
5007   [(set (match_operand:DI 0 "register_operand" "=r")
5008         (sign_extend:DI
5009          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
5010   "TARGET_64BIT"
5011   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
5012   [(set_attr "type" "imovx")
5013    (set_attr "mode" "DI")])
5015 (define_insn "extendhisi2"
5016   [(set (match_operand:SI 0 "register_operand" "=*a,r")
5017         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
5018   ""
5020   switch (get_attr_prefix_0f (insn))
5021     {
5022     case 0:
5023       return "{cwtl|cwde}";
5024     default:
5025       return "movs{wl|x}\t{%1, %0|%0, %1}";
5026     }
5028   [(set_attr "type" "imovx")
5029    (set_attr "mode" "SI")
5030    (set (attr "prefix_0f")
5031      ;; movsx is short decodable while cwtl is vector decoded.
5032      (if_then_else (and (eq_attr "cpu" "!k6")
5033                         (eq_attr "alternative" "0"))
5034         (const_string "0")
5035         (const_string "1")))
5036    (set (attr "znver1_decode")
5037      (if_then_else (eq_attr "prefix_0f" "0")
5038         (const_string "double")
5039         (const_string "direct")))
5040    (set (attr "modrm")
5041      (if_then_else (eq_attr "prefix_0f" "0")
5042         (const_string "0")
5043         (const_string "1")))])
5045 (define_insn "*extendhisi2_zext"
5046   [(set (match_operand:DI 0 "register_operand" "=*a,r")
5047         (zero_extend:DI
5048          (sign_extend:SI
5049           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
5050   "TARGET_64BIT"
5052   switch (get_attr_prefix_0f (insn))
5053     {
5054     case 0:
5055       return "{cwtl|cwde}";
5056     default:
5057       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
5058     }
5060   [(set_attr "type" "imovx")
5061    (set_attr "mode" "SI")
5062    (set (attr "prefix_0f")
5063      ;; movsx is short decodable while cwtl is vector decoded.
5064      (if_then_else (and (eq_attr "cpu" "!k6")
5065                         (eq_attr "alternative" "0"))
5066         (const_string "0")
5067         (const_string "1")))
5068    (set (attr "modrm")
5069      (if_then_else (eq_attr "prefix_0f" "0")
5070         (const_string "0")
5071         (const_string "1")))])
5073 (define_insn "extendqisi2"
5074   [(set (match_operand:SI 0 "register_operand" "=r")
5075         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
5076   ""
5077   "movs{bl|x}\t{%1, %0|%0, %1}"
5078    [(set_attr "type" "imovx")
5079     (set_attr "mode" "SI")])
5081 (define_insn "*extendqisi2_zext"
5082   [(set (match_operand:DI 0 "register_operand" "=r")
5083         (zero_extend:DI
5084           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
5085   "TARGET_64BIT"
5086   "movs{bl|x}\t{%1, %k0|%k0, %1}"
5087    [(set_attr "type" "imovx")
5088     (set_attr "mode" "SI")])
5090 (define_insn "extendqihi2"
5091   [(set (match_operand:HI 0 "register_operand" "=*a,r")
5092         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
5093   ""
5095   switch (get_attr_prefix_0f (insn))
5096     {
5097     case 0:
5098       return "{cbtw|cbw}";
5099     default:
5100       return "movs{bw|x}\t{%1, %0|%0, %1}";
5101     }
5103   [(set_attr "type" "imovx")
5104    (set_attr "mode" "HI")
5105    (set (attr "prefix_0f")
5106      ;; movsx is short decodable while cwtl is vector decoded.
5107      (if_then_else (and (eq_attr "cpu" "!k6")
5108                         (eq_attr "alternative" "0"))
5109         (const_string "0")
5110         (const_string "1")))
5111    (set (attr "modrm")
5112      (if_then_else (eq_attr "prefix_0f" "0")
5113         (const_string "0")
5114         (const_string "1")))])
5116 (define_insn "*extendqi<SWI24:mode>_ext_1"
5117   [(set (match_operand:SWI24 0 "register_operand" "=R")
5118         (sign_extend:SWI24
5119           (subreg:QI
5120             (match_operator:SWI248 2 "extract_operator"
5121               [(match_operand 1 "int248_register_operand" "Q")
5122                (const_int 8)
5123                (const_int 8)]) 0)))]
5124   ""
5125   "movs{b<SWI24:imodesuffix>|x}\t{%h1, %0|%0, %h1}"
5126    [(set_attr "type" "imovx")
5127     (set_attr "mode" "<SWI24:MODE>")])
5129 ;; Conversions between float and double.
5131 ;; These are all no-ops in the model used for the 80387.
5132 ;; So just emit moves.
5134 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
5135 (define_split
5136   [(set (match_operand:DF 0 "push_operand")
5137         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
5138   "reload_completed"
5139   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
5140    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
5142 (define_split
5143   [(set (match_operand:XF 0 "push_operand")
5144         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
5145   "reload_completed"
5146   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
5147    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
5148   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
5150 (define_expand "extendsfdf2"
5151   [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
5152         (float_extend:DF (match_operand:SF 1 "general_operand")))]
5153   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5155   /* ??? Needed for compress_float_constant since all fp constants
5156      are TARGET_LEGITIMATE_CONSTANT_P.  */
5157   if (CONST_DOUBLE_P (operands[1]))
5158     {
5159       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
5160           && standard_80387_constant_p (operands[1]) > 0)
5161         {
5162           operands[1] = simplify_const_unary_operation
5163             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
5164           emit_move_insn_1 (operands[0], operands[1]);
5165           DONE;
5166         }
5167       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
5168     }
5171 (define_insn "*extendsfdf2"
5172   [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
5173         (float_extend:DF
5174           (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
5175   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5177   switch (which_alternative)
5178     {
5179     case 0:
5180     case 1:
5181       return output_387_reg_move (insn, operands);
5183     case 2:
5184       return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
5185     case 3:
5186       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
5188     default:
5189       gcc_unreachable ();
5190     }
5192   [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5193    (set_attr "avx_partial_xmm_update" "false,false,false,true")
5194    (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
5195    (set_attr "mode" "SF,XF,DF,DF")
5196    (set (attr "enabled")
5197      (if_then_else
5198        (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5199        (if_then_else
5200          (eq_attr "alternative" "0,1")
5201          (symbol_ref "TARGET_MIX_SSE_I387")
5202          (symbol_ref "true"))
5203        (if_then_else
5204          (eq_attr "alternative" "0,1")
5205          (symbol_ref "true")
5206          (symbol_ref "false"))))])
5208 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
5209    cvtss2sd:
5210       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
5211       cvtps2pd xmm2,xmm1
5212    We do the conversion post reload to avoid producing of 128bit spills
5213    that might lead to ICE on 32bit target.  The sequence unlikely combine
5214    anyway.  */
5215 (define_split
5216   [(set (match_operand:DF 0 "sse_reg_operand")
5217         (float_extend:DF
5218           (match_operand:SF 1 "nonimmediate_operand")))]
5219   "TARGET_USE_VECTOR_FP_CONVERTS
5220    && optimize_insn_for_speed_p ()
5221    && reload_completed
5222    && (!EXT_REX_SSE_REG_P (operands[0])
5223        || TARGET_AVX512VL)"
5224    [(set (match_dup 2)
5225          (float_extend:V2DF
5226            (vec_select:V2SF
5227              (match_dup 3)
5228              (parallel [(const_int 0) (const_int 1)]))))]
5230   operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5231   operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
5232   /* Use movss for loading from memory, unpcklps reg, reg for registers.
5233      Try to avoid move when unpacking can be done in source.  */
5234   if (REG_P (operands[1]))
5235     {
5236       /* If it is unsafe to overwrite upper half of source, we need
5237          to move to destination and unpack there.  */
5238       if (REGNO (operands[0]) != REGNO (operands[1])
5239           || (EXT_REX_SSE_REG_P (operands[1]) && !TARGET_AVX512VL))
5240         {
5241           rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
5242           emit_move_insn (tmp, operands[1]);
5243         }
5244       else
5245         operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
5246       /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
5247          =v, v, then vbroadcastss will be only needed for AVX512F without
5248          AVX512VL.  */
5249       if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
5250         emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
5251                                                operands[3]));
5252       else
5253         {
5254           rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
5255           emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
5256         }
5257     }
5258   else
5259     emit_insn (gen_vec_setv4sf_0 (operands[3],
5260                                   CONST0_RTX (V4SFmode), operands[1]));
5263 ;; It's more profitable to split and then extend in the same register.
5264 (define_peephole2
5265   [(set (match_operand:DF 0 "sse_reg_operand")
5266         (float_extend:DF
5267           (match_operand:SF 1 "memory_operand")))]
5268   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5269    && optimize_insn_for_speed_p ()"
5270   [(set (match_dup 2) (match_dup 1))
5271    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
5272   "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
5274 ;; Break partial SSE register dependency stall.  This splitter should split
5275 ;; late in the pass sequence (after register rename pass), so allocated
5276 ;; registers won't change anymore
5278 (define_split
5279   [(set (match_operand:DF 0 "sse_reg_operand")
5280         (float_extend:DF
5281           (match_operand:SF 1 "nonimmediate_operand")))]
5282   "!TARGET_AVX
5283    && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5284    && epilogue_completed
5285    && optimize_function_for_speed_p (cfun)
5286    && (!REG_P (operands[1])
5287        || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5288    && (!EXT_REX_SSE_REG_P (operands[0])
5289        || TARGET_AVX512VL)"
5290   [(set (match_dup 0)
5291         (vec_merge:V2DF
5292           (vec_duplicate:V2DF
5293             (float_extend:DF
5294               (match_dup 1)))
5295           (match_dup 0)
5296           (const_int 1)))]
5298   operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5299   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5302 (define_expand "extendhfsf2"
5303   [(set (match_operand:SF 0 "register_operand")
5304         (float_extend:SF
5305           (match_operand:HF 1 "nonimmediate_operand")))]
5306   "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5308   if (!TARGET_AVX512FP16)
5309     {
5310       rtx res = gen_reg_rtx (V4SFmode);
5311       rtx tmp = gen_reg_rtx (V8HFmode);
5312       rtx zero = force_reg (V8HFmode, CONST0_RTX (V8HFmode));
5314       emit_insn (gen_vec_setv8hf_0 (tmp, zero, operands[1]));
5315       emit_insn (gen_vcvtph2ps (res, gen_lowpart (V8HImode, tmp)));
5316       emit_move_insn (operands[0], gen_lowpart (SFmode, res));
5317       DONE;
5318     }
5321 (define_expand "extendhfdf2"
5322   [(set (match_operand:DF 0 "register_operand")
5323         (float_extend:DF
5324           (match_operand:HF 1 "nonimmediate_operand")))]
5325   "TARGET_AVX512FP16")
5327 (define_insn "*extendhf<mode>2"
5328   [(set (match_operand:MODEF 0 "register_operand" "=v")
5329         (float_extend:MODEF
5330           (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5331   "TARGET_AVX512FP16"
5332   "vcvtsh2<ssemodesuffix>\t{%1, %0, %0|%0, %0, %1}"
5333   [(set_attr "type" "ssecvt")
5334    (set_attr "prefix" "evex")
5335    (set_attr "mode" "<MODE>")])
5337 (define_expand "extendbfsf2"
5338   [(set (match_operand:SF 0 "register_operand")
5339         (unspec:SF
5340           [(match_operand:BF 1 "register_operand")]
5341          UNSPEC_CVTBFSF))]
5342  "TARGET_SSE2 && !HONOR_NANS (BFmode)")
5344 ;; Don't use float_extend since psrlld doesn't raise
5345 ;; exceptions and turn a sNaN into a qNaN.
5346 (define_insn "extendbfsf2_1"
5347   [(set (match_operand:SF 0 "register_operand"   "=x,Yv,v")
5348         (unspec:SF
5349           [(match_operand:BF 1 "register_operand" " 0,Yv,v")]
5350           UNSPEC_CVTBFSF))]
5351  "TARGET_SSE2"
5352  "@
5353   pslld\t{$16, %0|%0, 16}
5354   vpslld\t{$16, %1, %0|%0, %1, 16}
5355   vpslld\t{$16, %g1, %g0|%g0, %g1, 16}"
5356   [(set_attr "isa" "noavx,avx,*")
5357    (set_attr "type" "sseishft1")
5358    (set_attr "length_immediate" "1")
5359    (set_attr "prefix_data16" "1,*,*")
5360    (set_attr "prefix" "orig,maybe_evex,evex")
5361    (set_attr "mode" "TI,TI,XI")
5362    (set_attr "memory" "none")
5363    (set (attr "enabled")
5364      (if_then_else (eq_attr "alternative" "2")
5365        (symbol_ref "TARGET_AVX512F && TARGET_EVEX512
5366                     && !TARGET_AVX512VL && !TARGET_PREFER_AVX256")
5367        (const_string "*")))])
5369 (define_expand "extend<mode>xf2"
5370   [(set (match_operand:XF 0 "nonimmediate_operand")
5371         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
5372   "TARGET_80387"
5374   /* ??? Needed for compress_float_constant since all fp constants
5375      are TARGET_LEGITIMATE_CONSTANT_P.  */
5376   if (CONST_DOUBLE_P (operands[1]))
5377     {
5378       if (standard_80387_constant_p (operands[1]) > 0)
5379         {
5380           operands[1] = simplify_const_unary_operation
5381             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
5382           emit_move_insn_1 (operands[0], operands[1]);
5383           DONE;
5384         }
5385       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
5386     }
5389 (define_insn "*extend<mode>xf2_i387"
5390   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
5391         (float_extend:XF
5392           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
5393   "TARGET_80387"
5394   "* return output_387_reg_move (insn, operands);"
5395   [(set_attr "type" "fmov")
5396    (set_attr "mode" "<MODE>,XF")])
5398 ;; %%% This seems like bad news.
5399 ;; This cannot output into an f-reg because there is no way to be sure
5400 ;; of truncating in that case.  Otherwise this is just like a simple move
5401 ;; insn.  So we pretend we can output to a reg in order to get better
5402 ;; register preferencing, but we really use a stack slot.
5404 ;; Conversion from DFmode to SFmode.
5406 (define_insn "truncdfsf2"
5407   [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
5408         (float_truncate:SF
5409           (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
5410   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5412   switch (which_alternative)
5413     {
5414     case 0:
5415     case 1:
5416       return output_387_reg_move (insn, operands);
5418     case 2:
5419       return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
5420     case 3:
5421       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
5423     default:
5424       gcc_unreachable ();
5425     }
5427   [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5428    (set_attr "avx_partial_xmm_update" "false,false,false,true")
5429    (set_attr "mode" "SF")
5430    (set (attr "enabled")
5431      (if_then_else
5432        (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5433        (cond [(eq_attr "alternative" "0")
5434                 (symbol_ref "TARGET_MIX_SSE_I387")
5435               (eq_attr "alternative" "1")
5436                 (symbol_ref "TARGET_MIX_SSE_I387
5437                              && flag_unsafe_math_optimizations")
5438            ]
5439            (symbol_ref "true"))
5440        (cond [(eq_attr "alternative" "0")
5441                 (symbol_ref "true")
5442               (eq_attr "alternative" "1")
5443                 (symbol_ref "flag_unsafe_math_optimizations")
5444            ]
5445            (symbol_ref "false"))))])
5447 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
5448    cvtsd2ss:
5449       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
5450       cvtpd2ps xmm2,xmm1
5451    We do the conversion post reload to avoid producing of 128bit spills
5452    that might lead to ICE on 32bit target.  The sequence unlikely combine
5453    anyway.  */
5454 (define_split
5455   [(set (match_operand:SF 0 "sse_reg_operand")
5456         (float_truncate:SF
5457           (match_operand:DF 1 "nonimmediate_operand")))]
5458   "TARGET_USE_VECTOR_FP_CONVERTS
5459    && optimize_insn_for_speed_p ()
5460    && reload_completed
5461    && (!EXT_REX_SSE_REG_P (operands[0])
5462        || TARGET_AVX512VL)"
5463    [(set (match_dup 2)
5464          (vec_concat:V4SF
5465            (float_truncate:V2SF
5466              (match_dup 4))
5467            (match_dup 3)))]
5469   operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5470   operands[3] = CONST0_RTX (V2SFmode);
5471   operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
5472   /* Use movsd for loading from memory, unpcklpd for registers.
5473      Try to avoid move when unpacking can be done in source, or SSE3
5474      movddup is available.  */
5475   if (REG_P (operands[1]))
5476     {
5477       if ((!TARGET_SSE3 && REGNO (operands[0]) != REGNO (operands[1]))
5478           || (EXT_REX_SSE_REG_P (operands[1]) && !TARGET_AVX512VL))
5479         {
5480           rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
5481           emit_move_insn (tmp, operands[1]);
5482           operands[1] = tmp;
5483         }
5484       else if (!TARGET_SSE3)
5485         operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
5486       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
5487     }
5488   else
5489     emit_insn (gen_vec_concatv2df (operands[4], operands[1],
5490                                    CONST0_RTX (DFmode)));
5493 ;; It's more profitable to split and then truncate in the same register.
5494 (define_peephole2
5495   [(set (match_operand:SF 0 "sse_reg_operand")
5496         (float_truncate:SF
5497           (match_operand:DF 1 "memory_operand")))]
5498   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5499    && optimize_insn_for_speed_p ()"
5500   [(set (match_dup 2) (match_dup 1))
5501    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
5502   "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
5504 ;; Break partial SSE register dependency stall.  This splitter should split
5505 ;; late in the pass sequence (after register rename pass), so allocated
5506 ;; registers won't change anymore
5508 (define_split
5509   [(set (match_operand:SF 0 "sse_reg_operand")
5510         (float_truncate:SF
5511           (match_operand:DF 1 "nonimmediate_operand")))]
5512   "!TARGET_AVX
5513    && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5514    && epilogue_completed
5515    && optimize_function_for_speed_p (cfun)
5516    && (!REG_P (operands[1])
5517        || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5518    && (!EXT_REX_SSE_REG_P (operands[0])
5519        || TARGET_AVX512VL)"
5520   [(set (match_dup 0)
5521         (vec_merge:V4SF
5522           (vec_duplicate:V4SF
5523             (float_truncate:SF
5524               (match_dup 1)))
5525           (match_dup 0)
5526           (const_int 1)))]
5528   operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5529   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5532 ;; Conversion from XFmode to {SF,DF}mode
5534 (define_insn "truncxf<mode>2"
5535   [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
5536         (float_truncate:MODEF
5537           (match_operand:XF 1 "register_operand" "f,f")))]
5538   "TARGET_80387"
5539   "* return output_387_reg_move (insn, operands);"
5540   [(set_attr "type" "fmov")
5541    (set_attr "mode" "<MODE>")
5542    (set (attr "enabled")
5543      (cond [(eq_attr "alternative" "1")
5544               (symbol_ref "flag_unsafe_math_optimizations")
5545            ]
5546            (symbol_ref "true")))])
5548 ;; Conversion from {SF,DF}mode to HFmode.
5550 (define_expand "truncsfhf2"
5551   [(set (match_operand:HF 0 "register_operand")
5552         (float_truncate:HF
5553           (match_operand:SF 1 "nonimmediate_operand")))]
5554   "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5555   {
5556     if (!TARGET_AVX512FP16)
5557     {
5558       rtx res = gen_reg_rtx (V8HFmode);
5559       rtx tmp = gen_reg_rtx (V4SFmode);
5560       rtx zero = force_reg (V4SFmode, CONST0_RTX (V4SFmode));
5562       emit_insn (gen_vec_setv4sf_0 (tmp, zero, operands[1]));
5563       emit_insn (gen_vcvtps2ph (gen_lowpart (V8HImode, res), tmp, GEN_INT (4)));
5564       emit_move_insn (operands[0], gen_lowpart (HFmode, res));
5565       DONE;
5566     }
5567   })
5569 (define_expand "truncdfhf2"
5570   [(set (match_operand:HF 0 "register_operand")
5571         (float_truncate:HF
5572           (match_operand:DF 1 "nonimmediate_operand")))]
5573   "TARGET_AVX512FP16")
5575 (define_insn "*trunc<mode>hf2"
5576   [(set (match_operand:HF 0 "register_operand" "=v")
5577        (float_truncate:HF
5578          (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5579   "TARGET_AVX512FP16"
5580   "vcvt<ssemodesuffix>2sh\t{%1, %d0|%d0, %1}"
5581   [(set_attr "type" "ssecvt")
5582    (set_attr "prefix" "evex")
5583    (set_attr "mode" "HF")])
5585 (define_insn "truncsfbf2"
5586   [(set (match_operand:BF 0 "register_operand" "=x, v")
5587         (float_truncate:BF
5588           (match_operand:SF 1 "register_operand" "x,v")))]
5589   "((TARGET_AVX512BF16 && TARGET_AVX512VL) || TARGET_AVXNECONVERT)
5590    && !HONOR_NANS (BFmode) && flag_unsafe_math_optimizations"
5591   "@
5592   %{vex%} vcvtneps2bf16\t{%1, %0|%0, %1}
5593   vcvtneps2bf16\t{%1, %0|%0, %1}"
5594   [(set_attr "isa" "avxneconvert,avx512bf16vl")
5595    (set_attr "prefix" "vex,evex")])
5597 ;; Signed conversion to DImode.
5599 (define_expand "fix_truncxfdi2"
5600   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5601                    (fix:DI (match_operand:XF 1 "register_operand")))
5602               (clobber (reg:CC FLAGS_REG))])]
5603   "TARGET_80387"
5605   if (TARGET_FISTTP)
5606    {
5607      emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5608      DONE;
5609    }
5612 (define_expand "fix_trunc<mode>di2"
5613   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5614                    (fix:DI (match_operand:MODEF 1 "register_operand")))
5615               (clobber (reg:CC FLAGS_REG))])]
5616   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
5618   if (TARGET_FISTTP
5619       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5620    {
5621      emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5622      DONE;
5623    }
5624   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
5625    {
5626      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
5627      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
5628      if (out != operands[0])
5629         emit_move_insn (operands[0], out);
5630      DONE;
5631    }
5634 (define_insn "fix<fixunssuffix>_trunchf<mode>2"
5635   [(set (match_operand:SWI48 0 "register_operand" "=r")
5636         (any_fix:SWI48
5637           (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5638   "TARGET_AVX512FP16"
5639   "vcvttsh2<fixsuffix>si\t{%1, %0|%0, %1}"
5640   [(set_attr "type" "sseicvt")
5641    (set_attr "prefix" "evex")
5642    (set_attr "mode" "<MODE>")])
5644 ;; Signed conversion to SImode.
5646 (define_expand "fix_truncxfsi2"
5647   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5648                    (fix:SI (match_operand:XF 1 "register_operand")))
5649               (clobber (reg:CC FLAGS_REG))])]
5650   "TARGET_80387"
5652   if (TARGET_FISTTP)
5653    {
5654      emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5655      DONE;
5656    }
5659 (define_expand "fix_trunc<mode>si2"
5660   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5661                    (fix:SI (match_operand:MODEF 1 "register_operand")))
5662               (clobber (reg:CC FLAGS_REG))])]
5663   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
5665   if (TARGET_FISTTP
5666       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5667    {
5668      emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5669      DONE;
5670    }
5671   if (SSE_FLOAT_MODE_P (<MODE>mode))
5672    {
5673      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
5674      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
5675      if (out != operands[0])
5676         emit_move_insn (operands[0], out);
5677      DONE;
5678    }
5681 ;; Signed conversion to HImode.
5683 (define_expand "fix_trunc<mode>hi2"
5684   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
5685                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
5686               (clobber (reg:CC FLAGS_REG))])]
5687   "TARGET_80387
5688    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5690   if (TARGET_FISTTP)
5691    {
5692      emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
5693      DONE;
5694    }
5697 ;; Unsigned conversion to DImode
5699 (define_insn "fixuns_trunc<mode>di2"
5700   [(set (match_operand:DI 0 "register_operand" "=r")
5701         (unsigned_fix:DI
5702           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5703   "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5704   "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5705   [(set_attr "type" "sseicvt")
5706    (set_attr "prefix" "evex")
5707    (set_attr "mode" "DI")])
5709 ;; Unsigned conversion to SImode.
5711 (define_expand "fixuns_trunc<mode>si2"
5712   [(parallel
5713     [(set (match_operand:SI 0 "register_operand")
5714           (unsigned_fix:SI
5715             (match_operand:MODEF 1 "nonimmediate_operand")))
5716      (use (match_dup 2))
5717      (clobber (scratch:<ssevecmode>))
5718      (clobber (scratch:<ssevecmode>))])]
5719   "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
5721   machine_mode mode = <MODE>mode;
5722   machine_mode vecmode = <ssevecmode>mode;
5723   REAL_VALUE_TYPE TWO31r;
5724   rtx two31;
5726   if (TARGET_AVX512F)
5727     {
5728       emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
5729       DONE;
5730     }
5732   if (optimize_insn_for_size_p ())
5733     FAIL;
5735   real_ldexp (&TWO31r, &dconst1, 31);
5736   two31 = const_double_from_real_value (TWO31r, mode);
5737   two31 = ix86_build_const_vector (vecmode, true, two31);
5738   operands[2] = force_reg (vecmode, two31);
5741 (define_insn "fixuns_trunc<mode>si2_avx512f"
5742   [(set (match_operand:SI 0 "register_operand" "=r")
5743         (unsigned_fix:SI
5744           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5745   "TARGET_AVX512F && TARGET_SSE_MATH"
5746   "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5747   [(set_attr "type" "sseicvt")
5748    (set_attr "prefix" "evex")
5749    (set_attr "mode" "SI")])
5751 (define_insn "*fixuns_trunchfsi2zext"
5752   [(set (match_operand:DI 0 "register_operand" "=r")
5753         (zero_extend:DI
5754           (unsigned_fix:SI
5755             (match_operand:HF 1 "nonimmediate_operand" "vm"))))]
5756   "TARGET_64BIT && TARGET_AVX512FP16"
5757   "vcvttsh2usi\t{%1, %k0|%k0, %1}"
5758   [(set_attr "type" "sseicvt")
5759    (set_attr "prefix" "evex")
5760    (set_attr "mode" "SI")])
5762 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
5763   [(set (match_operand:DI 0 "register_operand" "=r")
5764         (zero_extend:DI
5765           (unsigned_fix:SI
5766             (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
5767   "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5768   "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
5769   [(set_attr "type" "sseicvt")
5770    (set_attr "prefix" "evex")
5771    (set_attr "mode" "SI")])
5773 (define_insn_and_split "*fixuns_trunc<mode>_1"
5774   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5775         (unsigned_fix:SI
5776           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5777    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
5778    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5779    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5780   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5781    && optimize_function_for_speed_p (cfun)"
5782   "#"
5783   "&& reload_completed"
5784   [(const_int 0)]
5786   ix86_split_convert_uns_si_sse (operands);
5787   DONE;
5790 ;; Unsigned conversion to HImode.
5791 ;; Without these patterns, we'll try the unsigned SI conversion which
5792 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5794 (define_expand "fixuns_trunchfhi2"
5795   [(set (match_dup 2)
5796         (fix:SI (match_operand:HF 1 "nonimmediate_operand")))
5797    (set (match_operand:HI 0 "nonimmediate_operand")
5798         (subreg:HI (match_dup 2) 0))]
5799   "TARGET_AVX512FP16"
5800   "operands[2] = gen_reg_rtx (SImode);")
5802 (define_expand "fixuns_trunc<mode>hi2"
5803   [(set (match_dup 2)
5804         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5805    (set (match_operand:HI 0 "nonimmediate_operand")
5806         (subreg:HI (match_dup 2) 0))]
5807   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5808   "operands[2] = gen_reg_rtx (SImode);")
5810 ;; When SSE is available, it is always faster to use it!
5811 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5812   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5813         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5814   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5815    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5816   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5817   [(set_attr "type" "sseicvt")
5818    (set_attr "prefix" "maybe_vex")
5819    (set (attr "prefix_rex")
5820         (if_then_else
5821           (match_test "<SWI48:MODE>mode == DImode")
5822           (const_string "1")
5823           (const_string "*")))
5824    (set_attr "mode" "<MODEF:MODE>")
5825    (set_attr "athlon_decode" "double,vector")
5826    (set_attr "amdfam10_decode" "double,double")
5827    (set_attr "bdver1_decode" "double,double")])
5829 ;; Avoid vector decoded forms of the instruction.
5830 (define_peephole2
5831   [(match_scratch:MODEF 2 "x")
5832    (set (match_operand:SWI48 0 "register_operand")
5833         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5834   "TARGET_AVOID_VECTOR_DECODE
5835    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5836    && optimize_insn_for_speed_p ()"
5837   [(set (match_dup 2) (match_dup 1))
5838    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5840 (define_insn "fix_trunc<mode>_i387_fisttp"
5841   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
5842         (fix:SWI248x (match_operand 1 "register_operand" "f")))
5843    (clobber (match_scratch:XF 2 "=&f"))]
5844   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5845    && TARGET_FISTTP
5846    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5847          && (TARGET_64BIT || <MODE>mode != DImode))
5848         && TARGET_SSE_MATH)"
5849   "* return output_fix_trunc (insn, operands, true);"
5850   [(set_attr "type" "fisttp")
5851    (set_attr "mode" "<MODE>")])
5853 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5854 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5855 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5856 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5857 ;; function in i386.cc.
5858 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5859   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5860         (fix:SWI248x (match_operand 1 "register_operand")))
5861    (clobber (reg:CC FLAGS_REG))]
5862   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5863    && !TARGET_FISTTP
5864    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5865          && (TARGET_64BIT || <MODE>mode != DImode))
5866    && ix86_pre_reload_split ()"
5867   "#"
5868   "&& 1"
5869   [(const_int 0)]
5871   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5873   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5874   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5876   emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5877                                        operands[2], operands[3]));
5878   DONE;
5880   [(set_attr "type" "fistp")
5881    (set_attr "i387_cw" "trunc")
5882    (set_attr "mode" "<MODE>")])
5884 (define_insn "fix_truncdi_i387"
5885   [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
5886         (fix:DI (match_operand 1 "register_operand" "f")))
5887    (use (match_operand:HI 2 "memory_operand" "m"))
5888    (use (match_operand:HI 3 "memory_operand" "m"))
5889    (clobber (match_scratch:XF 4 "=&f"))]
5890   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5891    && !TARGET_FISTTP
5892    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5893   "* return output_fix_trunc (insn, operands, false);"
5894   [(set_attr "type" "fistp")
5895    (set_attr "i387_cw" "trunc")
5896    (set_attr "mode" "DI")])
5898 (define_insn "fix_trunc<mode>_i387"
5899   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
5900         (fix:SWI24 (match_operand 1 "register_operand" "f")))
5901    (use (match_operand:HI 2 "memory_operand" "m"))
5902    (use (match_operand:HI 3 "memory_operand" "m"))]
5903   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5904    && !TARGET_FISTTP
5905    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5906   "* return output_fix_trunc (insn, operands, false);"
5907   [(set_attr "type" "fistp")
5908    (set_attr "i387_cw" "trunc")
5909    (set_attr "mode" "<MODE>")])
5911 (define_insn "x86_fnstcw_1"
5912   [(set (match_operand:HI 0 "memory_operand" "=m")
5913         (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
5914   "TARGET_80387"
5915   "fnstcw\t%0"
5916   [(set (attr "length")
5917         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5918    (set_attr "mode" "HI")
5919    (set_attr "unit" "i387")
5920    (set_attr "bdver1_decode" "vector")])
5922 ;; Conversion between fixed point and floating point.
5924 ;; Even though we only accept memory inputs, the backend _really_
5925 ;; wants to be able to do this between registers.  Thankfully, LRA
5926 ;; will fix this up for us during register allocation.
5928 (define_insn "floathi<mode>2"
5929   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5930         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5931   "TARGET_80387
5932    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5933        || TARGET_MIX_SSE_I387)"
5934   "fild%Z1\t%1"
5935   [(set_attr "type" "fmov")
5936    (set_attr "mode" "<MODE>")
5937    (set_attr "znver1_decode" "double")
5938    (set_attr "fp_int_src" "true")])
5940 (define_insn "float<SWI48x:mode>xf2"
5941   [(set (match_operand:XF 0 "register_operand" "=f")
5942         (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5943   "TARGET_80387"
5944   "fild%Z1\t%1"
5945   [(set_attr "type" "fmov")
5946    (set_attr "mode" "XF")
5947    (set_attr "znver1_decode" "double")
5948    (set_attr "fp_int_src" "true")])
5950 (define_expand "float<SWI48x:mode><MODEF:mode>2"
5951   [(set (match_operand:MODEF 0 "register_operand")
5952         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
5953   "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
5954    || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5955        && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
5957 (define_insn "*float<SWI48:mode><MODEF:mode>2"
5958   [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5959         (float:MODEF
5960           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5961   "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5962    || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5963   "@
5964    fild%Z1\t%1
5965    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5966    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5967   [(set_attr "type" "fmov,sseicvt,sseicvt")
5968    (set_attr "avx_partial_xmm_update" "false,true,true")
5969    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5970    (set_attr "mode" "<MODEF:MODE>")
5971    (set (attr "prefix_rex")
5972      (if_then_else
5973        (and (eq_attr "prefix" "maybe_vex")
5974             (match_test "<SWI48:MODE>mode == DImode"))
5975        (const_string "1")
5976        (const_string "*")))
5977    (set_attr "unit" "i387,*,*")
5978    (set_attr "athlon_decode" "*,double,direct")
5979    (set_attr "amdfam10_decode" "*,vector,double")
5980    (set_attr "bdver1_decode" "*,double,direct")
5981    (set_attr "znver1_decode" "double,*,*")
5982    (set_attr "fp_int_src" "true")
5983    (set (attr "enabled")
5984      (if_then_else
5985        (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
5986        (if_then_else
5987          (eq_attr "alternative" "0")
5988          (symbol_ref "TARGET_MIX_SSE_I387
5989                       && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5990                                            <SWI48:MODE>mode)")
5991          (symbol_ref "true"))
5992        (if_then_else
5993          (eq_attr "alternative" "0")
5994          (symbol_ref "true")
5995          (symbol_ref "false"))))
5996    (set (attr "preferred_for_speed")
5997      (cond [(eq_attr "alternative" "1")
5998               (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5999            (symbol_ref "true")))])
6001 (define_insn "float<floatunssuffix><mode>hf2"
6002   [(set (match_operand:HF 0 "register_operand" "=v")
6003         (any_float:HF
6004           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
6005   "TARGET_AVX512FP16"
6006   "vcvt<floatsuffix>si2sh<rex64suffix>\t{%1, %d0|%d0, %1}"
6007   [(set_attr "type" "sseicvt")
6008    (set_attr "prefix" "evex")
6009    (set_attr "mode" "HF")])
6011 (define_insn "*floatdi<MODEF:mode>2_i387"
6012   [(set (match_operand:MODEF 0 "register_operand" "=f")
6013         (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
6014   "!TARGET_64BIT
6015    && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
6016   "fild%Z1\t%1"
6017   [(set_attr "type" "fmov")
6018    (set_attr "mode" "<MODEF:MODE>")
6019    (set_attr "znver1_decode" "double")
6020    (set_attr "fp_int_src" "true")])
6022 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
6023 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
6024 ;; alternative in sse2_loadld.
6025 (define_split
6026   [(set (match_operand:MODEF 0 "sse_reg_operand")
6027         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
6028   "TARGET_SSE2
6029    && TARGET_USE_VECTOR_CONVERTS
6030    && optimize_function_for_speed_p (cfun)
6031    && reload_completed
6032    && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
6033    && (!EXT_REX_SSE_REG_P (operands[0])
6034        || TARGET_AVX512VL)"
6035   [(const_int 0)]
6037   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
6038   operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
6040   emit_insn (gen_sse2_loadld (operands[4],
6041                               CONST0_RTX (V4SImode), operands[1]));
6043   if (<ssevecmode>mode == V4SFmode)
6044     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
6045   else
6046     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
6047   DONE;
6050 ;; Avoid store forwarding (partial memory) stall penalty
6051 ;; by passing DImode value through XMM registers.  */
6053 (define_split
6054   [(set (match_operand:X87MODEF 0 "register_operand")
6055         (float:X87MODEF
6056           (match_operand:DI 1 "register_operand")))]
6057   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
6058    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6059    && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
6060    && can_create_pseudo_p ()"
6061   [(const_int 0)]
6063   rtx s = assign_386_stack_local (DImode, SLOT_FLOATxFDI_387);
6064   emit_insn (gen_floatdi<mode>2_i387_with_xmm (operands[0], operands[1], s));
6065   DONE;
6068 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
6069   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
6070         (float:X87MODEF
6071           (match_operand:DI 1 "register_operand" "r,r")))
6072    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
6073    (clobber (match_scratch:V4SI 3 "=x,x"))
6074    (clobber (match_scratch:V4SI 4 "=X,x"))]
6075   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
6076    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6077    && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
6078   "#"
6079   "&& reload_completed"
6080   [(set (match_dup 2) (match_dup 3))
6081    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
6083   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
6084      Assemble the 64-bit DImode value in an xmm register.  */
6085   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
6086                               gen_lowpart (SImode, operands[1])));
6087   if (TARGET_SSE4_1)
6088     emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
6089                                   gen_highpart (SImode, operands[1]),
6090                                   GEN_INT (2)));
6091   else
6092     {
6093       emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
6094                                   gen_highpart (SImode, operands[1])));
6095       emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
6096                                              operands[4]));
6097     }
6098   operands[3] = gen_lowpart (DImode, operands[3]);
6100   [(set_attr "isa" "sse4,*")
6101    (set_attr "type" "multi")
6102    (set_attr "mode" "<X87MODEF:MODE>")
6103    (set_attr "unit" "i387")
6104    (set_attr "fp_int_src" "true")])
6106 ;; Break partial SSE register dependency stall.  This splitter should split
6107 ;; late in the pass sequence (after register rename pass), so allocated
6108 ;; registers won't change anymore
6110 (define_split
6111   [(set (match_operand:MODEF 0 "sse_reg_operand")
6112         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
6113   "!TARGET_AVX
6114    && TARGET_SSE_PARTIAL_REG_CONVERTS_DEPENDENCY
6115    && epilogue_completed
6116    && optimize_function_for_speed_p (cfun)
6117    && (!EXT_REX_SSE_REG_P (operands[0])
6118        || TARGET_AVX512VL)"
6119   [(set (match_dup 0)
6120         (vec_merge:<MODEF:ssevecmode>
6121           (vec_duplicate:<MODEF:ssevecmode>
6122             (float:MODEF
6123               (match_dup 1)))
6124           (match_dup 0)
6125           (const_int 1)))]
6127   const machine_mode vmode = <MODEF:ssevecmode>mode;
6129   operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
6130   emit_move_insn (operands[0], CONST0_RTX (vmode));
6133 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
6134   [(set (match_operand:MODEF 0 "register_operand")
6135         (unsigned_float:MODEF
6136           (match_operand:SWI12 1 "nonimmediate_operand")))]
6137   "!TARGET_64BIT
6138    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
6140   operands[1] = convert_to_mode (SImode, operands[1], 1);
6141   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
6142   DONE;
6145 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
6146   [(set (match_operand:MODEF 0 "register_operand" "=v")
6147         (unsigned_float:MODEF
6148           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
6149   "TARGET_AVX512F && TARGET_SSE_MATH"
6150   "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
6151   [(set_attr "type" "sseicvt")
6152    (set_attr "avx_partial_xmm_update" "true")
6153    (set_attr "prefix" "evex")
6154    (set_attr "mode" "<MODEF:MODE>")])
6156 ;; Avoid store forwarding (partial memory) stall penalty by extending
6157 ;; SImode value to DImode through XMM register instead of pushing two
6158 ;; SImode values to stack. Also note that fild loads from memory only.
6160 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
6161   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
6162         (unsigned_float:X87MODEF
6163           (match_operand:SI 1 "nonimmediate_operand" "rm")))
6164    (clobber (match_operand:DI 2 "memory_operand" "=m"))
6165    (clobber (match_scratch:DI 3 "=x"))]
6166   "!TARGET_64BIT
6167    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6168    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
6169   "#"
6170   "&& reload_completed"
6171   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
6172    (set (match_dup 2) (match_dup 3))
6173    (set (match_dup 0)
6174         (float:X87MODEF (match_dup 2)))]
6175   ""
6176   [(set_attr "type" "multi")
6177    (set_attr "mode" "<MODE>")])
6179 (define_expand "floatunssi<mode>2"
6180   [(set (match_operand:X87MODEF 0 "register_operand")
6181         (unsigned_float:X87MODEF
6182           (match_operand:SI 1 "nonimmediate_operand")))]
6183   "(!TARGET_64BIT
6184     && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6185     && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
6186    || ((!TARGET_64BIT || TARGET_AVX512F)
6187        && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6189   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
6190     {
6191       emit_insn (gen_floatunssi<mode>2_i387_with_xmm
6192                   (operands[0], operands[1],
6193                    assign_386_stack_local (DImode, SLOT_TEMP)));
6194       DONE;
6195     }
6196   if (!TARGET_AVX512F)
6197     {
6198       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6199       DONE;
6200     }
6203 (define_expand "floatunsdisf2"
6204   [(set (match_operand:SF 0 "register_operand")
6205         (unsigned_float:SF
6206           (match_operand:DI 1 "nonimmediate_operand")))]
6207   "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
6209   if (!TARGET_AVX512F)
6210     {
6211       x86_emit_floatuns (operands);
6212       DONE;
6213     }
6216 (define_expand "floatunsdidf2"
6217   [(set (match_operand:DF 0 "register_operand")
6218         (unsigned_float:DF
6219           (match_operand:DI 1 "nonimmediate_operand")))]
6220   "((TARGET_64BIT && TARGET_AVX512F)
6221     || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6222    && TARGET_SSE2 && TARGET_SSE_MATH"
6224   if (!TARGET_64BIT)
6225     {
6226       ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6227       DONE;
6228     }
6229   if (!TARGET_AVX512F)
6230     {
6231       x86_emit_floatuns (operands);
6232       DONE;
6233     }
6236 ;; Load effective address instructions
6238 (define_insn "*lea<mode>"
6239   [(set (match_operand:SWI48 0 "register_operand" "=r")
6240         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
6241   "ix86_hardreg_mov_ok (operands[0], operands[1])"
6243   if (SImode_address_operand (operands[1], VOIDmode))
6244     {
6245       gcc_assert (TARGET_64BIT);
6246       return "lea{l}\t{%E1, %k0|%k0, %E1}";
6247     }
6248   else
6249     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
6251   [(set_attr "type" "lea")
6252    (set (attr "mode")
6253      (if_then_else
6254        (match_operand 1 "SImode_address_operand")
6255        (const_string "SI")
6256        (const_string "<MODE>")))])
6258 (define_peephole2
6259   [(set (match_operand:SWI48 0 "register_operand")
6260         (match_operand:SWI48 1 "address_no_seg_operand"))]
6261   "ix86_hardreg_mov_ok (operands[0], operands[1])
6262    && peep2_regno_dead_p (0, FLAGS_REG)
6263    && ix86_avoid_lea_for_addr (peep2_next_insn (0), operands)"
6264   [(const_int 0)]
6266   machine_mode mode = <MODE>mode;
6268   /* Emit all operations in SImode for zero-extended addresses.  */
6269   if (SImode_address_operand (operands[1], VOIDmode))
6270     mode = SImode;
6272   ix86_split_lea_for_addr (peep2_next_insn (0), operands, mode);
6274   /* Zero-extend return register to DImode for zero-extended addresses.  */
6275   if (mode != <MODE>mode)
6276     emit_insn (gen_zero_extendsidi2 (operands[0],
6277                                      gen_lowpart (mode, operands[0])));
6279   DONE;
6282 ;; ix86_split_lea_for_addr emits the shifts as MULT to avoid it from being
6283 ;; peephole2 optimized back into a lea.  Split that into the shift during
6284 ;; the following split pass.
6285 (define_split
6286   [(set (match_operand:SWI48 0 "general_reg_operand")
6287         (mult:SWI48 (match_dup 0) (match_operand:SWI48 1 "const1248_operand")))
6288    (clobber (reg:CC FLAGS_REG))]
6289   "reload_completed"
6290   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
6291               (clobber (reg:CC FLAGS_REG))])]
6292   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
6294 ;; Add instructions
6296 (define_expand "add<mode>3"
6297   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6298         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6299                     (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6300   ""
6302   ix86_expand_binary_operator (PLUS, <MODE>mode, operands, TARGET_APX_NDD);
6303   DONE;
6306 (define_insn_and_split "*add<dwi>3_doubleword"
6307   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r,&r,&r,&r")
6308         (plus:<DWI>
6309           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r,ro,jO,r")
6310           (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r,<di>,K,<di>,r")))
6311    (clobber (reg:CC FLAGS_REG))]
6312   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands, TARGET_APX_NDD)"
6313   "#"
6314   "&& reload_completed"
6315   [(parallel [(set (reg:CCC FLAGS_REG)
6316                    (compare:CCC
6317                      (plus:DWIH (match_dup 1) (match_dup 2))
6318                      (match_dup 1)))
6319               (set (match_dup 0)
6320                    (plus:DWIH (match_dup 1) (match_dup 2)))])
6321    (parallel [(set (match_dup 3)
6322                    (plus:DWIH
6323                      (plus:DWIH
6324                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6325                        (match_dup 4))
6326                      (match_dup 5)))
6327               (clobber (reg:CC FLAGS_REG))])]
6329   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6330   if (operands[2] == const0_rtx)
6331     {
6332       /* Under NDD op0 and op1 may not equal, do not delete insn then.  */
6333       bool emit_insn_deleted_note_p = true;
6334       if (!rtx_equal_p (operands[0], operands[1]))
6335         {
6336           emit_move_insn (operands[0], operands[1]);
6337           emit_insn_deleted_note_p = false;
6338         }
6339       if (operands[5] != const0_rtx)
6340         ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3],
6341                                      TARGET_APX_NDD);
6342       else if (!rtx_equal_p (operands[3], operands[4]))
6343         emit_move_insn (operands[3], operands[4]);
6344       else if (emit_insn_deleted_note_p)
6345         emit_note (NOTE_INSN_DELETED);
6346       DONE;
6347     }
6349 [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd_64,apx_ndd")])
6351 (define_insn_and_split "*add<dwi>3_doubleword_zext"
6352   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,&r,&r")
6353         (plus:<DWI>
6354           (zero_extend:<DWI>
6355             (match_operand:DWIH 2 "nonimmediate_operand" "rm,r,rm,r"))
6356           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0,r,m")))
6357    (clobber (reg:CC FLAGS_REG))]
6358   "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands, TARGET_APX_NDD)"
6359   "#"
6360   "&& reload_completed"
6361   [(parallel [(set (reg:CCC FLAGS_REG)
6362                    (compare:CCC
6363                      (plus:DWIH (match_dup 1) (match_dup 2))
6364                      (match_dup 1)))
6365               (set (match_dup 0)
6366                    (plus:DWIH (match_dup 1) (match_dup 2)))])
6367    (parallel [(set (match_dup 3)
6368                    (plus:DWIH
6369                      (plus:DWIH
6370                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6371                        (match_dup 4))
6372                      (const_int 0)))
6373               (clobber (reg:CC FLAGS_REG))])]
6374  "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);"
6375  [(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
6377 (define_insn_and_split "*add<dwi>3_doubleword_concat"
6378   [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6379         (plus:<DWI>
6380           (any_or_plus:<DWI>
6381             (ashift:<DWI>
6382               (zero_extend:<DWI>
6383                 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6384               (match_operand:QI 3 "const_int_operand"))
6385             (zero_extend:<DWI>
6386               (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6387           (match_operand:<DWI> 1 "register_operand" "0")))
6388    (clobber (reg:CC FLAGS_REG))]
6389   "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6390   "#"
6391   "&& reload_completed"
6392   [(parallel [(set (reg:CCC FLAGS_REG)
6393                    (compare:CCC
6394                      (plus:DWIH (match_dup 1) (match_dup 4))
6395                      (match_dup 1)))
6396               (set (match_dup 0)
6397                    (plus:DWIH (match_dup 1) (match_dup 4)))])
6398    (parallel [(set (match_dup 5)
6399                    (plus:DWIH
6400                      (plus:DWIH
6401                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6402                        (match_dup 6))
6403                      (match_dup 2)))
6404               (clobber (reg:CC FLAGS_REG))])]
6405  "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[5]);")
6407 (define_insn_and_split "*add<dwi>3_doubleword_concat_zext"
6408   [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6409         (plus:<DWI>
6410           (any_or_plus:<DWI>
6411             (ashift:<DWI>
6412               (zero_extend:<DWI>
6413                 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6414               (match_operand:QI 3 "const_int_operand"))
6415             (zero_extend:<DWI>
6416               (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6417           (zero_extend:<DWI>
6418             (match_operand:DWIH 1 "nonimmediate_operand" "rm"))))
6419    (clobber (reg:CC FLAGS_REG))]
6420   "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6421   "#"
6422   "&& reload_completed"
6423   [(set (match_dup 0) (match_dup 4))
6424    (parallel [(set (reg:CCC FLAGS_REG)
6425                    (compare:CCC
6426                      (plus:DWIH (match_dup 0) (match_dup 1))
6427                      (match_dup 0)))
6428               (set (match_dup 0)
6429                    (plus:DWIH (match_dup 0) (match_dup 1)))])
6430    (set (match_dup 5) (match_dup 2))
6431    (parallel [(set (match_dup 5)
6432                    (plus:DWIH
6433                      (plus:DWIH
6434                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6435                        (match_dup 5))
6436                      (const_int 0)))
6437               (clobber (reg:CC FLAGS_REG))])]
6438  "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[5]);")
6440 (define_insn "*add<mode>_1"
6441   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r,r,r,r")
6442         (plus:SWI48
6443           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r,rje,jM,r")
6444           (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le,r,e,BM")))
6445    (clobber (reg:CC FLAGS_REG))]
6446   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
6448   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
6449   switch (get_attr_type (insn))
6450     {
6451     case TYPE_LEA:
6452       return "#";
6454     case TYPE_INCDEC:
6455       if (operands[2] == const1_rtx)
6456         return use_ndd ? "inc{<imodesuffix>}\t{%1, %0|%0, %1}"
6457                       : "inc{<imodesuffix>}\t%0";
6458       else
6459         {
6460           gcc_assert (operands[2] == constm1_rtx);
6461           return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}"
6462                         : "dec{<imodesuffix>}\t%0";
6463         }
6465     default:
6466       /* For most processors, ADD is faster than LEA.  This alternative
6467          was added to use ADD as much as possible.  */
6468       if (which_alternative == 2)
6469         std::swap (operands[1], operands[2]);
6470         
6471       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6472         return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6473                       : "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6475       return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6476                     : "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6477     }
6479   [(set_attr "isa" "*,*,*,*,apx_ndd,apx_ndd,apx_ndd")
6480    (set (attr "type")
6481      (cond [(eq_attr "alternative" "3")
6482               (const_string "lea")
6483             (match_operand:SWI48 2 "incdec_operand")
6484               (const_string "incdec")
6485            ]
6486            (const_string "alu")))
6487    (set (attr "length_immediate")
6488       (if_then_else
6489         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6490         (const_string "1")
6491         (const_string "*")))
6492    (set_attr "mode" "<MODE>")])
6494 ;; It may seem that nonimmediate operand is proper one for operand 1.
6495 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6496 ;; we take care in ix86_binary_operator_ok to not allow two memory
6497 ;; operands so proper swapping will be done in reload.  This allow
6498 ;; patterns constructed from addsi_1 to match.
6500 (define_insn "addsi_1_zext"
6501   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r")
6502         (zero_extend:DI
6503           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r,r,rm,rjM")
6504                    (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le,rBMe,r,e"))))
6505    (clobber (reg:CC FLAGS_REG))]
6506   "TARGET_64BIT
6507    && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
6509   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
6510   switch (get_attr_type (insn))
6511     {
6512     case TYPE_LEA:
6513       return "#";
6515     case TYPE_INCDEC:
6516       if (operands[2] == const1_rtx)
6517         return use_ndd ? "inc{l}\t{%1, %k0|%k0, %1}"
6518                        : "inc{l}\t%k0";
6519       else
6520         {
6521           gcc_assert (operands[2] == constm1_rtx);
6522           return use_ndd ? "dec{l}\t{%1, %k0|%k0, %1}"
6523                          : "dec{l}\t%k0";
6524         }
6526     default:
6527       /* For most processors, ADD is faster than LEA.  This alternative
6528          was added to use ADD as much as possible.  */
6529       if (which_alternative == 1)
6530         std::swap (operands[1], operands[2]);
6532       if (x86_maybe_negate_const_int (&operands[2], SImode))
6533         return use_ndd ? "sub{l}\t{%2 ,%1, %k0|%k0, %1, %2}"
6534                        : "sub{l}\t{%2, %k0|%k0, %2}";
6536       return use_ndd ? "add{l}\t{%2 ,%1, %k0|%k0, %1, %2}"
6537                      : "add{l}\t{%2, %k0|%k0, %2}";
6538     }
6540   [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd")
6541    (set (attr "type")
6542      (cond [(eq_attr "alternative" "2")
6543               (const_string "lea")
6544             (match_operand:SI 2 "incdec_operand")
6545               (const_string "incdec")
6546            ]
6547            (const_string "alu")))
6548    (set (attr "length_immediate")
6549       (if_then_else
6550         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6551         (const_string "1")
6552         (const_string "*")))
6553    (set_attr "mode" "SI")])
6555 (define_insn "*addhi_1"
6556   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp,r,r")
6557         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp,rm,r")
6558                  (match_operand:HI 2 "general_operand" "rn,m,0,ln,rn,m")))
6559    (clobber (reg:CC FLAGS_REG))]
6560   "ix86_binary_operator_ok (PLUS, HImode, operands, TARGET_APX_NDD)"
6562   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
6563   switch (get_attr_type (insn))
6564     {
6565     case TYPE_LEA:
6566       return "#";
6568     case TYPE_INCDEC:
6569       if (operands[2] == const1_rtx)
6570         return use_ndd ? "inc{w}\t{%1, %0|%0, %1}" : "inc{w}\t%0";
6571       else
6572         {
6573           gcc_assert (operands[2] == constm1_rtx);
6574           return use_ndd ? "dec{w}\t{%1, %0|%0, %1}" : "dec{w}\t%0";
6575         }
6577     default:
6578       /* For most processors, ADD is faster than LEA.  This alternative
6579          was added to use ADD as much as possible.  */
6580       if (which_alternative == 2)
6581         std::swap (operands[1], operands[2]);
6583       if (x86_maybe_negate_const_int (&operands[2], HImode))
6584         return use_ndd ? "sub{w}\t{%2, %1, %0|%0, %1, %2}"
6585                        : "sub{w}\t{%2, %0|%0, %2}";
6587       return use_ndd ? "add{w}\t{%2, %1, %0|%0, %1, %2}"
6588                      : "add{w}\t{%2, %0|%0, %2}";
6589     }
6591   [(set_attr "isa" "*,*,*,*,apx_ndd,apx_ndd")
6592    (set (attr "type")
6593      (cond [(eq_attr "alternative" "3")
6594               (const_string "lea")
6595             (match_operand:HI 2 "incdec_operand")
6596               (const_string "incdec")
6597            ]
6598            (const_string "alu")))
6599    (set (attr "length_immediate")
6600       (if_then_else
6601         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6602         (const_string "1")
6603         (const_string "*")))
6604    (set_attr "mode" "HI,HI,HI,SI,HI,HI")])
6606 (define_insn "*addqi_1"
6607   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp,r,r")
6608         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp,rm,r")
6609                  (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln,rn,m")))
6610    (clobber (reg:CC FLAGS_REG))]
6611   "ix86_binary_operator_ok (PLUS, QImode, operands, TARGET_APX_NDD)"
6613   bool widen = (get_attr_mode (insn) != MODE_QI);
6614   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
6615   switch (get_attr_type (insn))
6616     {
6617     case TYPE_LEA:
6618       return "#";
6620     case TYPE_INCDEC:
6621       if (operands[2] == const1_rtx)
6622         if (use_ndd)
6623           return "inc{b}\t{%1, %0|%0, %1}";
6624         else
6625           return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6626       else
6627         {
6628           gcc_assert (operands[2] == constm1_rtx);
6629           if (use_ndd)
6630             return "dec{b}\t{%1, %0|%0, %1}";
6631           else
6632             return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6633         }
6635     default:
6636       /* For most processors, ADD is faster than LEA.  These alternatives
6637          were added to use ADD as much as possible.  */
6638       if (which_alternative == 2 || which_alternative == 4)
6639         std::swap (operands[1], operands[2]);
6641       if (x86_maybe_negate_const_int (&operands[2], QImode))
6642         {
6643           if (use_ndd)
6644             return "sub{b}\t{%2, %1, %0|%0, %1, %2}";
6645           else
6646             return widen ? "sub{l}\t{%2, %k0|%k0, %2}"
6647                          : "sub{b}\t{%2, %0|%0, %2}";
6648         }
6649       if (use_ndd)
6650         return "add{b}\t{%2, %1, %0|%0, %1, %2}";
6651       else
6652         return widen ? "add{l}\t{%k2, %k0|%k0, %k2}"
6653                      : "add{b}\t{%2, %0|%0, %2}";
6654     }
6656   [(set_attr "isa" "*,*,*,*,*,*,apx_ndd,apx_ndd")
6657    (set (attr "type")
6658      (cond [(eq_attr "alternative" "5")
6659               (const_string "lea")
6660             (match_operand:QI 2 "incdec_operand")
6661               (const_string "incdec")
6662            ]
6663            (const_string "alu")))
6664    (set (attr "length_immediate")
6665       (if_then_else
6666         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6667         (const_string "1")
6668         (const_string "*")))
6669    (set_attr "mode" "QI,QI,QI,SI,SI,SI,QI,QI")
6670    ;; Potential partial reg stall on alternatives 3 and 4.
6671    (set (attr "preferred_for_speed")
6672      (cond [(eq_attr "alternative" "3,4")
6673               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
6674            (symbol_ref "true")))])
6676 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6677 (define_insn_and_split "*add<mode>_1_slp"
6678   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
6679         (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
6680                     (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
6681    (clobber (reg:CC FLAGS_REG))]
6682   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6684   if (which_alternative)
6685     return "#";
6687   switch (get_attr_type (insn))
6688     {
6689     case TYPE_INCDEC:
6690       if (operands[2] == const1_rtx)
6691         return "inc{<imodesuffix>}\t%0";
6692       else
6693         {
6694           gcc_assert (operands[2] == constm1_rtx);
6695           return "dec{<imodesuffix>}\t%0";
6696         }
6698     default:
6699       if (x86_maybe_negate_const_int (&operands[2], QImode))
6700         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6702       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6703     }
6705   "&& reload_completed
6706    && !(rtx_equal_p (operands[0], operands[1])
6707         || rtx_equal_p (operands[0], operands[2]))"
6708   [(set (strict_low_part (match_dup 0)) (match_dup 1))
6709    (parallel
6710      [(set (strict_low_part (match_dup 0))
6711            (plus:SWI12 (match_dup 0) (match_dup 2)))
6712       (clobber (reg:CC FLAGS_REG))])]
6713   ""
6714   [(set (attr "type")
6715      (if_then_else (match_operand:QI 2 "incdec_operand")
6716         (const_string "incdec")
6717         (const_string "alu")))
6718    (set_attr "mode" "<MODE>")])
6720 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6721 (define_insn_and_split "*addqi_ext<mode>_1_slp"
6722   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
6723         (plus:QI
6724           (subreg:QI
6725             (match_operator:SWI248 3 "extract_operator"
6726               [(match_operand 2 "int248_register_operand" "Q,Q")
6727                (const_int 8)
6728                (const_int 8)]) 0)
6729           (match_operand:QI 1 "nonimmediate_operand" "0,!qm")))
6730    (clobber (reg:CC FLAGS_REG))]
6731   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6732   "@
6733    add{b}\t{%h2, %0|%0, %h2}
6734    #"
6735   "&& reload_completed
6736    && !rtx_equal_p (operands[0], operands[1])"
6737   [(set (strict_low_part (match_dup 0)) (match_dup 1))
6738    (parallel
6739      [(set (strict_low_part (match_dup 0))
6740            (plus:QI
6741              (subreg:QI
6742                (match_op_dup 3
6743                  [(match_dup 2) (const_int 8) (const_int 8)]) 0)
6744              (match_dup 0)))
6745       (clobber (reg:CC FLAGS_REG))])]
6746   ""
6747   [(set_attr "type" "alu")
6748    (set_attr "mode" "QI")])
6750 (define_insn_and_split "*addqi_ext<mode>_2_slp"
6751   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
6752         (plus:QI
6753           (subreg:QI
6754             (match_operator:SWI248 3 "extract_operator"
6755               [(match_operand 1 "int248_register_operand" "Q")
6756                (const_int 8)
6757                (const_int 8)]) 0)
6758           (subreg:QI
6759             (match_operator:SWI248 4 "extract_operator"
6760               [(match_operand 2 "int248_register_operand" "Q")
6761                (const_int 8)
6762                (const_int 8)]) 0)))
6763    (clobber (reg:CC FLAGS_REG))]
6764   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6765   "#"
6766   "&& reload_completed"
6767   [(set (strict_low_part (match_dup 0))
6768         (subreg:QI
6769           (match_op_dup 4
6770             [(match_dup 2) (const_int 8) (const_int 8)]) 0))
6771    (parallel
6772      [(set (strict_low_part (match_dup 0))
6773            (plus:QI
6774              (subreg:QI
6775                (match_op_dup 3
6776                  [(match_dup 1) (const_int 8) (const_int 8)]) 0)
6777              (match_dup 0)))
6778       (clobber (reg:CC FLAGS_REG))])]
6779   ""
6780   [(set_attr "type" "alu")
6781    (set_attr "mode" "QI")])
6783 ;; Split non destructive adds if we cannot use lea.
6784 (define_split
6785   [(set (match_operand:SWI48 0 "register_operand")
6786         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
6787                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
6788    (clobber (reg:CC FLAGS_REG))]
6789   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6790   [(set (match_dup 0) (match_dup 1))
6791    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
6792               (clobber (reg:CC FLAGS_REG))])])
6794 ;; Split non destructive adds if we cannot use lea.
6795 (define_split
6796   [(set (match_operand:DI 0 "register_operand")
6797         (zero_extend:DI
6798           (plus:SI (match_operand:SI 1 "register_operand")
6799                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6800    (clobber (reg:CC FLAGS_REG))]
6801   "TARGET_64BIT
6802    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6803   [(set (match_dup 3) (match_dup 1))
6804    (parallel [(set (match_dup 0)
6805                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
6806               (clobber (reg:CC FLAGS_REG))])]
6807   "operands[3] = gen_lowpart (SImode, operands[0]);")
6809 ;; Convert add to the lea pattern to avoid flags dependency.
6810 (define_split
6811   [(set (match_operand:SWI 0 "register_operand")
6812         (plus:SWI (match_operand:SWI 1 "register_operand")
6813                   (match_operand:SWI 2 "<nonmemory_operand>")))
6814    (clobber (reg:CC FLAGS_REG))]
6815   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
6816   [(set (match_dup 0)
6817         (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
6819   if (<MODE>mode != <LEAMODE>mode)
6820     {
6821       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
6822       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
6823       operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
6824     }
6827 ;; Convert add to the lea pattern to avoid flags dependency.
6828 (define_split
6829   [(set (match_operand:DI 0 "register_operand")
6830         (zero_extend:DI
6831           (plus:SI (match_operand:SI 1 "register_operand")
6832                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6833    (clobber (reg:CC FLAGS_REG))]
6834   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6835   [(set (match_dup 0)
6836         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6838 (define_insn "*add<mode>_2"
6839   [(set (reg FLAGS_REG)
6840         (compare
6841           (plus:SWI
6842             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>,rm,r")
6843             (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,0,r<i>,<m>"))
6844           (const_int 0)))
6845    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>,r,r")
6846         (plus:SWI (match_dup 1) (match_dup 2)))]
6847   "ix86_match_ccmode (insn, CCGOCmode)
6848    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
6850   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
6851   switch (get_attr_type (insn))
6852     {
6853     case TYPE_INCDEC:
6854       if (operands[2] == const1_rtx)
6855         return use_ndd ? "inc{<imodesuffix>}\t{%1, %0|%0, %1}"
6856                        : "inc{<imodesuffix>}\t%0";
6857       else
6858         {
6859           gcc_assert (operands[2] == constm1_rtx);
6860           return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}"
6861                          : "dec{<imodesuffix>}\t%0";
6862         }
6864     default:
6865       if (which_alternative == 2)
6866         std::swap (operands[1], operands[2]);
6867         
6868       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6869         return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6870                        : "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6872       return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6873                      : "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6874     }
6876   [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd")
6877    (set (attr "type")
6878      (if_then_else (match_operand:SWI 2 "incdec_operand")
6879         (const_string "incdec")
6880         (const_string "alu")))
6881    (set (attr "length_immediate")
6882       (if_then_else
6883         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6884         (const_string "1")
6885         (const_string "*")))
6886    (set_attr "mode" "<MODE>")])
6888 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6889 (define_insn "*addsi_2_zext"
6890   [(set (reg FLAGS_REG)
6891         (compare
6892           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r,rm")
6893                    (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,rBMe,re"))
6894           (const_int 0)))
6895    (set (match_operand:DI 0 "register_operand" "=r,r,r,r")
6896         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6897   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6898    && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
6900   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
6901   switch (get_attr_type (insn))
6902     {
6903     case TYPE_INCDEC:
6904       if (operands[2] == const1_rtx)
6905         return use_ndd ? "inc{l}\t{%1, %k0|%k0, %1}"
6906                        : "inc{l}\t%k0";
6907       else
6908         {
6909           gcc_assert (operands[2] == constm1_rtx);
6910           return use_ndd ? "dec{l}\t{%1, %k0|%k0, %1}"
6911                          : "dec{l}\t%k0";
6912         }
6914     default:
6915       if (which_alternative == 1)
6916         std::swap (operands[1], operands[2]);
6918       if (x86_maybe_negate_const_int (&operands[2], SImode))
6919         return use_ndd ? "sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
6920                        : "sub{l}\t{%2, %k0|%k0, %2}";
6922       return use_ndd ? "add{l}\t{%2, %1, %k0|%k0, %1, %2}"
6923                      : "add{l}\t{%2, %k0|%k0, %2}";
6924     }
6926   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
6927    (set (attr "type")
6928      (if_then_else (match_operand:SI 2 "incdec_operand")
6929         (const_string "incdec")
6930         (const_string "alu")))
6931    (set (attr "length_immediate")
6932       (if_then_else
6933         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6934         (const_string "1")
6935         (const_string "*")))
6936    (set_attr "mode" "SI")])
6938 (define_insn "*add<mode>_3"
6939   [(set (reg FLAGS_REG)
6940         (compare
6941           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0,<g>,re"))
6942           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>,r,rm")))
6943    (clobber (match_scratch:SWI 0 "=<r>,<r>,r,r"))]
6944   "ix86_match_ccmode (insn, CCZmode)
6945    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6947   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
6948   switch (get_attr_type (insn))
6949     {
6950     case TYPE_INCDEC:
6951       if (operands[2] == const1_rtx)
6952         return use_ndd ? "inc{<imodesuffix>}\t{%1, %0|%0, %1}"
6953                        : "inc{<imodesuffix>}\t%0";
6954       else
6955         {
6956           gcc_assert (operands[2] == constm1_rtx);
6957           return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}"
6958                          : "dec{<imodesuffix>}\t%0";
6959         }
6961     default:
6962       if (which_alternative == 1)
6963         std::swap (operands[1], operands[2]);
6965       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6966         return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6967                        : "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6969       return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6970                      : "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6971     }
6973   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
6974    (set (attr "type")
6975      (if_then_else (match_operand:SWI 2 "incdec_operand")
6976         (const_string "incdec")
6977         (const_string "alu")))
6978    (set (attr "length_immediate")
6979       (if_then_else
6980         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6981         (const_string "1")
6982         (const_string "*")))
6983    (set_attr "mode" "<MODE>")])
6985 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6986 (define_insn "*addsi_3_zext"
6987   [(set (reg FLAGS_REG)
6988         (compare
6989           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,rBMe,re"))
6990           (match_operand:SI 1 "nonimmediate_operand" "%0,r,r,rm")))
6991    (set (match_operand:DI 0 "register_operand" "=r,r,r,r")
6992         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6993   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6994    && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
6996   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
6997   switch (get_attr_type (insn))
6998     {
6999     case TYPE_INCDEC:
7000       if (operands[2] == const1_rtx)
7001         return use_ndd ? "inc{l}\t{%1, %k0|%k0, %1}" : "inc{l}\t%k0";
7002       else
7003         {
7004           gcc_assert (operands[2] == constm1_rtx);
7005           return use_ndd ? "dec{l}\t{%1, %k0|%k0, %1}" : "dec{l}\t%k0";
7006         }
7008     default:
7009       if (which_alternative == 1)
7010         std::swap (operands[1], operands[2]);
7012       if (x86_maybe_negate_const_int (&operands[2], SImode))
7013         return use_ndd ? "sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
7014                        : "sub{l}\t{%2, %k0|%k0, %2}";
7016       return use_ndd ? "add{l}\t{%2, %1, %k0|%k0, %1, %2}"
7017                      : "add{l}\t{%2, %k0|%k0, %2}";
7018     }
7020   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
7021    (set (attr "type")
7022      (if_then_else (match_operand:SI 2 "incdec_operand")
7023         (const_string "incdec")
7024         (const_string "alu")))
7025    (set (attr "length_immediate")
7026       (if_then_else
7027         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7028         (const_string "1")
7029         (const_string "*")))
7030    (set_attr "mode" "SI")])
7032 ; For comparisons against 1, -1 and 128, we may generate better code
7033 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
7034 ; is matched then.  We can't accept general immediate, because for
7035 ; case of overflows,  the result is messed up.
7036 ; Also carry flag is reversed compared to cmp, so this conversion is valid
7037 ; only for comparisons not depending on it.
7039 (define_insn "*adddi_4"
7040   [(set (reg FLAGS_REG)
7041         (compare
7042           (match_operand:DI 1 "nonimmediate_operand" "0,rm")
7043           (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
7044    (clobber (match_scratch:DI 0 "=r,r"))]
7045   "TARGET_64BIT
7046    && ix86_match_ccmode (insn, CCGCmode)"
7048   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
7049   switch (get_attr_type (insn))
7050     {
7051     case TYPE_INCDEC:
7052       if (operands[2] == constm1_rtx)
7053         return use_ndd ? "inc{q}\t{%1, %0|%0, %1}" : "inc{q}\t%0";
7054       else
7055         {
7056           gcc_assert (operands[2] == const1_rtx);
7057           return use_ndd ? "dec{q}\t{%1, %0|%0, %1}" : "dec{q}\t%0";
7058         }
7060     default:
7061       if (x86_maybe_negate_const_int (&operands[2], DImode))
7062         return use_ndd ? "add{q}\t{%2, %1, %0|%0, %1, %2}"
7063                        : "add{q}\t{%2, %0|%0, %2}";
7065       return use_ndd ? "sub{q}\t{%2, %1, %0|%0, %1, %2}"
7066                      : "sub{q}\t{%2, %0|%0, %2}";
7067     }
7069   [(set_attr "isa" "*,apx_ndd")
7070    (set (attr "type")
7071      (if_then_else (match_operand:DI 2 "incdec_operand")
7072         (const_string "incdec")
7073         (const_string "alu")))
7074    (set (attr "length_immediate")
7075       (if_then_else
7076         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7077         (const_string "1")
7078         (const_string "*")))
7079    (set_attr "mode" "DI")])
7081 ; For comparisons against 1, -1 and 128, we may generate better code
7082 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
7083 ; is matched then.  We can't accept general immediate, because for
7084 ; case of overflows,  the result is messed up.
7085 ; Also carry flag is reversed compared to cmp, so this conversion is valid
7086 ; only for comparisons not depending on it.
7088 (define_insn "*add<mode>_4"
7089   [(set (reg FLAGS_REG)
7090         (compare
7091           (match_operand:SWI124 1 "nonimmediate_operand" "0,rm")
7092           (match_operand:SWI124 2 "const_int_operand")))
7093    (clobber (match_scratch:SWI124 0 "=<r>,r"))]
7094   "ix86_match_ccmode (insn, CCGCmode)"
7096   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
7097   switch (get_attr_type (insn))
7098     {
7099     case TYPE_INCDEC:
7100       if (operands[2] == constm1_rtx)
7101         return use_ndd ? "inc{<imodesuffix>}\t{%1, %0|%0, %1}"
7102                        : "inc{<imodesuffix>}\t%0";
7103       else
7104         {
7105           gcc_assert (operands[2] == const1_rtx);
7106           return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}"
7107                          : "dec{<imodesuffix>}\t%0";
7108         }
7110     default:
7111       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
7112         return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7113                        : "add{<imodesuffix>}\t{%2, %0|%0, %2}";
7115       return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7116                      : "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
7117     }
7119   [(set_attr "isa" "*,apx_ndd")
7120    (set (attr "type")
7121      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
7122         (const_string "incdec")
7123         (const_string "alu")))
7124    (set (attr "length_immediate")
7125       (if_then_else
7126         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7127         (const_string "1")
7128         (const_string "*")))
7129    (set_attr "mode" "<MODE>")])
7131 (define_insn "*add<mode>_5"
7132   [(set (reg FLAGS_REG)
7133         (compare
7134           (plus:SWI
7135             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>,r,rm")
7136             (match_operand:SWI 2 "<general_operand>" "<g>,0,<g>,re"))
7137           (const_int 0)))
7138    (clobber (match_scratch:SWI 0 "=<r>,<r>,r,r"))]
7139   "ix86_match_ccmode (insn, CCGOCmode)
7140    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7142   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
7143   switch (get_attr_type (insn))
7144     {
7145     case TYPE_INCDEC:
7146       if (operands[2] == const1_rtx)
7147         return use_ndd ? "inc{<imodesuffix>}\t{%1, %0|%0, %1}"
7148                        : "inc{<imodesuffix>}\t%0";
7149       else
7150         {
7151           gcc_assert (operands[2] == constm1_rtx);
7152           return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}"
7153                          : "dec{<imodesuffix>}\t%0";
7154         }
7156     default:
7157       if (which_alternative == 1)
7158         std::swap (operands[1], operands[2]);
7160       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
7161         return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7162                        : "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
7164       return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7165                      : "add{<imodesuffix>}\t{%2, %0|%0, %2}";
7166     }
7168   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
7169    (set (attr "type")
7170      (if_then_else (match_operand:SWI 2 "incdec_operand")
7171         (const_string "incdec")
7172         (const_string "alu")))
7173    (set (attr "length_immediate")
7174       (if_then_else
7175         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7176         (const_string "1")
7177         (const_string "*")))
7178    (set_attr "mode" "<MODE>")])
7180 (define_insn "*addqi_ext<mode>_0"
7181   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
7182         (plus:QI
7183           (subreg:QI
7184             (match_operator:SWI248 3 "extract_operator"
7185               [(match_operand 2 "int248_register_operand" "Q")
7186                (const_int 8)
7187                (const_int 8)]) 0)
7188           (match_operand:QI 1 "nonimmediate_operand" "0")))
7189    (clobber (reg:CC FLAGS_REG))]
7190   ""
7191   "add{b}\t{%h2, %0|%0, %h2}"
7192   [(set_attr "addr" "gpr8")
7193    (set_attr "type" "alu")
7194    (set_attr "mode" "QI")])
7196 (define_insn_and_split "*addqi_ext2<mode>_0"
7197   [(set (match_operand:QI 0 "register_operand" "=&Q")
7198         (plus:QI
7199           (subreg:QI
7200             (match_operator:SWI248 3 "extract_operator"
7201               [(match_operand 1 "int248_register_operand" "Q")
7202                (const_int 8)
7203                (const_int 8)]) 0)
7204           (subreg:QI
7205             (match_operator:SWI248 4 "extract_operator"
7206               [(match_operand 2 "int248_register_operand" "Q")
7207                (const_int 8)
7208                (const_int 8)]) 0)))
7209    (clobber (reg:CC FLAGS_REG))]
7210   ""
7211   "#"
7212   "&& reload_completed"
7213   [(set (match_dup 0)
7214         (subreg:QI
7215           (match_op_dup 4
7216             [(match_dup 2) (const_int 8) (const_int 8)]) 0))
7217    (parallel
7218      [(set (match_dup 0)
7219            (plus:QI
7220              (subreg:QI
7221                (match_op_dup 3
7222                  [(match_dup 1) (const_int 8) (const_int 8)]) 0)
7223            (match_dup 0)))
7224       (clobber (reg:CC FLAGS_REG))])]
7225   ""
7226   [(set_attr "type" "alu")
7227    (set_attr "mode" "QI")])
7229 (define_expand "addqi_ext_1"
7230   [(parallel
7231      [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
7232                             (const_int 8)
7233                             (const_int 8))
7234            (subreg:HI
7235              (plus:QI
7236                (subreg:QI
7237                  (zero_extract:HI (match_operand:HI 1 "register_operand")
7238                                   (const_int 8)
7239                                   (const_int 8)) 0)
7240                (match_operand:QI 2 "const_int_operand")) 0))
7241       (clobber (reg:CC FLAGS_REG))])])
7243 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7244 (define_insn_and_split "*addqi_ext<mode>_1"
7245   [(set (zero_extract:SWI248
7246           (match_operand 0 "int248_register_operand" "+Q,&Q")
7247           (const_int 8)
7248           (const_int 8))
7249         (subreg:SWI248
7250           (plus:QI
7251             (subreg:QI
7252               (match_operator:SWI248 3 "extract_operator"
7253                 [(match_operand 1 "int248_register_operand" "0,!Q")
7254                  (const_int 8)
7255                  (const_int 8)]) 0)
7256             (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
7257    (clobber (reg:CC FLAGS_REG))]
7258   ""
7260   if (which_alternative)
7261     return "#";
7263   switch (get_attr_type (insn))
7264     {
7265     case TYPE_INCDEC:
7266       if (operands[2] == const1_rtx)
7267         return "inc{b}\t%h0";
7268       else
7269         {
7270           gcc_assert (operands[2] == constm1_rtx);
7271           return "dec{b}\t%h0";
7272         }
7274     default:
7275       return "add{b}\t{%2, %h0|%h0, %2}";
7276     }
7278   "reload_completed
7279    && !rtx_equal_p (operands[0], operands[1])"
7280   [(set (zero_extract:SWI248
7281           (match_dup 0) (const_int 8) (const_int 8))
7282         (zero_extract:SWI248
7283           (match_dup 1) (const_int 8) (const_int 8)))
7284    (parallel
7285      [(set (zero_extract:SWI248
7286              (match_dup 0) (const_int 8) (const_int 8))
7287            (subreg:SWI248
7288              (plus:QI
7289                (subreg:QI
7290                  (match_op_dup 3
7291                    [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7292                (match_dup 2)) 0))
7293       (clobber (reg:CC FLAGS_REG))])]
7294   ""
7295   [(set_attr "addr" "gpr8")
7296    (set (attr "type")
7297      (if_then_else (match_operand:QI 2 "incdec_operand")
7298         (const_string "incdec")
7299         (const_string "alu")))
7300    (set_attr "mode" "QI")])
7302 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7303 (define_insn_and_split "*<insn>qi_ext<mode>_2"
7304   [(set (zero_extract:SWI248
7305           (match_operand 0 "int248_register_operand" "+Q,&Q")
7306           (const_int 8)
7307           (const_int 8))
7308         (subreg:SWI248
7309           (plusminus:QI
7310             (subreg:QI
7311               (match_operator:SWI248 3 "extract_operator"
7312                 [(match_operand 1 "int248_register_operand" "<comm>0,!Q")
7313                  (const_int 8)
7314                  (const_int 8)]) 0)
7315             (subreg:QI
7316               (match_operator:SWI248 4 "extract_operator"
7317                 [(match_operand 2 "int248_register_operand" "Q,Q")
7318                  (const_int 8)
7319                  (const_int 8)]) 0)) 0))
7320    (clobber (reg:CC FLAGS_REG))]
7321   ""
7322   "@
7323    <insn>{b}\t{%h2, %h0|%h0, %h2}
7324    #"
7325   "reload_completed
7326    && !(rtx_equal_p (operands[0], operands[1])
7327         || (<CODE> == PLUS && rtx_equal_p (operands[0], operands[2])))"
7328   [(set (zero_extract:SWI248
7329           (match_dup 0) (const_int 8) (const_int 8))
7330         (zero_extract:SWI248
7331           (match_dup 1) (const_int 8) (const_int 8)))
7332    (parallel
7333      [(set (zero_extract:SWI248
7334              (match_dup 0) (const_int 8) (const_int 8))
7335            (subreg:SWI248
7336              (plusminus:QI
7337                (subreg:QI
7338                  (match_op_dup 3
7339                    [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7340                (subreg:QI
7341                  (match_op_dup 4
7342                    [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
7343       (clobber (reg:CC FLAGS_REG))])]
7344   ""
7345   [(set_attr "type" "alu")
7346    (set_attr "mode" "QI")])
7348 ;; Like DWI, but use POImode instead of OImode.
7349 (define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
7351 ;; Add with jump on overflow.
7352 (define_expand "addv<mode>4"
7353   [(parallel [(set (reg:CCO FLAGS_REG)
7354                    (eq:CCO
7355                      (plus:<DPWI>
7356                        (sign_extend:<DPWI>
7357                          (match_operand:SWIDWI 1 "nonimmediate_operand"))
7358                        (match_dup 4))
7359                          (sign_extend:<DPWI>
7360                            (plus:SWIDWI (match_dup 1)
7361                              (match_operand:SWIDWI 2
7362                                "<general_hilo_operand>")))))
7363               (set (match_operand:SWIDWI 0 "register_operand")
7364                    (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7365    (set (pc) (if_then_else
7366                (eq (reg:CCO FLAGS_REG) (const_int 0))
7367                (label_ref (match_operand 3))
7368                (pc)))]
7369   ""
7371   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
7372   if (CONST_SCALAR_INT_P (operands[2]))
7373     operands[4] = operands[2];
7374   else
7375     operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7378 (define_insn "*addv<mode>4"
7379   [(set (reg:CCO FLAGS_REG)
7380         (eq:CCO (plus:<DWI>
7381                    (sign_extend:<DWI>
7382                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r"))
7383                    (sign_extend:<DWI>
7384                       (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m,rWe,m")))
7385                 (sign_extend:<DWI>
7386                    (plus:SWI (match_dup 1) (match_dup 2)))))
7387    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
7388         (plus:SWI (match_dup 1) (match_dup 2)))]
7389   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
7390   "@
7391    add{<imodesuffix>}\t{%2, %0|%0, %2}
7392    add{<imodesuffix>}\t{%2, %0|%0, %2}
7393    add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7394    add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7395   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
7396    (set_attr "type" "alu")
7397    (set_attr "mode" "<MODE>")])
7399 (define_insn "addv<mode>4_1"
7400   [(set (reg:CCO FLAGS_REG)
7401         (eq:CCO (plus:<DWI>
7402                    (sign_extend:<DWI>
7403                       (match_operand:SWI 1 "nonimmediate_operand" "0,rm"))
7404                    (match_operand:<DWI> 3 "const_int_operand"))
7405                 (sign_extend:<DWI>
7406                    (plus:SWI
7407                      (match_dup 1)
7408                      (match_operand:SWI 2 "x86_64_immediate_operand" "<i>,<i>")))))
7409    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
7410         (plus:SWI (match_dup 1) (match_dup 2)))]
7411   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
7412    && CONST_INT_P (operands[2])
7413    && INTVAL (operands[2]) == INTVAL (operands[3])"
7414   "@
7415   add{<imodesuffix>}\t{%2, %0|%0, %2}
7416   add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7417   [(set_attr "isa" "*,apx_ndd")
7418    (set_attr "type" "alu")
7419    (set_attr "mode" "<MODE>")
7420    (set (attr "length_immediate")
7421         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7422                   (const_string "1")
7423                (match_test "<MODE_SIZE> == 8")
7424                   (const_string "4")]
7425               (const_string "<MODE_SIZE>")))])
7427 ;; Quad word integer modes as mode attribute.
7428 (define_mode_attr QPWI [(SI "TI") (DI "POI")])
7430 (define_insn_and_split "*addv<dwi>4_doubleword"
7431   [(set (reg:CCO FLAGS_REG)
7432         (eq:CCO
7433           (plus:<QPWI>
7434             (sign_extend:<QPWI>
7435               (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r"))
7436             (sign_extend:<QPWI>
7437               (match_operand:<DWI> 2 "nonimmediate_operand" "r,o,r,o")))
7438           (sign_extend:<QPWI>
7439             (plus:<DWI> (match_dup 1) (match_dup 2)))))
7440    (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r")
7441         (plus:<DWI> (match_dup 1) (match_dup 2)))]
7442   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands, TARGET_APX_NDD)"
7443   "#"
7444   "&& reload_completed"
7445   [(parallel [(set (reg:CCC FLAGS_REG)
7446                    (compare:CCC
7447                      (plus:DWIH (match_dup 1) (match_dup 2))
7448                      (match_dup 1)))
7449               (set (match_dup 0)
7450                    (plus:DWIH (match_dup 1) (match_dup 2)))])
7451    (parallel [(set (reg:CCO FLAGS_REG)
7452                    (eq:CCO
7453                      (plus:<DWI>
7454                        (plus:<DWI>
7455                          (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7456                          (sign_extend:<DWI> (match_dup 4)))
7457                        (sign_extend:<DWI> (match_dup 5)))
7458                      (sign_extend:<DWI>
7459                        (plus:DWIH
7460                          (plus:DWIH
7461                            (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7462                            (match_dup 4))
7463                          (match_dup 5)))))
7464               (set (match_dup 3)
7465                    (plus:DWIH
7466                      (plus:DWIH
7467                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7468                        (match_dup 4))
7469                      (match_dup 5)))])]
7471   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7473 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
7475 (define_insn_and_split "*addv<dwi>4_doubleword_1"
7476   [(set (reg:CCO FLAGS_REG)
7477         (eq:CCO
7478           (plus:<QPWI>
7479             (sign_extend:<QPWI>
7480               (match_operand:<DWI> 1 "nonimmediate_operand" "%0,rjM"))
7481             (match_operand:<QPWI> 3 "const_scalar_int_operand" "n,n"))
7482           (sign_extend:<QPWI>
7483             (plus:<DWI>
7484               (match_dup 1)
7485               (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>,<di>")))))
7486    (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,&r")
7487         (plus:<DWI> (match_dup 1) (match_dup 2)))]
7488   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands, TARGET_APX_NDD)
7489    && CONST_SCALAR_INT_P (operands[2])
7490    && rtx_equal_p (operands[2], operands[3])"
7491   "#"
7492   "&& reload_completed"
7493   [(parallel [(set (reg:CCC FLAGS_REG)
7494                    (compare:CCC
7495                      (plus:DWIH (match_dup 1) (match_dup 2))
7496                      (match_dup 1)))
7497               (set (match_dup 0)
7498                    (plus:DWIH (match_dup 1) (match_dup 2)))])
7499    (parallel [(set (reg:CCO FLAGS_REG)
7500                    (eq:CCO
7501                      (plus:<DWI>
7502                        (plus:<DWI>
7503                          (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7504                          (sign_extend:<DWI> (match_dup 4)))
7505                        (match_dup 5))
7506                      (sign_extend:<DWI>
7507                        (plus:DWIH
7508                          (plus:DWIH
7509                            (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7510                            (match_dup 4))
7511                          (match_dup 5)))))
7512               (set (match_dup 3)
7513                    (plus:DWIH
7514                      (plus:DWIH
7515                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7516                        (match_dup 4))
7517                      (match_dup 5)))])]
7519   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7520   if (operands[2] == const0_rtx)
7521     {
7522       if (!rtx_equal_p (operands[0], operands[1]))
7523         emit_move_insn (operands[0], operands[1]);
7524       emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
7525                                     operands[5]));
7526       DONE;
7527     }
7529 [(set_attr "isa" "*,apx_ndd")])
7531 (define_insn "*addv<mode>4_overflow_1"
7532   [(set (reg:CCO FLAGS_REG)
7533         (eq:CCO
7534           (plus:<DWI>
7535             (plus:<DWI>
7536               (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7537                 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7538               (sign_extend:<DWI>
7539                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r")))
7540             (sign_extend:<DWI>
7541               (match_operand:SWI 2 "<general_sext_operand>" "rWe,m,rWe,m")))
7542           (sign_extend:<DWI>
7543             (plus:SWI
7544               (plus:SWI
7545                 (match_operator:SWI 5 "ix86_carry_flag_operator"
7546                   [(match_dup 3) (const_int 0)])
7547                 (match_dup 1))
7548               (match_dup 2)))))
7549    (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r,r,r")
7550         (plus:SWI
7551           (plus:SWI
7552             (match_op_dup 5 [(match_dup 3) (const_int 0)])
7553             (match_dup 1))
7554           (match_dup 2)))]
7555   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
7556   "@
7557    adc{<imodesuffix>}\t{%2, %0|%0, %2}
7558    adc{<imodesuffix>}\t{%2, %0|%0, %2}
7559    adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7560    adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7561   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
7562    (set_attr "type" "alu")
7563    (set_attr "mode" "<MODE>")])
7565 (define_insn "*addv<mode>4_overflow_2"
7566   [(set (reg:CCO FLAGS_REG)
7567         (eq:CCO
7568           (plus:<DWI>
7569             (plus:<DWI>
7570               (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7571                 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7572               (sign_extend:<DWI>
7573                 (match_operand:SWI 1 "nonimmediate_operand" "%0,rm")))
7574             (match_operand:<DWI> 6 "const_int_operand" "n,n"))
7575           (sign_extend:<DWI>
7576             (plus:SWI
7577               (plus:SWI
7578                 (match_operator:SWI 5 "ix86_carry_flag_operator"
7579                   [(match_dup 3) (const_int 0)])
7580                 (match_dup 1))
7581               (match_operand:SWI 2 "x86_64_immediate_operand" "e,e")))))
7582    (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7583         (plus:SWI
7584           (plus:SWI
7585             (match_op_dup 5 [(match_dup 3) (const_int 0)])
7586             (match_dup 1))
7587           (match_dup 2)))]
7588   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
7589    && CONST_INT_P (operands[2])
7590    && INTVAL (operands[2]) == INTVAL (operands[6])"
7591   "@
7592   adc{<imodesuffix>}\t{%2, %0|%0, %2}
7593   adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7594   [(set_attr "isa" "*,apx_ndd")
7595    (set_attr "type" "alu")
7596    (set_attr "mode" "<MODE>")
7597    (set (attr "length_immediate")
7598      (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7599        (const_string "1")
7600        (const_string "4")))])
7602 (define_expand "uaddv<mode>4"
7603   [(parallel [(set (reg:CCC FLAGS_REG)
7604                    (compare:CCC
7605                      (plus:SWIDWI
7606                        (match_operand:SWIDWI 1 "nonimmediate_operand")
7607                        (match_operand:SWIDWI 2 "<general_hilo_operand>"))
7608                      (match_dup 1)))
7609               (set (match_operand:SWIDWI 0 "register_operand")
7610                    (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7611    (set (pc) (if_then_else
7612                (ltu (reg:CCC FLAGS_REG) (const_int 0))
7613                (label_ref (match_operand 3))
7614                (pc)))]
7615   ""
7616   "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
7618 ;; The lea patterns for modes less than 32 bits need to be matched by
7619 ;; several insns converted to real lea by splitters.
7621 (define_insn_and_split "*lea<mode>_general_1"
7622   [(set (match_operand:SWI12 0 "register_operand" "=r")
7623         (plus:SWI12
7624           (plus:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7625                       (match_operand:SWI12 2 "register_operand" "r"))
7626           (match_operand:SWI12 3 "immediate_operand" "i")))]
7627   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7628   "#"
7629   "&& reload_completed"
7630   [(set (match_dup 0)
7631         (plus:SI
7632           (plus:SI (match_dup 1) (match_dup 2))
7633           (match_dup 3)))]
7635   operands[0] = gen_lowpart (SImode, operands[0]);
7636   operands[1] = gen_lowpart (SImode, operands[1]);
7637   operands[2] = gen_lowpart (SImode, operands[2]);
7638   operands[3] = gen_lowpart (SImode, operands[3]);
7640   [(set_attr "type" "lea")
7641    (set_attr "mode" "SI")])
7643 (define_insn_and_split "*lea<mode>_general_2"
7644   [(set (match_operand:SWI12 0 "register_operand" "=r")
7645         (plus:SWI12
7646           (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7647                       (match_operand 2 "const248_operand" "n"))
7648           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7649   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7650   "#"
7651   "&& reload_completed"
7652   [(set (match_dup 0)
7653         (plus:SI
7654           (mult:SI (match_dup 1) (match_dup 2))
7655           (match_dup 3)))]
7657   operands[0] = gen_lowpart (SImode, operands[0]);
7658   operands[1] = gen_lowpart (SImode, operands[1]);
7659   operands[3] = gen_lowpart (SImode, operands[3]);
7661   [(set_attr "type" "lea")
7662    (set_attr "mode" "SI")])
7664 (define_insn_and_split "*lea<mode>_general_2b"
7665   [(set (match_operand:SWI12 0 "register_operand" "=r")
7666         (plus:SWI12
7667           (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7668                         (match_operand 2 "const123_operand" "n"))
7669           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7670   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7671   "#"
7672   "&& reload_completed"
7673   [(set (match_dup 0)
7674         (plus:SI
7675           (ashift:SI (match_dup 1) (match_dup 2))
7676           (match_dup 3)))]
7678   operands[0] = gen_lowpart (SImode, operands[0]);
7679   operands[1] = gen_lowpart (SImode, operands[1]);
7680   operands[3] = gen_lowpart (SImode, operands[3]);
7682   [(set_attr "type" "lea")
7683    (set_attr "mode" "SI")])
7685 (define_insn_and_split "*lea<mode>_general_3"
7686   [(set (match_operand:SWI12 0 "register_operand" "=r")
7687         (plus:SWI12
7688           (plus:SWI12
7689             (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7690                         (match_operand 2 "const248_operand" "n"))
7691             (match_operand:SWI12 3 "register_operand" "r"))
7692           (match_operand:SWI12 4 "immediate_operand" "i")))]
7693   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7694   "#"
7695   "&& reload_completed"
7696   [(set (match_dup 0)
7697         (plus:SI
7698           (plus:SI
7699             (mult:SI (match_dup 1) (match_dup 2))
7700             (match_dup 3))
7701           (match_dup 4)))]
7703   operands[0] = gen_lowpart (SImode, operands[0]);
7704   operands[1] = gen_lowpart (SImode, operands[1]);
7705   operands[3] = gen_lowpart (SImode, operands[3]);
7706   operands[4] = gen_lowpart (SImode, operands[4]);
7708   [(set_attr "type" "lea")
7709    (set_attr "mode" "SI")])
7711 (define_insn_and_split "*lea<mode>_general_3b"
7712   [(set (match_operand:SWI12 0 "register_operand" "=r")
7713         (plus:SWI12
7714           (plus:SWI12
7715             (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7716                           (match_operand 2 "const123_operand" "n"))
7717             (match_operand:SWI12 3 "register_operand" "r"))
7718           (match_operand:SWI12 4 "immediate_operand" "i")))]
7719   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7720   "#"
7721   "&& reload_completed"
7722   [(set (match_dup 0)
7723         (plus:SI
7724           (plus:SI
7725             (ashift:SI (match_dup 1) (match_dup 2))
7726             (match_dup 3))
7727           (match_dup 4)))]
7729   operands[0] = gen_lowpart (SImode, operands[0]);
7730   operands[1] = gen_lowpart (SImode, operands[1]);
7731   operands[3] = gen_lowpart (SImode, operands[3]);
7732   operands[4] = gen_lowpart (SImode, operands[4]);
7734   [(set_attr "type" "lea")
7735    (set_attr "mode" "SI")])
7737 (define_insn_and_split "*lea<mode>_general_4"
7738   [(set (match_operand:SWI12 0 "register_operand" "=r")
7739         (any_or:SWI12
7740           (ashift:SWI12
7741             (match_operand:SWI12 1 "register_no_SP_operand" "l")
7742             (match_operand 2 "const_0_to_3_operand"))
7743           (match_operand 3 "const_int_operand")))]
7744   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7745    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
7746        < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
7747   "#"
7748   "&& reload_completed"
7749   [(set (match_dup 0)
7750         (plus:SI
7751           (mult:SI (match_dup 1) (match_dup 2))
7752           (match_dup 3)))]
7754   operands[0] = gen_lowpart (SImode, operands[0]);
7755   operands[1] = gen_lowpart (SImode, operands[1]);
7756   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
7758   [(set_attr "type" "lea")
7759    (set_attr "mode" "SI")])
7761 (define_insn_and_split "*lea<mode>_general_4"
7762   [(set (match_operand:SWI48 0 "register_operand" "=r")
7763         (any_or:SWI48
7764           (ashift:SWI48
7765             (match_operand:SWI48 1 "register_no_SP_operand" "l")
7766             (match_operand 2 "const_0_to_3_operand"))
7767           (match_operand 3 "const_int_operand")))]
7768   "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
7769    < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
7770   "#"
7771   "&& reload_completed"
7772   [(set (match_dup 0)
7773         (plus:SWI48
7774           (mult:SWI48 (match_dup 1) (match_dup 2))
7775           (match_dup 3)))]
7776   "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
7777   [(set_attr "type" "lea")
7778    (set_attr "mode" "<MODE>")])
7780 ;; Subtract instructions
7782 (define_expand "sub<mode>3"
7783   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
7784         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
7785                      (match_operand:SDWIM 2 "<general_hilo_operand>")))]
7786   ""
7788   ix86_expand_binary_operator (MINUS, <MODE>mode, operands, TARGET_APX_NDD);
7789   DONE;
7792 (define_insn_and_split "*sub<dwi>3_doubleword"
7793   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r")
7794         (minus:<DWI>
7795           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0,ro,r")
7796           (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r<di>,o")))
7797    (clobber (reg:CC FLAGS_REG))]
7798   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
7799   "#"
7800   "&& reload_completed"
7801   [(parallel [(set (reg:CC FLAGS_REG)
7802                    (compare:CC (match_dup 1) (match_dup 2)))
7803               (set (match_dup 0)
7804                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7805    (parallel [(set (match_dup 3)
7806                    (minus:DWIH
7807                      (minus:DWIH
7808                        (match_dup 4)
7809                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7810                      (match_dup 5)))
7811               (clobber (reg:CC FLAGS_REG))])]
7813   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7814   if (operands[2] == const0_rtx)
7815     {
7816       if (!rtx_equal_p (operands[0], operands[1]))
7817         emit_move_insn (operands[0], operands[1]);
7818       ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3],
7819                                    TARGET_APX_NDD);
7820       DONE;
7821     }
7823 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
7825 (define_insn_and_split "*sub<dwi>3_doubleword_zext"
7826   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,&r,&r")
7827         (minus:<DWI>
7828           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0,r,o")
7829           (zero_extend:<DWI>
7830             (match_operand:DWIH 2 "nonimmediate_operand" "rm,r,rm,r"))))
7831    (clobber (reg:CC FLAGS_REG))]
7832   "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands, TARGET_APX_NDD)"
7833   "#"
7834   "&& reload_completed"
7835   [(parallel [(set (reg:CC FLAGS_REG)
7836                    (compare:CC (match_dup 1) (match_dup 2)))
7837               (set (match_dup 0)
7838                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7839    (parallel [(set (match_dup 3)
7840                    (minus:DWIH
7841                      (minus:DWIH
7842                        (match_dup 4)
7843                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7844                      (const_int 0)))
7845               (clobber (reg:CC FLAGS_REG))])]
7846   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);"
7847 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
7849 (define_insn "*sub<mode>_1"
7850   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r,r")
7851         (minus:SWI
7852           (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,rjM,r")
7853           (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r,<i>,<m>")))
7854    (clobber (reg:CC FLAGS_REG))]
7855   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
7856   "@
7857   sub{<imodesuffix>}\t{%2, %0|%0, %2}
7858   sub{<imodesuffix>}\t{%2, %0|%0, %2}
7859   sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7860   sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7861   sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7862   [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd")
7863    (set_attr "type" "alu")
7864    (set_attr "mode" "<MODE>")])
7866 (define_insn "*subsi_1_zext"
7867   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7868         (zero_extend:DI
7869           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,r,rm")
7870                     (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))))
7871    (clobber (reg:CC FLAGS_REG))]
7872   "TARGET_64BIT
7873    && ix86_binary_operator_ok (MINUS, SImode, operands, TARGET_APX_NDD)"
7874   "@
7875   sub{l}\t{%2, %k0|%k0, %2}
7876   sub{l}\t{%2, %1, %k0|%k0, %1, %2}
7877   sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
7878   [(set_attr "isa" "*,apx_ndd,apx_ndd")
7879    (set_attr "type" "alu")
7880    (set_attr "mode" "SI")])
7882 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7883 (define_insn_and_split "*sub<mode>_1_slp"
7884   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
7885         (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
7886                      (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
7887    (clobber (reg:CC FLAGS_REG))]
7888   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7889   "@
7890    sub{<imodesuffix>}\t{%2, %0|%0, %2}
7891    #"
7892   "&& reload_completed
7893    && !(rtx_equal_p (operands[0], operands[1]))"
7894   [(set (strict_low_part (match_dup 0)) (match_dup 1))
7895    (parallel
7896      [(set (strict_low_part (match_dup 0))
7897            (minus:SWI12 (match_dup 0) (match_dup 2)))
7898       (clobber (reg:CC FLAGS_REG))])]
7899   ""
7900   [(set_attr "type" "alu")
7901    (set_attr "mode" "<MODE>")])
7903 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7904 (define_insn_and_split "*subqi_ext<mode>_1_slp"
7905   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
7906         (minus:QI
7907           (match_operand:QI 1 "nonimmediate_operand" "0,!qm")
7908           (subreg:QI
7909             (match_operator:SWI248 3 "extract_operator"
7910               [(match_operand 2 "int248_register_operand" "Q,Q")
7911                (const_int 8)
7912                (const_int 8)]) 0)))
7913    (clobber (reg:CC FLAGS_REG))]
7914   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7915   "@
7916    sub{b}\t{%h2, %0|%0, %h2}
7917    #"
7918   "&& reload_completed
7919    && !rtx_equal_p (operands[0], operands[1])"
7920   [(set (strict_low_part (match_dup 0)) (match_dup 1))
7921    (parallel
7922      [(set (strict_low_part (match_dup 0))
7923            (minus:QI
7924              (match_dup 0)
7925              (subreg:QI
7926                (match_op_dup 3
7927                  [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
7928       (clobber (reg:CC FLAGS_REG))])]
7929   ""
7930   [(set_attr "type" "alu")
7931    (set_attr "mode" "QI")])
7933 (define_insn_and_split "*subqi_ext<mode>_2_slp"
7934   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
7935         (minus:QI
7936           (subreg:QI
7937             (match_operator:SWI248 3 "extract_operator"
7938               [(match_operand 1 "int248_register_operand" "Q")
7939                (const_int 8)
7940                (const_int 8)]) 0)
7941           (subreg:QI
7942             (match_operator:SWI248 4 "extract_operator"
7943               [(match_operand 2 "int248_register_operand" "Q")
7944                (const_int 8)
7945                (const_int 8)]) 0)))
7946    (clobber (reg:CC FLAGS_REG))]
7947   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7948   "#"
7949   "&& reload_completed"
7950   [(set (strict_low_part (match_dup 0))
7951         (subreg:QI
7952           (match_op_dup 3
7953             [(match_dup 1) (const_int 8) (const_int 8)]) 0))
7954    (parallel
7955      [(set (strict_low_part (match_dup 0))
7956            (minus:QI
7957            (match_dup 0)
7958              (subreg:QI
7959                (match_op_dup 4
7960                  [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
7961       (clobber (reg:CC FLAGS_REG))])]
7962   ""
7963   [(set_attr "type" "alu")
7964    (set_attr "mode" "QI")])
7966 (define_insn "*sub<mode>_2"
7967   [(set (reg FLAGS_REG)
7968         (compare
7969           (minus:SWI
7970             (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r")
7971             (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>"))
7972           (const_int 0)))
7973    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
7974         (minus:SWI (match_dup 1) (match_dup 2)))]
7975   "ix86_match_ccmode (insn, CCGOCmode)
7976    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
7977   "@
7978   sub{<imodesuffix>}\t{%2, %0|%0, %2}
7979   sub{<imodesuffix>}\t{%2, %0|%0, %2}
7980   sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7981   sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7982   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
7983    (set_attr "type" "alu")
7984    (set_attr "mode" "<MODE>")])
7986 (define_insn "*subsi_2_zext"
7987   [(set (reg FLAGS_REG)
7988         (compare
7989           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,r,rm")
7990                     (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))
7991           (const_int 0)))
7992    (set (match_operand:DI 0 "register_operand" "=r,r,r")
7993         (zero_extend:DI
7994           (minus:SI (match_dup 1)
7995                     (match_dup 2))))]
7996   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7997    && ix86_binary_operator_ok (MINUS, SImode, operands, TARGET_APX_NDD)"
7998   "@
7999   sub{l}\t{%2, %k0|%k0, %2}
8000   sub{l}\t{%2, %1, %k0|%k0, %1, %2}
8001   sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
8002   [(set_attr "isa" "*,apx_ndd,apx_ndd")
8003    (set_attr "type" "alu")
8004    (set_attr "mode" "SI")])
8006 (define_insn "*subqi_ext<mode>_0"
8007   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
8008         (minus:QI
8009           (match_operand:QI 1 "nonimmediate_operand" "0")
8010           (subreg:QI
8011             (match_operator:SWI248 3 "extract_operator"
8012               [(match_operand 2 "int248_register_operand" "Q")
8013                (const_int 8)
8014                (const_int 8)]) 0)))
8015    (clobber (reg:CC FLAGS_REG))]
8016   ""
8017   "sub{b}\t{%h2, %0|%0, %h2}"
8018   [(set_attr "addr" "gpr8")
8019    (set_attr "type" "alu")
8020    (set_attr "mode" "QI")])
8022 (define_insn_and_split "*subqi_ext2<mode>_0"
8023   [(set (match_operand:QI 0 "register_operand" "=&Q")
8024         (minus:QI
8025           (subreg:QI
8026             (match_operator:SWI248 3 "extract_operator"
8027               [(match_operand 1 "int248_register_operand" "Q")
8028                (const_int 8)
8029                (const_int 8)]) 0)
8030           (subreg:QI
8031             (match_operator:SWI248 4 "extract_operator"
8032               [(match_operand 2 "int248_register_operand" "Q")
8033                (const_int 8)
8034                (const_int 8)]) 0)))
8035    (clobber (reg:CC FLAGS_REG))]
8036   ""
8037   "#"
8038   "&& reload_completed"
8039   [(set (match_dup 0)
8040         (subreg:QI
8041           (match_op_dup 3
8042             [(match_dup 1) (const_int 8) (const_int 8)]) 0))
8043    (parallel
8044      [(set (match_dup 0)
8045            (minus:QI
8046              (match_dup 0)
8047              (subreg:QI
8048                (match_op_dup 4
8049                  [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
8050       (clobber (reg:CC FLAGS_REG))])]
8051   ""
8052   [(set_attr "type" "alu")
8053    (set_attr "mode" "QI")])
8055 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
8056 (define_insn_and_split "*subqi_ext<mode>_1"
8057   [(set (zero_extract:SWI248
8058           (match_operand 0 "int248_register_operand" "+Q,&Q")
8059           (const_int 8)
8060           (const_int 8))
8061         (subreg:SWI248
8062           (minus:QI
8063             (subreg:QI
8064               (match_operator:SWI248 3 "extract_operator"
8065                 [(match_operand 1 "int248_register_operand" "0,!Q")
8066                  (const_int 8)
8067                  (const_int 8)]) 0)
8068             (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
8069    (clobber (reg:CC FLAGS_REG))]
8070   ""
8071   "@
8072    sub{b}\t{%2, %h0|%h0, %2}
8073    #"
8074   "reload_completed
8075    && !(rtx_equal_p (operands[0], operands[1]))"
8076   [(set (zero_extract:SWI248
8077           (match_dup 0) (const_int 8) (const_int 8))
8078         (zero_extract:SWI248
8079           (match_dup 1) (const_int 8) (const_int 8)))
8080    (parallel
8081      [(set (zero_extract:SWI248
8082              (match_dup 0) (const_int 8) (const_int 8))
8083            (subreg:SWI248
8084              (minus:QI
8085                (subreg:QI
8086                  (match_op_dup 3
8087                    [(match_dup 0) (const_int 8) (const_int 8)]) 0)
8088                (match_dup 2)) 0))
8089       (clobber (reg:CC FLAGS_REG))])]
8090   ""
8091   [(set_attr "addr" "gpr8")
8092    (set_attr "type" "alu")
8093    (set_attr "mode" "QI")])
8095 ;; Subtract with jump on overflow.
8096 (define_expand "subv<mode>4"
8097   [(parallel [(set (reg:CCO FLAGS_REG)
8098                    (eq:CCO
8099                      (minus:<DPWI>
8100                        (sign_extend:<DPWI>
8101                          (match_operand:SWIDWI 1 "nonimmediate_operand"))
8102                        (match_dup 4))
8103                      (sign_extend:<DPWI>
8104                        (minus:SWIDWI (match_dup 1)
8105                                      (match_operand:SWIDWI 2
8106                                                 "<general_hilo_operand>")))))
8107               (set (match_operand:SWIDWI 0 "register_operand")
8108                    (minus:SWIDWI (match_dup 1) (match_dup 2)))])
8109    (set (pc) (if_then_else
8110                (eq (reg:CCO FLAGS_REG) (const_int 0))
8111                (label_ref (match_operand 3))
8112                (pc)))]
8113   ""
8115   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands,
8116                                       TARGET_APX_NDD);
8117   if (CONST_SCALAR_INT_P (operands[2]))
8118     operands[4] = operands[2];
8119   else
8120     operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
8123 (define_insn "*subv<mode>4"
8124   [(set (reg:CCO FLAGS_REG)
8125         (eq:CCO (minus:<DWI>
8126                    (sign_extend:<DWI>
8127                       (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r"))
8128                    (sign_extend:<DWI>
8129                       (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m,rWe,m")))
8130                 (sign_extend:<DWI>
8131                    (minus:SWI (match_dup 1) (match_dup 2)))))
8132    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
8133         (minus:SWI (match_dup 1) (match_dup 2)))]
8134   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
8135   "@
8136   sub{<imodesuffix>}\t{%2, %0|%0, %2}
8137   sub{<imodesuffix>}\t{%2, %0|%0, %2}
8138   sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8139   sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8140   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
8141    (set_attr "type" "alu")
8142    (set_attr "mode" "<MODE>")])
8144 (define_insn "subv<mode>4_1"
8145   [(set (reg:CCO FLAGS_REG)
8146         (eq:CCO (minus:<DWI>
8147                    (sign_extend:<DWI>
8148                       (match_operand:SWI 1 "nonimmediate_operand" "0,rm"))
8149                    (match_operand:<DWI> 3 "const_int_operand"))
8150                 (sign_extend:<DWI>
8151                    (minus:SWI
8152                      (match_dup 1)
8153                      (match_operand:SWI 2 "x86_64_immediate_operand" "<i>,<i>")))))
8154    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
8155         (minus:SWI (match_dup 1) (match_dup 2)))]
8156   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
8157    && CONST_INT_P (operands[2])
8158    && INTVAL (operands[2]) == INTVAL (operands[3])"
8159   "@
8160   sub{<imodesuffix>}\t{%2, %0|%0, %2}
8161   sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8162   [(set_attr "isa" "*,apx_ndd")
8163    (set_attr "type" "alu")
8164    (set_attr "mode" "<MODE>")
8165    (set (attr "length_immediate")
8166         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8167                   (const_string "1")
8168                (match_test "<MODE_SIZE> == 8")
8169                   (const_string "4")]
8170               (const_string "<MODE_SIZE>")))])
8172 (define_insn_and_split "*subv<dwi>4_doubleword"
8173   [(set (reg:CCO FLAGS_REG)
8174         (eq:CCO
8175           (minus:<QPWI>
8176             (sign_extend:<QPWI>
8177               (match_operand:<DWI> 1 "nonimmediate_operand" "0,0,ro,r"))
8178             (sign_extend:<QPWI>
8179               (match_operand:<DWI> 2 "nonimmediate_operand" "r,o,r,o")))
8180           (sign_extend:<QPWI>
8181             (minus:<DWI> (match_dup 1) (match_dup 2)))))
8182    (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r")
8183         (minus:<DWI> (match_dup 1) (match_dup 2)))]
8184   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
8185   "#"
8186   "&& reload_completed"
8187   [(parallel [(set (reg:CC FLAGS_REG)
8188                    (compare:CC (match_dup 1) (match_dup 2)))
8189               (set (match_dup 0)
8190                    (minus:DWIH (match_dup 1) (match_dup 2)))])
8191    (parallel [(set (reg:CCO FLAGS_REG)
8192                    (eq:CCO
8193                      (minus:<DWI>
8194                        (minus:<DWI>
8195                          (sign_extend:<DWI> (match_dup 4))
8196                          (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
8197                        (sign_extend:<DWI> (match_dup 5)))
8198                      (sign_extend:<DWI>
8199                        (minus:DWIH
8200                          (minus:DWIH
8201                            (match_dup 4)
8202                            (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
8203                          (match_dup 5)))))
8204               (set (match_dup 3)
8205                    (minus:DWIH
8206                      (minus:DWIH
8207                        (match_dup 4)
8208                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
8209                      (match_dup 5)))])]
8211   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
8213 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
8215 (define_insn_and_split "*subv<dwi>4_doubleword_1"
8216   [(set (reg:CCO FLAGS_REG)
8217         (eq:CCO
8218           (minus:<QPWI>
8219             (sign_extend:<QPWI>
8220               (match_operand:<DWI> 1 "nonimmediate_operand" "0,ro"))
8221             (match_operand:<QPWI> 3 "const_scalar_int_operand"))
8222           (sign_extend:<QPWI>
8223             (minus:<DWI>
8224               (match_dup 1)
8225               (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>,<di>")))))
8226    (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,&r")
8227         (minus:<DWI> (match_dup 1) (match_dup 2)))]
8228   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
8229    && CONST_SCALAR_INT_P (operands[2])
8230    && rtx_equal_p (operands[2], operands[3])"
8231   "#"
8232   "&& reload_completed"
8233   [(parallel [(set (reg:CC FLAGS_REG)
8234                    (compare:CC (match_dup 1) (match_dup 2)))
8235               (set (match_dup 0)
8236                    (minus:DWIH (match_dup 1) (match_dup 2)))])
8237    (parallel [(set (reg:CCO FLAGS_REG)
8238                    (eq:CCO
8239                      (minus:<DWI>
8240                        (minus:<DWI>
8241                          (sign_extend:<DWI> (match_dup 4))
8242                          (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
8243                        (match_dup 5))
8244                      (sign_extend:<DWI>
8245                        (minus:DWIH
8246                          (minus:DWIH
8247                            (match_dup 4)
8248                            (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
8249                          (match_dup 5)))))
8250               (set (match_dup 3)
8251                    (minus:DWIH
8252                      (minus:DWIH
8253                        (match_dup 4)
8254                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
8255                      (match_dup 5)))])]
8257   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
8258   if (operands[2] == const0_rtx)
8259     {
8260       if (!rtx_equal_p (operands[0], operands[1]))
8261         emit_move_insn (operands[0], operands[1]);
8262       emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
8263                                     operands[5]));
8264       DONE;
8265     }
8267 [(set_attr "isa" "*,apx_ndd")])
8269 (define_insn "*subv<mode>4_overflow_1"
8270   [(set (reg:CCO FLAGS_REG)
8271         (eq:CCO
8272           (minus:<DWI>
8273             (minus:<DWI>
8274               (sign_extend:<DWI>
8275                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r"))
8276               (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8277                 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8278             (sign_extend:<DWI>
8279               (match_operand:SWI 2 "<general_sext_operand>" "rWe,m,rWe,m")))
8280           (sign_extend:<DWI>
8281             (minus:SWI
8282               (minus:SWI
8283                 (match_dup 1)
8284                 (match_operator:SWI 5 "ix86_carry_flag_operator"
8285                   [(match_dup 3) (const_int 0)]))
8286               (match_dup 2)))))
8287    (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r,r,r")
8288         (minus:SWI
8289           (minus:SWI
8290             (match_dup 1)
8291             (match_op_dup 5 [(match_dup 3) (const_int 0)]))
8292           (match_dup 2)))]
8293   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
8294   "@
8295   sbb{<imodesuffix>}\t{%2, %0|%0, %2}
8296   sbb{<imodesuffix>}\t{%2, %0|%0, %2}
8297   sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8298   sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8299   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
8300    (set_attr "type" "alu")
8301    (set_attr "mode" "<MODE>")])
8303 (define_insn "*subv<mode>4_overflow_2"
8304   [(set (reg:CCO FLAGS_REG)
8305         (eq:CCO
8306           (minus:<DWI>
8307             (minus:<DWI>
8308               (sign_extend:<DWI>
8309                 (match_operand:SWI 1 "nonimmediate_operand" "%0,rm"))
8310               (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8311                 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8312             (match_operand:<DWI> 6 "const_int_operand" "n,n"))
8313           (sign_extend:<DWI>
8314             (minus:SWI
8315               (minus:SWI
8316                 (match_dup 1)
8317                 (match_operator:SWI 5 "ix86_carry_flag_operator"
8318                   [(match_dup 3) (const_int 0)]))
8319               (match_operand:SWI 2 "x86_64_immediate_operand" "e,e")))))
8320    (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
8321         (minus:SWI
8322           (minus:SWI
8323             (match_dup 1)
8324             (match_op_dup 5 [(match_dup 3) (const_int 0)]))
8325           (match_dup 2)))]
8326   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
8327    && CONST_INT_P (operands[2])
8328    && INTVAL (operands[2]) == INTVAL (operands[6])"
8329   "@
8330   sbb{<imodesuffix>}\t{%2, %0|%0, %2}
8331   sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8332   [(set_attr "isa" "*,apx_ndd")
8333    (set_attr "type" "alu")
8334    (set_attr "mode" "<MODE>")
8335    (set (attr "length_immediate")
8336      (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8337        (const_string "1")
8338        (const_string "4")))])
8340 (define_expand "usubv<mode>4"
8341   [(parallel [(set (reg:CC FLAGS_REG)
8342                    (compare:CC
8343                      (match_operand:SWI 1 "nonimmediate_operand")
8344                      (match_operand:SWI 2 "<general_operand>")))
8345               (set (match_operand:SWI 0 "register_operand")
8346                    (minus:SWI (match_dup 1) (match_dup 2)))])
8347    (set (pc) (if_then_else
8348                (ltu (reg:CC FLAGS_REG) (const_int 0))
8349                (label_ref (match_operand 3))
8350                (pc)))]
8351   ""
8352   "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands,
8353                                        TARGET_APX_NDD);")
8355 (define_insn "*sub<mode>_3"
8356   [(set (reg FLAGS_REG)
8357         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r")
8358                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>")))
8359    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>i,r,r")
8360         (minus:SWI (match_dup 1) (match_dup 2)))]
8361   "ix86_match_ccmode (insn, CCmode)
8362    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
8363   "@
8364   sub{<imodesuffix>}\t{%2, %0|%0, %2}
8365   sub{<imodesuffix>}\t{%2, %0|%0, %2}
8366   sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8367   sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8368   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
8369    (set_attr "type" "alu")
8370    (set_attr "mode" "<MODE>")])
8372 (define_peephole2
8373   [(parallel
8374      [(set (reg:CC FLAGS_REG)
8375            (compare:CC (match_operand:SWI 0 "general_reg_operand")
8376                        (match_operand:SWI 1 "general_gr_operand")))
8377       (set (match_dup 0)
8378            (minus:SWI (match_dup 0) (match_dup 1)))])]
8379   "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
8380   [(set (reg:CC FLAGS_REG)
8381         (compare:CC (match_dup 0) (match_dup 1)))])
8383 (define_peephole2
8384   [(set (match_operand:SWI 0 "general_reg_operand")
8385         (match_operand:SWI 1 "memory_operand"))
8386    (parallel [(set (reg:CC FLAGS_REG)
8387                    (compare:CC (match_dup 0)
8388                                (match_operand:SWI 2 "memory_operand")))
8389               (set (match_dup 0)
8390                    (minus:SWI (match_dup 0) (match_dup 2)))])
8391    (set (match_dup 1) (match_dup 0))]
8392   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8393    && peep2_reg_dead_p (3, operands[0])
8394    && !reg_overlap_mentioned_p (operands[0], operands[1])
8395    && !reg_overlap_mentioned_p (operands[0], operands[2])"
8396   [(set (match_dup 0) (match_dup 2))
8397    (parallel [(set (reg:CC FLAGS_REG)
8398                    (compare:CC (match_dup 1) (match_dup 0)))
8399               (set (match_dup 1)
8400                    (minus:SWI (match_dup 1) (match_dup 0)))])])
8402 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
8403 ;; subl $1, %eax; jnc .Lxx;
8404 (define_peephole2
8405   [(parallel
8406      [(set (match_operand:SWI 0 "general_reg_operand")
8407            (plus:SWI (match_dup 0) (const_int -1)))
8408       (clobber (reg FLAGS_REG))])
8409    (set (reg:CCZ FLAGS_REG)
8410         (compare:CCZ (match_dup 0) (const_int -1)))
8411    (set (pc)
8412         (if_then_else (match_operator 1 "bt_comparison_operator"
8413                         [(reg:CCZ FLAGS_REG) (const_int 0)])
8414                       (match_operand 2)
8415                       (pc)))]
8416    "peep2_regno_dead_p (3, FLAGS_REG)"
8417    [(parallel
8418       [(set (reg:CC FLAGS_REG)
8419             (compare:CC (match_dup 0) (const_int 1)))
8420        (set (match_dup 0)
8421             (minus:SWI (match_dup 0) (const_int 1)))])
8422     (set (pc)
8423          (if_then_else (match_dup 3)
8424                        (match_dup 2)
8425                        (pc)))]
8427   rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
8428   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
8429                                 ? GEU : LTU, VOIDmode, cc, const0_rtx);
8432 ;; Help combine use borrow flag to test for -1 after dec (add $-1).
8433 (define_insn_and_split "*dec_cmov<mode>"
8434   [(set (match_operand:SWI248 0 "register_operand" "=r")
8435         (if_then_else:SWI248
8436          (match_operator 1 "bt_comparison_operator"
8437           [(match_operand:SWI248 2 "register_operand" "0") (const_int 0)])
8438          (plus:SWI248 (match_dup 2) (const_int -1))
8439          (match_operand:SWI248 3 "nonimmediate_operand" "rm")))
8440    (clobber (reg:CC FLAGS_REG))]
8441   "TARGET_CMOVE"
8442   "#"
8443   "&& reload_completed"
8444   [(parallel [(set (reg:CC FLAGS_REG)
8445                    (compare:CC (match_dup 2) (const_int 1)))
8446               (set (match_dup 0) (minus:SWI248 (match_dup 2) (const_int 1)))])
8447    (set (match_dup 0)
8448         (if_then_else:SWI248 (match_dup 4) (match_dup 0) (match_dup 3)))]
8450   rtx cc = gen_rtx_REG (CCCmode, FLAGS_REG);
8451   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
8452                                 ? GEU : LTU, VOIDmode, cc, const0_rtx);
8455 (define_insn "*subsi_3_zext"
8456   [(set (reg FLAGS_REG)
8457         (compare (match_operand:SI 1 "nonimmediate_operand" "0,r,rm")
8458                  (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re")))
8459    (set (match_operand:DI 0 "register_operand" "=r,r,r")
8460         (zero_extend:DI
8461           (minus:SI (match_dup 1)
8462                     (match_dup 2))))]
8463   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
8464    && ix86_binary_operator_ok (MINUS, SImode, operands, TARGET_APX_NDD)"
8465   "@
8466   sub{l}\t{%2, %1|%1, %2}
8467   sub{l}\t{%2, %1, %k0|%k0, %1, %2}
8468   sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
8469   [(set_attr "isa" "*,apx_ndd,apx_ndd")
8470    (set_attr "type" "alu")
8471    (set_attr "mode" "SI")])
8473 ;; Add with carry and subtract with borrow
8475 (define_insn "@add<mode>3_carry"
8476   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
8477         (plus:SWI
8478           (plus:SWI
8479             (match_operator:SWI 4 "ix86_carry_flag_operator"
8480              [(match_operand 3 "flags_reg_operand") (const_int 0)])
8481             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r"))
8482           (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>")))
8483    (clobber (reg:CC FLAGS_REG))]
8484   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
8485   "@
8486    adc{<imodesuffix>}\t{%2, %0|%0, %2}
8487    adc{<imodesuffix>}\t{%2, %0|%0, %2}
8488    adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8489    adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8490   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
8491    (set_attr "type" "alu")
8492    (set_attr "use_carry" "1")
8493    (set_attr "pent_pair" "pu")
8494    (set_attr "mode" "<MODE>")])
8496 (define_peephole2
8497   [(set (match_operand:SWI 0 "general_reg_operand")
8498         (match_operand:SWI 1 "memory_operand"))
8499    (parallel [(set (match_dup 0)
8500                    (plus:SWI
8501                      (plus:SWI
8502                        (match_operator:SWI 4 "ix86_carry_flag_operator"
8503                          [(match_operand 3 "flags_reg_operand")
8504                           (const_int 0)])
8505                        (match_dup 0))
8506                      (match_operand:SWI 2 "memory_operand")))
8507               (clobber (reg:CC FLAGS_REG))])
8508    (set (match_dup 1) (match_dup 0))]
8509   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8510    && peep2_reg_dead_p (3, operands[0])
8511    && !reg_overlap_mentioned_p (operands[0], operands[1])
8512    && !reg_overlap_mentioned_p (operands[0], operands[2])"
8513   [(set (match_dup 0) (match_dup 2))
8514    (parallel [(set (match_dup 1)
8515                    (plus:SWI (plus:SWI (match_op_dup 4
8516                                          [(match_dup 3) (const_int 0)])
8517                                        (match_dup 1))
8518                              (match_dup 0)))
8519               (clobber (reg:CC FLAGS_REG))])])
8521 (define_peephole2
8522   [(set (match_operand:SWI 0 "general_reg_operand")
8523         (match_operand:SWI 1 "memory_operand"))
8524    (parallel [(set (match_dup 0)
8525                    (plus:SWI
8526                      (plus:SWI
8527                        (match_operator:SWI 4 "ix86_carry_flag_operator"
8528                          [(match_operand 3 "flags_reg_operand")
8529                           (const_int 0)])
8530                        (match_dup 0))
8531                      (match_operand:SWI 2 "memory_operand")))
8532               (clobber (reg:CC FLAGS_REG))])
8533    (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8534    (set (match_dup 1) (match_dup 5))]
8535   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8536    && peep2_reg_dead_p (3, operands[0])
8537    && peep2_reg_dead_p (4, operands[5])
8538    && !reg_overlap_mentioned_p (operands[0], operands[1])
8539    && !reg_overlap_mentioned_p (operands[0], operands[2])
8540    && !reg_overlap_mentioned_p (operands[5], operands[1])"
8541   [(set (match_dup 0) (match_dup 2))
8542    (parallel [(set (match_dup 1)
8543                    (plus:SWI (plus:SWI (match_op_dup 4
8544                                          [(match_dup 3) (const_int 0)])
8545                                        (match_dup 1))
8546                              (match_dup 0)))
8547               (clobber (reg:CC FLAGS_REG))])])
8549 (define_insn "*add<mode>3_carry_0"
8550   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8551         (plus:SWI
8552           (match_operator:SWI 2 "ix86_carry_flag_operator"
8553             [(reg FLAGS_REG) (const_int 0)])
8554           (match_operand:SWI 1 "nonimmediate_operand" "0")))
8555    (clobber (reg:CC FLAGS_REG))]
8556   "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8557   "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
8558   [(set_attr "type" "alu")
8559    (set_attr "use_carry" "1")
8560    (set_attr "pent_pair" "pu")
8561    (set_attr "mode" "<MODE>")])
8563 (define_insn "*add<mode>3_carry_0r"
8564   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8565         (plus:SWI
8566           (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8567             [(reg FLAGS_REG) (const_int 0)])
8568           (match_operand:SWI 1 "nonimmediate_operand" "0")))
8569    (clobber (reg:CC FLAGS_REG))]
8570   "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8571   "sbb{<imodesuffix>}\t{$-1, %0|%0, -1}"
8572   [(set_attr "type" "alu")
8573    (set_attr "use_carry" "1")
8574    (set_attr "pent_pair" "pu")
8575    (set_attr "mode" "<MODE>")])
8577 (define_insn "*addsi3_carry_zext"
8578   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8579         (zero_extend:DI
8580           (plus:SI
8581             (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
8582                       [(reg FLAGS_REG) (const_int 0)])
8583                      (match_operand:SI 1 "nonimmediate_operand" "%0,r,rm"))
8584             (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))))
8585    (clobber (reg:CC FLAGS_REG))]
8586   "TARGET_64BIT
8587    && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
8588   "@
8589   adc{l}\t{%2, %k0|%k0, %2}
8590   adc{l}\t{%2, %1, %k0|%k0, %1, %2}
8591   adc{l}\t{%2, %1, %k0|%k0, %1, %2}"
8592   [(set_attr "isa" "*,apx_ndd,apx_ndd")
8593    (set_attr "type" "alu")
8594    (set_attr "use_carry" "1")
8595    (set_attr "pent_pair" "pu")
8596    (set_attr "mode" "SI")])
8598 (define_insn "*addsi3_carry_zext_0"
8599   [(set (match_operand:DI 0 "register_operand" "=r,r")
8600         (zero_extend:DI
8601           (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
8602                     [(reg FLAGS_REG) (const_int 0)])
8603                    (match_operand:SI 1 "nonimmediate_operand" "0,rm"))))
8604    (clobber (reg:CC FLAGS_REG))]
8605   "TARGET_64BIT"
8606   "@
8607   adc{l}\t{$0, %k0|%k0, 0}
8608   adc{l}\t{$0, %1, %k0|%k0, %1, 0}"
8609   [(set_attr "isa" "*,apx_ndd")
8610    (set_attr "type" "alu")
8611    (set_attr "use_carry" "1")
8612    (set_attr "pent_pair" "pu")
8613    (set_attr "mode" "SI")])
8615 (define_insn "*addsi3_carry_zext_0r"
8616   [(set (match_operand:DI 0 "register_operand" "=r,r")
8617         (zero_extend:DI
8618           (plus:SI (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8619                     [(reg FLAGS_REG) (const_int 0)])
8620                    (match_operand:SI 1 "nonimmediate_operand" "0,rm"))))
8621    (clobber (reg:CC FLAGS_REG))]
8622   "TARGET_64BIT"
8623   "@
8624   sbb{l}\t{$-1, %k0|%k0, -1}
8625   sbb{l}\t{$-1, %1, %k0|%k0, %1, -1}"
8626   [(set_attr "isa" "*,apx_ndd")
8627    (set_attr "type" "alu")
8628    (set_attr "use_carry" "1")
8629    (set_attr "pent_pair" "pu")
8630    (set_attr "mode" "SI")])
8632 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
8634 (define_insn "addcarry<mode>"
8635   [(set (reg:CCC FLAGS_REG)
8636         (compare:CCC
8637           (zero_extend:<DWI>
8638             (plus:SWI48
8639               (plus:SWI48
8640                 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8641                   [(match_operand 3 "flags_reg_operand") (const_int 0)])
8642                 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,rm,r"))
8643               (match_operand:SWI48 2 "nonimmediate_operand" "r,rm,r,m")))
8644           (plus:<DWI>
8645             (zero_extend:<DWI> (match_dup 2))
8646             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8647               [(match_dup 3) (const_int 0)]))))
8648    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
8649         (plus:SWI48 (plus:SWI48 (match_op_dup 5
8650                                  [(match_dup 3) (const_int 0)])
8651                                 (match_dup 1))
8652                     (match_dup 2)))]
8653   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
8654   "@
8655   adc{<imodesuffix>}\t{%2, %0|%0, %2}
8656   adc{<imodesuffix>}\t{%2, %0|%0, %2}
8657   adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8658   adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8659   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
8660    (set_attr "type" "alu")
8661    (set_attr "use_carry" "1")
8662    (set_attr "pent_pair" "pu")
8663    (set_attr "mode" "<MODE>")])
8665 (define_peephole2
8666   [(parallel [(set (reg:CCC FLAGS_REG)
8667                    (compare:CCC
8668                      (zero_extend:<DWI>
8669                        (plus:SWI48
8670                          (plus:SWI48
8671                            (match_operator:SWI48 4 "ix86_carry_flag_operator"
8672                              [(match_operand 2 "flags_reg_operand")
8673                               (const_int 0)])
8674                            (match_operand:SWI48 0 "general_reg_operand"))
8675                          (match_operand:SWI48 1 "memory_operand")))
8676                      (plus:<DWI>
8677                        (zero_extend:<DWI> (match_dup 1))
8678                        (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8679                          [(match_dup 2) (const_int 0)]))))
8680               (set (match_dup 0)
8681                    (plus:SWI48 (plus:SWI48 (match_op_dup 4
8682                                              [(match_dup 2) (const_int 0)])
8683                                            (match_dup 0))
8684                                (match_dup 1)))])
8685    (set (match_dup 1) (match_dup 0))]
8686   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8687    && peep2_reg_dead_p (2, operands[0])
8688    && !reg_overlap_mentioned_p (operands[0], operands[1])"
8689   [(parallel [(set (reg:CCC FLAGS_REG)
8690                    (compare:CCC
8691                      (zero_extend:<DWI>
8692                        (plus:SWI48
8693                          (plus:SWI48
8694                            (match_op_dup 4
8695                              [(match_dup 2) (const_int 0)])
8696                            (match_dup 1))
8697                          (match_dup 0)))
8698                      (plus:<DWI>
8699                        (zero_extend:<DWI> (match_dup 0))
8700                        (match_op_dup 3
8701                          [(match_dup 2) (const_int 0)]))))
8702               (set (match_dup 1)
8703                    (plus:SWI48 (plus:SWI48 (match_op_dup 4
8704                                              [(match_dup 2) (const_int 0)])
8705                                            (match_dup 1))
8706                                (match_dup 0)))])])
8708 (define_peephole2
8709   [(set (match_operand:SWI48 0 "general_reg_operand")
8710         (match_operand:SWI48 1 "memory_operand"))
8711    (parallel [(set (reg:CCC FLAGS_REG)
8712                    (compare:CCC
8713                      (zero_extend:<DWI>
8714                        (plus:SWI48
8715                          (plus:SWI48
8716                            (match_operator:SWI48 5 "ix86_carry_flag_operator"
8717                              [(match_operand 3 "flags_reg_operand")
8718                               (const_int 0)])
8719                            (match_dup 0))
8720                          (match_operand:SWI48 2 "memory_operand")))
8721                      (plus:<DWI>
8722                        (zero_extend:<DWI> (match_dup 2))
8723                        (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8724                          [(match_dup 3) (const_int 0)]))))
8725               (set (match_dup 0)
8726                    (plus:SWI48 (plus:SWI48 (match_op_dup 5
8727                                              [(match_dup 3) (const_int 0)])
8728                                            (match_dup 0))
8729                                (match_dup 2)))])
8730    (set (match_dup 1) (match_dup 0))]
8731   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8732    && peep2_reg_dead_p (3, operands[0])
8733    && !reg_overlap_mentioned_p (operands[0], operands[1])
8734    && !reg_overlap_mentioned_p (operands[0], operands[2])"
8735   [(set (match_dup 0) (match_dup 2))
8736    (parallel [(set (reg:CCC FLAGS_REG)
8737                    (compare:CCC
8738                      (zero_extend:<DWI>
8739                        (plus:SWI48
8740                          (plus:SWI48
8741                            (match_op_dup 5
8742                              [(match_dup 3) (const_int 0)])
8743                            (match_dup 1))
8744                          (match_dup 0)))
8745                      (plus:<DWI>
8746                        (zero_extend:<DWI> (match_dup 0))
8747                        (match_op_dup 4
8748                          [(match_dup 3) (const_int 0)]))))
8749               (set (match_dup 1)
8750                    (plus:SWI48 (plus:SWI48 (match_op_dup 5
8751                                              [(match_dup 3) (const_int 0)])
8752                                            (match_dup 1))
8753                                (match_dup 0)))])])
8755 (define_peephole2
8756   [(parallel [(set (reg:CCC FLAGS_REG)
8757                    (compare:CCC
8758                      (zero_extend:<DWI>
8759                        (plus:SWI48
8760                          (plus:SWI48
8761                            (match_operator:SWI48 4 "ix86_carry_flag_operator"
8762                              [(match_operand 2 "flags_reg_operand")
8763                               (const_int 0)])
8764                            (match_operand:SWI48 0 "general_reg_operand"))
8765                          (match_operand:SWI48 1 "memory_operand")))
8766                      (plus:<DWI>
8767                        (zero_extend:<DWI> (match_dup 1))
8768                        (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8769                          [(match_dup 2) (const_int 0)]))))
8770               (set (match_dup 0)
8771                    (plus:SWI48 (plus:SWI48 (match_op_dup 4
8772                                              [(match_dup 2) (const_int 0)])
8773                                            (match_dup 0))
8774                                (match_dup 1)))])
8775    (set (match_operand:QI 5 "general_reg_operand")
8776         (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8777    (set (match_operand:SWI48 6 "general_reg_operand")
8778         (zero_extend:SWI48 (match_dup 5)))
8779    (set (match_dup 1) (match_dup 0))]
8780   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8781    && peep2_reg_dead_p (4, operands[0])
8782    && !reg_overlap_mentioned_p (operands[0], operands[1])
8783    && !reg_overlap_mentioned_p (operands[0], operands[5])
8784    && !reg_overlap_mentioned_p (operands[5], operands[1])
8785    && !reg_overlap_mentioned_p (operands[0], operands[6])
8786    && !reg_overlap_mentioned_p (operands[6], operands[1])"
8787   [(parallel [(set (reg:CCC FLAGS_REG)
8788                    (compare:CCC
8789                      (zero_extend:<DWI>
8790                        (plus:SWI48
8791                          (plus:SWI48
8792                            (match_op_dup 4
8793                              [(match_dup 2) (const_int 0)])
8794                            (match_dup 1))
8795                          (match_dup 0)))
8796                      (plus:<DWI>
8797                        (zero_extend:<DWI> (match_dup 0))
8798                        (match_op_dup 3
8799                          [(match_dup 2) (const_int 0)]))))
8800               (set (match_dup 1)
8801                    (plus:SWI48 (plus:SWI48 (match_op_dup 4
8802                                              [(match_dup 2) (const_int 0)])
8803                                            (match_dup 1))
8804                                (match_dup 0)))])
8805    (set (match_dup 5) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8806    (set (match_dup 6) (zero_extend:SWI48 (match_dup 5)))])
8808 (define_expand "addcarry<mode>_0"
8809   [(parallel
8810      [(set (reg:CCC FLAGS_REG)
8811            (compare:CCC
8812              (plus:SWI48
8813                (match_operand:SWI48 1 "nonimmediate_operand")
8814                (match_operand:SWI48 2 "x86_64_general_operand"))
8815              (match_dup 1)))
8816       (set (match_operand:SWI48 0 "nonimmediate_operand")
8817            (plus:SWI48 (match_dup 1) (match_dup 2)))])]
8818   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)")
8820 (define_insn "*addcarry<mode>_1"
8821   [(set (reg:CCC FLAGS_REG)
8822         (compare:CCC
8823           (zero_extend:<DWI>
8824             (plus:SWI48
8825               (plus:SWI48
8826                 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8827                   [(match_operand 3 "flags_reg_operand") (const_int 0)])
8828                 (match_operand:SWI48 1 "nonimmediate_operand" "%0,rm"))
8829               (match_operand:SWI48 2 "x86_64_immediate_operand" "e,e")))
8830           (plus:<DWI>
8831             (match_operand:<DWI> 6 "const_scalar_int_operand")
8832             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8833               [(match_dup 3) (const_int 0)]))))
8834    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8835         (plus:SWI48 (plus:SWI48 (match_op_dup 5
8836                                  [(match_dup 3) (const_int 0)])
8837                                 (match_dup 1))
8838                     (match_dup 2)))]
8839   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
8840    && CONST_INT_P (operands[2])
8841    /* Check that operands[6] is operands[2] zero extended from
8842       <MODE>mode to <DWI>mode.  */
8843    && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0)
8844        ? (CONST_INT_P (operands[6])
8845           && UINTVAL (operands[6]) == (UINTVAL (operands[2])
8846                                        & GET_MODE_MASK (<MODE>mode)))
8847        : (CONST_WIDE_INT_P (operands[6])
8848           && CONST_WIDE_INT_NUNITS (operands[6]) == 2
8849           && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
8850               == UINTVAL (operands[2]))
8851           && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
8852   "@
8853   adc{<imodesuffix>}\t{%2, %0|%0, %2}
8854   adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8855   [(set_attr "isa" "*,apx_ndd")
8856    (set_attr "type" "alu")
8857    (set_attr "use_carry" "1")
8858    (set_attr "pent_pair" "pu")
8859    (set_attr "mode" "<MODE>")
8860    (set (attr "length_immediate")
8861      (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8862        (const_string "1")
8863        (const_string "4")))])
8865 (define_insn "@sub<mode>3_carry"
8866   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
8867         (minus:SWI
8868           (minus:SWI
8869             (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r")
8870             (match_operator:SWI 4 "ix86_carry_flag_operator"
8871              [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8872           (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>")))
8873    (clobber (reg:CC FLAGS_REG))]
8874   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
8875   "@
8876   sbb{<imodesuffix>}\t{%2, %0|%0, %2}
8877   sbb{<imodesuffix>}\t{%2, %0|%0, %2}
8878   sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8879   sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8880   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
8881    (set_attr "type" "alu")
8882    (set_attr "use_carry" "1")
8883    (set_attr "pent_pair" "pu")
8884    (set_attr "mode" "<MODE>")])
8886 (define_peephole2
8887   [(set (match_operand:SWI 0 "general_reg_operand")
8888         (match_operand:SWI 1 "memory_operand"))
8889    (parallel [(set (match_dup 0)
8890                    (minus:SWI
8891                      (minus:SWI
8892                        (match_dup 0)
8893                        (match_operator:SWI 4 "ix86_carry_flag_operator"
8894                          [(match_operand 3 "flags_reg_operand")
8895                           (const_int 0)]))
8896                      (match_operand:SWI 2 "memory_operand")))
8897               (clobber (reg:CC FLAGS_REG))])
8898    (set (match_dup 1) (match_dup 0))]
8899   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8900    && peep2_reg_dead_p (3, operands[0])
8901    && !reg_overlap_mentioned_p (operands[0], operands[1])
8902    && !reg_overlap_mentioned_p (operands[0], operands[2])"
8903   [(set (match_dup 0) (match_dup 2))
8904    (parallel [(set (match_dup 1)
8905                    (minus:SWI (minus:SWI (match_dup 1)
8906                                          (match_op_dup 4
8907                                            [(match_dup 3) (const_int 0)]))
8908                               (match_dup 0)))
8909               (clobber (reg:CC FLAGS_REG))])])
8911 (define_peephole2
8912   [(set (match_operand:SWI 0 "general_reg_operand")
8913         (match_operand:SWI 1 "memory_operand"))
8914    (parallel [(set (match_dup 0)
8915                    (minus:SWI
8916                      (minus:SWI
8917                        (match_dup 0)
8918                        (match_operator:SWI 4 "ix86_carry_flag_operator"
8919                          [(match_operand 3 "flags_reg_operand")
8920                           (const_int 0)]))
8921                      (match_operand:SWI 2 "memory_operand")))
8922               (clobber (reg:CC FLAGS_REG))])
8923    (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8924    (set (match_dup 1) (match_dup 5))]
8925   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8926    && peep2_reg_dead_p (3, operands[0])
8927    && peep2_reg_dead_p (4, operands[5])
8928    && !reg_overlap_mentioned_p (operands[0], operands[1])
8929    && !reg_overlap_mentioned_p (operands[0], operands[2])
8930    && !reg_overlap_mentioned_p (operands[5], operands[1])"
8931   [(set (match_dup 0) (match_dup 2))
8932    (parallel [(set (match_dup 1)
8933                    (minus:SWI (minus:SWI (match_dup 1)
8934                                          (match_op_dup 4
8935                                            [(match_dup 3) (const_int 0)]))
8936                               (match_dup 0)))
8937               (clobber (reg:CC FLAGS_REG))])])
8939 (define_insn "*sub<mode>3_carry_0"
8940   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8941         (minus:SWI
8942           (match_operand:SWI 1 "nonimmediate_operand" "0")
8943           (match_operator:SWI 2 "ix86_carry_flag_operator"
8944             [(reg FLAGS_REG) (const_int 0)])))
8945    (clobber (reg:CC FLAGS_REG))]
8946   "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8947   "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
8948   [(set_attr "type" "alu")
8949    (set_attr "use_carry" "1")
8950    (set_attr "pent_pair" "pu")
8951    (set_attr "mode" "<MODE>")])
8953 (define_insn "*sub<mode>3_carry_0r"
8954   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8955         (minus:SWI
8956           (match_operand:SWI 1 "nonimmediate_operand" "0")
8957           (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8958             [(reg FLAGS_REG) (const_int 0)])))
8959    (clobber (reg:CC FLAGS_REG))]
8960   "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8961   "adc{<imodesuffix>}\t{$-1, %0|%0, -1}"
8962   [(set_attr "type" "alu")
8963    (set_attr "use_carry" "1")
8964    (set_attr "pent_pair" "pu")
8965    (set_attr "mode" "<MODE>")])
8967 (define_insn "*subsi3_carry_zext"
8968   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8969         (zero_extend:DI
8970           (minus:SI
8971             (minus:SI
8972               (match_operand:SI 1 "nonimmediate_operand" "0,r,rm")
8973               (match_operator:SI 3 "ix86_carry_flag_operator"
8974                [(reg FLAGS_REG) (const_int 0)]))
8975             (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))))
8976    (clobber (reg:CC FLAGS_REG))]
8977   "TARGET_64BIT
8978    && ix86_binary_operator_ok (MINUS, SImode, operands, TARGET_APX_NDD)"
8979   "@
8980   sbb{l}\t{%2, %k0|%k0, %2}
8981   sbb{l}\t{%2, %1, %k0|%k0, %1, %2}
8982   sbb{l}\t{%2, %1, %k0|%k0, %1, %2}"
8983   [(set_attr "isa" "*,apx_ndd,apx_ndd")
8984    (set_attr "type" "alu")
8985    (set_attr "use_carry" "1")
8986    (set_attr "pent_pair" "pu")
8987    (set_attr "mode" "SI")])
8989 (define_insn "*subsi3_carry_zext_0"
8990   [(set (match_operand:DI 0 "register_operand" "=r")
8991         (zero_extend:DI
8992           (minus:SI
8993             (match_operand:SI 1 "register_operand" "0")
8994             (match_operator:SI 2 "ix86_carry_flag_operator"
8995               [(reg FLAGS_REG) (const_int 0)]))))
8996    (clobber (reg:CC FLAGS_REG))]
8997   "TARGET_64BIT"
8998   "sbb{l}\t{$0, %k0|%k0, 0}"
8999   [(set_attr "type" "alu")
9000    (set_attr "use_carry" "1")
9001    (set_attr "pent_pair" "pu")
9002    (set_attr "mode" "SI")])
9004 (define_insn "*subsi3_carry_zext_0r"
9005   [(set (match_operand:DI 0 "register_operand" "=r")
9006         (zero_extend:DI
9007           (minus:SI
9008             (match_operand:SI 1 "register_operand" "0")
9009             (match_operator:SI 2 "ix86_carry_flag_unset_operator"
9010               [(reg FLAGS_REG) (const_int 0)]))))
9011    (clobber (reg:CC FLAGS_REG))]
9012   "TARGET_64BIT"
9013   "adc{l}\t{$-1, %k0|%k0, -1}"
9014   [(set_attr "type" "alu")
9015    (set_attr "use_carry" "1")
9016    (set_attr "pent_pair" "pu")
9017    (set_attr "mode" "SI")])
9019 (define_insn "@sub<mode>3_carry_ccc"
9020   [(set (reg:CCC FLAGS_REG)
9021         (compare:CCC
9022           (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
9023           (plus:<DWI>
9024             (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
9025             (zero_extend:<DWI>
9026               (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
9027    (clobber (match_scratch:DWIH 0 "=r"))]
9028   ""
9029   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
9030   [(set_attr "type" "alu")
9031    (set_attr "mode" "<MODE>")])
9033 (define_insn "*sub<mode>3_carry_ccc_1"
9034   [(set (reg:CCC FLAGS_REG)
9035         (compare:CCC
9036           (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
9037           (plus:<DWI>
9038             (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
9039             (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
9040    (clobber (match_scratch:DWIH 0 "=r"))]
9041   ""
9043   operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
9044   return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
9046   [(set_attr "type" "alu")
9047    (set_attr "mode" "<MODE>")])
9049 ;; The sign flag is set from the
9050 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
9051 ;; result, the overflow flag likewise, but the overflow flag is also
9052 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
9053 (define_insn "@sub<mode>3_carry_ccgz"
9054   [(set (reg:CCGZ FLAGS_REG)
9055         (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
9056                       (match_operand:DWIH 2 "x86_64_general_operand" "rBMe")
9057                       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
9058                      UNSPEC_SBB))
9059    (clobber (match_scratch:DWIH 0 "=r"))]
9060   ""
9061   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
9062   [(set_attr "type" "alu")
9063    (set_attr "mode" "<MODE>")])
9065 (define_insn "subborrow<mode>"
9066   [(set (reg:CCC FLAGS_REG)
9067         (compare:CCC
9068           (zero_extend:<DWI>
9069             (match_operand:SWI48 1 "nonimmediate_operand" "0,0,r,rm"))
9070           (plus:<DWI>
9071             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
9072               [(match_operand 3 "flags_reg_operand") (const_int 0)])
9073             (zero_extend:<DWI>
9074               (match_operand:SWI48 2 "nonimmediate_operand" "r,rm,rm,r")))))
9075    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
9076         (minus:SWI48 (minus:SWI48
9077                        (match_dup 1)
9078                        (match_operator:SWI48 5 "ix86_carry_flag_operator"
9079                          [(match_dup 3) (const_int 0)]))
9080                      (match_dup 2)))]
9081   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
9082   "@
9083   sbb{<imodesuffix>}\t{%2, %0|%0, %2}
9084   sbb{<imodesuffix>}\t{%2, %0|%0, %2}
9085   sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9086   sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9087   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
9088    (set_attr "type" "alu")
9089    (set_attr "use_carry" "1")
9090    (set_attr "pent_pair" "pu")
9091    (set_attr "mode" "<MODE>")])
9093 (define_peephole2
9094   [(set (match_operand:SWI48 0 "general_reg_operand")
9095         (match_operand:SWI48 1 "memory_operand"))
9096    (parallel [(set (reg:CCC FLAGS_REG)
9097                    (compare:CCC
9098                      (zero_extend:<DWI> (match_dup 0))
9099                      (plus:<DWI>
9100                        (match_operator:<DWI> 4 "ix86_carry_flag_operator"
9101                          [(match_operand 3 "flags_reg_operand") (const_int 0)])
9102                        (zero_extend:<DWI>
9103                          (match_operand:SWI48 2 "memory_operand")))))
9104               (set (match_dup 0)
9105                    (minus:SWI48
9106                      (minus:SWI48
9107                        (match_dup 0)
9108                        (match_operator:SWI48 5 "ix86_carry_flag_operator"
9109                          [(match_dup 3) (const_int 0)]))
9110                      (match_dup 2)))])
9111    (set (match_dup 1) (match_dup 0))]
9112   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9113    && peep2_reg_dead_p (3, operands[0])
9114    && !reg_overlap_mentioned_p (operands[0], operands[1])
9115    && !reg_overlap_mentioned_p (operands[0], operands[2])"
9116   [(set (match_dup 0) (match_dup 2))
9117    (parallel [(set (reg:CCC FLAGS_REG)
9118                    (compare:CCC
9119                      (zero_extend:<DWI> (match_dup 1))
9120                      (plus:<DWI> (match_op_dup 4
9121                                    [(match_dup 3) (const_int 0)])
9122                                  (zero_extend:<DWI> (match_dup 0)))))
9123               (set (match_dup 1)
9124                    (minus:SWI48 (minus:SWI48 (match_dup 1)
9125                                              (match_op_dup 5
9126                                                [(match_dup 3) (const_int 0)]))
9127                                 (match_dup 0)))])])
9129 (define_peephole2
9130   [(set (match_operand:SWI48 6 "general_reg_operand")
9131         (match_operand:SWI48 7 "memory_operand"))
9132    (set (match_operand:SWI48 8 "general_reg_operand")
9133         (match_operand:SWI48 9 "memory_operand"))
9134    (parallel [(set (reg:CCC FLAGS_REG)
9135                    (compare:CCC
9136                      (zero_extend:<DWI>
9137                        (match_operand:SWI48 0 "general_reg_operand"))
9138                      (plus:<DWI>
9139                        (match_operator:<DWI> 4 "ix86_carry_flag_operator"
9140                          [(match_operand 3 "flags_reg_operand") (const_int 0)])
9141                        (zero_extend:<DWI>
9142                          (match_operand:SWI48 2 "general_reg_operand")))))
9143               (set (match_dup 0)
9144                    (minus:SWI48
9145                      (minus:SWI48
9146                        (match_dup 0)
9147                        (match_operator:SWI48 5 "ix86_carry_flag_operator"
9148                          [(match_dup 3) (const_int 0)]))
9149                      (match_dup 2)))])
9150    (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
9151   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9152    && peep2_reg_dead_p (4, operands[0])
9153    && peep2_reg_dead_p (3, operands[2])
9154    && !reg_overlap_mentioned_p (operands[0], operands[1])
9155    && !reg_overlap_mentioned_p (operands[2], operands[1])
9156    && !reg_overlap_mentioned_p (operands[6], operands[9])
9157    && (rtx_equal_p (operands[6], operands[0])
9158        ? (rtx_equal_p (operands[7], operands[1])
9159           && rtx_equal_p (operands[8], operands[2]))
9160        : (rtx_equal_p (operands[8], operands[0])
9161           && rtx_equal_p (operands[9], operands[1])
9162           && rtx_equal_p (operands[6], operands[2])))"
9163   [(set (match_dup 0) (match_dup 9))
9164    (parallel [(set (reg:CCC FLAGS_REG)
9165                    (compare:CCC
9166                      (zero_extend:<DWI> (match_dup 1))
9167                      (plus:<DWI> (match_op_dup 4
9168                                    [(match_dup 3) (const_int 0)])
9169                                  (zero_extend:<DWI> (match_dup 0)))))
9170               (set (match_dup 1)
9171                    (minus:SWI48 (minus:SWI48 (match_dup 1)
9172                                              (match_op_dup 5
9173                                                [(match_dup 3) (const_int 0)]))
9174                                 (match_dup 0)))])]
9176   if (!rtx_equal_p (operands[6], operands[0]))
9177     operands[9] = operands[7];
9180 (define_peephole2
9181   [(set (match_operand:SWI48 6 "general_reg_operand")
9182         (match_operand:SWI48 7 "memory_operand"))
9183    (set (match_operand:SWI48 8 "general_reg_operand")
9184         (match_operand:SWI48 9 "memory_operand"))
9185    (parallel [(set (reg:CCC FLAGS_REG)
9186                    (compare:CCC
9187                      (zero_extend:<DWI>
9188                        (match_operand:SWI48 0 "general_reg_operand"))
9189                      (plus:<DWI>
9190                        (match_operator:<DWI> 4 "ix86_carry_flag_operator"
9191                          [(match_operand 3 "flags_reg_operand") (const_int 0)])
9192                        (zero_extend:<DWI>
9193                          (match_operand:SWI48 2 "general_reg_operand")))))
9194               (set (match_dup 0)
9195                    (minus:SWI48
9196                      (minus:SWI48
9197                        (match_dup 0)
9198                        (match_operator:SWI48 5 "ix86_carry_flag_operator"
9199                          [(match_dup 3) (const_int 0)]))
9200                      (match_dup 2)))])
9201    (set (match_operand:QI 10 "general_reg_operand")
9202         (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
9203    (set (match_operand:SWI48 11 "general_reg_operand")
9204         (zero_extend:SWI48 (match_dup 10)))
9205    (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
9206   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9207    && peep2_reg_dead_p (6, operands[0])
9208    && peep2_reg_dead_p (3, operands[2])
9209    && !reg_overlap_mentioned_p (operands[0], operands[1])
9210    && !reg_overlap_mentioned_p (operands[2], operands[1])
9211    && !reg_overlap_mentioned_p (operands[6], operands[9])
9212    && !reg_overlap_mentioned_p (operands[0], operands[10])
9213    && !reg_overlap_mentioned_p (operands[10], operands[1])
9214    && !reg_overlap_mentioned_p (operands[0], operands[11])
9215    && !reg_overlap_mentioned_p (operands[11], operands[1])
9216    && (rtx_equal_p (operands[6], operands[0])
9217        ? (rtx_equal_p (operands[7], operands[1])
9218           && rtx_equal_p (operands[8], operands[2]))
9219        : (rtx_equal_p (operands[8], operands[0])
9220           && rtx_equal_p (operands[9], operands[1])
9221           && rtx_equal_p (operands[6], operands[2])))"
9222   [(set (match_dup 0) (match_dup 9))
9223    (parallel [(set (reg:CCC FLAGS_REG)
9224                    (compare:CCC
9225                      (zero_extend:<DWI> (match_dup 1))
9226                      (plus:<DWI> (match_op_dup 4
9227                                    [(match_dup 3) (const_int 0)])
9228                                  (zero_extend:<DWI> (match_dup 0)))))
9229               (set (match_dup 1)
9230                    (minus:SWI48 (minus:SWI48 (match_dup 1)
9231                                              (match_op_dup 5
9232                                                [(match_dup 3) (const_int 0)]))
9233                                 (match_dup 0)))])
9234    (set (match_dup 10) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
9235    (set (match_dup 11) (zero_extend:SWI48 (match_dup 10)))]
9237   if (!rtx_equal_p (operands[6], operands[0]))
9238     operands[9] = operands[7];
9241 (define_expand "subborrow<mode>_0"
9242   [(parallel
9243      [(set (reg:CC FLAGS_REG)
9244            (compare:CC
9245              (match_operand:SWI48 1 "nonimmediate_operand")
9246              (match_operand:SWI48 2 "<general_operand>")))
9247       (set (match_operand:SWI48 0 "register_operand")
9248            (minus:SWI48 (match_dup 1) (match_dup 2)))])]
9249   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)")
9251 (define_expand "uaddc<mode>5"
9252   [(match_operand:SWI48 0 "register_operand")
9253    (match_operand:SWI48 1 "register_operand")
9254    (match_operand:SWI48 2 "register_operand")
9255    (match_operand:SWI48 3 "register_operand")
9256    (match_operand:SWI48 4 "nonmemory_operand")]
9257   ""
9259   rtx cf = gen_rtx_REG (CCCmode, FLAGS_REG), pat, pat2;
9260   if (operands[4] == const0_rtx)
9261     emit_insn (gen_addcarry<mode>_0 (operands[0], operands[2], operands[3]));
9262   else
9263     {
9264       ix86_expand_carry (operands[4]);
9265       pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
9266       pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
9267       emit_insn (gen_addcarry<mode> (operands[0], operands[2], operands[3],
9268                                      cf, pat, pat2));
9269     }
9270   rtx cc = gen_reg_rtx (QImode);
9271   pat = gen_rtx_LTU (QImode, cf, const0_rtx);
9272   emit_insn (gen_rtx_SET (cc, pat));
9273   emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
9274   DONE;
9277 (define_expand "usubc<mode>5"
9278   [(match_operand:SWI48 0 "register_operand")
9279    (match_operand:SWI48 1 "register_operand")
9280    (match_operand:SWI48 2 "register_operand")
9281    (match_operand:SWI48 3 "register_operand")
9282    (match_operand:SWI48 4 "nonmemory_operand")]
9283   ""
9285   rtx cf, pat, pat2;
9286   if (operands[4] == const0_rtx)
9287     {
9288       cf = gen_rtx_REG (CCmode, FLAGS_REG);
9289       emit_insn (gen_subborrow<mode>_0 (operands[0], operands[2],
9290                                         operands[3]));
9291     }
9292   else
9293     {
9294       cf = gen_rtx_REG (CCCmode, FLAGS_REG);
9295       ix86_expand_carry (operands[4]);
9296       pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
9297       pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
9298       emit_insn (gen_subborrow<mode> (operands[0], operands[2], operands[3],
9299                                       cf, pat, pat2));
9300     }
9301   rtx cc = gen_reg_rtx (QImode);
9302   pat = gen_rtx_LTU (QImode, cf, const0_rtx);
9303   emit_insn (gen_rtx_SET (cc, pat));
9304   emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
9305   DONE;
9308 (define_mode_iterator CC_CCC [CC CCC])
9310 ;; Pre-reload splitter to optimize
9311 ;; *setcc_qi followed by *addqi3_cconly_overflow_1 with the same QI
9312 ;; operand and no intervening flags modifications into nothing.
9313 (define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1_<mode>"
9314   [(set (reg:CCC FLAGS_REG)
9315         (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
9316                      (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))))]
9317   "ix86_pre_reload_split ()"
9318   "#"
9319   "&& 1"
9320   [(const_int 0)]
9321   "emit_note (NOTE_INSN_DELETED); DONE;")
9323 ;; Set the carry flag from the carry flag.
9324 (define_insn_and_split "*setccc"
9325   [(set (reg:CCC FLAGS_REG)
9326         (reg:CCC FLAGS_REG))]
9327   "ix86_pre_reload_split ()"
9328   "#"
9329   "&& 1"
9330   [(const_int 0)]
9331   "emit_note (NOTE_INSN_DELETED); DONE;")
9333 ;; Set the carry flag from the carry flag.
9334 (define_insn_and_split "*setcc_qi_negqi_ccc_1_<mode>"
9335   [(set (reg:CCC FLAGS_REG)
9336         (ltu:CCC (reg:CC_CCC FLAGS_REG) (const_int 0)))]
9337   "ix86_pre_reload_split ()"
9338   "#"
9339   "&& 1"
9340   [(const_int 0)]
9341   "emit_note (NOTE_INSN_DELETED); DONE;")
9343 ;; Set the carry flag from the carry flag.
9344 (define_insn_and_split "*setcc_qi_negqi_ccc_2_<mode>"
9345   [(set (reg:CCC FLAGS_REG)
9346         (unspec:CCC [(ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
9347                      (const_int 0)] UNSPEC_CC_NE))]
9348   "ix86_pre_reload_split ()"
9349   "#"
9350   "&& 1"
9351   [(const_int 0)]
9352   "emit_note (NOTE_INSN_DELETED); DONE;")
9354 ;; Overflow setting add instructions
9356 (define_expand "addqi3_cconly_overflow"
9357   [(parallel
9358      [(set (reg:CCC FLAGS_REG)
9359            (compare:CCC
9360              (plus:QI
9361                (match_operand:QI 0 "nonimmediate_operand")
9362                (match_operand:QI 1 "general_operand"))
9363              (match_dup 0)))
9364       (clobber (scratch:QI))])]
9365   "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
9367 (define_insn "*add<mode>3_cconly_overflow_1"
9368   [(set (reg:CCC FLAGS_REG)
9369         (compare:CCC
9370           (plus:SWI
9371             (match_operand:SWI 1 "nonimmediate_operand" "%0,r,rm")
9372             (match_operand:SWI 2 "<general_operand>" "<g>,<g>,re"))
9373           (match_dup 1)))
9374    (clobber (match_scratch:SWI 0 "=<r>,r,r"))]
9375   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9376   "@
9377   add{<imodesuffix>}\t{%2, %0|%0, %2}
9378   add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9379   add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9380   [(set_attr "isa" "*,apx_ndd,apx_ndd")
9381    (set_attr "type" "alu")
9382    (set_attr "mode" "<MODE>")])
9384 (define_insn "@add<mode>3_cc_overflow_1"
9385   [(set (reg:CCC FLAGS_REG)
9386         (compare:CCC
9387             (plus:SWI
9388                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,rjM,r")
9389                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r,<i>,<m>"))
9390             (match_dup 1)))
9391    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r,r")
9392         (plus:SWI (match_dup 1) (match_dup 2)))]
9393   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
9394   "@
9395    add{<imodesuffix>}\t{%2, %0|%0, %2}
9396    add{<imodesuffix>}\t{%2, %0|%0, %2}
9397    add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9398    add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9399    add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9400   [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd")
9401    (set_attr "type" "alu")
9402    (set_attr "mode" "<MODE>")])
9404 (define_peephole2
9405   [(parallel [(set (reg:CCC FLAGS_REG)
9406                    (compare:CCC
9407                      (plus:SWI (match_operand:SWI 0 "general_reg_operand")
9408                                (match_operand:SWI 1 "memory_operand"))
9409                      (match_dup 0)))
9410               (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 1)))])
9411    (set (match_dup 1) (match_dup 0))]
9412   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9413    && peep2_reg_dead_p (2, operands[0])
9414    && !reg_overlap_mentioned_p (operands[0], operands[1])"
9415   [(parallel [(set (reg:CCC FLAGS_REG)
9416                    (compare:CCC
9417                      (plus:SWI (match_dup 1) (match_dup 0))
9418                      (match_dup 1)))
9419               (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
9421 (define_peephole2
9422   [(set (match_operand:SWI 0 "general_reg_operand")
9423         (match_operand:SWI 1 "memory_operand"))
9424    (parallel [(set (reg:CCC FLAGS_REG)
9425                    (compare:CCC
9426                      (plus:SWI (match_dup 0)
9427                                (match_operand:SWI 2 "memory_operand"))
9428                      (match_dup 0)))
9429               (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 2)))])
9430    (set (match_dup 1) (match_dup 0))]
9431   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9432    && peep2_reg_dead_p (3, operands[0])
9433    && !reg_overlap_mentioned_p (operands[0], operands[1])
9434    && !reg_overlap_mentioned_p (operands[0], operands[2])"
9435   [(set (match_dup 0) (match_dup 2))
9436    (parallel [(set (reg:CCC FLAGS_REG)
9437                    (compare:CCC
9438                      (plus:SWI (match_dup 1) (match_dup 0))
9439                      (match_dup 1)))
9440               (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
9442 (define_insn "*addsi3_zext_cc_overflow_1"
9443   [(set (reg:CCC FLAGS_REG)
9444         (compare:CCC
9445           (plus:SI
9446             (match_operand:SI 1 "nonimmediate_operand" "%0,r,rm")
9447             (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))
9448           (match_dup 1)))
9449    (set (match_operand:DI 0 "register_operand" "=r,r,r")
9450         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9451   "TARGET_64BIT
9452    && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
9453   "@
9454   add{l}\t{%2, %k0|%k0, %2}
9455   add{l}\t{%2, %1, %k0|%k0, %1, %2}
9456   add{l}\t{%2, %1, %k0|%k0, %1, %2}"
9457   [(set_attr "isa" "*,apx_ndd,apx_ndd")
9458    (set_attr "type" "alu")
9459    (set_attr "mode" "SI")])
9461 (define_insn "*add<mode>3_cconly_overflow_2"
9462   [(set (reg:CCC FLAGS_REG)
9463         (compare:CCC
9464           (plus:SWI
9465             (match_operand:SWI 1 "nonimmediate_operand" "%0,r,rm")
9466             (match_operand:SWI 2 "<general_operand>" "<g>,<g>,re"))
9467           (match_dup 2)))
9468    (clobber (match_scratch:SWI 0 "=<r>,r,r"))]
9469   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9470   "@
9471   add{<imodesuffix>}\t{%2, %0|%0, %2}
9472   add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9473   add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9474   [(set_attr "isa" "*,apx_ndd,apx_ndd")
9475    (set_attr "type" "alu")
9476    (set_attr "mode" "<MODE>")])
9478 (define_insn "*add<mode>3_cc_overflow_2"
9479   [(set (reg:CCC FLAGS_REG)
9480         (compare:CCC
9481             (plus:SWI
9482                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r")
9483                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>"))
9484             (match_dup 2)))
9485    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
9486         (plus:SWI (match_dup 1) (match_dup 2)))]
9487   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
9488   "@
9489   add{<imodesuffix>}\t{%2, %0|%0, %2}
9490   add{<imodesuffix>}\t{%2, %0|%0, %2}
9491   add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9492   add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9493   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
9494    (set_attr "type" "alu")
9495    (set_attr "mode" "<MODE>")])
9497 (define_insn "*addsi3_zext_cc_overflow_2"
9498   [(set (reg:CCC FLAGS_REG)
9499         (compare:CCC
9500           (plus:SI
9501             (match_operand:SI 1 "nonimmediate_operand" "%0,r,rm")
9502             (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))
9503           (match_dup 2)))
9504    (set (match_operand:DI 0 "register_operand" "=r,r,r")
9505         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9506   "TARGET_64BIT
9507    && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
9508   "@
9509   add{l}\t{%2, %k0|%k0, %2}
9510   add{l}\t{%2, %1, %k0|%k0, %1, %2}
9511   add{l}\t{%2, %1, %k0|%k0, %1, %2}"
9512   [(set_attr "isa" "*,apx_ndd,apx_ndd")
9513    (set_attr "type" "alu")
9514    (set_attr "mode" "SI")])
9516 (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
9517   [(set (reg:CCC FLAGS_REG)
9518         (compare:CCC
9519           (plus:<DWI>
9520             (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r,ro,jO,r")
9521             (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r,<di>,K,<di>,o"))
9522           (match_dup 1)))
9523    (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r,&r,&r,&r")
9524         (plus:<DWI> (match_dup 1) (match_dup 2)))]
9525   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands, TARGET_APX_NDD)"
9526   "#"
9527   "&& reload_completed"
9528   [(parallel [(set (reg:CCC FLAGS_REG)
9529                    (compare:CCC
9530                      (plus:DWIH (match_dup 1) (match_dup 2))
9531                      (match_dup 1)))
9532               (set (match_dup 0)
9533                    (plus:DWIH (match_dup 1) (match_dup 2)))])
9534    (parallel [(set (reg:CCC FLAGS_REG)
9535                    (compare:CCC
9536                      (zero_extend:<DWI>
9537                        (plus:DWIH
9538                          (plus:DWIH
9539                            (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9540                            (match_dup 4))
9541                          (match_dup 5)))
9542                      (plus:<DWI>
9543                        (match_dup 6)
9544                        (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))))
9545               (set (match_dup 3)
9546                    (plus:DWIH
9547                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9548                                 (match_dup 4))
9549                      (match_dup 5)))])]
9551   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
9552   if (operands[2] == const0_rtx)
9553     {
9554       if (!rtx_equal_p (operands[0], operands[1]))
9555         emit_move_insn (operands[0], operands[1]);
9556       emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
9557       DONE;
9558     }
9559   if (CONST_INT_P (operands[5]))
9560     operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode,
9561                                             operands[5], <MODE>mode);
9562   else
9563     operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
9565 [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd_64,apx_ndd")])
9567 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
9568 ;; test, where the latter is preferrable if we have some carry consuming
9569 ;; instruction.
9570 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
9571 ;; + (1 - CF).
9572 (define_insn_and_split "*add<mode>3_eq"
9573   [(set (match_operand:SWI 0 "nonimmediate_operand")
9574         (plus:SWI
9575           (plus:SWI
9576             (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9577             (match_operand:SWI 1 "nonimmediate_operand"))
9578           (match_operand:SWI 2 "<general_operand>")))
9579    (clobber (reg:CC FLAGS_REG))]
9580   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
9581    && ix86_pre_reload_split ()"
9582   "#"
9583   "&& 1"
9584   [(set (reg:CC FLAGS_REG)
9585         (compare:CC (match_dup 3) (const_int 1)))
9586    (parallel [(set (match_dup 0)
9587                    (plus:SWI
9588                      (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9589                                (match_dup 1))
9590                      (match_dup 2)))
9591               (clobber (reg:CC FLAGS_REG))])])
9593 (define_insn_and_split "*add<mode>3_ne"
9594   [(set (match_operand:SWI 0 "nonimmediate_operand")
9595         (plus:SWI
9596           (plus:SWI
9597             (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9598             (match_operand:SWI 1 "nonimmediate_operand"))
9599           (match_operand:SWI 2 "<immediate_operand>")))
9600    (clobber (reg:CC FLAGS_REG))]
9601   "CONST_INT_P (operands[2])
9602    && (<MODE>mode != DImode
9603        || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9604    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
9605    && ix86_pre_reload_split ()"
9606   "#"
9607   "&& 1"
9608   [(set (reg:CC FLAGS_REG)
9609         (compare:CC (match_dup 3) (const_int 1)))
9610    (parallel [(set (match_dup 0)
9611                    (minus:SWI
9612                      (minus:SWI (match_dup 1)
9613                                 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9614                      (match_dup 2)))
9615               (clobber (reg:CC FLAGS_REG))])]
9617   operands[2] = gen_int_mode (~INTVAL (operands[2]),
9618                               <MODE>mode == DImode ? SImode : <MODE>mode);
9621 (define_insn_and_split "*add<mode>3_eq_0"
9622   [(set (match_operand:SWI 0 "nonimmediate_operand")
9623         (plus:SWI
9624           (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9625           (match_operand:SWI 1 "<general_operand>")))
9626    (clobber (reg:CC FLAGS_REG))]
9627   "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9628    && ix86_pre_reload_split ()"
9629   "#"
9630   "&& 1"
9631   [(set (reg:CC FLAGS_REG)
9632         (compare:CC (match_dup 2) (const_int 1)))
9633    (parallel [(set (match_dup 0)
9634                    (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9635                              (match_dup 1)))
9636               (clobber (reg:CC FLAGS_REG))])]
9638   if (!nonimmediate_operand (operands[1], <MODE>mode))
9639     operands[1] = force_reg (<MODE>mode, operands[1]);
9642 (define_insn_and_split "*add<mode>3_ne_0"
9643   [(set (match_operand:SWI 0 "nonimmediate_operand")
9644         (plus:SWI
9645           (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9646           (match_operand:SWI 1 "<general_operand>")))
9647    (clobber (reg:CC FLAGS_REG))]
9648   "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9649    && ix86_pre_reload_split ()"
9650   "#"
9651   "&& 1"
9652   [(set (reg:CC FLAGS_REG)
9653         (compare:CC (match_dup 2) (const_int 1)))
9654    (parallel [(set (match_dup 0)
9655                    (minus:SWI (minus:SWI
9656                                 (match_dup 1)
9657                                 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9658                               (const_int -1)))
9659               (clobber (reg:CC FLAGS_REG))])]
9661   if (!nonimmediate_operand (operands[1], <MODE>mode))
9662     operands[1] = force_reg (<MODE>mode, operands[1]);
9665 (define_insn_and_split "*sub<mode>3_eq"
9666   [(set (match_operand:SWI 0 "nonimmediate_operand")
9667         (minus:SWI
9668           (minus:SWI
9669             (match_operand:SWI 1 "nonimmediate_operand")
9670             (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9671                     (const_int 0)))
9672           (match_operand:SWI 2 "<general_operand>")))
9673    (clobber (reg:CC FLAGS_REG))]
9674   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
9675    && ix86_pre_reload_split ()"
9676   "#"
9677   "&& 1"
9678   [(set (reg:CC FLAGS_REG)
9679         (compare:CC (match_dup 3) (const_int 1)))
9680    (parallel [(set (match_dup 0)
9681                    (minus:SWI
9682                      (minus:SWI (match_dup 1)
9683                                 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9684                      (match_dup 2)))
9685               (clobber (reg:CC FLAGS_REG))])])
9687 (define_insn_and_split "*sub<mode>3_ne"
9688   [(set (match_operand:SWI 0 "nonimmediate_operand")
9689         (plus:SWI
9690           (minus:SWI
9691             (match_operand:SWI 1 "nonimmediate_operand")
9692             (ne:SWI (match_operand 3 "int_nonimmediate_operand")
9693                     (const_int 0)))
9694           (match_operand:SWI 2 "<immediate_operand>")))
9695    (clobber (reg:CC FLAGS_REG))]
9696   "CONST_INT_P (operands[2])
9697    && (<MODE>mode != DImode
9698        || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9699    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
9700    && ix86_pre_reload_split ()"
9701   "#"
9702   "&& 1"
9703   [(set (reg:CC FLAGS_REG)
9704         (compare:CC (match_dup 3) (const_int 1)))
9705    (parallel [(set (match_dup 0)
9706                    (plus:SWI
9707                      (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9708                                (match_dup 1))
9709                      (match_dup 2)))
9710               (clobber (reg:CC FLAGS_REG))])]
9712   operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
9713                               <MODE>mode == DImode ? SImode : <MODE>mode);
9716 (define_insn_and_split "*sub<mode>3_eq_1"
9717   [(set (match_operand:SWI 0 "nonimmediate_operand")
9718         (plus:SWI
9719           (minus:SWI
9720             (match_operand:SWI 1 "nonimmediate_operand")
9721             (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9722                     (const_int 0)))
9723           (match_operand:SWI 2 "<immediate_operand>")))
9724    (clobber (reg:CC FLAGS_REG))]
9725   "CONST_INT_P (operands[2])
9726    && (<MODE>mode != DImode
9727        || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9728    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
9729    && ix86_pre_reload_split ()"
9730   "#"
9731   "&& 1"
9732   [(set (reg:CC FLAGS_REG)
9733         (compare:CC (match_dup 3) (const_int 1)))
9734    (parallel [(set (match_dup 0)
9735                    (minus:SWI
9736                      (minus:SWI (match_dup 1)
9737                                 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9738                      (match_dup 2)))
9739               (clobber (reg:CC FLAGS_REG))])]
9741   operands[2] = gen_int_mode (-INTVAL (operands[2]),
9742                               <MODE>mode == DImode ? SImode : <MODE>mode);
9745 (define_insn_and_split "*sub<mode>3_eq_0"
9746   [(set (match_operand:SWI 0 "nonimmediate_operand")
9747         (minus:SWI
9748           (match_operand:SWI 1 "<general_operand>")
9749           (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9750    (clobber (reg:CC FLAGS_REG))]
9751   "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9752    && ix86_pre_reload_split ()"
9753   "#"
9754   "&& 1"
9755   [(set (reg:CC FLAGS_REG)
9756         (compare:CC (match_dup 2) (const_int 1)))
9757    (parallel [(set (match_dup 0)
9758                    (minus:SWI (match_dup 1)
9759                               (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
9760               (clobber (reg:CC FLAGS_REG))])]
9762   if (!nonimmediate_operand (operands[1], <MODE>mode))
9763     operands[1] = force_reg (<MODE>mode, operands[1]);
9766 (define_insn_and_split "*sub<mode>3_ne_0"
9767   [(set (match_operand:SWI 0 "nonimmediate_operand")
9768         (minus:SWI
9769           (match_operand:SWI 1 "<general_operand>")
9770           (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9771    (clobber (reg:CC FLAGS_REG))]
9772   "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9773    && ix86_pre_reload_split ()"
9774   "#"
9775   "&& 1"
9776   [(set (reg:CC FLAGS_REG)
9777         (compare:CC (match_dup 2) (const_int 1)))
9778    (parallel [(set (match_dup 0)
9779                    (plus:SWI (plus:SWI
9780                                (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9781                                (match_dup 1))
9782                              (const_int -1)))
9783               (clobber (reg:CC FLAGS_REG))])]
9785   if (!nonimmediate_operand (operands[1], <MODE>mode))
9786     operands[1] = force_reg (<MODE>mode, operands[1]);
9789 ;; The patterns that match these are at the end of this file.
9791 (define_expand "<insn>xf3"
9792   [(set (match_operand:XF 0 "register_operand")
9793         (plusminus:XF
9794           (match_operand:XF 1 "register_operand")
9795           (match_operand:XF 2 "register_operand")))]
9796   "TARGET_80387")
9798 (define_expand "<insn>hf3"
9799   [(set (match_operand:HF 0 "register_operand")
9800         (plusminus:HF
9801           (match_operand:HF 1 "register_operand")
9802           (match_operand:HF 2 "nonimmediate_operand")))]
9803   "TARGET_AVX512FP16")
9805 (define_expand "<insn><mode>3"
9806   [(set (match_operand:MODEF 0 "register_operand")
9807         (plusminus:MODEF
9808           (match_operand:MODEF 1 "register_operand")
9809           (match_operand:MODEF 2 "nonimmediate_operand")))]
9810   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9811     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9813 ;; Multiply instructions
9815 (define_expand "mul<mode>3"
9816   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
9817                    (mult:SWIM248
9818                      (match_operand:SWIM248 1 "register_operand")
9819                      (match_operand:SWIM248 2 "<general_operand>")))
9820               (clobber (reg:CC FLAGS_REG))])])
9822 (define_expand "mulqi3"
9823   [(parallel [(set (match_operand:QI 0 "register_operand")
9824                    (mult:QI
9825                      (match_operand:QI 1 "register_operand")
9826                      (match_operand:QI 2 "nonimmediate_operand")))
9827               (clobber (reg:CC FLAGS_REG))])]
9828   "TARGET_QIMODE_MATH")
9830 ;; On AMDFAM10
9831 ;; IMUL reg32/64, reg32/64, imm8        Direct
9832 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
9833 ;; IMUL reg32/64, reg32/64, imm32       Direct
9834 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
9835 ;; IMUL reg32/64, reg32/64              Direct
9836 ;; IMUL reg32/64, mem32/64              Direct
9838 ;; On BDVER1, all above IMULs use DirectPath
9840 ;; On AMDFAM10
9841 ;; IMUL reg16, reg16, imm8      VectorPath
9842 ;; IMUL reg16, mem16, imm8      VectorPath
9843 ;; IMUL reg16, reg16, imm16     VectorPath
9844 ;; IMUL reg16, mem16, imm16     VectorPath
9845 ;; IMUL reg16, reg16            Direct
9846 ;; IMUL reg16, mem16            Direct
9848 ;; On BDVER1, all HI MULs use DoublePath
9850 (define_insn "*mul<mode>3_1"
9851   [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
9852         (mult:SWIM248
9853           (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
9854           (match_operand:SWIM248 2 "<general_operand>" "K,<i>,<m>r")))
9855    (clobber (reg:CC FLAGS_REG))]
9856   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9857   "@
9858    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9859    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9860    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9861   [(set_attr "type" "imul")
9862    (set_attr "prefix_0f" "0,0,1")
9863    (set (attr "athlon_decode")
9864         (cond [(eq_attr "cpu" "athlon")
9865                   (const_string "vector")
9866                (eq_attr "alternative" "1")
9867                   (const_string "vector")
9868                (and (eq_attr "alternative" "2")
9869                     (ior (match_test "<MODE>mode == HImode")
9870                          (match_operand 1 "memory_operand")))
9871                   (const_string "vector")]
9872               (const_string "direct")))
9873    (set (attr "amdfam10_decode")
9874         (cond [(and (eq_attr "alternative" "0,1")
9875                     (ior (match_test "<MODE>mode == HImode")
9876                          (match_operand 1 "memory_operand")))
9877                   (const_string "vector")]
9878               (const_string "direct")))
9879    (set (attr "bdver1_decode")
9880         (if_then_else
9881           (match_test "<MODE>mode == HImode")
9882             (const_string "double")
9883             (const_string "direct")))
9884    (set_attr "mode" "<MODE>")])
9886 (define_insn "*mulsi3_1_zext"
9887   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9888         (zero_extend:DI
9889           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
9890                    (match_operand:SI 2 "x86_64_general_operand" "K,e,BMr"))))
9891    (clobber (reg:CC FLAGS_REG))]
9892   "TARGET_64BIT
9893    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9894   "@
9895    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9896    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9897    imul{l}\t{%2, %k0|%k0, %2}"
9898   [(set_attr "type" "imul")
9899    (set_attr "prefix_0f" "0,0,1")
9900    (set (attr "athlon_decode")
9901         (cond [(eq_attr "cpu" "athlon")
9902                   (const_string "vector")
9903                (eq_attr "alternative" "1")
9904                   (const_string "vector")
9905                (and (eq_attr "alternative" "2")
9906                     (match_operand 1 "memory_operand"))
9907                   (const_string "vector")]
9908               (const_string "direct")))
9909    (set (attr "amdfam10_decode")
9910         (cond [(and (eq_attr "alternative" "0,1")
9911                     (match_operand 1 "memory_operand"))
9912                   (const_string "vector")]
9913               (const_string "direct")))
9914    (set_attr "bdver1_decode" "direct")
9915    (set_attr "mode" "SI")])
9917 ;;On AMDFAM10 and BDVER1
9918 ;; MUL reg8     Direct
9919 ;; MUL mem8     Direct
9921 (define_insn "*mulqi3_1"
9922   [(set (match_operand:QI 0 "register_operand" "=a")
9923         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9924                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
9925    (clobber (reg:CC FLAGS_REG))]
9926   "TARGET_QIMODE_MATH
9927    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9928   "mul{b}\t%2"
9929   [(set_attr "type" "imul")
9930    (set_attr "length_immediate" "0")
9931    (set (attr "athlon_decode")
9932      (if_then_else (eq_attr "cpu" "athlon")
9933         (const_string "vector")
9934         (const_string "direct")))
9935    (set_attr "amdfam10_decode" "direct")
9936    (set_attr "bdver1_decode" "direct")
9937    (set_attr "mode" "QI")])
9939 ;; Multiply with jump on overflow.
9940 (define_expand "mulv<mode>4"
9941   [(parallel [(set (reg:CCO FLAGS_REG)
9942                    (eq:CCO (mult:<DWI>
9943                               (sign_extend:<DWI>
9944                                  (match_operand:SWI248 1 "register_operand"))
9945                               (match_dup 4))
9946                            (sign_extend:<DWI>
9947                               (mult:SWI248 (match_dup 1)
9948                                            (match_operand:SWI248 2
9949                                               "<general_operand>")))))
9950               (set (match_operand:SWI248 0 "register_operand")
9951                    (mult:SWI248 (match_dup 1) (match_dup 2)))])
9952    (set (pc) (if_then_else
9953                (eq (reg:CCO FLAGS_REG) (const_int 0))
9954                (label_ref (match_operand 3))
9955                (pc)))]
9956   ""
9958   if (CONST_INT_P (operands[2]))
9959     operands[4] = operands[2];
9960   else
9961     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
9964 (define_insn "*mulv<mode>4"
9965   [(set (reg:CCO FLAGS_REG)
9966         (eq:CCO (mult:<DWI>
9967                    (sign_extend:<DWI>
9968                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
9969                    (sign_extend:<DWI>
9970                       (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
9971                 (sign_extend:<DWI>
9972                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
9973    (set (match_operand:SWI48 0 "register_operand" "=r,r")
9974         (mult:SWI48 (match_dup 1) (match_dup 2)))]
9975   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9976   "@
9977    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9978    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9979   [(set_attr "type" "imul")
9980    (set_attr "prefix_0f" "0,1")
9981    (set (attr "athlon_decode")
9982         (cond [(eq_attr "cpu" "athlon")
9983                   (const_string "vector")
9984                (eq_attr "alternative" "0")
9985                   (const_string "vector")
9986                (and (eq_attr "alternative" "1")
9987                     (match_operand 1 "memory_operand"))
9988                   (const_string "vector")]
9989               (const_string "direct")))
9990    (set (attr "amdfam10_decode")
9991         (cond [(and (eq_attr "alternative" "1")
9992                     (match_operand 1 "memory_operand"))
9993                   (const_string "vector")]
9994               (const_string "direct")))
9995    (set_attr "bdver1_decode" "direct")
9996    (set_attr "mode" "<MODE>")])
9998 (define_insn "*mulvhi4"
9999   [(set (reg:CCO FLAGS_REG)
10000         (eq:CCO (mult:SI
10001                    (sign_extend:SI
10002                       (match_operand:HI 1 "nonimmediate_operand" "%0"))
10003                    (sign_extend:SI
10004                       (match_operand:HI 2 "nonimmediate_operand" "mr")))
10005                 (sign_extend:SI
10006                    (mult:HI (match_dup 1) (match_dup 2)))))
10007    (set (match_operand:HI 0 "register_operand" "=r")
10008         (mult:HI (match_dup 1) (match_dup 2)))]
10009   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
10010   "imul{w}\t{%2, %0|%0, %2}"
10011   [(set_attr "type" "imul")
10012    (set_attr "prefix_0f" "1")
10013    (set_attr "athlon_decode" "vector")
10014    (set_attr "amdfam10_decode" "direct")
10015    (set_attr "bdver1_decode" "double")
10016    (set_attr "mode" "HI")])
10018 (define_insn "*mulv<mode>4_1"
10019   [(set (reg:CCO FLAGS_REG)
10020         (eq:CCO (mult:<DWI>
10021                    (sign_extend:<DWI>
10022                       (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
10023                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
10024                 (sign_extend:<DWI>
10025                    (mult:SWI248 (match_dup 1)
10026                                 (match_operand:SWI248 2
10027                                    "<immediate_operand>" "K,<i>")))))
10028    (set (match_operand:SWI248 0 "register_operand" "=r,r")
10029         (mult:SWI248 (match_dup 1) (match_dup 2)))]
10030   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
10031    && CONST_INT_P (operands[2])
10032    && INTVAL (operands[2]) == INTVAL (operands[3])"
10033   "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
10034   [(set_attr "type" "imul")
10035    (set (attr "prefix_0f")
10036         (if_then_else
10037           (match_test "<MODE>mode == HImode")
10038             (const_string "0")
10039             (const_string "*")))
10040    (set (attr "athlon_decode")
10041         (cond [(eq_attr "cpu" "athlon")
10042                   (const_string "vector")
10043                (eq_attr "alternative" "1")
10044                   (const_string "vector")]
10045               (const_string "direct")))
10046    (set (attr "amdfam10_decode")
10047         (cond [(ior (match_test "<MODE>mode == HImode")
10048                     (match_operand 1 "memory_operand"))
10049                   (const_string "vector")]
10050               (const_string "direct")))
10051    (set (attr "bdver1_decode")
10052         (if_then_else
10053           (match_test "<MODE>mode == HImode")
10054             (const_string "double")
10055             (const_string "direct")))
10056    (set_attr "mode" "<MODE>")
10057    (set (attr "length_immediate")
10058         (cond [(eq_attr "alternative" "0")
10059                   (const_string "1")
10060                (match_test "<MODE_SIZE> == 8")
10061                   (const_string "4")]
10062               (const_string "<MODE_SIZE>")))])
10064 (define_expand "umulv<mode>4"
10065   [(parallel [(set (reg:CCO FLAGS_REG)
10066                    (eq:CCO (mult:<DWI>
10067                               (zero_extend:<DWI>
10068                                  (match_operand:SWI248 1
10069                                                       "nonimmediate_operand"))
10070                               (zero_extend:<DWI>
10071                                  (match_operand:SWI248 2
10072                                                       "nonimmediate_operand")))
10073                            (zero_extend:<DWI>
10074                               (mult:SWI248 (match_dup 1) (match_dup 2)))))
10075               (set (match_operand:SWI248 0 "register_operand")
10076                    (mult:SWI248 (match_dup 1) (match_dup 2)))
10077               (clobber (scratch:SWI248))])
10078    (set (pc) (if_then_else
10079                (eq (reg:CCO FLAGS_REG) (const_int 0))
10080                (label_ref (match_operand 3))
10081                (pc)))]
10082   ""
10084   if (MEM_P (operands[1]) && MEM_P (operands[2]))
10085     operands[1] = force_reg (<MODE>mode, operands[1]);
10088 (define_insn "*umulv<mode>4"
10089   [(set (reg:CCO FLAGS_REG)
10090         (eq:CCO (mult:<DWI>
10091                    (zero_extend:<DWI>
10092                       (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
10093                    (zero_extend:<DWI>
10094                       (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
10095                 (zero_extend:<DWI>
10096                    (mult:SWI248 (match_dup 1) (match_dup 2)))))
10097    (set (match_operand:SWI248 0 "register_operand" "=a")
10098         (mult:SWI248 (match_dup 1) (match_dup 2)))
10099    (clobber (match_scratch:SWI248 3 "=d"))]
10100   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
10101   "mul{<imodesuffix>}\t%2"
10102   [(set_attr "type" "imul")
10103    (set_attr "length_immediate" "0")
10104    (set (attr "athlon_decode")
10105      (if_then_else (eq_attr "cpu" "athlon")
10106        (const_string "vector")
10107        (const_string "double")))
10108    (set_attr "amdfam10_decode" "double")
10109    (set_attr "bdver1_decode" "direct")
10110    (set_attr "mode" "<MODE>")])
10112 (define_expand "<u>mulvqi4"
10113   [(parallel [(set (reg:CCO FLAGS_REG)
10114                    (eq:CCO (mult:HI
10115                               (any_extend:HI
10116                                  (match_operand:QI 1 "nonimmediate_operand"))
10117                               (any_extend:HI
10118                                  (match_operand:QI 2 "nonimmediate_operand")))
10119                            (any_extend:HI
10120                               (mult:QI (match_dup 1) (match_dup 2)))))
10121               (set (match_operand:QI 0 "register_operand")
10122                    (mult:QI (match_dup 1) (match_dup 2)))])
10123    (set (pc) (if_then_else
10124                (eq (reg:CCO FLAGS_REG) (const_int 0))
10125                (label_ref (match_operand 3))
10126                (pc)))]
10127   "TARGET_QIMODE_MATH"
10129   if (MEM_P (operands[1]) && MEM_P (operands[2]))
10130     operands[1] = force_reg (QImode, operands[1]);
10133 (define_insn "*<u>mulvqi4"
10134   [(set (reg:CCO FLAGS_REG)
10135         (eq:CCO (mult:HI
10136                    (any_extend:HI
10137                       (match_operand:QI 1 "nonimmediate_operand" "%0"))
10138                    (any_extend:HI
10139                       (match_operand:QI 2 "nonimmediate_operand" "qm")))
10140                 (any_extend:HI
10141                    (mult:QI (match_dup 1) (match_dup 2)))))
10142    (set (match_operand:QI 0 "register_operand" "=a")
10143         (mult:QI (match_dup 1) (match_dup 2)))]
10144   "TARGET_QIMODE_MATH
10145    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10146   "<sgnprefix>mul{b}\t%2"
10147   [(set_attr "type" "imul")
10148    (set_attr "length_immediate" "0")
10149    (set (attr "athlon_decode")
10150      (if_then_else (eq_attr "cpu" "athlon")
10151         (const_string "vector")
10152         (const_string "direct")))
10153    (set_attr "amdfam10_decode" "direct")
10154    (set_attr "bdver1_decode" "direct")
10155    (set_attr "mode" "QI")])
10157 (define_expand "<u>mul<mode><dwi>3"
10158   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
10159                    (mult:<DWI>
10160                      (any_extend:<DWI>
10161                        (match_operand:DWIH 1 "register_operand"))
10162                      (any_extend:<DWI>
10163                        (match_operand:DWIH 2 "nonimmediate_operand"))))
10164               (clobber (reg:CC FLAGS_REG))])])
10166 (define_expand "<u>mulqihi3"
10167   [(parallel [(set (match_operand:HI 0 "register_operand")
10168                    (mult:HI
10169                      (any_extend:HI
10170                        (match_operand:QI 1 "register_operand"))
10171                      (any_extend:HI
10172                        (match_operand:QI 2 "nonimmediate_operand"))))
10173               (clobber (reg:CC FLAGS_REG))])]
10174   "TARGET_QIMODE_MATH")
10176 (define_insn "*bmi2_umul<mode><dwi>3_1"
10177   [(set (match_operand:DWIH 0 "register_operand" "=r")
10178         (mult:DWIH
10179           (match_operand:DWIH 2 "register_operand" "%d")
10180           (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
10181    (set (match_operand:DWIH 1 "register_operand" "=r")
10182         (umul_highpart:DWIH (match_dup 2) (match_dup 3)))]
10183   "TARGET_BMI2"
10184   "mulx\t{%3, %0, %1|%1, %0, %3}"
10185   [(set_attr "type" "imulx")
10186    (set_attr "prefix" "vex")
10187    (set_attr "mode" "<MODE>")])
10189 ;; Tweak *bmi2_umul<mode><dwi>3_1 to eliminate following mov.
10190 (define_peephole2
10191   [(parallel [(set (match_operand:DWIH 0 "general_reg_operand")
10192                    (mult:DWIH (match_operand:DWIH 2 "register_operand")
10193                               (match_operand:DWIH 3 "nonimmediate_operand")))
10194               (set (match_operand:DWIH 1 "general_reg_operand")
10195                    (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])
10196    (set (match_operand:DWIH 4 "general_reg_operand")
10197         (match_operand:DWIH 5 "general_reg_operand"))]
10198   "TARGET_BMI2
10199    && ((REGNO (operands[5]) == REGNO (operands[0])
10200         && REGNO (operands[1]) != REGNO (operands[4]))
10201        || (REGNO (operands[5]) == REGNO (operands[1])
10202            && REGNO (operands[0]) != REGNO (operands[4])))
10203    && peep2_reg_dead_p (2, operands[5])"
10204   [(parallel [(set (match_dup 0) (mult:DWIH (match_dup 2) (match_dup 3)))
10205               (set (match_dup 1)
10206                    (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])]
10208   if (REGNO (operands[5]) == REGNO (operands[0]))
10209     operands[0] = operands[4];
10210   else
10211     operands[1] = operands[4];
10214 (define_insn "*umul<mode><dwi>3_1"
10215   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
10216         (mult:<DWI>
10217           (zero_extend:<DWI>
10218             (match_operand:DWIH 1 "register_operand" "%d,a"))
10219           (zero_extend:<DWI>
10220             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
10221    (clobber (reg:CC FLAGS_REG))]
10222   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
10223   "@
10224    #
10225    mul{<imodesuffix>}\t%2"
10226   [(set_attr "isa" "bmi2,*")
10227    (set_attr "type" "imulx,imul")
10228    (set_attr "length_immediate" "*,0")
10229    (set (attr "athlon_decode")
10230         (cond [(eq_attr "alternative" "1")
10231                  (if_then_else (eq_attr "cpu" "athlon")
10232                    (const_string "vector")
10233                    (const_string "double"))]
10234               (const_string "*")))
10235    (set_attr "amdfam10_decode" "*,double")
10236    (set_attr "bdver1_decode" "*,direct")
10237    (set_attr "prefix" "vex,orig")
10238    (set_attr "mode" "<MODE>")])
10240 ;; Convert mul to the mulx pattern to avoid flags dependency.
10241 (define_split
10242  [(set (match_operand:<DWI> 0 "register_operand")
10243        (mult:<DWI>
10244          (zero_extend:<DWI>
10245            (match_operand:DWIH 1 "register_operand"))
10246          (zero_extend:<DWI>
10247            (match_operand:DWIH 2 "nonimmediate_operand"))))
10248   (clobber (reg:CC FLAGS_REG))]
10249  "TARGET_BMI2 && reload_completed
10250   && REGNO (operands[1]) == DX_REG"
10251   [(parallel [(set (match_dup 3)
10252                    (mult:DWIH (match_dup 1) (match_dup 2)))
10253               (set (match_dup 4)
10254                    (umul_highpart:DWIH (match_dup 1) (match_dup 2)))])]
10256   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
10258   operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10261 (define_insn "*mul<mode><dwi>3_1"
10262   [(set (match_operand:<DWI> 0 "register_operand" "=A")
10263         (mult:<DWI>
10264           (sign_extend:<DWI>
10265             (match_operand:DWIH 1 "register_operand" "%a"))
10266           (sign_extend:<DWI>
10267             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
10268    (clobber (reg:CC FLAGS_REG))]
10269   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
10270   "imul{<imodesuffix>}\t%2"
10271   [(set_attr "type" "imul")
10272    (set_attr "length_immediate" "0")
10273    (set (attr "athlon_decode")
10274      (if_then_else (eq_attr "cpu" "athlon")
10275         (const_string "vector")
10276         (const_string "double")))
10277    (set_attr "amdfam10_decode" "double")
10278    (set_attr "bdver1_decode" "direct")
10279    (set_attr "mode" "<MODE>")])
10281 (define_insn "*<u>mulqihi3_1"
10282   [(set (match_operand:HI 0 "register_operand" "=a")
10283         (mult:HI
10284           (any_extend:HI
10285             (match_operand:QI 1 "register_operand" "%0"))
10286           (any_extend:HI
10287             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
10288    (clobber (reg:CC FLAGS_REG))]
10289   "TARGET_QIMODE_MATH
10290    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10291   "<sgnprefix>mul{b}\t%2"
10292   [(set_attr "type" "imul")
10293    (set_attr "length_immediate" "0")
10294    (set (attr "athlon_decode")
10295      (if_then_else (eq_attr "cpu" "athlon")
10296         (const_string "vector")
10297         (const_string "direct")))
10298    (set_attr "amdfam10_decode" "direct")
10299    (set_attr "bdver1_decode" "direct")
10300    (set_attr "mode" "QI")])
10302 ;; Widening multiplication peephole2s to tweak register allocation.
10303 ;; mov imm,%rdx; mov %rdi,%rax; mulq %rdx  ->  mov imm,%rax; mulq %rdi
10304 (define_peephole2
10305   [(set (match_operand:DWIH 0 "general_reg_operand")
10306         (match_operand:DWIH 1 "immediate_operand"))
10307    (set (match_operand:DWIH 2 "general_reg_operand")
10308         (match_operand:DWIH 3 "general_reg_operand"))
10309    (parallel [(set (match_operand:<DWI> 4 "general_reg_operand")
10310                    (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
10311                                (zero_extend:<DWI> (match_dup 0))))
10312               (clobber (reg:CC FLAGS_REG))])]
10313   "REGNO (operands[3]) != AX_REG
10314    && REGNO (operands[0]) != REGNO (operands[2])
10315    && REGNO (operands[0]) != REGNO (operands[3])
10316    && (REGNO (operands[0]) == REGNO (operands[4])
10317        || REGNO (operands[0]) == DX_REG
10318        || peep2_reg_dead_p (3, operands[0]))"
10319   [(set (match_dup 2) (match_dup 1))
10320    (parallel [(set (match_dup 4)
10321                    (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
10322                                (zero_extend:<DWI> (match_dup 3))))
10323               (clobber (reg:CC FLAGS_REG))])])
10325 ;; mov imm,%rax; mov %rdi,%rdx; mulx %rax  ->  mov imm,%rdx; mulx %rdi
10326 (define_peephole2
10327   [(set (match_operand:DWIH 0 "general_reg_operand")
10328         (match_operand:DWIH 1 "immediate_operand"))
10329    (set (match_operand:DWIH 2 "general_reg_operand")
10330         (match_operand:DWIH 3 "general_reg_operand"))
10331    (parallel [(set (match_operand:DWIH 4 "general_reg_operand")
10332                    (mult:DWIH (match_dup 2) (match_dup 0)))
10333               (set (match_operand:DWIH 5 "general_reg_operand")
10334                    (umul_highpart:DWIH (match_dup 2) (match_dup 0)))])]
10335   "REGNO (operands[3]) != DX_REG
10336    && REGNO (operands[0]) != REGNO (operands[2])
10337    && REGNO (operands[0]) != REGNO (operands[3])
10338    && (REGNO (operands[0]) == REGNO (operands[4])
10339        || REGNO (operands[0]) == REGNO (operands[5])
10340        || peep2_reg_dead_p (3, operands[0]))
10341    && (REGNO (operands[2]) == REGNO (operands[4])
10342        || REGNO (operands[2]) == REGNO (operands[5])
10343        || peep2_reg_dead_p (3, operands[2]))"
10344   [(set (match_dup 2) (match_dup 1))
10345    (parallel [(set (match_dup 4)
10346                    (mult:DWIH (match_dup 2) (match_dup 3)))
10347               (set (match_dup 5)
10348                    (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])])
10350 ;; Highpart multiplication patterns
10351 (define_insn "<s>mul<mode>3_highpart"
10352   [(set (match_operand:DWIH 0 "register_operand" "=d")
10353         (any_mul_highpart:DWIH
10354           (match_operand:DWIH 1 "register_operand" "%a")
10355           (match_operand:DWIH 2 "nonimmediate_operand" "rm")))
10356    (clobber (match_scratch:DWIH 3 "=1"))
10357    (clobber (reg:CC FLAGS_REG))]
10358   ""
10359   "<sgnprefix>mul{<imodesuffix>}\t%2"
10360   [(set_attr "type" "imul")
10361    (set_attr "length_immediate" "0")
10362    (set (attr "athlon_decode")
10363      (if_then_else (eq_attr "cpu" "athlon")
10364         (const_string "vector")
10365         (const_string "double")))
10366    (set_attr "amdfam10_decode" "double")
10367    (set_attr "bdver1_decode" "direct")
10368    (set_attr "mode" "<MODE>")])
10370 (define_insn "*<s>mulsi3_highpart_zext"
10371   [(set (match_operand:DI 0 "register_operand" "=d")
10372         (zero_extend:DI 
10373           (any_mul_highpart:SI
10374             (match_operand:SI 1 "register_operand" "%a")
10375             (match_operand:SI 2 "nonimmediate_operand" "rm"))))
10376    (clobber (match_scratch:SI 3 "=1"))
10377    (clobber (reg:CC FLAGS_REG))]
10378   "TARGET_64BIT"
10379   "<sgnprefix>mul{l}\t%2"
10380   [(set_attr "type" "imul")
10381    (set_attr "length_immediate" "0")
10382    (set (attr "athlon_decode")
10383      (if_then_else (eq_attr "cpu" "athlon")
10384         (const_string "vector")
10385         (const_string "double")))
10386    (set_attr "amdfam10_decode" "double")
10387    (set_attr "bdver1_decode" "direct")
10388    (set_attr "mode" "SI")])
10390 (define_insn "*<s>muldi3_highpart_1"
10391   [(set (match_operand:DI 0 "register_operand" "=d")
10392         (truncate:DI
10393           (lshiftrt:TI
10394             (mult:TI
10395               (any_extend:TI
10396                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
10397               (any_extend:TI
10398                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
10399             (const_int 64))))
10400    (clobber (match_scratch:DI 3 "=1"))
10401    (clobber (reg:CC FLAGS_REG))]
10402   "TARGET_64BIT
10403    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10404   "<sgnprefix>mul{q}\t%2"
10405   [(set_attr "type" "imul")
10406    (set_attr "length_immediate" "0")
10407    (set (attr "athlon_decode")
10408      (if_then_else (eq_attr "cpu" "athlon")
10409         (const_string "vector")
10410         (const_string "double")))
10411    (set_attr "amdfam10_decode" "double")
10412    (set_attr "bdver1_decode" "direct")
10413    (set_attr "mode" "DI")])
10415 (define_insn "*<s>mulsi3_highpart_zext"
10416   [(set (match_operand:DI 0 "register_operand" "=d")
10417         (zero_extend:DI (truncate:SI
10418           (lshiftrt:DI
10419             (mult:DI (any_extend:DI
10420                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
10421                      (any_extend:DI
10422                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
10423             (const_int 32)))))
10424    (clobber (match_scratch:SI 3 "=1"))
10425    (clobber (reg:CC FLAGS_REG))]
10426   "TARGET_64BIT
10427    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10428   "<sgnprefix>mul{l}\t%2"
10429   [(set_attr "type" "imul")
10430    (set_attr "length_immediate" "0")
10431    (set (attr "athlon_decode")
10432      (if_then_else (eq_attr "cpu" "athlon")
10433         (const_string "vector")
10434         (const_string "double")))
10435    (set_attr "amdfam10_decode" "double")
10436    (set_attr "bdver1_decode" "direct")
10437    (set_attr "mode" "SI")])
10439 (define_insn "*<s>mulsi3_highpart_1"
10440   [(set (match_operand:SI 0 "register_operand" "=d")
10441         (truncate:SI
10442           (lshiftrt:DI
10443             (mult:DI
10444               (any_extend:DI
10445                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
10446               (any_extend:DI
10447                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
10448             (const_int 32))))
10449    (clobber (match_scratch:SI 3 "=1"))
10450    (clobber (reg:CC FLAGS_REG))]
10451   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
10452   "<sgnprefix>mul{l}\t%2"
10453   [(set_attr "type" "imul")
10454    (set_attr "length_immediate" "0")
10455    (set (attr "athlon_decode")
10456      (if_then_else (eq_attr "cpu" "athlon")
10457         (const_string "vector")
10458         (const_string "double")))
10459    (set_attr "amdfam10_decode" "double")
10460    (set_attr "bdver1_decode" "direct")
10461    (set_attr "mode" "SI")])
10463 ;; Highpart multiplication peephole2s to tweak register allocation.
10464 ;; mov imm,%rdx; mov %rdi,%rax; imulq %rdx  ->  mov imm,%rax; imulq %rdi
10465 (define_peephole2
10466   [(set (match_operand:SWI48 0 "general_reg_operand")
10467         (match_operand:SWI48 1 "immediate_operand"))
10468    (set (match_operand:SWI48 2 "general_reg_operand")
10469         (match_operand:SWI48 3 "general_reg_operand"))
10470    (parallel [(set (match_operand:SWI48 4 "general_reg_operand")
10471                    (any_mul_highpart:SWI48 (match_dup 2) (match_dup 0)))
10472               (clobber (match_dup 2))
10473               (clobber (reg:CC FLAGS_REG))])]
10474   "REGNO (operands[3]) != AX_REG
10475    && REGNO (operands[0]) != REGNO (operands[2])
10476    && REGNO (operands[0]) != REGNO (operands[3])
10477    && (REGNO (operands[0]) == REGNO (operands[4])
10478        || peep2_reg_dead_p (3, operands[0]))"
10479   [(set (match_dup 2) (match_dup 1))
10480    (parallel [(set (match_dup 4)
10481                    (any_mul_highpart:SWI48 (match_dup 2) (match_dup 3)))
10482               (clobber (match_dup 2))
10483               (clobber (reg:CC FLAGS_REG))])])
10485 (define_peephole2
10486   [(set (match_operand:SI 0 "general_reg_operand")
10487         (match_operand:SI 1 "immediate_operand"))
10488    (set (match_operand:SI 2 "general_reg_operand")
10489         (match_operand:SI 3 "general_reg_operand"))
10490    (parallel [(set (match_operand:DI 4 "general_reg_operand")
10491                    (zero_extend:DI
10492                      (any_mul_highpart:SI (match_dup 2) (match_dup 0))))
10493               (clobber (match_dup 2))
10494               (clobber (reg:CC FLAGS_REG))])]
10495   "TARGET_64BIT
10496    && REGNO (operands[3]) != AX_REG
10497    && REGNO (operands[0]) != REGNO (operands[2])
10498    && REGNO (operands[2]) != REGNO (operands[3])
10499    && REGNO (operands[0]) != REGNO (operands[3])
10500    && (REGNO (operands[0]) == REGNO (operands[4])
10501        || peep2_reg_dead_p (3, operands[0]))"
10502   [(set (match_dup 2) (match_dup 1))
10503    (parallel [(set (match_dup 4)
10504                    (zero_extend:DI
10505                      (any_mul_highpart:SI (match_dup 2) (match_dup 3))))
10506               (clobber (match_dup 2))
10507               (clobber (reg:CC FLAGS_REG))])])
10509 ;; The patterns that match these are at the end of this file.
10511 (define_expand "mulxf3"
10512   [(set (match_operand:XF 0 "register_operand")
10513         (mult:XF (match_operand:XF 1 "register_operand")
10514                  (match_operand:XF 2 "register_operand")))]
10515   "TARGET_80387")
10517 (define_expand "mulhf3"
10518   [(set (match_operand:HF 0 "register_operand")
10519         (mult:HF (match_operand:HF 1 "register_operand")
10520                     (match_operand:HF 2 "nonimmediate_operand")))]
10521   "TARGET_AVX512FP16")
10523 (define_expand "mul<mode>3"
10524   [(set (match_operand:MODEF 0 "register_operand")
10525         (mult:MODEF (match_operand:MODEF 1 "register_operand")
10526                     (match_operand:MODEF 2 "nonimmediate_operand")))]
10527   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
10528     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
10530 ;; Divide instructions
10532 ;; The patterns that match these are at the end of this file.
10534 (define_expand "divxf3"
10535   [(set (match_operand:XF 0 "register_operand")
10536         (div:XF (match_operand:XF 1 "register_operand")
10537                 (match_operand:XF 2 "register_operand")))]
10538   "TARGET_80387")
10540 /* There is no more precision loss than Newton-Rhapson approximation
10541   when using HFmode rcp/rsqrt, so do the transformation directly under
10542   TARGET_RECIP_DIV and fast-math.  */
10543 (define_expand "divhf3"
10544   [(set (match_operand:HF 0 "register_operand")
10545         (div:HF (match_operand:HF 1 "register_operand")
10546                    (match_operand:HF 2 "nonimmediate_operand")))]
10547   "TARGET_AVX512FP16"
10549   if (TARGET_RECIP_DIV
10550       && optimize_insn_for_speed_p ()
10551       && flag_finite_math_only && !flag_trapping_math
10552       && flag_unsafe_math_optimizations)
10553     {
10554       rtx op = gen_reg_rtx (HFmode);
10555       operands[2] = force_reg (HFmode, operands[2]);
10556       emit_insn (gen_rcphf2 (op, operands[2]));
10557       emit_insn (gen_mulhf3 (operands[0], operands[1], op));
10558       DONE;
10559     }
10562 (define_expand "div<mode>3"
10563   [(set (match_operand:MODEF 0 "register_operand")
10564         (div:MODEF (match_operand:MODEF 1 "register_operand")
10565                    (match_operand:MODEF 2 "nonimmediate_operand")))]
10566   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
10567     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10569   if (<MODE>mode == SFmode
10570       && TARGET_SSE && TARGET_SSE_MATH
10571       && TARGET_RECIP_DIV
10572       && optimize_insn_for_speed_p ()
10573       && flag_finite_math_only && !flag_trapping_math
10574       && flag_unsafe_math_optimizations)
10575     {
10576       ix86_emit_swdivsf (operands[0], operands[1],
10577                          operands[2], SFmode);
10578       DONE;
10579     }
10582 ;; Divmod instructions.
10584 (define_code_iterator any_div [div udiv])
10585 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
10587 (define_expand "<u>divmod<mode>4"
10588   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
10589                    (any_div:SWIM248
10590                      (match_operand:SWIM248 1 "register_operand")
10591                      (match_operand:SWIM248 2 "nonimmediate_operand")))
10592               (set (match_operand:SWIM248 3 "register_operand")
10593                    (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
10594               (clobber (reg:CC FLAGS_REG))])])
10596 ;; Split with 8bit unsigned divide:
10597 ;;      if (dividend an divisor are in [0-255])
10598 ;;         use 8bit unsigned integer divide
10599 ;;       else
10600 ;;         use original integer divide
10601 (define_split
10602   [(set (match_operand:SWI48 0 "register_operand")
10603         (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
10604                        (match_operand:SWI48 3 "nonimmediate_operand")))
10605    (set (match_operand:SWI48 1 "register_operand")
10606         (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
10607    (clobber (reg:CC FLAGS_REG))]
10608   "TARGET_USE_8BIT_IDIV
10609    && TARGET_QIMODE_MATH
10610    && can_create_pseudo_p ()
10611    && !optimize_insn_for_size_p ()"
10612   [(const_int 0)]
10613   "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
10615 (define_split
10616   [(set (match_operand:DI 0 "register_operand")
10617         (zero_extend:DI
10618           (any_div:SI (match_operand:SI 2 "register_operand")
10619                       (match_operand:SI 3 "nonimmediate_operand"))))
10620    (set (match_operand:SI 1 "register_operand")
10621         (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10622    (clobber (reg:CC FLAGS_REG))]
10623   "TARGET_64BIT
10624    && TARGET_USE_8BIT_IDIV
10625    && TARGET_QIMODE_MATH
10626    && can_create_pseudo_p ()
10627    && !optimize_insn_for_size_p ()"
10628   [(const_int 0)]
10629   "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10631 (define_split
10632   [(set (match_operand:DI 1 "register_operand")
10633         (zero_extend:DI
10634           (<paired_mod>:SI (match_operand:SI 2 "register_operand")
10635                            (match_operand:SI 3 "nonimmediate_operand"))))
10636    (set (match_operand:SI 0 "register_operand")
10637         (any_div:SI  (match_dup 2) (match_dup 3)))
10638    (clobber (reg:CC FLAGS_REG))]
10639   "TARGET_64BIT
10640    && TARGET_USE_8BIT_IDIV
10641    && TARGET_QIMODE_MATH
10642    && can_create_pseudo_p ()
10643    && !optimize_insn_for_size_p ()"
10644   [(const_int 0)]
10645   "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10647 (define_insn_and_split "divmod<mode>4_1"
10648   [(set (match_operand:SWI48 0 "register_operand" "=a")
10649         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10650                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10651    (set (match_operand:SWI48 1 "register_operand" "=&d")
10652         (mod:SWI48 (match_dup 2) (match_dup 3)))
10653    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10654    (clobber (reg:CC FLAGS_REG))]
10655   ""
10656   "#"
10657   "reload_completed"
10658   [(parallel [(set (match_dup 1)
10659                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
10660               (clobber (reg:CC FLAGS_REG))])
10661    (parallel [(set (match_dup 0)
10662                    (div:SWI48 (match_dup 2) (match_dup 3)))
10663               (set (match_dup 1)
10664                    (mod:SWI48 (match_dup 2) (match_dup 3)))
10665               (use (match_dup 1))
10666               (clobber (reg:CC FLAGS_REG))])]
10668   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10670   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10671     operands[4] = operands[2];
10672   else
10673     {
10674       /* Avoid use of cltd in favor of a mov+shift.  */
10675       emit_move_insn (operands[1], operands[2]);
10676       operands[4] = operands[1];
10677     }
10679   [(set_attr "type" "multi")
10680    (set_attr "mode" "<MODE>")])
10682 (define_insn_and_split "udivmod<mode>4_1"
10683   [(set (match_operand:SWI48 0 "register_operand" "=a")
10684         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10685                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10686    (set (match_operand:SWI48 1 "register_operand" "=&d")
10687         (umod:SWI48 (match_dup 2) (match_dup 3)))
10688    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10689    (clobber (reg:CC FLAGS_REG))]
10690   ""
10691   "#"
10692   "reload_completed"
10693   [(set (match_dup 1) (const_int 0))
10694    (parallel [(set (match_dup 0)
10695                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
10696               (set (match_dup 1)
10697                    (umod:SWI48 (match_dup 2) (match_dup 3)))
10698               (use (match_dup 1))
10699               (clobber (reg:CC FLAGS_REG))])]
10700   ""
10701   [(set_attr "type" "multi")
10702    (set_attr "mode" "<MODE>")])
10704 (define_insn_and_split "divmodsi4_zext_1"
10705   [(set (match_operand:DI 0 "register_operand" "=a")
10706         (zero_extend:DI
10707           (div:SI (match_operand:SI 2 "register_operand" "0")
10708                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10709    (set (match_operand:SI 1 "register_operand" "=&d")
10710         (mod:SI (match_dup 2) (match_dup 3)))
10711    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10712    (clobber (reg:CC FLAGS_REG))]
10713   "TARGET_64BIT"
10714   "#"
10715   "&& reload_completed"
10716   [(parallel [(set (match_dup 1)
10717                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
10718               (clobber (reg:CC FLAGS_REG))])
10719    (parallel [(set (match_dup 0)
10720                    (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10721               (set (match_dup 1)
10722                    (mod:SI (match_dup 2) (match_dup 3)))
10723               (use (match_dup 1))
10724               (clobber (reg:CC FLAGS_REG))])]
10726   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10728   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10729     operands[4] = operands[2];
10730   else
10731     {
10732       /* Avoid use of cltd in favor of a mov+shift.  */
10733       emit_move_insn (operands[1], operands[2]);
10734       operands[4] = operands[1];
10735     }
10737   [(set_attr "type" "multi")
10738    (set_attr "mode" "SI")])
10740 (define_insn_and_split "udivmodsi4_zext_1"
10741   [(set (match_operand:DI 0 "register_operand" "=a")
10742         (zero_extend:DI
10743           (udiv:SI (match_operand:SI 2 "register_operand" "0")
10744                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10745    (set (match_operand:SI 1 "register_operand" "=&d")
10746         (umod:SI (match_dup 2) (match_dup 3)))
10747    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10748    (clobber (reg:CC FLAGS_REG))]
10749   "TARGET_64BIT"
10750   "#"
10751   "&& reload_completed"
10752   [(set (match_dup 1) (const_int 0))
10753    (parallel [(set (match_dup 0)
10754                    (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10755               (set (match_dup 1)
10756                    (umod:SI (match_dup 2) (match_dup 3)))
10757               (use (match_dup 1))
10758               (clobber (reg:CC FLAGS_REG))])]
10759   ""
10760   [(set_attr "type" "multi")
10761    (set_attr "mode" "SI")])
10763 (define_insn_and_split "divmodsi4_zext_2"
10764   [(set (match_operand:DI 1 "register_operand" "=&d")
10765         (zero_extend:DI
10766           (mod:SI (match_operand:SI 2 "register_operand" "0")
10767                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10768    (set (match_operand:SI 0 "register_operand" "=a")
10769         (div:SI (match_dup 2) (match_dup 3)))
10770    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10771    (clobber (reg:CC FLAGS_REG))]
10772   "TARGET_64BIT"
10773   "#"
10774   "&& reload_completed"
10775   [(parallel [(set (match_dup 6)
10776                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
10777               (clobber (reg:CC FLAGS_REG))])
10778    (parallel [(set (match_dup 1)
10779                    (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10780               (set (match_dup 0)
10781                    (div:SI (match_dup 2) (match_dup 3)))
10782               (use (match_dup 6))
10783               (clobber (reg:CC FLAGS_REG))])]
10785   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10786   operands[6] = gen_lowpart (SImode, operands[1]);
10788   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10789     operands[4] = operands[2];
10790   else
10791     {
10792       /* Avoid use of cltd in favor of a mov+shift.  */
10793       emit_move_insn (operands[6], operands[2]);
10794       operands[4] = operands[6];
10795     }
10797   [(set_attr "type" "multi")
10798    (set_attr "mode" "SI")])
10800 (define_insn_and_split "udivmodsi4_zext_2"
10801   [(set (match_operand:DI 1 "register_operand" "=&d")
10802         (zero_extend:DI
10803           (umod:SI (match_operand:SI 2 "register_operand" "0")
10804                  (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10805    (set (match_operand:SI 0 "register_operand" "=a")
10806         (udiv:SI (match_dup 2) (match_dup 3)))
10807    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10808    (clobber (reg:CC FLAGS_REG))]
10809   "TARGET_64BIT"
10810   "#"
10811   "&& reload_completed"
10812   [(set (match_dup 4) (const_int 0))
10813    (parallel [(set (match_dup 1)
10814                    (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10815               (set (match_dup 0)
10816                    (udiv:SI (match_dup 2) (match_dup 3)))
10817               (use (match_dup 4))
10818               (clobber (reg:CC FLAGS_REG))])]
10819   "operands[4] = gen_lowpart (SImode, operands[1]);"
10820   [(set_attr "type" "multi")
10821    (set_attr "mode" "SI")])
10823 (define_insn_and_split "*divmod<mode>4"
10824   [(set (match_operand:SWIM248 0 "register_operand" "=a")
10825         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10826                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10827    (set (match_operand:SWIM248 1 "register_operand" "=&d")
10828         (mod:SWIM248 (match_dup 2) (match_dup 3)))
10829    (clobber (reg:CC FLAGS_REG))]
10830   ""
10831   "#"
10832   "reload_completed"
10833   [(parallel [(set (match_dup 1)
10834                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
10835               (clobber (reg:CC FLAGS_REG))])
10836    (parallel [(set (match_dup 0)
10837                    (div:SWIM248 (match_dup 2) (match_dup 3)))
10838               (set (match_dup 1)
10839                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
10840               (use (match_dup 1))
10841               (clobber (reg:CC FLAGS_REG))])]
10843   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10845   if (<MODE>mode != HImode
10846       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
10847     operands[4] = operands[2];
10848   else
10849     {
10850       /* Avoid use of cltd in favor of a mov+shift.  */
10851       emit_move_insn (operands[1], operands[2]);
10852       operands[4] = operands[1];
10853     }
10855   [(set_attr "type" "multi")
10856    (set_attr "mode" "<MODE>")])
10858 (define_insn_and_split "*udivmod<mode>4"
10859   [(set (match_operand:SWIM248 0 "register_operand" "=a")
10860         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10861                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10862    (set (match_operand:SWIM248 1 "register_operand" "=&d")
10863         (umod:SWIM248 (match_dup 2) (match_dup 3)))
10864    (clobber (reg:CC FLAGS_REG))]
10865   ""
10866   "#"
10867   "reload_completed"
10868   [(set (match_dup 1) (const_int 0))
10869    (parallel [(set (match_dup 0)
10870                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
10871               (set (match_dup 1)
10872                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
10873               (use (match_dup 1))
10874               (clobber (reg:CC FLAGS_REG))])]
10875   ""
10876   [(set_attr "type" "multi")
10877    (set_attr "mode" "<MODE>")])
10879 ;; Optimize division or modulo by constant power of 2, if the constant
10880 ;; materializes only after expansion.
10881 (define_insn_and_split "*udivmod<mode>4_pow2"
10882   [(set (match_operand:SWI48 0 "register_operand" "=r")
10883         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10884                     (match_operand:SWI48 3 "const_int_operand")))
10885    (set (match_operand:SWI48 1 "register_operand" "=r")
10886         (umod:SWI48 (match_dup 2) (match_dup 3)))
10887    (clobber (reg:CC FLAGS_REG))]
10888   "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10889   "#"
10890   "&& reload_completed"
10891   [(set (match_dup 1) (match_dup 2))
10892    (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
10893               (clobber (reg:CC FLAGS_REG))])
10894    (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
10895               (clobber (reg:CC FLAGS_REG))])]
10897   int v = exact_log2 (UINTVAL (operands[3]));
10898   operands[4] = GEN_INT (v);
10899   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10901   [(set_attr "type" "multi")
10902    (set_attr "mode" "<MODE>")])
10904 (define_insn_and_split "*divmodsi4_zext_1"
10905   [(set (match_operand:DI 0 "register_operand" "=a")
10906         (zero_extend:DI
10907           (div:SI (match_operand:SI 2 "register_operand" "0")
10908                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10909    (set (match_operand:SI 1 "register_operand" "=&d")
10910         (mod:SI (match_dup 2) (match_dup 3)))
10911    (clobber (reg:CC FLAGS_REG))]
10912   "TARGET_64BIT"
10913   "#"
10914   "&& reload_completed"
10915   [(parallel [(set (match_dup 1)
10916                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
10917               (clobber (reg:CC FLAGS_REG))])
10918    (parallel [(set (match_dup 0)
10919                    (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10920               (set (match_dup 1)
10921                    (mod:SI (match_dup 2) (match_dup 3)))
10922               (use (match_dup 1))
10923               (clobber (reg:CC FLAGS_REG))])]
10925   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10927   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10928     operands[4] = operands[2];
10929   else
10930     {
10931       /* Avoid use of cltd in favor of a mov+shift.  */
10932       emit_move_insn (operands[1], operands[2]);
10933       operands[4] = operands[1];
10934     }
10936   [(set_attr "type" "multi")
10937    (set_attr "mode" "SI")])
10939 (define_insn_and_split "*udivmodsi4_zext_1"
10940   [(set (match_operand:DI 0 "register_operand" "=a")
10941         (zero_extend:DI
10942           (udiv:SI (match_operand:SI 2 "register_operand" "0")
10943                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10944    (set (match_operand:SI 1 "register_operand" "=&d")
10945         (umod:SI (match_dup 2) (match_dup 3)))
10946    (clobber (reg:CC FLAGS_REG))]
10947   "TARGET_64BIT"
10948   "#"
10949   "&& reload_completed"
10950   [(set (match_dup 1) (const_int 0))
10951    (parallel [(set (match_dup 0)
10952                    (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10953               (set (match_dup 1)
10954                    (umod:SI (match_dup 2) (match_dup 3)))
10955               (use (match_dup 1))
10956               (clobber (reg:CC FLAGS_REG))])]
10957   ""
10958   [(set_attr "type" "multi")
10959    (set_attr "mode" "SI")])
10961 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
10962   [(set (match_operand:DI 0 "register_operand" "=r")
10963         (zero_extend:DI
10964           (udiv:SI (match_operand:SI 2 "register_operand" "0")
10965                    (match_operand:SI 3 "const_int_operand"))))
10966    (set (match_operand:SI 1 "register_operand" "=r")
10967         (umod:SI (match_dup 2) (match_dup 3)))
10968    (clobber (reg:CC FLAGS_REG))]
10969   "TARGET_64BIT
10970    && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10971   "#"
10972   "&& reload_completed"
10973   [(set (match_dup 1) (match_dup 2))
10974    (parallel [(set (match_dup 0)
10975                    (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
10976               (clobber (reg:CC FLAGS_REG))])
10977    (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
10978               (clobber (reg:CC FLAGS_REG))])]
10980   int v = exact_log2 (UINTVAL (operands[3]));
10981   operands[4] = GEN_INT (v);
10982   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10984   [(set_attr "type" "multi")
10985    (set_attr "mode" "SI")])
10987 (define_insn_and_split "*divmodsi4_zext_2"
10988   [(set (match_operand:DI 1 "register_operand" "=&d")
10989         (zero_extend:DI
10990           (mod:SI (match_operand:SI 2 "register_operand" "0")
10991                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10992    (set (match_operand:SI 0 "register_operand" "=a")
10993         (div:SI (match_dup 2) (match_dup 3)))
10994    (clobber (reg:CC FLAGS_REG))]
10995   "TARGET_64BIT"
10996   "#"
10997   "&& reload_completed"
10998   [(parallel [(set (match_dup 6)
10999                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
11000               (clobber (reg:CC FLAGS_REG))])
11001    (parallel [(set (match_dup 1)
11002                    (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
11003               (set (match_dup 0)
11004                    (div:SI (match_dup 2) (match_dup 3)))
11005               (use (match_dup 6))
11006               (clobber (reg:CC FLAGS_REG))])]
11008   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
11009   operands[6] = gen_lowpart (SImode, operands[1]);
11011   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
11012     operands[4] = operands[2];
11013   else
11014     {
11015       /* Avoid use of cltd in favor of a mov+shift.  */
11016       emit_move_insn (operands[6], operands[2]);
11017       operands[4] = operands[6];
11018     }
11020   [(set_attr "type" "multi")
11021    (set_attr "mode" "SI")])
11023 (define_insn_and_split "*udivmodsi4_zext_2"
11024   [(set (match_operand:DI 1 "register_operand" "=&d")
11025         (zero_extend:DI
11026           (umod:SI (match_operand:SI 2 "register_operand" "0")
11027                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11028    (set (match_operand:SI 0 "register_operand" "=a")
11029         (udiv:SI (match_dup 2) (match_dup 3)))
11030    (clobber (reg:CC FLAGS_REG))]
11031   "TARGET_64BIT"
11032   "#"
11033   "&& reload_completed"
11034   [(set (match_dup 4) (const_int 0))
11035    (parallel [(set (match_dup 1)
11036                    (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
11037               (set (match_dup 0)
11038                    (udiv:SI (match_dup 2) (match_dup 3)))
11039               (use (match_dup 4))
11040               (clobber (reg:CC FLAGS_REG))])]
11041   "operands[4] = gen_lowpart (SImode, operands[1]);"
11042   [(set_attr "type" "multi")
11043    (set_attr "mode" "SI")])
11045 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
11046   [(set (match_operand:DI 1 "register_operand" "=r")
11047         (zero_extend:DI
11048           (umod:SI (match_operand:SI 2 "register_operand" "0")
11049                    (match_operand:SI 3 "const_int_operand"))))
11050    (set (match_operand:SI 0 "register_operand" "=r")
11051         (udiv:SI (match_dup 2) (match_dup 3)))
11052    (clobber (reg:CC FLAGS_REG))]
11053   "TARGET_64BIT
11054    && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
11055   "#"
11056   "&& reload_completed"
11057   [(set (match_dup 1) (match_dup 2))
11058    (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
11059               (clobber (reg:CC FLAGS_REG))])
11060    (parallel [(set (match_dup 1)
11061                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
11062               (clobber (reg:CC FLAGS_REG))])]
11064   int v = exact_log2 (UINTVAL (operands[3]));
11065   operands[4] = GEN_INT (v);
11066   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
11068   [(set_attr "type" "multi")
11069    (set_attr "mode" "SI")])
11071 (define_insn "*<u>divmod<mode>4_noext"
11072   [(set (match_operand:SWIM248 0 "register_operand" "=a")
11073         (any_div:SWIM248
11074           (match_operand:SWIM248 2 "register_operand" "0")
11075           (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
11076    (set (match_operand:SWIM248 1 "register_operand" "=d")
11077         (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
11078    (use (match_operand:SWIM248 4 "register_operand" "1"))
11079    (clobber (reg:CC FLAGS_REG))]
11080   ""
11081   "<sgnprefix>div{<imodesuffix>}\t%3"
11082   [(set_attr "type" "idiv")
11083    (set_attr "mode" "<MODE>")])
11085 (define_insn "*<u>divmodsi4_noext_zext_1"
11086   [(set (match_operand:DI 0 "register_operand" "=a")
11087         (zero_extend:DI
11088           (any_div:SI (match_operand:SI 2 "register_operand" "0")
11089                       (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11090    (set (match_operand:SI 1 "register_operand" "=d")
11091         (<paired_mod>:SI (match_dup 2) (match_dup 3)))
11092    (use (match_operand:SI 4 "register_operand" "1"))
11093    (clobber (reg:CC FLAGS_REG))]
11094   "TARGET_64BIT"
11095   "<sgnprefix>div{l}\t%3"
11096   [(set_attr "type" "idiv")
11097    (set_attr "mode" "SI")])
11099 (define_insn "*<u>divmodsi4_noext_zext_2"
11100   [(set (match_operand:DI 1 "register_operand" "=d")
11101         (zero_extend:DI
11102           (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
11103                            (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11104    (set (match_operand:SI 0 "register_operand" "=a")
11105         (any_div:SI (match_dup 2) (match_dup 3)))
11106    (use (match_operand:SI 4 "register_operand" "1"))
11107    (clobber (reg:CC FLAGS_REG))]
11108   "TARGET_64BIT"
11109   "<sgnprefix>div{l}\t%3"
11110   [(set_attr "type" "idiv")
11111    (set_attr "mode" "SI")])
11113 ;; Avoid sign-extension (using cdq) for constant numerators.
11114 (define_insn_and_split "*divmodsi4_const"
11115   [(set (match_operand:SI 0 "register_operand" "=&a")
11116         (div:SI (match_operand:SI 2 "const_int_operand")
11117                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
11118    (set (match_operand:SI 1 "register_operand" "=&d")
11119         (mod:SI (match_dup 2) (match_dup 3)))
11120    (clobber (reg:CC FLAGS_REG))]
11121   "!optimize_function_for_size_p (cfun)"
11122   "#"
11123   "&& reload_completed"
11124   [(set (match_dup 0) (match_dup 2))
11125    (set (match_dup 1) (match_dup 4))
11126    (parallel [(set (match_dup 0)
11127                    (div:SI (match_dup 0) (match_dup 3)))
11128               (set (match_dup 1)
11129                    (mod:SI (match_dup 0) (match_dup 3)))
11130               (use (match_dup 1))
11131               (clobber (reg:CC FLAGS_REG))])]
11133   operands[4] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
11135   [(set_attr "type" "multi")
11136    (set_attr "mode" "SI")])
11138 (define_expand "divmodqi4"
11139   [(parallel [(set (match_operand:QI 0 "register_operand")
11140                    (div:QI
11141                      (match_operand:QI 1 "register_operand")
11142                      (match_operand:QI 2 "nonimmediate_operand")))
11143               (set (match_operand:QI 3 "register_operand")
11144                    (mod:QI (match_dup 1) (match_dup 2)))
11145               (clobber (reg:CC FLAGS_REG))])]
11146   "TARGET_QIMODE_MATH"
11148   rtx div, mod;
11149   rtx tmp0, tmp1;
11151   tmp0 = gen_reg_rtx (HImode);
11152   tmp1 = gen_reg_rtx (HImode);
11154   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
11155   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
11156   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
11158   /* Extract remainder from AH.  */
11159   tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
11160   tmp1 = lowpart_subreg (QImode, tmp1, HImode);
11161   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
11163   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
11164   set_unique_reg_note (insn, REG_EQUAL, mod);
11166   /* Extract quotient from AL.  */
11167   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
11169   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
11170   set_unique_reg_note (insn, REG_EQUAL, div);
11172   DONE;
11175 (define_expand "udivmodqi4"
11176   [(parallel [(set (match_operand:QI 0 "register_operand")
11177                    (udiv:QI
11178                      (match_operand:QI 1 "register_operand")
11179                      (match_operand:QI 2 "nonimmediate_operand")))
11180               (set (match_operand:QI 3 "register_operand")
11181                    (umod:QI (match_dup 1) (match_dup 2)))
11182               (clobber (reg:CC FLAGS_REG))])]
11183   "TARGET_QIMODE_MATH"
11185   rtx div, mod;
11186   rtx tmp0, tmp1;
11188   tmp0 = gen_reg_rtx (HImode);
11189   tmp1 = gen_reg_rtx (HImode);
11191   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
11192   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
11193   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
11195   /* Extract remainder from AH.  */
11196   tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
11197   tmp1 = lowpart_subreg (QImode, tmp1, HImode);
11198   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
11200   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
11201   set_unique_reg_note (insn, REG_EQUAL, mod);
11203   /* Extract quotient from AL.  */
11204   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
11206   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
11207   set_unique_reg_note (insn, REG_EQUAL, div);
11209   DONE;
11212 ;; Divide AX by r/m8, with result stored in
11213 ;; AL <- Quotient
11214 ;; AH <- Remainder
11215 ;; Change div/mod to HImode and extend the second argument to HImode
11216 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
11217 ;; combine may fail.
11218 (define_insn "<u>divmodhiqi3"
11219   [(set (match_operand:HI 0 "register_operand" "=a")
11220         (ior:HI
11221           (ashift:HI
11222             (zero_extend:HI
11223               (truncate:QI
11224                 (mod:HI (match_operand:HI 1 "register_operand" "0")
11225                         (any_extend:HI
11226                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
11227             (const_int 8))
11228           (zero_extend:HI
11229             (truncate:QI
11230               (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
11231    (clobber (reg:CC FLAGS_REG))]
11232   "TARGET_QIMODE_MATH"
11233   "<sgnprefix>div{b}\t%2"
11234   [(set_attr "type" "idiv")
11235    (set_attr "mode" "QI")])
11237 ;; We cannot use div/idiv for double division, because it causes
11238 ;; "division by zero" on the overflow and that's not what we expect
11239 ;; from truncate.  Because true (non truncating) double division is
11240 ;; never generated, we can't create this insn anyway.
11242 ;(define_insn ""
11243 ;  [(set (match_operand:SI 0 "register_operand" "=a")
11244 ;       (truncate:SI
11245 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
11246 ;                  (zero_extend:DI
11247 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
11248 ;   (set (match_operand:SI 3 "register_operand" "=d")
11249 ;       (truncate:SI
11250 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
11251 ;   (clobber (reg:CC FLAGS_REG))]
11252 ;  ""
11253 ;  "div{l}\t{%2, %0|%0, %2}"
11254 ;  [(set_attr "type" "idiv")])
11256 ;;- Logical AND instructions
11258 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
11259 ;; Note that this excludes ah.
11261 (define_expand "@test<mode>_ccno_1"
11262   [(set (reg:CCNO FLAGS_REG)
11263         (compare:CCNO
11264           (and:SWI48
11265             (match_operand:SWI48 0 "nonimmediate_operand")
11266             (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
11267           (const_int 0)))])
11269 (define_expand "testqi_ccz_1"
11270   [(set (reg:CCZ FLAGS_REG)
11271         (compare:CCZ
11272           (and:QI
11273             (match_operand:QI 0 "nonimmediate_operand")
11274             (match_operand:QI 1 "nonmemory_operand"))
11275           (const_int 0)))])
11277 (define_insn "*testdi_1"
11278   [(set (reg FLAGS_REG)
11279         (compare
11280           (and:DI
11281             (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
11282             (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
11283          (const_int 0)))]
11284   "TARGET_64BIT
11285    && ix86_match_ccmode
11286         (insn,
11287          /* If we are going to emit testl instead of testq, and the operands[1]
11288             constant might have the SImode sign bit set, make sure the sign
11289             flag isn't tested, because the instruction will set the sign flag
11290             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
11291             conservatively assume it might have bit 31 set.  */
11292          (satisfies_constraint_Z (operands[1])
11293           && (!CONST_INT_P (operands[1])
11294               || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
11295          ? CCZmode : CCNOmode)"
11296   "@
11297    test{l}\t{%k1, %k0|%k0, %k1}
11298    test{q}\t{%1, %0|%0, %1}"
11299   [(set_attr "type" "test")
11300    (set_attr "mode" "SI,DI")])
11302 (define_insn "*testqi_1_maybe_si"
11303   [(set (reg FLAGS_REG)
11304         (compare
11305           (and:QI
11306             (match_operand:QI 0 "nonimmediate_operand" "%qm,qm,r")
11307             (match_operand:QI 1 "nonmemory_operand" "q,n,n"))
11308           (const_int 0)))]
11309   "ix86_match_ccmode (insn,
11310                       CONST_INT_P (operands[1])
11311                       && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
11313   if (get_attr_mode (insn) == MODE_SI)
11314     {
11315       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
11316         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
11317       return "test{l}\t{%1, %k0|%k0, %1}";
11318     }
11319   return "test{b}\t{%1, %0|%0, %1}";
11321   [(set_attr "type" "test")
11322    (set (attr "mode")
11323      (cond [(eq_attr "alternative" "2")
11324               (const_string "SI")
11325             (and (match_test "optimize_insn_for_size_p ()")
11326                  (and (match_operand 0 "ext_QIreg_operand")
11327                       (match_operand 1 "const_0_to_127_operand")))
11328               (const_string "SI")
11329            ]
11330            (const_string "QI")))
11331    (set_attr "pent_pair" "uv,np,np")])
11333 (define_insn "*test<mode>_1"
11334   [(set (reg FLAGS_REG)
11335         (compare
11336           (and:SWI124
11337             (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
11338             (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
11339          (const_int 0)))]
11340   "ix86_match_ccmode (insn, CCNOmode)"
11341   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
11342   [(set_attr "type" "test")
11343    (set_attr "mode" "<MODE>")
11344    (set_attr "pent_pair" "uv,uv,np")])
11346 (define_expand "testqi_ext_1_ccno"
11347   [(set (reg:CCNO FLAGS_REG)
11348         (compare:CCNO
11349           (and:QI
11350             (subreg:QI
11351               (zero_extract:HI
11352                 (match_operand:HI 0 "register_operand")
11353                 (const_int 8)
11354                 (const_int 8)) 0)
11355               (match_operand:QI 1 "const_int_operand"))
11356           (const_int 0)))])
11358 (define_insn "*testqi_ext<mode>_1"
11359   [(set (reg FLAGS_REG)
11360         (compare
11361           (and:QI
11362             (subreg:QI
11363               (match_operator:SWI248 2 "extract_operator"
11364                 [(match_operand 0 "int248_register_operand" "Q")
11365                  (const_int 8)
11366                  (const_int 8)]) 0)
11367             (match_operand:QI 1 "general_operand" "QnBn"))
11368           (const_int 0)))]
11369   "ix86_match_ccmode (insn, CCNOmode)"
11370   "test{b}\t{%1, %h0|%h0, %1}"
11371   [(set_attr "addr" "gpr8")
11372    (set_attr "type" "test")
11373    (set_attr "mode" "QI")])
11375 (define_insn "*testqi_ext<mode>_2"
11376   [(set (reg FLAGS_REG)
11377         (compare
11378           (and:QI
11379             (subreg:QI
11380               (match_operator:SWI248 2 "extract_operator"
11381                 [(match_operand 0 "int248_register_operand" "Q")
11382                  (const_int 8)
11383                  (const_int 8)]) 0)
11384             (subreg:QI
11385               (match_operator:SWI248 3 "extract_operator"
11386                 [(match_operand 1 "int248_register_operand" "Q")
11387                  (const_int 8)
11388                  (const_int 8)]) 0))
11389           (const_int 0)))]
11390   "ix86_match_ccmode (insn, CCNOmode)"
11391   "test{b}\t{%h1, %h0|%h0, %h1}"
11392   [(set_attr "type" "test")
11393    (set_attr "mode" "QI")])
11395 ;; Provide a *testti instruction that STV can implement using ptest.
11396 ;; This pattern splits into *andti3_doubleword and *cmpti_doubleword.
11397 (define_insn_and_split "*testti_doubleword"
11398   [(set (reg:CCZ FLAGS_REG)
11399         (compare:CCZ
11400           (and:TI (match_operand:TI 0 "register_operand")
11401                   (match_operand:TI 1 "general_operand"))
11402           (const_int 0)))]
11403   "TARGET_64BIT
11404    && ix86_pre_reload_split ()"
11405   "#"
11406   "&& 1"
11407   [(parallel [(set (match_dup 2) (and:TI (match_dup 0) (match_dup 1)))
11408               (clobber (reg:CC FLAGS_REG))])
11409    (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
11411   operands[2] = gen_reg_rtx (TImode);
11412   if (!x86_64_hilo_general_operand (operands[1], TImode))
11413     operands[1] = force_reg (TImode, operands[1]);
11416 ;; Combine likes to form bit extractions for some tests.  Humor it.
11417 (define_insn_and_split "*testqi_ext_3"
11418   [(set (match_operand 0 "flags_reg_operand")
11419         (match_operator 1 "compare_operator"
11420           [(zero_extract:SWI248
11421              (match_operand 2 "int_nonimmediate_operand" "rm")
11422              (match_operand:QI 3 "const_int_operand")
11423              (match_operand:QI 4 "const_int_operand"))
11424            (const_int 0)]))]
11425   "/* Ensure that resulting mask is zero or sign extended operand.  */
11426    INTVAL (operands[4]) >= 0
11427    && ((INTVAL (operands[3]) > 0
11428         && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
11429        || (<MODE>mode == DImode
11430            && INTVAL (operands[3]) > 32
11431            && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
11432    && ix86_match_ccmode (insn,
11433                          /* If zero_extract mode precision is the same
11434                             as len, the SF of the zero_extract
11435                             comparison will be the most significant
11436                             extracted bit, but this could be matched
11437                             after splitting only for pos 0 len all bits
11438                             trivial extractions.  Require CCZmode.  */
11439                          (GET_MODE_PRECISION (<MODE>mode)
11440                           == INTVAL (operands[3]))
11441                          /* Otherwise, require CCZmode if we'd use a mask
11442                             with the most significant bit set and can't
11443                             widen it to wider mode.  *testdi_1 also
11444                             requires CCZmode if the mask has bit
11445                             31 set and all bits above it clear.  */
11446                          || (INTVAL (operands[3]) + INTVAL (operands[4])
11447                              >= 32)
11448                          /* We can't widen also if val is not a REG.  */
11449                          || (INTVAL (operands[3]) + INTVAL (operands[4])
11450                              == GET_MODE_PRECISION (GET_MODE (operands[2]))
11451                              && !register_operand (operands[2],
11452                                                    GET_MODE (operands[2])))
11453                          /* And we shouldn't widen if
11454                             TARGET_PARTIAL_REG_STALL.  */
11455                          || (TARGET_PARTIAL_REG_STALL
11456                              && (INTVAL (operands[3]) + INTVAL (operands[4])
11457                                  >= (paradoxical_subreg_p (operands[2])
11458                                      && (GET_MODE_CLASS
11459                                           (GET_MODE (SUBREG_REG (operands[2])))
11460                                          == MODE_INT)
11461                                      ? GET_MODE_PRECISION
11462                                          (GET_MODE (SUBREG_REG (operands[2])))
11463                                      : GET_MODE_PRECISION
11464                                          (GET_MODE (operands[2])))))
11465                          ? CCZmode : CCNOmode)"
11466   "#"
11467   "&& 1"
11468   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11470   rtx val = operands[2];
11471   HOST_WIDE_INT len = INTVAL (operands[3]);
11472   HOST_WIDE_INT pos = INTVAL (operands[4]);
11473   machine_mode mode = GET_MODE (val);
11475   if (SUBREG_P (val))
11476     {
11477       machine_mode submode = GET_MODE (SUBREG_REG (val));
11479       /* Narrow paradoxical subregs to prevent partial register stalls.  */
11480       if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
11481           && GET_MODE_CLASS (submode) == MODE_INT
11482           && (GET_MODE (operands[0]) == CCZmode
11483               || pos + len < GET_MODE_PRECISION (submode)
11484               || REG_P (SUBREG_REG (val))))
11485         {
11486           val = SUBREG_REG (val);
11487           mode = submode;
11488         }
11489     }
11491   /* Small HImode tests can be converted to QImode.  */
11492   if (pos + len <= 8
11493       && register_operand (val, HImode))
11494     {
11495       rtx nval = gen_lowpart (QImode, val);
11496       if (!MEM_P (nval)
11497           || GET_MODE (operands[0]) == CCZmode
11498           || pos + len < 8)
11499         {
11500           val = nval;
11501           mode = QImode;
11502         }
11503     }
11505   gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
11507   /* If the mask is going to have the sign bit set in the mode
11508      we want to do the comparison in and user isn't interested just
11509      in the zero flag, then we must widen the target mode.  */
11510   if (pos + len == GET_MODE_PRECISION (mode)
11511       && GET_MODE (operands[0]) != CCZmode)
11512     {
11513       gcc_assert (pos + len < 32 && !MEM_P (val));
11514       mode = SImode;
11515       val = gen_lowpart (mode, val);
11516     }
11518   wide_int mask
11519     = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
11521   operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
11524 ;; Split and;cmp (as optimized by combine) into not;test
11525 ;; Except when TARGET_BMI provides andn (*andn_<mode>_ccno).
11526 (define_insn_and_split "*test<mode>_not"
11527   [(set (reg:CCZ FLAGS_REG)
11528         (compare:CCZ
11529           (and:SWI
11530             (not:SWI (match_operand:SWI 0 "register_operand"))
11531             (match_operand:SWI 1 "<nonmemory_szext_operand>"))
11532           (const_int 0)))]
11533   "ix86_pre_reload_split ()
11534    && (!TARGET_BMI || !REG_P (operands[1]))"
11535   "#"
11536   "&& 1"
11537   [(set (match_dup 2) (not:SWI (match_dup 0)))
11538    (set (reg:CCZ FLAGS_REG)
11539         (compare:CCZ (and:SWI (match_dup 2) (match_dup 1))
11540                      (const_int 0)))]
11541   "operands[2] = gen_reg_rtx (<MODE>mode);")
11543 ;; Split and;cmp (as optimized by combine) into andn;cmp $0
11544 (define_insn_and_split "*test<mode>_not_doubleword"
11545   [(set (reg:CCZ FLAGS_REG)
11546         (compare:CCZ
11547           (and:DWI
11548             (not:DWI (match_operand:DWI 0 "nonimmediate_operand"))
11549             (match_operand:DWI 1 "nonimmediate_operand"))
11550           (const_int 0)))]
11551   "ix86_pre_reload_split ()"
11552   "#"
11553   "&& 1"
11554   [(parallel
11555       [(set (match_dup 2) (and:DWI (not:DWI (match_dup 0)) (match_dup 1)))
11556        (clobber (reg:CC FLAGS_REG))])
11557    (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
11559   operands[0] = force_reg (<MODE>mode, operands[0]);
11560   operands[2] = gen_reg_rtx (<MODE>mode);
11563 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
11564 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
11565 ;; this is relatively important trick.
11566 ;; Do the conversion only post-reload to avoid limiting of the register class
11567 ;; to QI regs.
11568 (define_split
11569   [(set (match_operand 0 "flags_reg_operand")
11570         (match_operator 1 "compare_operator"
11571           [(and (match_operand 2 "QIreg_operand")
11572                 (match_operand 3 "const_int_operand"))
11573            (const_int 0)]))]
11574    "reload_completed
11575     && GET_MODE (operands[2]) != QImode
11576     && ((ix86_match_ccmode (insn, CCZmode)
11577          && !(INTVAL (operands[3]) & ~(255 << 8)))
11578         || (ix86_match_ccmode (insn, CCNOmode)
11579             && !(INTVAL (operands[3]) & ~(127 << 8))))"
11580   [(set (match_dup 0)
11581         (match_op_dup 1
11582           [(and:QI
11583              (subreg:QI
11584                (zero_extract:HI (match_dup 2)
11585                                 (const_int 8)
11586                                 (const_int 8)) 0)
11587              (match_dup 3))
11588            (const_int 0)]))]
11590   operands[2] = gen_lowpart (HImode, operands[2]);
11591   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
11594 (define_split
11595   [(set (match_operand 0 "flags_reg_operand")
11596         (match_operator 1 "compare_operator"
11597           [(and (match_operand 2 "nonimmediate_operand")
11598                 (match_operand 3 "const_int_operand"))
11599            (const_int 0)]))]
11600    "reload_completed
11601     && GET_MODE (operands[2]) != QImode
11602     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
11603     && ((ix86_match_ccmode (insn, CCZmode)
11604          && !(INTVAL (operands[3]) & ~255))
11605         || (ix86_match_ccmode (insn, CCNOmode)
11606             && !(INTVAL (operands[3]) & ~127)))"
11607   [(set (match_dup 0)
11608         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
11609                          (const_int 0)]))]
11611   operands[2] = gen_lowpart (QImode, operands[2]);
11612   operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
11615 ;; Narrow test instructions with immediate operands that test
11616 ;; memory locations for zero.  E.g. testl $0x00aa0000, mem can be
11617 ;; converted to testb $0xaa, mem+2.  Reject volatile locations and
11618 ;; targets where reading (possibly unaligned) part of memory
11619 ;; location after a large write to the same address causes
11620 ;; store-to-load forwarding stall.
11621 (define_peephole2
11622   [(set (reg:CCZ FLAGS_REG)
11623         (compare:CCZ
11624           (and:SWI248 (match_operand:SWI248 0 "memory_operand")
11625                       (match_operand 1 "const_int_operand"))
11626           (const_int 0)))]
11627   "!TARGET_PARTIAL_MEMORY_READ_STALL && !MEM_VOLATILE_P (operands[0])"
11628   [(set (reg:CCZ FLAGS_REG)
11629         (compare:CCZ (match_dup 2) (const_int 0)))]
11631   unsigned HOST_WIDE_INT ival = UINTVAL (operands[1]);
11632   int first_nonzero_byte, bitsize;
11633   rtx new_addr, new_const;
11634   machine_mode new_mode;
11636   if (ival == 0)
11637     FAIL;
11639   /* Clear bits outside mode width.  */
11640   ival &= GET_MODE_MASK (<MODE>mode);
11642   first_nonzero_byte = ctz_hwi (ival) / BITS_PER_UNIT;
11644   ival >>= first_nonzero_byte * BITS_PER_UNIT;
11646   bitsize = sizeof (ival) * BITS_PER_UNIT - clz_hwi (ival);
11648   if (bitsize <= GET_MODE_BITSIZE (QImode))
11649     new_mode = QImode;
11650   else if (bitsize <= GET_MODE_BITSIZE (HImode))
11651     new_mode = HImode;
11652   else if (bitsize <= GET_MODE_BITSIZE (SImode))
11653     new_mode = SImode;
11654   else
11655     new_mode = DImode;
11657   if (GET_MODE_SIZE (new_mode) >= GET_MODE_SIZE (<MODE>mode))
11658     FAIL;
11660   new_addr = adjust_address (operands[0], new_mode, first_nonzero_byte);
11661   new_const = gen_int_mode (ival, new_mode);
11663   operands[2] = gen_rtx_AND (new_mode, new_addr, new_const);
11666 ;; %%% This used to optimize known byte-wide and operations to memory,
11667 ;; and sometimes to QImode registers.  If this is considered useful,
11668 ;; it should be done with splitters.
11670 (define_expand "and<mode>3"
11671   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
11672         (and:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
11673                    (match_operand:SDWIM 2 "<general_szext_operand>")))]
11674   ""
11676   machine_mode mode = <MODE>mode;
11678   if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
11679       && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
11680     operands[2] = force_reg (<MODE>mode, operands[2]);
11682   if (GET_MODE_SIZE (<MODE>mode) <= UNITS_PER_WORD
11683       && const_int_operand (operands[2], <MODE>mode)
11684       && register_operand (operands[0], <MODE>mode)
11685       && !(TARGET_ZERO_EXTEND_WITH_AND
11686            && optimize_function_for_speed_p (cfun)))
11687     {
11688       unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11690       if (ival == GET_MODE_MASK (SImode))
11691         mode = SImode;
11692       else if (ival == GET_MODE_MASK (HImode))
11693         mode = HImode;
11694       else if (ival == GET_MODE_MASK (QImode))
11695         mode = QImode;
11696     }
11698   if (mode != <MODE>mode)
11699     emit_insn (gen_extend_insn
11700                (operands[0], gen_lowpart (mode, operands[1]),
11701                 <MODE>mode, mode, 1));
11702   else
11703     ix86_expand_binary_operator (AND, <MODE>mode, operands, TARGET_APX_NDD);
11705   DONE;
11708 (define_insn_and_split "*and<dwi>3_doubleword"
11709   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r,&r,&r,&r")
11710         (and:<DWI>
11711          (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r,ro,jO,r")
11712          (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r,<di>,K,<di>,o")))
11713    (clobber (reg:CC FLAGS_REG))]
11714   "ix86_binary_operator_ok (AND, <DWI>mode, operands, TARGET_APX_NDD)"
11715   "#"
11716   "&& reload_completed"
11717   [(const_int:DWIH 0)]
11719   bool emit_insn_deleted_note_p = false;
11721   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
11723   if (operands[2] == const0_rtx)
11724     emit_move_insn (operands[0], const0_rtx);
11725   else if (operands[2] == constm1_rtx)
11726     {
11727       if (!rtx_equal_p (operands[0], operands[1]))
11728         emit_move_insn (operands[0], operands[1]);
11729       else
11730         emit_insn_deleted_note_p = true;
11731     }
11732   else
11733     ix86_expand_binary_operator (AND, <MODE>mode, &operands[0], TARGET_APX_NDD);
11735   if (operands[5] == const0_rtx)
11736     emit_move_insn (operands[3], const0_rtx);
11737   else if (operands[5] == constm1_rtx)
11738     {
11739       if (!rtx_equal_p (operands[3], operands[4]))
11740         emit_move_insn (operands[3], operands[4]);
11741       else if (emit_insn_deleted_note_p)
11742         emit_note (NOTE_INSN_DELETED);
11743     }
11744   else
11745     ix86_expand_binary_operator (AND, <MODE>mode, &operands[3], TARGET_APX_NDD);
11747   DONE;
11749 [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd_64,apx_ndd")])
11751 (define_insn "*anddi_1"
11752   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm,r,r,r,r,r,?k")
11753         (and:DI
11754          (match_operand:DI 1 "nonimmediate_operand" "%0,r,0,0,rm,rjM,r,qm,k")
11755          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,Z,re,m,r,e,m,L,k")))
11756    (clobber (reg:CC FLAGS_REG))]
11757   "TARGET_64BIT
11758    && ix86_binary_operator_ok (AND, DImode, operands, TARGET_APX_NDD)"
11759   "@
11760    and{l}\t{%k2, %k0|%k0, %k2}
11761    and{l}\t{%k2, %k1, %k0|%k0, %k1, %k2}
11762    and{q}\t{%2, %0|%0, %2}
11763    and{q}\t{%2, %0|%0, %2}
11764    and{q}\t{%2, %1, %0|%0, %1, %2}
11765    and{q}\t{%2, %1, %0|%0, %1, %2}
11766    and{q}\t{%2, %1, %0|%0, %1, %2}
11767    #
11768    #"
11769   [(set_attr "isa" "x64,apx_ndd,x64,x64,apx_ndd,apx_ndd,apx_ndd,x64,avx512bw")
11770    (set_attr "type" "alu,alu,alu,alu,alu,alu,alu,imovx,msklog")
11771    (set_attr "length_immediate" "*,*,*,*,*,*,*,0,*")
11772    (set (attr "prefix_rex")
11773      (if_then_else
11774        (and (eq_attr "type" "imovx")
11775             (and (match_test "INTVAL (operands[2]) == 0xff")
11776                  (match_operand 1 "ext_QIreg_operand")))
11777        (const_string "1")
11778        (const_string "*")))
11779    (set_attr "mode" "SI,SI,DI,DI,DI,DI,DI,SI,DI")])
11781 (define_insn_and_split "*anddi_1_btr"
11782   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11783         (and:DI
11784          (match_operand:DI 1 "nonimmediate_operand" "%0")
11785          (match_operand:DI 2 "const_int_operand" "n")))
11786    (clobber (reg:CC FLAGS_REG))]
11787   "TARGET_64BIT && TARGET_USE_BT
11788    && ix86_binary_operator_ok (AND, DImode, operands)
11789    && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
11790   "#"
11791   "&& reload_completed"
11792   [(parallel [(set (zero_extract:DI (match_dup 0)
11793                                     (const_int 1)
11794                                     (match_dup 3))
11795                    (const_int 0))
11796               (clobber (reg:CC FLAGS_REG))])]
11797   "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
11798   [(set_attr "type" "alu1")
11799    (set_attr "prefix_0f" "1")
11800    (set_attr "znver1_decode" "double")
11801    (set_attr "mode" "DI")])
11803 ;; Turn *anddi_1 into *andsi_1_zext if possible.
11804 (define_split
11805   [(set (match_operand:DI 0 "register_operand")
11806         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
11807                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
11808    (clobber (reg:CC FLAGS_REG))]
11809   "TARGET_64BIT"
11810   [(parallel [(set (match_dup 0)
11811                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
11812               (clobber (reg:CC FLAGS_REG))])]
11814   if (GET_CODE (operands[2]) == SYMBOL_REF
11815       || GET_CODE (operands[2]) == LABEL_REF)
11816     {
11817       operands[2] = shallow_copy_rtx (operands[2]);
11818       PUT_MODE (operands[2], SImode);
11819     }
11820   else if (GET_CODE (operands[2]) == CONST)
11821     {
11822       /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
11823       operands[2] = copy_rtx (operands[2]);
11824       PUT_MODE (operands[2], SImode);
11825       PUT_MODE (XEXP (operands[2], 0), SImode);
11826       PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
11827     }    
11828   else
11829     operands[2] = gen_lowpart (SImode, operands[2]);
11832 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11833 (define_insn "*andsi_1_zext"
11834   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
11835         (zero_extend:DI
11836           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm,rjM,r")
11837                   (match_operand:SI 2 "x86_64_general_operand" "rBMe,r,e,BM"))))
11838    (clobber (reg:CC FLAGS_REG))]
11839   "TARGET_64BIT
11840    && ix86_binary_operator_ok (AND, SImode, operands, TARGET_APX_NDD)"
11841   "@
11842   and{l}\t{%2, %k0|%k0, %2}
11843   and{l}\t{%2, %1, %k0|%k0, %1, %2}
11844   and{l}\t{%2, %1, %k0|%k0, %1, %2}
11845   and{l}\t{%2, %1, %k0|%k0, %1, %2}"
11846   [(set_attr "type" "alu")
11847    (set_attr "isa" "*,apx_ndd,apx_ndd,apx_ndd")
11848    (set_attr "mode" "SI")])
11850 (define_insn "*and<mode>_1"
11851   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,r,r,r,Ya,?k")
11852         (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,rm,rjM,r,qm,k")
11853                    (match_operand:SWI24 2 "<general_operand>" "r<i>,<m>,r,<i>,<m>,L,k")))
11854    (clobber (reg:CC FLAGS_REG))]
11855   "ix86_binary_operator_ok (AND, <MODE>mode, operands, TARGET_APX_NDD)"
11856   "@
11857    and{<imodesuffix>}\t{%2, %0|%0, %2}
11858    and{<imodesuffix>}\t{%2, %0|%0, %2}
11859    and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
11860    and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
11861    and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
11862    #
11863    #"
11864   [(set (attr "isa")
11865         (cond [(eq_attr "alternative" "2,3,4")
11866                  (const_string "apx_ndd")
11867                (eq_attr "alternative" "6")
11868                  (if_then_else (eq_attr "mode" "SI")
11869                    (const_string "avx512bw")
11870                    (const_string "avx512f"))
11871               ]
11872               (const_string "*")))
11873    (set_attr "type" "alu,alu,alu,alu,alu,imovx,msklog")
11874    (set_attr "length_immediate" "*,*,*,*,*,0,*")
11875    (set (attr "prefix_rex")
11876      (if_then_else
11877        (and (eq_attr "type" "imovx")
11878             (and (match_test "INTVAL (operands[2]) == 0xff")
11879                  (match_operand 1 "ext_QIreg_operand")))
11880        (const_string "1")
11881        (const_string "*")))
11882    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<MODE>,SI,<MODE>")])
11884 (define_insn "*andqi_1"
11885   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r,?k")
11886         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r,k")
11887                 (match_operand:QI 2 "general_operand" "qn,m,rn,rn,m,k")))
11888    (clobber (reg:CC FLAGS_REG))]
11889   "ix86_binary_operator_ok (AND, QImode, operands, TARGET_APX_NDD)"
11890   "@
11891    and{b}\t{%2, %0|%0, %2}
11892    and{b}\t{%2, %0|%0, %2}
11893    and{l}\t{%k2, %k0|%k0, %k2}
11894    and{b}\t{%2, %1, %0|%0, %1, %2}
11895    and{b}\t{%2, %1, %0|%0, %1, %2}
11896    #"
11897   [(set_attr "type" "alu,alu,alu,alu,alu,msklog")
11898    (set_attr "isa" "*,*,*,apx_ndd,apx_ndd,*")
11899    (set (attr "mode")
11900         (cond [(eq_attr "alternative" "2")
11901                  (const_string "SI")
11902                 (and (eq_attr "alternative" "5")
11903                      (match_test "!TARGET_AVX512DQ"))
11904                  (const_string "HI")
11905                ]
11906                (const_string "QI")))
11907    ;; Potential partial reg stall on alternative 2.
11908    (set (attr "preferred_for_speed")
11909      (cond [(eq_attr "alternative" "2")
11910               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11911            (symbol_ref "true")))])
11913 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11914 (define_insn_and_split "*<code><mode>_1_slp"
11915   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
11916         (any_logic:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
11917                       (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
11918    (clobber (reg:CC FLAGS_REG))]
11919   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11920   "@
11921    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11922    #"
11923   "&& reload_completed
11924    && !(rtx_equal_p (operands[0], operands[1])
11925         || rtx_equal_p (operands[0], operands[2]))"
11926   [(set (strict_low_part (match_dup 0)) (match_dup 1))
11927    (parallel
11928      [(set (strict_low_part (match_dup 0))
11929            (any_logic:SWI12 (match_dup 0) (match_dup 2)))
11930       (clobber (reg:CC FLAGS_REG))])]
11931   ""
11932   [(set_attr "type" "alu")
11933    (set_attr "mode" "<MODE>")])
11935 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11936 (define_insn_and_split "*<code>qi_ext<mode>_1_slp"
11937   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
11938         (any_logic:QI
11939           (subreg:QI
11940             (match_operator:SWI248 3 "extract_operator"
11941               [(match_operand 2 "int248_register_operand" "Q,Q")
11942                (const_int 8)
11943                (const_int 8)]) 0)
11944           (match_operand:QI 1 "nonimmediate_operand" "0,!qm")))
11945    (clobber (reg:CC FLAGS_REG))]
11946   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11947   "@
11948    <logic>{b}\t{%h2, %0|%0, %h2}
11949    #"
11950   "&& reload_completed
11951    && !rtx_equal_p (operands[0], operands[1])"
11952   [(set (strict_low_part (match_dup 0)) (match_dup 1))
11953    (parallel
11954      [(set (strict_low_part (match_dup 0))
11955            (any_logic:QI
11956              (subreg:QI
11957                (match_op_dup 3
11958                  [(match_dup 2) (const_int 8) (const_int 8)]) 0)
11959              (match_dup 0)))
11960       (clobber (reg:CC FLAGS_REG))])]
11961   ""
11962   [(set_attr "type" "alu")
11963    (set_attr "mode" "QI")])
11965 (define_insn_and_split "*<code>qi_ext<mode>_2_slp"
11966   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
11967         (any_logic:QI
11968           (subreg:QI
11969             (match_operator:SWI248 3 "extract_operator"
11970               [(match_operand 1 "int248_register_operand" "Q")
11971                (const_int 8)
11972                (const_int 8)]) 0)
11973           (subreg:QI
11974             (match_operator:SWI248 4 "extract_operator"
11975               [(match_operand 2 "int248_register_operand" "Q")
11976                (const_int 8)
11977                (const_int 8)]) 0)))
11978    (clobber (reg:CC FLAGS_REG))]
11979   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11980   "#"
11981   "&& reload_completed"
11982   [(set (strict_low_part (match_dup 0))
11983         (subreg:QI
11984           (match_op_dup 4
11985             [(match_dup 2) (const_int 8) (const_int 8)]) 0))
11986    (parallel
11987      [(set (strict_low_part (match_dup 0))
11988            (any_logic:QI
11989              (subreg:QI
11990                (match_op_dup 3
11991                  [(match_dup 1) (const_int 8) (const_int 8)]) 0)
11992              (match_dup 0)))
11993       (clobber (reg:CC FLAGS_REG))])]
11994   ""
11995   [(set_attr "type" "alu")
11996    (set_attr "mode" "QI")])
11998 (define_split
11999   [(set (match_operand:SWI248 0 "register_operand")
12000         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
12001                     (match_operand:SWI248 2 "const_int_operand")))
12002    (clobber (reg:CC FLAGS_REG))]
12003   "reload_completed
12004    && (!REG_P (operands[1])
12005        || REGNO (operands[0]) != REGNO (operands[1]))
12006    && (UINTVAL (operands[2]) == GET_MODE_MASK (SImode)
12007        || UINTVAL (operands[2]) == GET_MODE_MASK (HImode)
12008        || UINTVAL (operands[2]) == GET_MODE_MASK (QImode))"
12009   [(const_int 0)]
12011   unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
12012   machine_mode mode;
12014   if (ival == GET_MODE_MASK (SImode))
12015     mode = SImode;
12016   else if (ival == GET_MODE_MASK (HImode))
12017     mode = HImode;
12018   else if (ival == GET_MODE_MASK (QImode))
12019     mode = QImode;
12020   else
12021     gcc_unreachable ();
12023   /* Zero extend to SImode to avoid partial register stalls.  */
12024   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
12025     operands[0] = gen_lowpart (SImode, operands[0]);
12027   emit_insn (gen_extend_insn
12028              (operands[0], gen_lowpart (mode, operands[1]),
12029               GET_MODE (operands[0]), mode, 1));
12030   DONE;
12033 (define_split
12034   [(set (match_operand:SWI48 0 "register_operand")
12035         (and:SWI48 (match_dup 0)
12036                    (const_int -65536)))
12037    (clobber (reg:CC FLAGS_REG))]
12038   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
12039     || optimize_function_for_size_p (cfun)"
12040   [(set (strict_low_part (match_dup 1)) (const_int 0))]
12041   "operands[1] = gen_lowpart (HImode, operands[0]);")
12043 (define_split
12044   [(set (match_operand:SWI248 0 "any_QIreg_operand")
12045         (and:SWI248 (match_dup 0)
12046                     (const_int -256)))
12047    (clobber (reg:CC FLAGS_REG))]
12048   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12049    && reload_completed"
12050   [(set (strict_low_part (match_dup 1)) (const_int 0))]
12051   "operands[1] = gen_lowpart (QImode, operands[0]);")
12053 (define_split
12054   [(set (match_operand:SWI248 0 "QIreg_operand")
12055         (and:SWI248 (match_dup 0)
12056                     (const_int -65281)))
12057    (clobber (reg:CC FLAGS_REG))]
12058   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12059    && reload_completed"
12060   [(parallel
12061      [(set (zero_extract:HI (match_dup 0)
12062                             (const_int 8)
12063                             (const_int 8))
12064            (subreg:HI
12065              (xor:QI
12066                (subreg:QI
12067                  (zero_extract:HI (match_dup 0)
12068                                   (const_int 8)
12069                                   (const_int 8)) 0)
12070                (subreg:QI
12071                  (zero_extract:HI (match_dup 0)
12072                                   (const_int 8)
12073                                   (const_int 8)) 0)) 0))
12074       (clobber (reg:CC FLAGS_REG))])]
12075   "operands[0] = gen_lowpart (HImode, operands[0]);")
12077 (define_insn "*anddi_2"
12078   [(set (reg FLAGS_REG)
12079         (compare
12080          (and:DI
12081           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,r,rm,r")
12082           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,Z,re,m"))
12083          (const_int 0)))
12084    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,r,r")
12085         (and:DI (match_dup 1) (match_dup 2)))]
12086   "TARGET_64BIT
12087    && ix86_match_ccmode
12088         (insn,
12089          /* If we are going to emit andl instead of andq, and the operands[2]
12090             constant might have the SImode sign bit set, make sure the sign
12091             flag isn't tested, because the instruction will set the sign flag
12092             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
12093             conservatively assume it might have bit 31 set.  */
12094          (satisfies_constraint_Z (operands[2])
12095           && (!CONST_INT_P (operands[2])
12096               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
12097          ? CCZmode : CCNOmode)
12098    && ix86_binary_operator_ok (AND, DImode, operands, TARGET_APX_NDD)"
12099   "@
12100    and{l}\t{%k2, %k0|%k0, %k2}
12101    and{q}\t{%2, %0|%0, %2}
12102    and{q}\t{%2, %0|%0, %2}
12103    and{l}\t{%k2, %k1, %k0|%k0, %k1, %k2}
12104    and{q}\t{%2, %1, %0|%0, %1, %2}
12105    and{q}\t{%2, %1, %0|%0, %1, %2}"
12106   [(set_attr "type" "alu")
12107    (set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd")
12108    (set_attr "mode" "SI,DI,DI,SI,DI,DI")])
12110 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12111 (define_insn "*andsi_2_zext"
12112   [(set (reg FLAGS_REG)
12113         (compare (and:SI
12114                   (match_operand:SI 1 "nonimmediate_operand" "%0,rm,r")
12115                   (match_operand:SI 2 "x86_64_general_operand" "rBMe,re,BM"))
12116                  (const_int 0)))
12117    (set (match_operand:DI 0 "register_operand" "=r,r,r")
12118         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
12119   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12120    && ix86_binary_operator_ok (AND, SImode, operands, TARGET_APX_NDD)"
12121   "@
12122   and{l}\t{%2, %k0|%k0, %2}
12123   and{l}\t{%2, %1, %k0|%k0, %1, %2}
12124   and{l}\t{%2, %1, %k0|%k0, %1, %2}"
12125   [(set_attr "type" "alu")
12126    (set_attr "isa" "*,apx_ndd,apx_ndd")
12127    (set_attr "mode" "SI")])
12129 (define_insn "*andqi_2_maybe_si"
12130   [(set (reg FLAGS_REG)
12131         (compare (and:QI
12132                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r")
12133                   (match_operand:QI 2 "general_operand" "qn,m,n,rn,m"))
12134                  (const_int 0)))
12135    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r")
12136         (and:QI (match_dup 1) (match_dup 2)))]
12137   "ix86_binary_operator_ok (AND, QImode, operands, TARGET_APX_NDD)
12138    && ix86_match_ccmode (insn,
12139                          CONST_INT_P (operands[2])
12140                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
12142   if (get_attr_mode (insn) == MODE_SI)
12143     {
12144       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
12145         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
12146       return "and{l}\t{%2, %k0|%k0, %2}";
12147     }
12148   if (which_alternative > 2)
12149     return "and{b}\t{%2, %1, %0|%0, %1, %2}";
12150   return "and{b}\t{%2, %0|%0, %2}";
12152   [(set_attr "type" "alu")
12153    (set_attr "isa" "*,*,*,apx_ndd,apx_ndd")
12154    (set (attr "mode")
12155      (cond [(eq_attr "alternative" "3,4")
12156               (const_string "QI")
12157             (eq_attr "alternative" "2")
12158               (const_string "SI")
12159             (and (match_test "optimize_insn_for_size_p ()")
12160                  (and (match_operand 0 "ext_QIreg_operand")
12161                       (match_operand 2 "const_0_to_127_operand")))
12162               (const_string "SI")
12163            ]
12164            (const_string "QI")))
12165    ;; Potential partial reg stall on alternative 2.
12166    (set (attr "preferred_for_speed")
12167      (cond [(eq_attr "alternative" "2")
12168               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12169            (symbol_ref "true")))])
12171 (define_insn "*and<mode>_2"
12172   [(set (reg FLAGS_REG)
12173         (compare (and:SWI124
12174                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0,rm,r")
12175                   (match_operand:SWI124 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>"))
12176                  (const_int 0)))
12177    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
12178         (and:SWI124 (match_dup 1) (match_dup 2)))]
12179   "ix86_match_ccmode (insn, CCNOmode)
12180    && ix86_binary_operator_ok (AND, <MODE>mode, operands, TARGET_APX_NDD)"
12181   "@
12182   and{<imodesuffix>}\t{%2, %0|%0, %2}
12183   and{<imodesuffix>}\t{%2, %0|%0, %2}
12184   and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
12185   and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
12186   [(set_attr "type" "alu")
12187    (set_attr "isa" "*,*,apx_ndd,apx_ndd")
12188    (set_attr "mode" "<MODE>")])
12190 (define_insn "*<code>qi_ext<mode>_0"
12191   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
12192         (any_logic:QI
12193           (subreg:QI
12194             (match_operator:SWI248 3 "extract_operator"
12195               [(match_operand 2 "int248_register_operand" "Q")
12196                (const_int 8)
12197                (const_int 8)]) 0)
12198           (match_operand:QI 1 "nonimmediate_operand" "0")))
12199    (clobber (reg:CC FLAGS_REG))]
12200   ""
12201   "<logic>{b}\t{%h2, %0|%0, %h2}"
12202   [(set_attr "addr" "gpr8")
12203    (set_attr "type" "alu")
12204    (set_attr "mode" "QI")])
12206 (define_insn_and_split "*<code>qi_ext2<mode>_0"
12207   [(set (match_operand:QI 0 "register_operand" "=&Q")
12208         (any_logic:QI
12209           (subreg:QI
12210             (match_operator:SWI248 3 "extract_operator"
12211               [(match_operand 1 "int248_register_operand" "Q")
12212                (const_int 8)
12213                (const_int 8)]) 0)
12214           (subreg:QI
12215             (match_operator:SWI248 4 "extract_operator"
12216               [(match_operand 2 "int248_register_operand" "Q")
12217                (const_int 8)
12218                (const_int 8)]) 0)))
12219    (clobber (reg:CC FLAGS_REG))]
12220   ""
12221   "#"
12222   "&& reload_completed"
12223   [(set (match_dup 0)
12224         (subreg:QI
12225           (match_op_dup 4
12226             [(match_dup 2) (const_int 8) (const_int 8)]) 0))
12227    (parallel
12228      [(set (match_dup 0)
12229            (any_logic:QI
12230              (subreg:QI
12231                (match_op_dup 3
12232                  [(match_dup 1) (const_int 8) (const_int 8)]) 0)
12233            (match_dup 0)))
12234       (clobber (reg:CC FLAGS_REG))])]
12235   ""
12236   [(set_attr "type" "alu")
12237    (set_attr "mode" "QI")])
12239 (define_expand "andqi_ext_1"
12240   [(parallel
12241      [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
12242                             (const_int 8)
12243                             (const_int 8))
12244            (subreg:HI
12245              (and:QI
12246                (subreg:QI
12247                  (zero_extract:HI (match_operand:HI 1 "register_operand")
12248                                   (const_int 8)
12249                                   (const_int 8)) 0)
12250                (match_operand:QI 2 "const_int_operand")) 0))
12251       (clobber (reg:CC FLAGS_REG))])])
12253 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12254 (define_insn_and_split "*<code>qi_ext<mode>_1"
12255   [(set (zero_extract:SWI248
12256           (match_operand 0 "int248_register_operand" "+Q,&Q")
12257           (const_int 8)
12258           (const_int 8))
12259         (subreg:SWI248
12260           (any_logic:QI
12261             (subreg:QI
12262               (match_operator:SWI248 3 "extract_operator"
12263                 [(match_operand 1 "int248_register_operand" "0,!Q")
12264                  (const_int 8)
12265                  (const_int 8)]) 0)
12266             (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
12267    (clobber (reg:CC FLAGS_REG))]
12268   ""
12269   "@
12270    <logic>{b}\t{%2, %h0|%h0, %2}
12271    #"
12272   "reload_completed
12273    && !(rtx_equal_p (operands[0], operands[1]))"
12274   [(set (zero_extract:SWI248
12275           (match_dup 0) (const_int 8) (const_int 8))
12276         (zero_extract:SWI248
12277           (match_dup 1) (const_int 8) (const_int 8)))
12278    (parallel
12279      [(set (zero_extract:SWI248
12280              (match_dup 0) (const_int 8) (const_int 8))
12281            (subreg:SWI248
12282              (any_logic:QI
12283                (subreg:QI
12284                  (match_op_dup 3
12285                    [(match_dup 0) (const_int 8) (const_int 8)]) 0)
12286                (match_dup 2)) 0))
12287       (clobber (reg:CC FLAGS_REG))])]
12288   ""
12289   [(set_attr "addr" "gpr8")
12290    (set_attr "type" "alu")
12291    (set_attr "mode" "QI")])
12293 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12294 (define_insn_and_split "*<code>qi_ext<mode>_1_cc"
12295   [(set (match_operand 4 "flags_reg_operand")
12296         (match_operator 5 "compare_operator"
12297           [(any_logic:QI
12298              (subreg:QI
12299                (match_operator:SWI248 3 "extract_operator"
12300                  [(match_operand 1 "int248_register_operand" "0,!Q")
12301                   (const_int 8)
12302                   (const_int 8)]) 0)
12303              (match_operand:QI 2 "general_operand" "QnBn,QnBn"))
12304           (const_int 0)]))
12305    (set (zero_extract:SWI248
12306           (match_operand 0 "int248_register_operand" "+Q,&Q")
12307           (const_int 8)
12308           (const_int 8))
12309         (subreg:SWI248
12310           (any_logic:QI
12311             (subreg:QI
12312               (match_op_dup 3
12313                 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
12314             (match_dup 2)) 0))]
12315   "ix86_match_ccmode (insn, CCNOmode)"
12316   "@
12317    <logic>{b}\t{%2, %h0|%h0, %2}
12318    #"
12319   "&& reload_completed
12320    && !(rtx_equal_p (operands[0], operands[1]))"
12321   [(set (zero_extract:SWI248
12322           (match_dup 0) (const_int 8) (const_int 8))
12323         (zero_extract:SWI248
12324           (match_dup 1) (const_int 8) (const_int 8)))
12325    (parallel
12326      [(set (match_dup 4)
12327            (match_op_dup 5
12328              [(any_logic:QI
12329                 (subreg:QI
12330                   (match_op_dup 3
12331                     [(match_dup 0) (const_int 8) (const_int 8)]) 0)
12332                 (match_dup 2))
12333               (const_int 0)]))
12334       (set (zero_extract:SWI248
12335              (match_dup 0) (const_int 8) (const_int 8))
12336            (subreg:SWI248
12337              (any_logic:QI
12338                (subreg:QI
12339                  (match_op_dup 3
12340                    [(match_dup 1) (const_int 8) (const_int 8)]) 0)
12341                (match_dup 2)) 0))])]
12342   ""
12343   [(set_attr "addr" "gpr8")
12344    (set_attr "type" "alu")
12345    (set_attr "mode" "QI")])
12347 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12348 (define_insn_and_split "*<code>qi_ext<mode>_2"
12349   [(set (zero_extract:SWI248
12350           (match_operand 0 "int248_register_operand" "+Q,&Q")
12351           (const_int 8)
12352           (const_int 8))
12353         (subreg:SWI248
12354           (any_logic:QI
12355             (subreg:QI
12356               (match_operator:SWI248 3 "extract_operator"
12357                 [(match_operand 1 "int248_register_operand" "%0,!Q")
12358                  (const_int 8)
12359                  (const_int 8)]) 0)
12360             (subreg:QI
12361               (match_operator:SWI248 4 "extract_operator"
12362                 [(match_operand 2 "int248_register_operand" "Q,Q")
12363                  (const_int 8)
12364                  (const_int 8)]) 0)) 0))
12365    (clobber (reg:CC FLAGS_REG))]
12366   ""
12367   "@
12368    <logic>{b}\t{%h2, %h0|%h0, %h2}
12369    #"
12370   "reload_completed
12371    && !(rtx_equal_p (operands[0], operands[1])
12372         || rtx_equal_p (operands[0], operands[2]))"
12373   [(set (zero_extract:SWI248
12374           (match_dup 0) (const_int 8) (const_int 8))
12375         (zero_extract:SWI248
12376           (match_dup 1) (const_int 8) (const_int 8)))
12377    (parallel
12378      [(set (zero_extract:SWI248
12379              (match_dup 0) (const_int 8) (const_int 8))
12380            (subreg:SWI248
12381              (any_logic:QI
12382                (subreg:QI
12383                  (match_op_dup 3
12384                    [(match_dup 0) (const_int 8) (const_int 8)]) 0)
12385                (subreg:QI
12386                  (match_op_dup 4
12387                    [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
12388       (clobber (reg:CC FLAGS_REG))])]
12389   ""
12390   [(set_attr "type" "alu")
12391    (set_attr "mode" "QI")])
12393 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12394 (define_insn_and_split "*<code>qi_ext<mode>_3"
12395   [(set (zero_extract:SWI248
12396           (match_operand 0 "int248_register_operand" "+Q,&Q")
12397           (const_int 8)
12398           (const_int 8))
12399         (match_operator:SWI248 3 "extract_operator"
12400           [(any_logic
12401              (match_operand 1 "int248_register_operand" "%0,!Q")
12402              (match_operand 2 "int248_register_operand" "Q,Q"))
12403            (const_int 8)
12404            (const_int 8)]))
12405    (clobber (reg:CC FLAGS_REG))]
12406   "GET_MODE (operands[1]) == GET_MODE (operands[2])"
12407   "@
12408    <logic>{b}\t{%h2, %h0|%h0, %h2}
12409    #"
12410   "&& reload_completed
12411    && !(rtx_equal_p (operands[0], operands[1])
12412         || rtx_equal_p (operands[0], operands[2]))"
12413   [(set (zero_extract:SWI248
12414           (match_dup 0) (const_int 8) (const_int 8))
12415         (zero_extract:SWI248
12416           (match_dup 1) (const_int 8) (const_int 8)))
12417    (parallel
12418      [(set (zero_extract:SWI248
12419              (match_dup 0) (const_int 8) (const_int 8))
12420            (match_op_dup 3
12421              [(any_logic (match_dup 4) (match_dup 2))
12422               (const_int 8) (const_int 8)]))
12423       (clobber (reg:CC FLAGS_REG))])]
12424   "operands[4] = gen_lowpart (GET_MODE (operands[1]), operands[0]);"
12425   [(set_attr "type" "alu")
12426    (set_attr "mode" "QI")])
12428 ;; Convert wide AND instructions with immediate operand to shorter QImode
12429 ;; equivalents when possible.
12430 ;; Don't do the splitting with memory operands, since it introduces risk
12431 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
12432 ;; for size, but that can (should?) be handled by generic code instead.
12433 ;; Don't do the splitting for APX NDD as NDD does not support *h registers.
12434 (define_split
12435   [(set (match_operand:SWI248 0 "QIreg_operand")
12436         (and:SWI248 (match_operand:SWI248 1 "register_operand")
12437                     (match_operand:SWI248 2 "const_int_operand")))
12438    (clobber (reg:CC FLAGS_REG))]
12439    "reload_completed
12440     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12441     && !(~INTVAL (operands[2]) & ~(255 << 8))
12442     && !(TARGET_APX_NDD && REGNO (operands[0]) != REGNO (operands[1]))"
12443   [(parallel
12444      [(set (zero_extract:HI (match_dup 0)
12445                             (const_int 8)
12446                             (const_int 8))
12447            (subreg:HI
12448              (and:QI
12449                (subreg:QI
12450                  (zero_extract:HI (match_dup 1)
12451                                   (const_int 8)
12452                                   (const_int 8)) 0)
12453                (match_dup 2)) 0))
12454       (clobber (reg:CC FLAGS_REG))])]
12456   operands[0] = gen_lowpart (HImode, operands[0]);
12457   operands[1] = gen_lowpart (HImode, operands[1]);
12458   operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
12461 ;; Since AND can be encoded with sign extended immediate, this is only
12462 ;; profitable when 7th bit is not set.
12463 (define_split
12464   [(set (match_operand:SWI248 0 "any_QIreg_operand")
12465         (and:SWI248 (match_operand:SWI248 1 "general_operand")
12466                     (match_operand:SWI248 2 "const_int_operand")))
12467    (clobber (reg:CC FLAGS_REG))]
12468    "reload_completed
12469     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12470     && !(~INTVAL (operands[2]) & ~255)
12471     && !(INTVAL (operands[2]) & 128)
12472     && !(TARGET_APX_NDD
12473          && !rtx_equal_p (operands[0], operands[1]))"
12474   [(parallel [(set (strict_low_part (match_dup 0))
12475                    (and:QI (match_dup 1)
12476                            (match_dup 2)))
12477               (clobber (reg:CC FLAGS_REG))])]
12479   operands[0] = gen_lowpart (QImode, operands[0]);
12480   operands[1] = gen_lowpart (QImode, operands[1]);
12481   operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
12484 (define_insn_and_split "*andn<dwi>3_doubleword_bmi"
12485   [(set (match_operand:<DWI> 0 "register_operand" "=&r,&r,r,r")
12486         (and:<DWI>
12487           (not:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r,0,r"))
12488           (match_operand:<DWI> 2 "nonimmediate_operand" "r,o,ro,0")))
12489    (clobber (reg:CC FLAGS_REG))]
12490   "TARGET_BMI"
12491   "#"
12492   "&& reload_completed"
12493   [(parallel [(set (match_dup 0)
12494                    (and:DWIH (not:DWIH (match_dup 1)) (match_dup 2)))
12495               (clobber (reg:CC FLAGS_REG))])
12496    (parallel [(set (match_dup 3)
12497                    (and:DWIH (not:DWIH (match_dup 4)) (match_dup 5)))
12498               (clobber (reg:CC FLAGS_REG))])]
12499   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);"
12500   [(set_attr "isa" "x64,*,*,*")])
12502 (define_insn_and_split "*andn<mode>3_doubleword"
12503   [(set (match_operand:DWI 0 "register_operand")
12504         (and:DWI
12505           (not:DWI (match_operand:DWI 1 "register_operand"))
12506           (match_operand:DWI 2 "nonimmediate_operand")))
12507    (clobber (reg:CC FLAGS_REG))]
12508   "!TARGET_BMI
12509    && ix86_pre_reload_split ()"
12510   "#"
12511   "&& 1"
12512   [(set (match_dup 3) (not:DWI (match_dup 1)))
12513    (parallel [(set (match_dup 0)
12514                    (and:DWI (match_dup 3) (match_dup 2)))
12515               (clobber (reg:CC FLAGS_REG))])]
12516   "operands[3] = gen_reg_rtx (<MODE>mode);")
12518 (define_insn "*andn<mode>_1"
12519   [(set (match_operand:SWI48 0 "register_operand" "=r,r,?k")
12520         (and:SWI48
12521           (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r,k"))
12522           (match_operand:SWI48 2 "nonimmediate_operand" "r,m,k")))
12523    (clobber (reg:CC FLAGS_REG))]
12524   "TARGET_BMI || TARGET_AVX512BW"
12525   "@
12526    andn\t{%2, %1, %0|%0, %1, %2}
12527    andn\t{%2, %1, %0|%0, %1, %2}
12528    #"
12529   [(set_attr "isa" "bmi,bmi,avx512bw")
12530    (set_attr "type" "bitmanip,bitmanip,msklog")
12531    (set_attr "btver2_decode" "direct, double,*")
12532    (set_attr "mode" "<MODE>")])
12534 (define_insn "*andn<mode>_1"
12535   [(set (match_operand:SWI12 0 "register_operand" "=r,?k")
12536         (and:SWI12
12537           (not:SWI12 (match_operand:SWI12 1 "register_operand" "r,k"))
12538           (match_operand:SWI12 2 "register_operand" "r,k")))
12539    (clobber (reg:CC FLAGS_REG))]
12540   "TARGET_BMI || TARGET_AVX512BW"
12541   "@
12542    andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
12543    #"
12544   [(set_attr "isa" "bmi,avx512f")
12545    (set_attr "type" "bitmanip,msklog")
12546    (set_attr "btver2_decode" "direct,*")
12547    (set (attr "mode")
12548         (cond [(eq_attr "alternative" "0")
12549                  (const_string "SI")
12550                (and (eq_attr "alternative" "1")
12551                     (match_test "!TARGET_AVX512DQ"))
12552                   (const_string "HI")
12553               ]
12554               (const_string "<MODE>")))])
12556 (define_insn "*andn_<mode>_ccno"
12557   [(set (reg FLAGS_REG)
12558         (compare
12559           (and:SWI48
12560             (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12561             (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
12562           (const_int 0)))
12563    (clobber (match_scratch:SWI48 0 "=r,r"))]
12564   "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
12565   "andn\t{%2, %1, %0|%0, %1, %2}"
12566   [(set_attr "type" "bitmanip")
12567    (set_attr "btver2_decode" "direct, double")
12568    (set_attr "mode" "<MODE>")])
12570 ;; Split *andnsi_1 after reload with -Oz when not;and is shorter.
12571 (define_split
12572   [(set (match_operand:SI 0 "register_operand")
12573         (and:SI (not:SI (match_operand:SI 1 "register_operand"))
12574                 (match_operand:SI 2 "nonimmediate_operand")))
12575    (clobber (reg:CC FLAGS_REG))]
12576   "reload_completed
12577    && optimize_insn_for_size_p () && optimize_size > 1
12578    && REGNO (operands[0]) == REGNO (operands[1])
12579    && LEGACY_INT_REG_P (operands[0])
12580    && !REX_INT_REG_P (operands[2])
12581    && !reg_overlap_mentioned_p (operands[0], operands[2])"
12582   [(set (match_dup 0) (not:SI (match_dup 1)))
12583    (parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
12584               (clobber (reg:CC FLAGS_REG))])])
12586 ;; Split *andn_si_ccno with -Oz when not;test is shorter.
12587 (define_split
12588   [(set (match_operand 0 "flags_reg_operand")
12589         (match_operator 1 "compare_operator"
12590           [(and:SI (not:SI (match_operand:SI 2 "general_reg_operand"))
12591                    (match_operand:SI 3 "nonimmediate_operand"))
12592            (const_int 0)]))
12593    (clobber (match_dup 2))]
12594   "reload_completed
12595    && optimize_insn_for_size_p () && optimize_size > 1
12596    && LEGACY_INT_REG_P (operands[2])
12597    && !REX_INT_REG_P (operands[3])
12598    && !reg_overlap_mentioned_p (operands[2], operands[3])"
12599   [(set (match_dup 2) (not:SI (match_dup 2)))
12600    (set (match_dup 0) (match_op_dup 1
12601                         [(and:SI (match_dup 3) (match_dup 2))
12602                          (const_int 0)]))])
12604 ;; Variant 1 of 4: Split ((A | B) ^ A) ^ C as (B & ~A) ^ C.
12605 (define_split
12606   [(set (match_operand:SWI48 0 "register_operand")
12607         (xor:SWI48
12608            (xor:SWI48
12609               (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12610                          (match_operand:SWI48 2 "nonimmediate_operand"))
12611               (match_dup 1))
12612            (match_operand:SWI48 3 "nonimmediate_operand")))
12613    (clobber (reg:CC FLAGS_REG))]
12614   "TARGET_BMI"
12615   [(parallel
12616       [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
12617        (clobber (reg:CC FLAGS_REG))])
12618    (parallel
12619       [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12620        (clobber (reg:CC FLAGS_REG))])]
12621   "operands[4] = gen_reg_rtx (<MODE>mode);")
12623 ;; Variant 2 of 4: Split ((A | B) ^ B) ^ C as (A & ~B) ^ C.
12624 (define_split
12625   [(set (match_operand:SWI48 0 "register_operand")
12626         (xor:SWI48
12627            (xor:SWI48
12628               (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12629                          (match_operand:SWI48 2 "register_operand"))
12630               (match_dup 2))
12631            (match_operand:SWI48 3 "nonimmediate_operand")))
12632    (clobber (reg:CC FLAGS_REG))]
12633   "TARGET_BMI"
12634   [(parallel
12635       [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
12636        (clobber (reg:CC FLAGS_REG))])
12637    (parallel
12638       [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12639        (clobber (reg:CC FLAGS_REG))])]
12640   "operands[4] = gen_reg_rtx (<MODE>mode);")
12642 ;; Variant 3 of 4: Split ((A | B) ^ C) ^ A as (B & ~A) ^ C.
12643 (define_split
12644   [(set (match_operand:SWI48 0 "register_operand")
12645         (xor:SWI48
12646            (xor:SWI48
12647               (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12648                          (match_operand:SWI48 2 "nonimmediate_operand"))
12649               (match_operand:SWI48 3 "nonimmediate_operand"))
12650            (match_dup 1)))
12651    (clobber (reg:CC FLAGS_REG))]
12652   "TARGET_BMI"
12653   [(parallel
12654       [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
12655        (clobber (reg:CC FLAGS_REG))])
12656    (parallel
12657       [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12658        (clobber (reg:CC FLAGS_REG))])]
12659   "operands[4] = gen_reg_rtx (<MODE>mode);")
12661 ;; Variant 4 of 4: Split ((A | B) ^ C) ^ B as (A & ~B) ^ C.
12662 (define_split
12663   [(set (match_operand:SWI48 0 "register_operand")
12664         (xor:SWI48
12665            (xor:SWI48
12666               (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12667                          (match_operand:SWI48 2 "register_operand"))
12668               (match_operand:SWI48 3 "nonimmediate_operand"))
12669            (match_dup 2)))
12670    (clobber (reg:CC FLAGS_REG))]
12671   "TARGET_BMI"
12672   [(parallel
12673       [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
12674        (clobber (reg:CC FLAGS_REG))])
12675    (parallel
12676       [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12677        (clobber (reg:CC FLAGS_REG))])]
12678   "operands[4] = gen_reg_rtx (<MODE>mode);")
12680 ;; Logical inclusive and exclusive OR instructions
12682 ;; %%% This used to optimize known byte-wide and operations to memory.
12683 ;; If this is considered useful, it should be done with splitters.
12685 (define_expand "<code><mode>3"
12686   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12687         (any_or:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
12688                       (match_operand:SDWIM 2 "<general_operand>")))]
12689   ""
12691   if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
12692       && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
12693     operands[2] = force_reg (<MODE>mode, operands[2]);
12695   ix86_expand_binary_operator (<CODE>, <MODE>mode, operands, TARGET_APX_NDD);
12696   DONE;
12699 (define_insn_and_split "*<code><dwi>3_doubleword"
12700   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r,&r,&r,&r")
12701         (any_or:<DWI>
12702          (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r,ro,jO,r")
12703          (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r,<di>,K,<di>,o")))
12704    (clobber (reg:CC FLAGS_REG))]
12705   "ix86_binary_operator_ok (<CODE>, <DWI>mode, operands, TARGET_APX_NDD)"
12706   "#"
12707   "&& reload_completed"
12708   [(const_int:DWIH 0)]
12710   /* This insn may disappear completely when operands[2] == const0_rtx
12711      and operands[0] == operands[1], which requires a NOTE_INSN_DELETED.  */
12712   bool emit_insn_deleted_note_p = false;
12714   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
12716   if (operands[2] == const0_rtx)
12717     {
12718       if (!rtx_equal_p (operands[0], operands[1]))
12719         emit_move_insn (operands[0], operands[1]);
12720       else
12721         emit_insn_deleted_note_p = true;
12722     }
12723   else if (operands[2] == constm1_rtx)
12724     {
12725       if (<CODE> == IOR)
12726         emit_move_insn (operands[0], constm1_rtx);
12727       else
12728         ix86_expand_unary_operator (NOT, <MODE>mode, &operands[0],
12729                                     TARGET_APX_NDD);
12730     }
12731   else
12732     ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[0],
12733                                  TARGET_APX_NDD);
12735   if (operands[5] == const0_rtx)
12736     {
12737       if (!rtx_equal_p (operands[3], operands[4]))
12738         emit_move_insn (operands[3], operands[4]);
12739       else if (emit_insn_deleted_note_p)
12740         emit_note (NOTE_INSN_DELETED);
12741     }
12742   else if (operands[5] == constm1_rtx)
12743     {
12744       if (<CODE> == IOR)
12745         emit_move_insn (operands[3], constm1_rtx);
12746       else
12747         ix86_expand_unary_operator (NOT, <MODE>mode, &operands[3],
12748                                     TARGET_APX_NDD);
12749     }
12750   else
12751     ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[3],
12752                                  TARGET_APX_NDD);
12754   DONE;
12756 [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd_64,apx_ndd")])
12758 (define_insn "*<code><mode>_1"
12759   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,r,r,r,?k")
12760         (any_or:SWI248
12761          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,rm,rjM,r,k")
12762          (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,r,<i>,<m>,k")))
12763    (clobber (reg:CC FLAGS_REG))]
12764   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)"
12765   "@
12766    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12767    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12768    <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
12769    <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
12770    <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
12771    #"
12772   [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,<kmov_isa>")
12773    (set_attr "type" "alu, alu, alu, alu, alu, msklog")
12774    (set_attr "mode" "<MODE>")])
12776 (define_insn_and_split "*notxor<mode>_1"
12777   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,r,r,?k")
12778         (not:SWI248
12779           (xor:SWI248
12780             (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,rm,r,k")
12781             (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,r<i>,<m>,k"))))
12782    (clobber (reg:CC FLAGS_REG))]
12783   "ix86_binary_operator_ok (XOR, <MODE>mode, operands, TARGET_APX_NDD)"
12784   "#"
12785   "&& reload_completed"
12786   [(parallel
12787     [(set (match_dup 0)
12788           (xor:SWI248 (match_dup 1) (match_dup 2)))
12789      (clobber (reg:CC FLAGS_REG))])
12790    (set (match_dup 0)
12791         (not:SWI248 (match_dup 0)))]
12793   if (MASK_REG_P (operands[0]))
12794     {
12795       emit_insn (gen_kxnor<mode> (operands[0], operands[1], operands[2]));
12796       DONE;
12797     }
12799   [(set_attr "isa" "*,*,apx_ndd,apx_ndd,<kmov_isa>")
12800    (set_attr "type" "alu, alu, alu, alu, msklog")
12801    (set_attr "mode" "<MODE>")])
12803 (define_insn_and_split "*iordi_1_bts"
12804   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12805         (ior:DI
12806          (match_operand:DI 1 "nonimmediate_operand" "%0")
12807          (match_operand:DI 2 "const_int_operand" "n")))
12808    (clobber (reg:CC FLAGS_REG))]
12809   "TARGET_64BIT && TARGET_USE_BT
12810    && ix86_binary_operator_ok (IOR, DImode, operands)
12811    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
12812   "#"
12813   "&& reload_completed"
12814   [(parallel [(set (zero_extract:DI (match_dup 0)
12815                                     (const_int 1)
12816                                     (match_dup 3))
12817                    (const_int 1))
12818               (clobber (reg:CC FLAGS_REG))])]
12819   "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
12820   [(set_attr "type" "alu1")
12821    (set_attr "prefix_0f" "1")
12822    (set_attr "znver1_decode" "double")
12823    (set_attr "mode" "DI")])
12825 (define_insn_and_split "*xordi_1_btc"
12826   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12827         (xor:DI
12828          (match_operand:DI 1 "nonimmediate_operand" "%0")
12829          (match_operand:DI 2 "const_int_operand" "n")))
12830    (clobber (reg:CC FLAGS_REG))]
12831   "TARGET_64BIT && TARGET_USE_BT
12832    && ix86_binary_operator_ok (XOR, DImode, operands)
12833    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
12834   "#"
12835   "&& reload_completed"
12836   [(parallel [(set (zero_extract:DI (match_dup 0)
12837                                     (const_int 1)
12838                                     (match_dup 3))
12839                    (not:DI (zero_extract:DI (match_dup 0)
12840                                             (const_int 1)
12841                                             (match_dup 3))))
12842               (clobber (reg:CC FLAGS_REG))])]
12843   "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
12844   [(set_attr "type" "alu1")
12845    (set_attr "prefix_0f" "1")
12846    (set_attr "znver1_decode" "double")
12847    (set_attr "mode" "DI")])
12849 ;; Optimize a ^ ((a ^ b) & mask) to (~mask & a) | (b & mask)
12850 (define_insn_and_split "*xor2andn"
12851   [(set (match_operand:SWI248 0 "register_operand")
12852         (xor:SWI248
12853           (and:SWI248
12854             (xor:SWI248
12855               (match_operand:SWI248 1 "nonimmediate_operand")
12856               (match_operand:SWI248 2 "nonimmediate_operand"))
12857             (match_operand:SWI248 3 "nonimmediate_operand"))
12858           (match_dup 1)))
12859     (clobber (reg:CC FLAGS_REG))]
12860   "TARGET_BMI && ix86_pre_reload_split ()"
12861   "#"
12862   "&& 1"
12863   [(parallel [(set (match_dup 4)
12864                 (and:SWI248
12865                   (not:SWI248
12866                     (match_dup 3))
12867                   (match_dup 1)))
12868               (clobber (reg:CC FLAGS_REG))])
12869    (parallel [(set (match_dup 5)
12870                 (and:SWI248
12871                   (match_dup 3)
12872                   (match_dup 2)))
12873               (clobber (reg:CC FLAGS_REG))])
12874    (parallel [(set (match_dup 0)
12875                 (ior:SWI248
12876                   (match_dup 4)
12877                   (match_dup 5)))
12878               (clobber (reg:CC FLAGS_REG))])]
12880   operands[1] = force_reg (<MODE>mode, operands[1]);
12881   operands[3] = force_reg (<MODE>mode, operands[3]);
12882   operands[4] = gen_reg_rtx (<MODE>mode);
12883   operands[5] = gen_reg_rtx (<MODE>mode);
12886 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12887 (define_insn "*<code>si_1_zext"
12888   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
12889         (zero_extend:DI
12890          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm,rjM,r")
12891                     (match_operand:SI 2 "x86_64_general_operand" "rBMe,r,e,BM"))))
12892    (clobber (reg:CC FLAGS_REG))]
12893   "TARGET_64BIT
12894    && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
12895   "@
12896   <logic>{l}\t{%2, %k0|%k0, %2}
12897   <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}
12898   <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}
12899   <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}"
12900   [(set_attr "type" "alu")
12901    (set_attr "isa" "*,apx_ndd,apx_ndd,apx_ndd")
12902    (set_attr "mode" "SI")])
12904 (define_insn "*<code>si_1_zext_imm"
12905   [(set (match_operand:DI 0 "register_operand" "=r,r")
12906         (any_or:DI
12907          (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0,rm"))
12908          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z,Z")))
12909    (clobber (reg:CC FLAGS_REG))]
12910   "TARGET_64BIT
12911    && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
12912   "@
12913   <logic>{l}\t{%2, %k0|%k0, %2}
12914   <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}"
12915   [(set_attr "type" "alu")
12916    (set_attr "isa" "*,apx_ndd")
12917    (set_attr "mode" "SI")])
12919 (define_insn "*<code>qi_1"
12920   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r,?k")
12921         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r,k")
12922                    (match_operand:QI 2 "general_operand" "qn,m,rn,rn,m,k")))
12923    (clobber (reg:CC FLAGS_REG))]
12924   "ix86_binary_operator_ok (<CODE>, QImode, operands, TARGET_APX_NDD)"
12925   "@
12926    <logic>{b}\t{%2, %0|%0, %2}
12927    <logic>{b}\t{%2, %0|%0, %2}
12928    <logic>{l}\t{%k2, %k0|%k0, %k2}
12929    <logic>{b}\t{%2, %1, %0|%0, %1, %2}
12930    <logic>{b}\t{%2, %1, %0|%0, %1, %2}
12931    #"
12932   [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,avx512f")
12933    (set_attr "type" "alu,alu,alu,alu,alu,msklog")
12934    (set (attr "mode")
12935         (cond [(eq_attr "alternative" "2")
12936                  (const_string "SI")
12937                 (and (eq_attr "alternative" "5")
12938                      (match_test "!TARGET_AVX512DQ"))
12939                  (const_string "HI")
12940                ]
12941                (const_string "QI")))
12942    ;; Potential partial reg stall on alternative 2.
12943    (set (attr "preferred_for_speed")
12944      (cond [(eq_attr "alternative" "2")
12945               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12946            (symbol_ref "true")))])
12948 (define_insn_and_split "*notxorqi_1"
12949   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r,?k")
12950         (not:QI
12951           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r,k")
12952                   (match_operand:QI 2 "general_operand" "qn,m,rn,rn,m,k"))))
12953    (clobber (reg:CC FLAGS_REG))]
12954   "ix86_binary_operator_ok (XOR, QImode, operands, TARGET_APX_NDD)"
12955   "#"
12956   "&& reload_completed"
12957   [(parallel
12958     [(set (match_dup 0)
12959           (xor:QI (match_dup 1) (match_dup 2)))
12960      (clobber (reg:CC FLAGS_REG))])
12961    (set (match_dup 0)
12962         (not:QI (match_dup 0)))]
12964   if (mask_reg_operand (operands[0], QImode))
12965     {
12966       emit_insn (gen_kxnorqi (operands[0], operands[1], operands[2]));
12967       DONE;
12968     }
12970   [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,avx512f")
12971    (set_attr "type" "alu,alu,alu,alu,alu,msklog")
12972    (set (attr "mode")
12973         (cond [(eq_attr "alternative" "2")
12974                  (const_string "SI")
12975                 (and (eq_attr "alternative" "5")
12976                      (match_test "!TARGET_AVX512DQ"))
12977                  (const_string "HI")
12978                ]
12979                (const_string "QI")))
12980    ;; Potential partial reg stall on alternative 2.
12981    (set (attr "preferred_for_speed")
12982      (cond [(eq_attr "alternative" "2")
12983               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12984            (symbol_ref "true")))])
12986 ;; convert (sign_extend:WIDE (any_logic:NARROW (memory, immediate)))
12987 ;; to (any_logic:WIDE (sign_extend (memory)), (sign_extend (immediate))).
12988 ;; This eliminates sign extension after logic operation.
12990 (define_split
12991   [(set (match_operand:SWI248 0 "register_operand")
12992         (sign_extend:SWI248
12993           (any_logic:QI (match_operand:QI 1 "memory_operand")
12994                         (match_operand:QI 2 "const_int_operand"))))]
12995   ""
12996   [(set (match_dup 3) (sign_extend:SWI248 (match_dup 1)))
12997    (set (match_dup 0) (any_logic:SWI248 (match_dup 3) (match_dup 2)))]
12998   "operands[3] = gen_reg_rtx (<MODE>mode);")
13000 (define_split
13001   [(set (match_operand:SWI48 0 "register_operand")
13002         (sign_extend:SWI48
13003           (any_logic:HI (match_operand:HI 1 "memory_operand")
13004                         (match_operand:HI 2 "const_int_operand"))))]
13005   ""
13006   [(set (match_dup 3) (sign_extend:SWI48 (match_dup 1)))
13007    (set (match_dup 0) (any_logic:SWI48 (match_dup 3) (match_dup 2)))]
13008   "operands[3] = gen_reg_rtx (<MODE>mode);")
13010 (define_split
13011   [(set (match_operand:DI 0 "register_operand")
13012         (sign_extend:DI
13013           (any_logic:SI (match_operand:SI 1 "memory_operand")
13014                         (match_operand:SI 2 "const_int_operand"))))]
13015   "TARGET_64BIT"
13016   [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
13017    (set (match_dup 0) (any_logic:DI (match_dup 3) (match_dup 2)))]
13018   "operands[3] = gen_reg_rtx (DImode);")
13020 (define_insn "*<code><mode>_2"
13021   [(set (reg FLAGS_REG)
13022         (compare (any_or:SWI
13023                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r")
13024                   (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>"))
13025                  (const_int 0)))
13026    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
13027         (any_or:SWI (match_dup 1) (match_dup 2)))]
13028   "ix86_match_ccmode (insn, CCNOmode)
13029    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)"
13030   "@
13031   <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
13032   <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
13033   <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
13034   <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
13035   [(set_attr "type" "alu")
13036    (set_attr "isa" "*,*,apx_ndd,apx_ndd")
13037    (set_attr "mode" "<MODE>")])
13039 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
13040 ;; ??? Special case for immediate operand is missing - it is tricky.
13041 (define_insn "*<code>si_2_zext"
13042   [(set (reg FLAGS_REG)
13043         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm,r")
13044                             (match_operand:SI 2 "x86_64_general_operand" "rBMe,re,BM"))
13045                  (const_int 0)))
13046    (set (match_operand:DI 0 "register_operand" "=r,r,r")
13047         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
13048   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
13049    && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
13050   "@
13051   <logic>{l}\t{%2, %k0|%k0, %2}
13052   <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}
13053   <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}"
13054   [(set_attr "type" "alu")
13055    (set_attr "isa" "*,apx_ndd,apx_ndd")
13056    (set_attr "mode" "SI")])
13058 (define_insn "*<code>si_2_zext_imm"
13059   [(set (reg FLAGS_REG)
13060         (compare (any_or:SI
13061                   (match_operand:SI 1 "nonimmediate_operand" "%0,rm")
13062                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z,Z"))
13063                  (const_int 0)))
13064    (set (match_operand:DI 0 "register_operand" "=r,r")
13065         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13066   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
13067    && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
13068   "@
13069   <logic>{l}\t{%2, %k0|%k0, %2}
13070   <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}"
13071   [(set_attr "type" "alu")
13072    (set_attr "isa" "*,apx_ndd")
13073    (set_attr "mode" "SI")])
13075 (define_insn "*<code><mode>_3"
13076   [(set (reg FLAGS_REG)
13077         (compare (any_or:SWI
13078                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
13079                   (match_operand:SWI 2 "<general_operand>" "<g>"))
13080                  (const_int 0)))
13081    (clobber (match_scratch:SWI 0 "=<r>"))]
13082   "ix86_match_ccmode (insn, CCNOmode)
13083    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13084   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
13085   [(set_attr "type" "alu")
13086    (set_attr "mode" "<MODE>")])
13088 ;; Convert wide OR instructions with immediate operand to shorter QImode
13089 ;; equivalents when possible.
13090 ;; Don't do the splitting with memory operands, since it introduces risk
13091 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
13092 ;; for size, but that can (should?) be handled by generic code instead.
13093 ;; Don't do the splitting for APX NDD as NDD does not support *h registers.
13094 (define_split
13095   [(set (match_operand:SWI248 0 "QIreg_operand")
13096         (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
13097                        (match_operand:SWI248 2 "const_int_operand")))
13098    (clobber (reg:CC FLAGS_REG))]
13099    "reload_completed
13100     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13101     && !(INTVAL (operands[2]) & ~(255 << 8))
13102     && !(TARGET_APX_NDD && REGNO (operands[0]) != REGNO (operands[1]))"
13103   [(parallel
13104      [(set (zero_extract:HI (match_dup 0)
13105                             (const_int 8)
13106                             (const_int 8))
13107            (subreg:HI
13108              (any_or:QI
13109                (subreg:QI
13110                  (zero_extract:HI (match_dup 1)
13111                                   (const_int 8)
13112                                   (const_int 8)) 0)
13113                (match_dup 2)) 0))
13114       (clobber (reg:CC FLAGS_REG))])]
13116   /* Handle the case where INTVAL (operands[2]) == 0.  */
13117   if (operands[2] == const0_rtx)
13118     {
13119       if (!rtx_equal_p (operands[0], operands[1]))
13120         emit_move_insn (operands[0], operands[1]);
13121       else
13122         emit_note (NOTE_INSN_DELETED);
13123       DONE;
13124     }
13125   operands[0] = gen_lowpart (HImode, operands[0]);
13126   operands[1] = gen_lowpart (HImode, operands[1]);
13127   operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
13130 ;; Since OR can be encoded with sign extended immediate, this is only
13131 ;; profitable when 7th bit is set.
13132 (define_split
13133   [(set (match_operand:SWI248 0 "any_QIreg_operand")
13134         (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
13135                        (match_operand:SWI248 2 "const_int_operand")))
13136    (clobber (reg:CC FLAGS_REG))]
13137    "reload_completed
13138     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13139     && !(INTVAL (operands[2]) & ~255)
13140     && (INTVAL (operands[2]) & 128)
13141     && !(TARGET_APX_NDD
13142          && !rtx_equal_p (operands[0], operands[1]))"
13143   [(parallel [(set (strict_low_part (match_dup 0))
13144                    (any_or:QI (match_dup 1)
13145                               (match_dup 2)))
13146               (clobber (reg:CC FLAGS_REG))])]
13148   operands[0] = gen_lowpart (QImode, operands[0]);
13149   operands[1] = gen_lowpart (QImode, operands[1]);
13150   operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
13153 (define_expand "xorqi_ext_1_cc"
13154   [(parallel
13155      [(set (reg:CCNO FLAGS_REG)
13156            (compare:CCNO
13157              (xor:QI
13158                (subreg:QI
13159                  (zero_extract:HI (match_operand:HI 1 "register_operand")
13160                                   (const_int 8)
13161                                   (const_int 8)) 0)
13162                (match_operand:QI 2 "const_int_operand"))
13163              (const_int 0)))
13164       (set (zero_extract:HI (match_operand:HI 0 "register_operand")
13165                             (const_int 8)
13166                             (const_int 8))
13167            (subreg:HI
13168              (xor:QI
13169                (subreg:QI
13170                  (zero_extract:HI (match_dup 1)
13171                                   (const_int 8)
13172                                   (const_int 8)) 0)
13173              (match_dup 2)) 0))])])
13175 ;; Peephole2 rega = 0; rega op= regb into rega = regb.
13176 (define_peephole2
13177   [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
13178                    (const_int 0))
13179               (clobber (reg:CC FLAGS_REG))])
13180    (parallel [(set (match_dup 0)
13181                    (any_or_plus:SWI (match_dup 0)
13182                                     (match_operand:SWI 1 "<general_operand>")))
13183               (clobber (reg:CC FLAGS_REG))])]
13184   "!reg_mentioned_p (operands[0], operands[1])"
13185   [(set (match_dup 0) (match_dup 1))])
13187 ;; Peephole2 dead instruction in rega = 0; rega op= rega.
13188 (define_peephole2
13189   [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
13190                    (const_int 0))
13191               (clobber (reg:CC FLAGS_REG))])
13192    (parallel [(set (match_dup 0)
13193                    (any_or_plus:SWI (match_dup 0) (match_dup 0)))
13194               (clobber (reg:CC FLAGS_REG))])]
13195   ""
13196   [(parallel [(set (match_dup 0) (const_int 0))
13197               (clobber (reg:CC FLAGS_REG))])])
13199 ;; Split DST = (HI<<32)|LO early to minimize register usage.
13200 (define_insn_and_split "*concat<mode><dwi>3_1"
13201   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
13202         (any_or_plus:<DWI>
13203           (ashift:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r")
13204                         (match_operand:QI 2 "const_int_operand"))
13205           (zero_extend:<DWI>
13206             (match_operand:DWIH 3 "nonimmediate_operand" "r,m"))))]
13207   "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
13208   "#"
13209   "&& reload_completed"
13210   [(const_int 0)]
13212   split_double_concat (<DWI>mode, operands[0], operands[3],
13213                        gen_lowpart (<MODE>mode, operands[1]));
13214   DONE;
13217 (define_insn_and_split "*concat<mode><dwi>3_2"
13218   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
13219         (any_or_plus:<DWI>
13220           (zero_extend:<DWI>
13221             (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
13222           (ashift:<DWI> (match_operand:<DWI> 2 "register_operand" "r,r")
13223                         (match_operand:QI 3 "const_int_operand"))))]
13224   "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13225   "#"
13226   "&& reload_completed"
13227   [(const_int 0)]
13229   split_double_concat (<DWI>mode, operands[0], operands[1],
13230                        gen_lowpart (<MODE>mode, operands[2]));
13231   DONE;
13234 (define_insn_and_split "*concat<mode><dwi>3_3"
13235   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r,x")
13236         (any_or_plus:<DWI>
13237           (ashift:<DWI>
13238             (zero_extend:<DWI>
13239               (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m,x"))
13240             (match_operand:QI 2 "const_int_operand"))
13241           (zero_extend:<DWI>
13242             (match_operand:DWIH 3 "nonimmediate_operand" "r,r,m,m,0"))))]
13243   "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
13244   "#"
13245   "&& reload_completed"
13246   [(const_int 0)]
13248   if (SSE_REG_P (operands[0]))
13249     {
13250       rtx tmp = gen_rtx_REG (V2DImode, REGNO (operands[0]));
13251       emit_insn (gen_vec_concatv2di (tmp, operands[3], operands[1]));
13252     }
13253   else
13254     split_double_concat (<DWI>mode, operands[0], operands[3], operands[1]);
13255   DONE;
13257   [(set_attr "isa" "*,*,*,x64,x64")])
13259 (define_insn_and_split "*concat<mode><dwi>3_4"
13260   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
13261         (any_or_plus:<DWI>
13262           (zero_extend:<DWI>
13263             (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
13264           (ashift:<DWI>
13265             (zero_extend:<DWI>
13266               (match_operand:DWIH 2 "nonimmediate_operand" "r,r,m,m"))
13267             (match_operand:QI 3 "const_int_operand"))))]
13268   "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13269   "#"
13270   "&& reload_completed"
13271   [(const_int 0)]
13273   split_double_concat (<DWI>mode, operands[0], operands[1], operands[2]);
13274   DONE;
13276   [(set_attr "isa" "*,*,*,x64")])
13278 (define_insn_and_split "*concat<half><mode>3_5"
13279   [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o,o")
13280         (any_or_plus:DWI
13281           (ashift:DWI (match_operand:DWI 1 "register_operand" "r,r,r")
13282                       (match_operand:QI 2 "const_int_operand"))
13283           (match_operand:DWI 3 "const_scalar_int_operand" "n,n,Wd")))]
13284   "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT / 2
13285    && (<MODE>mode == DImode
13286        ? CONST_INT_P (operands[3])
13287          && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
13288        : CONST_INT_P (operands[3])
13289        ? INTVAL (operands[3]) >= 0
13290        : CONST_WIDE_INT_NUNITS (operands[3]) == 2
13291          && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
13292    && !(CONST_INT_P (operands[3])
13293         ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
13294         : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
13295                                                                      0)),
13296                                         VOIDmode))"
13297   "#"
13298   "&& reload_completed"
13299   [(const_int 0)]
13301   rtx op3 = simplify_subreg (<HALF>mode, operands[3], <MODE>mode, 0);
13302   split_double_concat (<MODE>mode, operands[0], op3,
13303                        gen_lowpart (<HALF>mode, operands[1]));
13304   DONE;
13306   [(set_attr "isa" "*,nox64,x64")])
13308 (define_insn_and_split "*concat<mode><dwi>3_6"
13309   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
13310         (any_or_plus:<DWI>
13311           (ashift:<DWI>
13312             (zero_extend:<DWI>
13313               (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
13314             (match_operand:QI 2 "const_int_operand"))
13315           (match_operand:<DWI> 3 "const_scalar_int_operand" "n,n,Wd,n")))]
13316   "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT
13317    && (<DWI>mode == DImode
13318        ? CONST_INT_P (operands[3])
13319          && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
13320        : CONST_INT_P (operands[3])
13321        ? INTVAL (operands[3]) >= 0
13322        : CONST_WIDE_INT_NUNITS (operands[3]) == 2
13323          && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
13324    && !(CONST_INT_P (operands[3])
13325         ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
13326         : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
13327                                                                      0)),
13328                                         VOIDmode))"
13329   "#"
13330   "&& reload_completed"
13331   [(const_int 0)]
13333   rtx op3 = simplify_subreg (<MODE>mode, operands[3], <DWI>mode, 0);
13334   split_double_concat (<DWI>mode, operands[0], op3, operands[1]);
13335   DONE;
13337   [(set_attr "isa" "*,nox64,x64,*")])
13339 (define_insn_and_split "*concat<mode><dwi>3_7"
13340   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
13341         (any_or_plus:<DWI>
13342           (zero_extend:<DWI>
13343             (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
13344           (match_operand:<DWI> 2 "const_scalar_int_operand" "n,n,Wd,n")))]
13345   "<DWI>mode == DImode
13346    ? CONST_INT_P (operands[2])
13347      && (UINTVAL (operands[2]) & GET_MODE_MASK (SImode)) == 0
13348      && !ix86_endbr_immediate_operand (operands[2], VOIDmode)
13349    : CONST_WIDE_INT_P (operands[2])
13350      && CONST_WIDE_INT_NUNITS (operands[2]) == 2
13351      && CONST_WIDE_INT_ELT (operands[2], 0) == 0
13352      && !ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[2],
13353                                                                     1)),
13354                                        VOIDmode)"
13355   "#"
13356   "&& reload_completed"
13357   [(const_int 0)]
13359   rtx op2;
13360   if (<DWI>mode == DImode)
13361     op2 = gen_int_mode (INTVAL (operands[2]) >> 32, <MODE>mode);
13362   else
13363     op2 = gen_int_mode (CONST_WIDE_INT_ELT (operands[2], 1), <MODE>mode);
13364   split_double_concat (<DWI>mode, operands[0], operands[1], op2);
13365   DONE;
13367   [(set_attr "isa" "*,nox64,x64,*")])
13369 ;; Negation instructions
13371 (define_expand "neg<mode>2"
13372   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
13373         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
13374   ""
13376   ix86_expand_unary_operator (NEG, <MODE>mode, operands, TARGET_APX_NDD);
13377   DONE;
13380 (define_insn_and_split "*neg<dwi>2_doubleword"
13381   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,&r")
13382         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0,ro")))
13383    (clobber (reg:CC FLAGS_REG))]
13384   "ix86_unary_operator_ok (NEG, <DWI>mode, operands, TARGET_APX_NDD)"
13385   "#"
13386   "&& reload_completed"
13387   [(parallel
13388     [(set (reg:CCC FLAGS_REG)
13389           (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13390      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
13391    (parallel
13392     [(set (match_dup 2)
13393           (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
13394                                 (match_dup 3))
13395                      (const_int 0)))
13396      (clobber (reg:CC FLAGS_REG))])
13397    (parallel
13398     [(set (match_dup 2)
13399           (neg:DWIH (match_dup 2)))
13400      (clobber (reg:CC FLAGS_REG))])]
13401   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);"
13402   [(set_attr "isa" "*,apx_ndd")])
13404 ;; Convert:
13405 ;;   mov %esi, %edx
13406 ;;   negl %eax
13407 ;;   adcl $0, %edx
13408 ;;   negl %edx
13409 ;; to:
13410 ;;   xorl %edx, %edx
13411 ;;   negl %eax
13412 ;;   sbbl %esi, %edx
13414 (define_peephole2
13415   [(set (match_operand:SWI48 0 "general_reg_operand")
13416         (match_operand:SWI48 1 "nonimmediate_gr_operand"))
13417    (parallel
13418     [(set (reg:CCC FLAGS_REG)
13419           (unspec:CCC [(match_operand:SWI48 2 "general_reg_operand")
13420                        (const_int 0)] UNSPEC_CC_NE))
13421      (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
13422    (parallel
13423     [(set (match_dup 0)
13424           (plus:SWI48 (plus:SWI48
13425                         (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
13426                         (match_dup 0))
13427                       (const_int 0)))
13428      (clobber (reg:CC FLAGS_REG))])
13429    (parallel
13430     [(set (match_dup 0)
13431           (neg:SWI48 (match_dup 0)))
13432      (clobber (reg:CC FLAGS_REG))])]
13433   "REGNO (operands[0]) != REGNO (operands[2])
13434    && !reg_mentioned_p (operands[0], operands[1])
13435    && !reg_mentioned_p (operands[2], operands[1])"
13436   [(parallel
13437     [(set (reg:CCC FLAGS_REG)
13438           (unspec:CCC [(match_dup 2) (const_int 0)] UNSPEC_CC_NE))
13439      (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
13440    (parallel
13441     [(set (match_dup 0)
13442           (minus:SWI48 (minus:SWI48
13443                          (match_dup 0)
13444                          (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0)))
13445                        (match_dup 1)))
13446      (clobber (reg:CC FLAGS_REG))])]
13447   "ix86_expand_clear (operands[0]);")
13449 ;; Convert:
13450 ;;   xorl %edx, %edx
13451 ;;   negl %eax
13452 ;;   adcl $0, %edx
13453 ;;   negl %edx
13454 ;; to:
13455 ;;   negl %eax
13456 ;;   sbbl %edx, %edx    // *x86_mov<mode>cc_0_m1
13458 (define_peephole2
13459   [(parallel
13460     [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
13461      (clobber (reg:CC FLAGS_REG))])
13462    (parallel
13463     [(set (reg:CCC FLAGS_REG)
13464           (unspec:CCC [(match_operand:SWI48 1 "general_reg_operand")
13465                        (const_int 0)] UNSPEC_CC_NE))
13466      (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
13467    (parallel
13468     [(set (match_dup 0)
13469           (plus:SWI48 (plus:SWI48
13470                         (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
13471                         (match_dup 0))
13472                       (const_int 0)))
13473      (clobber (reg:CC FLAGS_REG))])
13474    (parallel
13475     [(set (match_dup 0)
13476           (neg:SWI48 (match_dup 0)))
13477      (clobber (reg:CC FLAGS_REG))])]
13478   "REGNO (operands[0]) != REGNO (operands[1])"
13479   [(parallel
13480     [(set (reg:CCC FLAGS_REG)
13481           (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13482      (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
13483    (parallel
13484     [(set (match_dup 0)
13485           (if_then_else:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
13486                               (const_int -1)
13487                               (const_int 0)))
13488      (clobber (reg:CC FLAGS_REG))])])
13490 (define_insn "*neg<mode>_1"
13491   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
13492         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm")))
13493    (clobber (reg:CC FLAGS_REG))]
13494   "ix86_unary_operator_ok (NEG, <MODE>mode, operands, TARGET_APX_NDD)"
13495   "@
13496   neg{<imodesuffix>}\t%0
13497   neg{<imodesuffix>}\t{%1, %0|%0, %1}"
13498   [(set_attr "type" "negnot")
13499    (set_attr "isa" "*,apx_ndd")
13500    (set_attr "mode" "<MODE>")])
13502 (define_insn "*negsi_1_zext"
13503   [(set (match_operand:DI 0 "register_operand" "=r,r")
13504         (zero_extend:DI
13505           (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm"))))
13506    (clobber (reg:CC FLAGS_REG))]
13507   "TARGET_64BIT
13508    && ix86_unary_operator_ok (NEG, SImode, operands, TARGET_APX_NDD)"
13509   "@
13510   neg{l}\t%k0
13511   neg{l}\t{%k1, %k0|%k0, %k1}"
13512   [(set_attr "type" "negnot")
13513    (set_attr "isa" "*,apx_ndd")
13514    (set_attr "mode" "SI")])
13516 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13517 (define_insn_and_split "*neg<mode>_1_slp"
13518   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
13519         (neg:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))
13520    (clobber (reg:CC FLAGS_REG))]
13521   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
13522   "@
13523    neg{<imodesuffix>}\t%0
13524    #"
13525   "&& reload_completed
13526    && !(rtx_equal_p (operands[0], operands[1]))"
13527   [(set (strict_low_part (match_dup 0)) (match_dup 1))
13528    (parallel
13529      [(set (strict_low_part (match_dup 0))
13530            (neg:SWI12 (match_dup 0)))
13531       (clobber (reg:CC FLAGS_REG))])]
13532   ""
13533   [(set_attr "type" "negnot")
13534    (set_attr "mode" "<MODE>")])
13536 (define_insn "*neg<mode>_2"
13537   [(set (reg FLAGS_REG)
13538         (compare
13539           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm"))
13540           (const_int 0)))
13541    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
13542         (neg:SWI (match_dup 1)))]
13543   "ix86_match_ccmode (insn, CCGOCmode)
13544    && ix86_unary_operator_ok (NEG, <MODE>mode, operands, TARGET_APX_NDD)"
13545   "@
13546    neg{<imodesuffix>}\t%0
13547    neg{<imodesuffix>}\t{%1, %0|%0, %1}"
13548   [(set_attr "type" "negnot")
13549    (set_attr "isa" "*,apx_ndd")
13550    (set_attr "mode" "<MODE>")])
13552 (define_insn "*negsi_2_zext"
13553   [(set (reg FLAGS_REG)
13554         (compare
13555           (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm"))
13556           (const_int 0)))
13557    (set (match_operand:DI 0 "register_operand" "=r,r")
13558         (zero_extend:DI
13559           (neg:SI (match_dup 1))))]
13560   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
13561    && ix86_unary_operator_ok (NEG, SImode, operands, TARGET_APX_NDD)"
13562   "@
13563    neg{l}\t%k0
13564    neg{l}\t{%1, %k0|%k0, %1}"
13565   [(set_attr "type" "negnot")
13566    (set_attr "isa" "*,apx_ndd")
13567    (set_attr "mode" "SI")])
13569 (define_insn "*neg<mode>_ccc_1"
13570   [(set (reg:CCC FLAGS_REG)
13571         (unspec:CCC
13572           [(match_operand:SWI 1 "nonimmediate_operand" "0,rm")
13573            (const_int 0)] UNSPEC_CC_NE))
13574    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
13575         (neg:SWI (match_dup 1)))]
13576   ""
13577   "@
13578   neg{<imodesuffix>}\t%0
13579   neg{<imodesuffix>}\t{%1, %0|%0, %1}"
13580   [(set_attr "type" "negnot")
13581    (set_attr "isa" "*,apx_ndd")
13582    (set_attr "mode" "<MODE>")])
13584 (define_insn "*neg<mode>_ccc_2"
13585   [(set (reg:CCC FLAGS_REG)
13586         (unspec:CCC
13587           [(match_operand:SWI 1 "nonimmediate_operand" "0,rm")
13588            (const_int 0)] UNSPEC_CC_NE))
13589    (clobber (match_scratch:SWI 0 "=<r>,r"))]
13590   ""
13591   "@
13592   neg{<imodesuffix>}\t%0
13593   neg{<imodesuffix>}\t{%1, %0|%0, %1}"
13594   [(set_attr "type" "negnot")
13595    (set_attr "isa" "*,apx_ndd")
13596    (set_attr "mode" "<MODE>")])
13598 (define_expand "x86_neg<mode>_ccc"
13599   [(parallel
13600     [(set (reg:CCC FLAGS_REG)
13601           (unspec:CCC [(match_operand:SWI48 1 "register_operand")
13602                        (const_int 0)] UNSPEC_CC_NE))
13603      (set (match_operand:SWI48 0 "register_operand")
13604           (neg:SWI48 (match_dup 1)))])])
13606 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13607 (define_insn_and_split "*negqi_ext<mode>_1"
13608   [(set (zero_extract:SWI248
13609           (match_operand 0 "int248_register_operand" "+Q,&Q")
13610           (const_int 8)
13611           (const_int 8))
13612         (subreg:SWI248
13613           (neg:QI
13614             (subreg:QI
13615               (match_operator:SWI248 2 "extract_operator"
13616                 [(match_operand 1 "int248_register_operand" "0,!Q")
13617                  (const_int 8)
13618                  (const_int 8)]) 0)) 0))
13619    (clobber (reg:CC FLAGS_REG))]
13620   ""
13621   "@
13622    neg{b}\t%h0
13623    #"
13624   "reload_completed
13625    && !(rtx_equal_p (operands[0], operands[1]))"
13626   [(set (zero_extract:SWI248
13627           (match_dup 0) (const_int 8) (const_int 8))
13628         (zero_extract:SWI248
13629           (match_dup 1) (const_int 8) (const_int 8)))
13630    (parallel
13631      [(set (zero_extract:SWI248
13632              (match_dup 0) (const_int 8) (const_int 8))
13633            (subreg:SWI248
13634              (neg:QI
13635                (subreg:QI
13636                  (match_op_dup 2
13637                    [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))
13638       (clobber (reg:CC FLAGS_REG))])]
13639   ""
13640   [(set_attr "type" "negnot")
13641    (set_attr "mode" "QI")])
13643 ;; Negate with jump on overflow.
13644 (define_expand "negv<mode>3"
13645   [(parallel [(set (reg:CCO FLAGS_REG)
13646                    (unspec:CCO
13647                      [(match_operand:SWI 1 "register_operand")
13648                       (match_dup 3)] UNSPEC_CC_NE))
13649               (set (match_operand:SWI 0 "register_operand")
13650                    (neg:SWI (match_dup 1)))])
13651    (set (pc) (if_then_else
13652                (eq (reg:CCO FLAGS_REG) (const_int 0))
13653                (label_ref (match_operand 2))
13654                (pc)))]
13655   ""
13657   operands[3]
13658     = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
13659                     <MODE>mode);
13662 (define_insn "*negv<mode>3"
13663   [(set (reg:CCO FLAGS_REG)
13664         (unspec:CCO [(match_operand:SWI 1 "nonimmediate_operand" "0")
13665                      (match_operand:SWI 2 "const_int_operand")]
13666                     UNSPEC_CC_NE))
13667    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13668         (neg:SWI (match_dup 1)))]
13669   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
13670    && mode_signbit_p (<MODE>mode, operands[2])"
13671   "neg{<imodesuffix>}\t%0"
13672   [(set_attr "type" "negnot")
13673    (set_attr "mode" "<MODE>")])
13675 ;; Optimize *negsi_1 followed by *cmpsi_ccno_1 (PR target/91384)
13676 (define_peephole2
13677   [(set (match_operand:SWI 0 "general_reg_operand")
13678         (match_operand:SWI 1 "general_reg_operand"))
13679    (parallel [(set (match_dup 0) (neg:SWI (match_dup 0)))
13680               (clobber (reg:CC FLAGS_REG))])
13681    (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))]
13682   ""
13683   [(set (match_dup 0) (match_dup 1))
13684    (parallel [(set (reg:CCZ FLAGS_REG)
13685                    (compare:CCZ (neg:SWI (match_dup 0)) (const_int 0)))
13686               (set (match_dup 0) (neg:SWI (match_dup 0)))])])
13688 ;; Special expand pattern to handle integer mode abs
13690 (define_expand "abs<mode>2"
13691   [(parallel
13692     [(set (match_operand:SDWIM 0 "register_operand")
13693           (abs:SDWIM
13694             (match_operand:SDWIM 1 "general_operand")))
13695      (clobber (reg:CC FLAGS_REG))])]
13696   "TARGET_CMOVE
13697    && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)"
13699   if (TARGET_EXPAND_ABS)
13700     {
13701       machine_mode mode = <MODE>mode;
13702       operands[1] = force_reg (mode, operands[1]);
13704       /* Generate rtx abs using:
13705          abs (x) = (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)) */
13707       rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
13708       rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
13709                                            shift_amount, NULL_RTX,
13710                                            0, OPTAB_DIRECT);
13711       rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
13712                                          operands[0], 0, OPTAB_DIRECT);
13713       rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
13714                                            operands[0], 0, OPTAB_DIRECT);
13715       if (!rtx_equal_p (minus_dst, operands[0]))
13716         emit_move_insn (operands[0], minus_dst);
13717       DONE;
13718     }
13721 (define_insn_and_split "*abs<dwi>2_doubleword"
13722   [(set (match_operand:<DWI> 0 "register_operand")
13723         (abs:<DWI>
13724           (match_operand:<DWI> 1 "general_operand")))
13725    (clobber (reg:CC FLAGS_REG))]
13726   "TARGET_CMOVE
13727    && ix86_pre_reload_split ()"
13728    "#"
13729    "&& 1"
13730   [(parallel
13731     [(set (reg:CCC FLAGS_REG)
13732           (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13733      (set (match_dup 2) (neg:DWIH (match_dup 1)))])
13734    (parallel
13735     [(set (match_dup 5)
13736           (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
13737                                 (match_dup 4))
13738                      (const_int 0)))
13739      (clobber (reg:CC FLAGS_REG))])
13740    (parallel
13741      [(set (reg:CCGOC FLAGS_REG)
13742            (compare:CCGOC
13743              (neg:DWIH (match_dup 5))
13744              (const_int 0)))
13745       (set (match_dup 5)
13746            (neg:DWIH (match_dup 5)))])
13747    (set (match_dup 0)
13748         (if_then_else:DWIH
13749           (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13750           (match_dup 2)
13751           (match_dup 1)))
13752    (set (match_dup 3)
13753         (if_then_else:DWIH
13754           (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13755           (match_dup 5)
13756           (match_dup 4)))]
13758   operands[1] = force_reg (<DWI>mode, operands[1]);
13759   operands[2] = gen_reg_rtx (<DWI>mode);
13761   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13764 (define_insn_and_split "*nabs<dwi>2_doubleword"
13765   [(set (match_operand:<DWI> 0 "register_operand")
13766         (neg:<DWI>
13767           (abs:<DWI>
13768             (match_operand:<DWI> 1 "general_operand"))))
13769    (clobber (reg:CC FLAGS_REG))]
13770   "TARGET_CMOVE
13771    && ix86_pre_reload_split ()"
13772    "#"
13773    "&& 1"
13774   [(parallel
13775     [(set (reg:CCC FLAGS_REG)
13776           (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13777      (set (match_dup 2) (neg:DWIH (match_dup 1)))])
13778    (parallel
13779     [(set (match_dup 5)
13780           (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
13781                                 (match_dup 4))
13782                      (const_int 0)))
13783      (clobber (reg:CC FLAGS_REG))])
13784    (parallel
13785      [(set (reg:CCGOC FLAGS_REG)
13786            (compare:CCGOC
13787              (neg:DWIH (match_dup 5))
13788              (const_int 0)))
13789       (set (match_dup 5)
13790            (neg:DWIH (match_dup 5)))])
13791    (set (match_dup 0)
13792         (if_then_else:DWIH
13793           (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13794           (match_dup 2)
13795           (match_dup 1)))
13796    (set (match_dup 3)
13797         (if_then_else:DWIH
13798           (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13799           (match_dup 5)
13800           (match_dup 4)))]
13802   operands[1] = force_reg (<DWI>mode, operands[1]);
13803   operands[2] = gen_reg_rtx (<DWI>mode);
13805   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13808 (define_insn_and_split "*abs<mode>2_1"
13809   [(set (match_operand:SWI 0 "register_operand")
13810         (abs:SWI
13811           (match_operand:SWI 1 "general_operand")))
13812    (clobber (reg:CC FLAGS_REG))]
13813   "TARGET_CMOVE
13814    && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
13815    && ix86_pre_reload_split ()"
13816    "#"
13817    "&& 1"
13818   [(parallel
13819      [(set (reg:CCGOC FLAGS_REG)
13820            (compare:CCGOC
13821              (neg:SWI (match_dup 1))
13822              (const_int 0)))
13823       (set (match_dup 2)
13824            (neg:SWI (match_dup 1)))])
13825    (set (match_dup 0)
13826         (if_then_else:SWI
13827           (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13828           (match_dup 2)
13829           (match_dup 1)))]
13831   operands[1] = force_reg (<MODE>mode, operands[1]);
13832   operands[2] = gen_reg_rtx (<MODE>mode);
13835 (define_insn_and_split "*nabs<mode>2_1"
13836   [(set (match_operand:SWI 0 "register_operand")
13837         (neg:SWI
13838           (abs:SWI
13839             (match_operand:SWI 1 "general_operand"))))
13840    (clobber (reg:CC FLAGS_REG))]
13841   "TARGET_CMOVE
13842    && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
13843    && ix86_pre_reload_split ()"
13844    "#"
13845    "&& 1"
13846   [(parallel
13847      [(set (reg:CCGOC FLAGS_REG)
13848            (compare:CCGOC
13849              (neg:SWI (match_dup 1))
13850              (const_int 0)))
13851       (set (match_dup 2)
13852            (neg:SWI (match_dup 1)))])
13853    (set (match_dup 0)
13854         (if_then_else:SWI
13855           (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13856           (match_dup 2)
13857           (match_dup 1)))]
13859   operands[1] = force_reg (<MODE>mode, operands[1]);
13860   operands[2] = gen_reg_rtx (<MODE>mode);
13863 (define_expand "<code>tf2"
13864   [(set (match_operand:TF 0 "register_operand")
13865         (absneg:TF (match_operand:TF 1 "register_operand")))]
13866   "TARGET_SSE"
13867   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
13869 (define_insn_and_split "*<code>tf2_1"
13870   [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13871         (absneg:TF
13872           (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
13873    (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13874   "TARGET_SSE"
13875   "#"
13876   "&& reload_completed"
13877   [(set (match_dup 0)
13878         (<absneg_op>:TF (match_dup 1) (match_dup 2)))]
13880   if (TARGET_AVX)
13881     {
13882       if (MEM_P (operands[1]))
13883         std::swap (operands[1], operands[2]);
13884     }
13885   else
13886    {
13887      if (operands_match_p (operands[0], operands[2]))
13888        std::swap (operands[1], operands[2]);
13889    }
13891   [(set_attr "isa" "noavx,noavx,avx,avx")])
13893 (define_insn_and_split "*nabstf2_1"
13894   [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13895         (neg:TF
13896           (abs:TF
13897             (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
13898    (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13899   "TARGET_SSE"
13900   "#"
13901   "&& reload_completed"
13902   [(set (match_dup 0)
13903         (ior:TF (match_dup 1) (match_dup 2)))]
13905   if (TARGET_AVX)
13906     {
13907       if (MEM_P (operands[1]))
13908         std::swap (operands[1], operands[2]);
13909     }
13910   else
13911    {
13912      if (operands_match_p (operands[0], operands[2]))
13913        std::swap (operands[1], operands[2]);
13914    }
13916   [(set_attr "isa" "noavx,noavx,avx,avx")])
13918 (define_expand "<code>hf2"
13919   [(set (match_operand:HF 0 "register_operand")
13920         (absneg:HF (match_operand:HF 1 "register_operand")))]
13921   "TARGET_AVX512FP16"
13922   "ix86_expand_fp_absneg_operator (<CODE>, HFmode, operands); DONE;")
13924 (define_expand "<code><mode>2"
13925   [(set (match_operand:X87MODEF 0 "register_operand")
13926         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
13927   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13928   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13930 ;; Changing of sign for FP values is doable using integer unit too.
13931 (define_insn "*<code><mode>2_i387_1"
13932   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
13933         (absneg:X87MODEF
13934           (match_operand:X87MODEF 1 "register_operand" "0,0")))
13935    (clobber (reg:CC FLAGS_REG))]
13936   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13937   "#")
13939 (define_split
13940   [(set (match_operand:X87MODEF 0 "fp_register_operand")
13941         (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
13942    (clobber (reg:CC FLAGS_REG))]
13943   "TARGET_80387 && reload_completed"
13944   [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
13946 (define_split
13947   [(set (match_operand:X87MODEF 0 "general_reg_operand")
13948         (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
13949    (clobber (reg:CC FLAGS_REG))]
13950   "TARGET_80387 && reload_completed"
13951   [(const_int 0)]
13952   "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13954 (define_insn_and_split "*<code>hf2_1"
13955   [(set (match_operand:HF 0 "register_operand" "=Yv")
13956         (absneg:HF
13957           (match_operand:HF 1 "register_operand" "Yv")))
13958    (use (match_operand:V8HF 2 "vector_operand" "Yvm"))
13959    (clobber (reg:CC FLAGS_REG))]
13960   "TARGET_AVX512FP16"
13961   "#"
13962   "&& reload_completed"
13963   [(set (match_dup 0)
13964         (<absneg_op>:V8HF (match_dup 1) (match_dup 2)))]
13966   operands[0] = lowpart_subreg (V8HFmode, operands[0], HFmode);
13967   operands[1] = lowpart_subreg (V8HFmode, operands[1], HFmode);
13970 (define_insn "*<code><mode>2_1"
13971   [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
13972         (absneg:MODEF
13973           (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
13974    (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
13975    (clobber (reg:CC FLAGS_REG))]
13976   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13977   "#"
13978   [(set_attr "isa" "noavx,noavx,avx,*,*")
13979    (set (attr "enabled")
13980      (if_then_else
13981        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
13982        (if_then_else
13983          (eq_attr "alternative" "3,4")
13984          (symbol_ref "TARGET_MIX_SSE_I387")
13985          (const_string "*"))
13986        (if_then_else
13987          (eq_attr "alternative" "3,4")
13988          (symbol_ref "true")
13989          (symbol_ref "false"))))])
13991 (define_split
13992   [(set (match_operand:MODEF 0 "sse_reg_operand")
13993         (absneg:MODEF
13994           (match_operand:MODEF 1 "sse_reg_operand")))
13995    (use (match_operand:<ssevecmodef> 2 "vector_operand"))
13996    (clobber (reg:CC FLAGS_REG))]
13997   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13998    && reload_completed"
13999   [(set (match_dup 0)
14000         (<absneg_op>:<ssevecmodef> (match_dup 1) (match_dup 2)))]
14002   machine_mode mode = <MODE>mode;
14003   machine_mode vmode = <ssevecmodef>mode;
14005   operands[0] = lowpart_subreg (vmode, operands[0], mode);
14006   operands[1] = lowpart_subreg (vmode, operands[1], mode);
14008   if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
14009     std::swap (operands[1], operands[2]);
14012 (define_split
14013   [(set (match_operand:MODEF 0 "fp_register_operand")
14014         (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
14015    (use (match_operand 2))
14016    (clobber (reg:CC FLAGS_REG))]
14017   "TARGET_80387 && reload_completed"
14018   [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
14020 (define_split
14021   [(set (match_operand:MODEF 0 "general_reg_operand")
14022         (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
14023    (use (match_operand 2))
14024    (clobber (reg:CC FLAGS_REG))]
14025   "TARGET_80387 && reload_completed"
14026   [(const_int 0)]
14027   "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
14029 (define_insn_and_split "*nabs<mode>2_1"
14030   [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
14031         (neg:MODEF
14032           (abs:MODEF
14033             (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
14034    (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
14035   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14036   "#"
14037   "&& reload_completed"
14038   [(set (match_dup 0)
14039         (ior:<ssevecmodef> (match_dup 1) (match_dup 2)))]
14041   machine_mode mode = <MODE>mode;
14042   machine_mode vmode = <ssevecmodef>mode;
14044   operands[0] = lowpart_subreg (vmode, operands[0], mode);
14045   operands[1] = lowpart_subreg (vmode, operands[1], mode);
14047   if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
14048     std::swap (operands[1], operands[2]);
14050   [(set_attr "isa" "noavx,noavx,avx")])
14052 ;; Conditionalize these after reload. If they match before reload, we
14053 ;; lose the clobber and ability to use integer instructions.
14055 (define_insn "*<code><mode>2_i387"
14056   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
14057         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
14058   "TARGET_80387 && reload_completed"
14059   "<absneg_mnemonic>"
14060   [(set_attr "type" "fsgn")
14061    (set_attr "mode" "<MODE>")])
14063 ;; Copysign instructions
14065 (define_expand "copysign<mode>3"
14066   [(match_operand:SSEMODEF 0 "register_operand")
14067    (match_operand:SSEMODEF 1 "nonmemory_operand")
14068    (match_operand:SSEMODEF 2 "register_operand")]
14069   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14070    || (TARGET_SSE && (<MODE>mode == TFmode))
14071    || (TARGET_AVX512FP16 && (<MODE>mode ==HFmode))"
14072   "ix86_expand_copysign (operands); DONE;")
14074 (define_expand "xorsign<mode>3"
14075   [(match_operand:MODEFH 0 "register_operand")
14076    (match_operand:MODEFH 1 "register_operand")
14077    (match_operand:MODEFH 2 "register_operand")]
14078   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14079   || <MODE>mode == HFmode"
14081   if (rtx_equal_p (operands[1], operands[2]))
14082     emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
14083   else
14084     ix86_expand_xorsign (operands);
14085   DONE;
14088 ;; One complement instructions
14090 (define_expand "one_cmpl<mode>2"
14091   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
14092         (not:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
14093   ""
14095   ix86_expand_unary_operator (NOT, <MODE>mode, operands, TARGET_APX_NDD);
14096   DONE;
14099 (define_insn_and_split "*one_cmpl<dwi>2_doubleword"
14100   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,&r")
14101         (not:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0,ro")))]
14102   "ix86_unary_operator_ok (NOT, <DWI>mode, operands, TARGET_APX_NDD)"
14103   "#"
14104   "&& reload_completed"
14105   [(set (match_dup 0)
14106         (not:DWIH (match_dup 1)))
14107    (set (match_dup 2)
14108         (not:DWIH (match_dup 3)))]
14109   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);"
14110   [(set_attr "isa" "*,apx_ndd")])
14112 (define_insn "*one_cmpl<mode>2_1"
14113   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
14114         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,rm,k")))]
14115   "ix86_unary_operator_ok (NOT, <MODE>mode, operands, TARGET_APX_NDD)"
14116   "@
14117    not{<imodesuffix>}\t%0
14118    not{<imodesuffix>}\t{%1, %0|%0, %1}
14119    #"
14120   [(set_attr "isa" "*,apx_ndd,<kmov_isa>")
14121    (set_attr "type" "negnot,negnot,msklog")
14122    (set_attr "mode" "<MODE>")])
14124 (define_insn "*one_cmplsi2_1_zext"
14125   [(set (match_operand:DI 0 "register_operand" "=r,r,?k")
14126         (zero_extend:DI
14127           (not:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm,k"))))]
14128   "TARGET_64BIT
14129    && ix86_unary_operator_ok (NOT, SImode, operands, TARGET_APX_NDD)"
14130   "@
14131    not{l}\t%k0
14132    not{l}\t{%1, %k0|%k0, %1}
14133    #"
14134   [(set_attr "isa" "x64,apx_ndd,avx512bw")
14135    (set_attr "type" "negnot,negnot,msklog")
14136    (set_attr "mode" "SI,SI,SI")])
14138 (define_insn "*one_cmplqi2_1"
14139   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r,?k")
14140         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,rm,k")))]
14141   "ix86_unary_operator_ok (NOT, QImode, operands, TARGET_APX_NDD)"
14142   "@
14143    not{b}\t%0
14144    not{l}\t%k0
14145    not{b}\t{%1, %0|%0, %1}
14146    #"
14147   [(set_attr "isa" "*,*,apx_ndd,avx512f")
14148    (set_attr "type" "negnot,negnot,negnot,msklog")
14149    (set (attr "mode")
14150         (cond [(eq_attr "alternative" "1")
14151                  (const_string "SI")
14152                 (and (eq_attr "alternative" "3")
14153                      (match_test "!TARGET_AVX512DQ"))
14154                  (const_string "HI")
14155                ]
14156                (const_string "QI")))
14157    ;; Potential partial reg stall on alternative 1.
14158    (set (attr "preferred_for_speed")
14159      (cond [(eq_attr "alternative" "1")
14160               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
14161            (symbol_ref "true")))])
14163 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14164 (define_insn_and_split "*one_cmpl<mode>_1_slp"
14165   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
14166         (not:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))]
14167   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
14168   "@
14169    not{<imodesuffix>}\t%0
14170    #"
14171   "&& reload_completed
14172    && !(rtx_equal_p (operands[0], operands[1]))"
14173   [(set (strict_low_part (match_dup 0)) (match_dup 1))
14174    (set (strict_low_part (match_dup 0))
14175         (not:SWI12 (match_dup 0)))]
14176   ""
14177   [(set_attr "type" "negnot")
14178    (set_attr "mode" "<MODE>")])
14180 (define_insn "*one_cmpl<mode>2_2"
14181   [(set (reg FLAGS_REG)
14182         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm"))
14183                  (const_int 0)))
14184    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
14185         (not:SWI (match_dup 1)))]
14186   "ix86_match_ccmode (insn, CCNOmode)
14187    && ix86_unary_operator_ok (NOT, <MODE>mode, operands, TARGET_APX_NDD)"
14188   "#"
14189   [(set_attr "type" "alu1")
14190    (set_attr "isa" "*,apx_ndd")
14191    (set_attr "mode" "<MODE>")])
14193 (define_split
14194   [(set (match_operand 0 "flags_reg_operand")
14195         (match_operator 2 "compare_operator"
14196           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
14197            (const_int 0)]))
14198    (set (match_operand:SWI 1 "nonimmediate_operand")
14199         (not:SWI (match_dup 3)))]
14200   "ix86_match_ccmode (insn, CCNOmode)"
14201   [(parallel [(set (match_dup 0)
14202                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
14203                                     (const_int 0)]))
14204               (set (match_dup 1)
14205                    (xor:SWI (match_dup 3) (const_int -1)))])])
14207 (define_insn "*one_cmplsi2_2_zext"
14208   [(set (reg FLAGS_REG)
14209         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm"))
14210                  (const_int 0)))
14211    (set (match_operand:DI 0 "register_operand" "=r,r")
14212         (zero_extend:DI (not:SI (match_dup 1))))]
14213   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
14214    && ix86_unary_operator_ok (NOT, SImode, operands, TARGET_APX_NDD)"
14215   "#"
14216   [(set_attr "type" "alu1")
14217    (set_attr "isa" "*,apx_ndd")
14218    (set_attr "mode" "SI")])
14220 (define_split
14221   [(set (match_operand 0 "flags_reg_operand")
14222         (match_operator 2 "compare_operator"
14223           [(not:SI (match_operand:SI 3 "nonimmediate_operand"))
14224            (const_int 0)]))
14225    (set (match_operand:DI 1 "register_operand")
14226         (zero_extend:DI (not:SI (match_dup 3))))]
14227   "ix86_match_ccmode (insn, CCNOmode)"
14228   [(parallel [(set (match_dup 0)
14229                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
14230                                     (const_int 0)]))
14231               (set (match_dup 1)
14232                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
14234 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14235 (define_insn_and_split "*one_cmplqi_ext<mode>_1"
14236   [(set (zero_extract:SWI248
14237           (match_operand 0 "int248_register_operand" "+Q,&Q")
14238           (const_int 8)
14239           (const_int 8))
14240         (subreg:SWI248
14241           (not:QI
14242             (subreg:QI
14243               (match_operator:SWI248 2 "extract_operator"
14244                 [(match_operand 1 "int248_register_operand" "0,!Q")
14245                  (const_int 8)
14246                  (const_int 8)]) 0)) 0))]
14247   ""
14248   "@
14249    not{b}\t%h0
14250    #"
14251   "reload_completed
14252    && !(rtx_equal_p (operands[0], operands[1]))"
14253   [(set (zero_extract:SWI248
14254           (match_dup 0) (const_int 8) (const_int 8))
14255         (zero_extract:SWI248
14256           (match_dup 1) (const_int 8) (const_int 8)))
14257    (set (zero_extract:SWI248
14258           (match_dup 0) (const_int 8) (const_int 8))
14259         (subreg:SWI248
14260           (not:QI
14261             (subreg:QI
14262               (match_op_dup 2
14263                 [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))]
14264   ""
14265   [(set_attr "type" "negnot")
14266    (set_attr "mode" "QI")])
14268 ;; Shift instructions
14270 ;; DImode shifts are implemented using the i386 "shift double" opcode,
14271 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
14272 ;; is variable, then the count is in %cl and the "imm" operand is dropped
14273 ;; from the assembler input.
14275 ;; This instruction shifts the target reg/mem as usual, but instead of
14276 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
14277 ;; is a left shift double, bits are taken from the high order bits of
14278 ;; reg, else if the insn is a shift right double, bits are taken from the
14279 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
14280 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
14282 ;; Since sh[lr]d does not change the `reg' operand, that is done
14283 ;; separately, making all shifts emit pairs of shift double and normal
14284 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
14285 ;; support a 63 bit shift, each shift where the count is in a reg expands
14286 ;; to a pair of shifts, a branch, a shift by 32 and a label.
14288 ;; If the shift count is a constant, we need never emit more than one
14289 ;; shift pair, instead using moves and sign extension for counts greater
14290 ;; than 31.
14292 (define_expand "ashl<mode>3"
14293   [(set (match_operand:SDWIM 0 "<shift_operand>")
14294         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
14295                       (match_operand:QI 2 "nonmemory_operand")))]
14296   ""
14298   ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands, TARGET_APX_NDD);
14299   DONE;
14302 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
14303   [(set (match_operand:<DWI> 0 "register_operand")
14304         (ashift:<DWI>
14305           (match_operand:<DWI> 1 "register_operand")
14306           (subreg:QI
14307             (and
14308               (match_operand 2 "int248_register_operand" "c")
14309               (match_operand 3 "const_int_operand")) 0)))
14310    (clobber (reg:CC FLAGS_REG))]
14311   "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14312     || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14313          == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14314    && ix86_pre_reload_split ()"
14315   "#"
14316   "&& 1"
14317   [(parallel
14318      [(set (match_dup 6)
14319            (ior:DWIH (ashift:DWIH (match_dup 6)
14320                        (and:QI (match_dup 2) (match_dup 8)))
14321                      (subreg:DWIH
14322                        (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
14323                          (minus:QI (match_dup 9)
14324                                    (and:QI (match_dup 2) (match_dup 8)))) 0)))
14325       (clobber (reg:CC FLAGS_REG))])
14326    (parallel
14327      [(set (match_dup 4)
14328            (ashift:DWIH (match_dup 5) (match_dup 2)))
14329       (clobber (reg:CC FLAGS_REG))])]
14331   if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14332     {
14333       operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14334       operands[2] = gen_lowpart (QImode, operands[2]);
14335       emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
14336                                             operands[2]));
14337       DONE;
14338     }
14340   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14342   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14343   operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14345   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14346       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14347     {
14348       rtx xops[3];
14349       xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
14350       xops[1] = operands[2];
14351       xops[2] = GEN_INT (INTVAL (operands[3])
14352                          & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
14353       ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
14354       operands[2] = xops[0];
14355     }
14357   operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14358   operands[2] = gen_lowpart (QImode, operands[2]);
14360   if (!rtx_equal_p (operands[6], operands[7]))
14361     emit_move_insn (operands[6], operands[7]);
14364 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
14365   [(set (match_operand:<DWI> 0 "register_operand")
14366         (ashift:<DWI>
14367           (match_operand:<DWI> 1 "register_operand")
14368           (and:QI
14369             (match_operand:QI 2 "register_operand" "c")
14370             (match_operand:QI 3 "const_int_operand"))))
14371    (clobber (reg:CC FLAGS_REG))]
14372   "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14373     || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14374          == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14375    && ix86_pre_reload_split ()"
14376   "#"
14377   "&& 1"
14378   [(parallel
14379      [(set (match_dup 6)
14380            (ior:DWIH (ashift:DWIH (match_dup 6)
14381                        (and:QI (match_dup 2) (match_dup 8)))
14382                      (subreg:DWIH
14383                        (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
14384                          (minus:QI (match_dup 9)
14385                                    (and:QI (match_dup 2) (match_dup 8)))) 0)))
14386       (clobber (reg:CC FLAGS_REG))])
14387    (parallel
14388      [(set (match_dup 4)
14389            (ashift:DWIH (match_dup 5) (match_dup 2)))
14390       (clobber (reg:CC FLAGS_REG))])]
14392   if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14393     {
14394       emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
14395                                             operands[2]));
14396       DONE;
14397     }
14399   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14401   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14402   operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14404   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14405       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14406     {
14407       rtx tem = gen_reg_rtx (QImode);
14408       emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
14409       operands[2] = tem;
14410     }
14412   if (!rtx_equal_p (operands[6], operands[7]))
14413     emit_move_insn (operands[6], operands[7]);
14416 (define_insn "ashl<mode>3_doubleword"
14417   [(set (match_operand:DWI 0 "register_operand" "=&r,&r")
14418         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n,r")
14419                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
14420    (clobber (reg:CC FLAGS_REG))]
14421   ""
14422   "#"
14423   [(set_attr "type" "multi")
14424    (set_attr "isa" "*,apx_ndd")])
14426 (define_split
14427   [(set (match_operand:DWI 0 "register_operand")
14428         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
14429                     (match_operand:QI 2 "nonmemory_operand")))
14430    (clobber (reg:CC FLAGS_REG))]
14431   "epilogue_completed"
14432   [(const_int 0)]
14434   if (TARGET_APX_NDD
14435       && !rtx_equal_p (operands[0], operands[1])
14436       && REG_P (operands[1]))
14437     ix86_split_ashl_ndd (operands, NULL_RTX);
14438   else
14439     ix86_split_ashl (operands, NULL_RTX, <MODE>mode);
14440   DONE;
14443 ;; By default we don't ask for a scratch register, because when DWImode
14444 ;; values are manipulated, registers are already at a premium.  But if
14445 ;; we have one handy, we won't turn it away.
14447 (define_peephole2
14448   [(match_scratch:DWIH 3 "r")
14449    (parallel [(set (match_operand:<DWI> 0 "register_operand")
14450                    (ashift:<DWI>
14451                      (match_operand:<DWI> 1 "nonmemory_operand")
14452                      (match_operand:QI 2 "nonmemory_operand")))
14453               (clobber (reg:CC FLAGS_REG))])
14454    (match_dup 3)]
14455   "TARGET_CMOVE"
14456   [(const_int 0)]
14458   if (TARGET_APX_NDD
14459       && !rtx_equal_p (operands[0], operands[1])
14460       && (REG_P (operands[1])))
14461     ix86_split_ashl_ndd (operands, operands[3]);
14462   else
14463     ix86_split_ashl (operands, operands[3], <DWI>mode);
14464   DONE;
14467 (define_insn_and_split "*ashl<dwi>3_doubleword_highpart"
14468   [(set (match_operand:<DWI> 0 "register_operand" "=r")
14469         (ashift:<DWI>
14470           (any_extend:<DWI> (match_operand:DWIH 1 "nonimmediate_operand" "rm"))
14471           (match_operand:QI 2 "const_int_operand")))
14472    (clobber (reg:CC FLAGS_REG))]
14473   "INTVAL (operands[2]) >= <MODE_SIZE> * BITS_PER_UNIT
14474    && INTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT * 2"
14475   "#"
14476   "&& reload_completed"
14477   [(const_int 0)]
14479   split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[3]);
14480   int bits = INTVAL (operands[2]) - (<MODE_SIZE> * BITS_PER_UNIT);
14481   bool op_equal_p = rtx_equal_p (operands[3], operands[1]);
14482   if (bits == 0)
14483     {
14484       if (!op_equal_p)
14485         emit_move_insn (operands[3], operands[1]);
14486     }
14487   else
14488     {
14489       if (!op_equal_p && !TARGET_APX_NDD)
14490         emit_move_insn (operands[3], operands[1]);
14491       rtx op_tmp = TARGET_APX_NDD ? operands[1] : operands[3];
14492       emit_insn (gen_ashl<mode>3 (operands[3], op_tmp, GEN_INT (bits)));
14493     }
14494   ix86_expand_clear (operands[0]);
14495   DONE;
14498 (define_insn "x86_64_shld"
14499   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14500         (ior:DI (ashift:DI (match_dup 0)
14501                   (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
14502                           (const_int 63)))
14503                 (subreg:DI
14504                   (lshiftrt:TI
14505                     (zero_extend:TI
14506                       (match_operand:DI 1 "register_operand" "r"))
14507                     (minus:QI (const_int 64)
14508                               (and:QI (match_dup 2) (const_int 63)))) 0)))
14509    (clobber (reg:CC FLAGS_REG))]
14510   "TARGET_64BIT"
14511   "shld{q}\t{%2, %1, %0|%0, %1, %2}"
14512   [(set_attr "type" "ishift")
14513    (set_attr "prefix_0f" "1")
14514    (set_attr "mode" "DI")
14515    (set_attr "athlon_decode" "vector")
14516    (set_attr "amdfam10_decode" "vector")
14517    (set_attr "bdver1_decode" "vector")])
14519 (define_insn "x86_64_shld_ndd"
14520   [(set (match_operand:DI 0 "register_operand" "=r")
14521         (ior:DI (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "rm")
14522                   (and:QI (match_operand:QI 3 "nonmemory_operand" "Jc")
14523                           (const_int 63)))
14524                 (subreg:DI
14525                   (lshiftrt:TI
14526                     (zero_extend:TI
14527                       (match_operand:DI 2 "register_operand" "r"))
14528                     (minus:QI (const_int 64)
14529                               (and:QI (match_dup 3) (const_int 63)))) 0)))
14530    (clobber (reg:CC FLAGS_REG))]
14531   "TARGET_APX_NDD"
14532   "shld{q}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
14533   [(set_attr "type" "ishift")
14534    (set_attr "mode" "DI")])
14536 (define_insn "x86_64_shld_1"
14537   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14538         (ior:DI (ashift:DI (match_dup 0)
14539                            (match_operand:QI 2 "const_0_to_63_operand"))
14540                 (subreg:DI
14541                   (lshiftrt:TI
14542                     (zero_extend:TI
14543                       (match_operand:DI 1 "register_operand" "r"))
14544                     (match_operand:QI 3 "const_0_to_255_operand")) 0)))
14545    (clobber (reg:CC FLAGS_REG))]
14546   "TARGET_64BIT
14547    && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
14548   "shld{q}\t{%2, %1, %0|%0, %1, %2}"
14549   [(set_attr "type" "ishift")
14550    (set_attr "prefix_0f" "1")
14551    (set_attr "mode" "DI")
14552    (set_attr "length_immediate" "1")
14553    (set_attr "athlon_decode" "vector")
14554    (set_attr "amdfam10_decode" "vector")
14555    (set_attr "bdver1_decode" "vector")])
14557 (define_insn "x86_64_shld_ndd_1"
14558   [(set (match_operand:DI 0 "register_operand" "=r")
14559         (ior:DI (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "rm")
14560                            (match_operand:QI 3 "const_0_to_63_operand"))
14561                 (subreg:DI
14562                   (lshiftrt:TI
14563                     (zero_extend:TI
14564                       (match_operand:DI 2 "register_operand" "r"))
14565                     (match_operand:QI 4 "const_0_to_255_operand")) 0)))
14566    (clobber (reg:CC FLAGS_REG))]
14567   "TARGET_APX_NDD
14568    && INTVAL (operands[4]) == 64 - INTVAL (operands[3])"
14569   "shld{q}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
14570   [(set_attr "type" "ishift")
14571    (set_attr "mode" "DI")
14572    (set_attr "length_immediate" "1")])
14575 (define_insn_and_split "*x86_64_shld_shrd_1_nozext"
14576   [(set (match_operand:DI 0 "nonimmediate_operand")
14577         (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
14578                              (match_operand:QI 2 "const_0_to_63_operand"))
14579                 (lshiftrt:DI
14580                   (match_operand:DI 1 "nonimmediate_operand")
14581                   (match_operand:QI 3 "const_0_to_63_operand"))))
14582    (clobber (reg:CC FLAGS_REG))]
14583   "TARGET_64BIT
14584    && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
14585    && ix86_pre_reload_split ()"
14586   "#"
14587   "&& 1"
14588   [(const_int 0)]
14590   if (rtx_equal_p (operands[4], operands[0]))
14591     {
14592       operands[1] = force_reg (DImode, operands[1]);
14593       emit_insn (gen_x86_64_shld_1 (operands[0], operands[1], operands[2], operands[3]));
14594     }
14595   else if (rtx_equal_p (operands[1], operands[0]))
14596     {
14597       operands[4] = force_reg (DImode, operands[4]);
14598       emit_insn (gen_x86_64_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
14599     }
14600   else if (TARGET_APX_NDD)
14601     {
14602      rtx tmp = gen_reg_rtx (DImode);
14603      if (MEM_P (operands[4]))
14604        {
14605          operands[1] = force_reg (DImode, operands[1]);
14606          emit_insn (gen_x86_64_shld_ndd_1 (tmp, operands[4], operands[1],
14607                                            operands[2], operands[3]));
14608        }
14609      else if (MEM_P (operands[1]))
14610        emit_insn (gen_x86_64_shrd_ndd_1 (tmp, operands[1], operands[4],
14611                                          operands[3], operands[2]));
14612      else
14613        emit_insn (gen_x86_64_shld_ndd_1 (tmp, operands[4], operands[1],
14614                                          operands[2], operands[3]));
14615      emit_move_insn (operands[0], tmp);
14616     }
14617   else
14618    {
14619      operands[1] = force_reg (DImode, operands[1]);
14620      rtx tmp = gen_reg_rtx (DImode);
14621      emit_move_insn (tmp, operands[4]);
14622      emit_insn (gen_x86_64_shld_1 (tmp, operands[1], operands[2], operands[3]));
14623      emit_move_insn (operands[0], tmp);
14624    }
14625    DONE;
14628 (define_insn_and_split "*x86_64_shld_2"
14629   [(set (match_operand:DI 0 "nonimmediate_operand")
14630         (ior:DI (ashift:DI (match_dup 0)
14631                            (match_operand:QI 2 "nonmemory_operand"))
14632                 (lshiftrt:DI (match_operand:DI 1 "register_operand")
14633                              (minus:QI (const_int 64) (match_dup 2)))))
14634    (clobber (reg:CC FLAGS_REG))]
14635   "TARGET_64BIT && ix86_pre_reload_split ()"
14636   "#"
14637   "&& 1"
14638   [(parallel [(set (match_dup 0)
14639                    (ior:DI (ashift:DI (match_dup 0)
14640                                       (and:QI (match_dup 2) (const_int 63)))
14641                            (subreg:DI
14642                              (lshiftrt:TI
14643                                (zero_extend:TI (match_dup 1))
14644                                  (minus:QI (const_int 64)
14645                                            (and:QI (match_dup 2)
14646                                                    (const_int 63)))) 0)))
14647               (clobber (reg:CC FLAGS_REG))])])
14649 (define_insn_and_split "*x86_64_shld_ndd_2"
14650   [(set (match_operand:DI 0 "nonimmediate_operand")
14651         (ior:DI (ashift:DI (match_operand:DI 1 "nonimmediate_operand")
14652                            (match_operand:QI 3 "nonmemory_operand"))
14653                 (lshiftrt:DI (match_operand:DI 2 "register_operand")
14654                              (minus:QI (const_int 64) (match_dup 3)))))
14655    (clobber (reg:CC FLAGS_REG))]
14656   "TARGET_APX_NDD
14657    && ix86_pre_reload_split ()"
14658   "#"
14659   "&& 1"
14660   [(parallel [(set (match_dup 4)
14661                    (ior:DI (ashift:DI (match_dup 1)
14662                                       (and:QI (match_dup 3) (const_int 63)))
14663                            (subreg:DI
14664                              (lshiftrt:TI
14665                                (zero_extend:TI (match_dup 2))
14666                                  (minus:QI (const_int 64)
14667                                            (and:QI (match_dup 3)
14668                                                    (const_int 63)))) 0)))
14669               (clobber (reg:CC FLAGS_REG))
14670               (set (match_dup 0) (match_dup 4))])]
14672   operands[4] = gen_reg_rtx (DImode);
14673   emit_move_insn (operands[4], operands[0]);
14676 (define_insn "x86_shld"
14677   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14678         (ior:SI (ashift:SI (match_dup 0)
14679                   (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
14680                           (const_int 31)))
14681                 (subreg:SI
14682                   (lshiftrt:DI
14683                     (zero_extend:DI
14684                       (match_operand:SI 1 "register_operand" "r"))
14685                     (minus:QI (const_int 32)
14686                               (and:QI (match_dup 2) (const_int 31)))) 0)))
14687    (clobber (reg:CC FLAGS_REG))]
14688   ""
14689   "shld{l}\t{%2, %1, %0|%0, %1, %2}"
14690   [(set_attr "type" "ishift")
14691    (set_attr "prefix_0f" "1")
14692    (set_attr "mode" "SI")
14693    (set_attr "pent_pair" "np")
14694    (set_attr "athlon_decode" "vector")
14695    (set_attr "amdfam10_decode" "vector")
14696    (set_attr "bdver1_decode" "vector")])
14698 (define_insn "x86_shld_ndd"
14699   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14700         (ior:SI (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
14701                   (and:QI (match_operand:QI 3 "nonmemory_operand" "Ic")
14702                           (const_int 31)))
14703                 (subreg:SI
14704                   (lshiftrt:DI
14705                     (zero_extend:DI
14706                       (match_operand:SI 2 "register_operand" "r"))
14707                     (minus:QI (const_int 32)
14708                               (and:QI (match_dup 3) (const_int 31)))) 0)))
14709    (clobber (reg:CC FLAGS_REG))]
14710   "TARGET_APX_NDD"
14711   "shld{l}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
14712   [(set_attr "type" "ishift")
14713    (set_attr "mode" "SI")])
14716 (define_insn "x86_shld_1"
14717   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14718         (ior:SI (ashift:SI (match_dup 0)
14719                            (match_operand:QI 2 "const_0_to_31_operand"))
14720                 (subreg:SI
14721                   (lshiftrt:DI
14722                     (zero_extend:DI
14723                       (match_operand:SI 1 "register_operand" "r"))
14724                     (match_operand:QI 3 "const_0_to_63_operand")) 0)))
14725    (clobber (reg:CC FLAGS_REG))]
14726   "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
14727   "shld{l}\t{%2, %1, %0|%0, %1, %2}"
14728   [(set_attr "type" "ishift")
14729    (set_attr "prefix_0f" "1")
14730    (set_attr "length_immediate" "1")
14731    (set_attr "mode" "SI")
14732    (set_attr "pent_pair" "np")
14733    (set_attr "athlon_decode" "vector")
14734    (set_attr "amdfam10_decode" "vector")
14735    (set_attr "bdver1_decode" "vector")])
14737 (define_insn "x86_shld_ndd_1"
14738   [(set (match_operand:SI 0 "register_operand" "=r")
14739         (ior:SI (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
14740                            (match_operand:QI 3 "const_0_to_31_operand"))
14741                 (subreg:SI
14742                   (lshiftrt:DI
14743                     (zero_extend:DI
14744                       (match_operand:SI 2 "register_operand" "r"))
14745                     (match_operand:QI 4 "const_0_to_63_operand")) 0)))
14746    (clobber (reg:CC FLAGS_REG))]
14747   "TARGET_APX_NDD 
14748    && INTVAL (operands[4]) == 32 - INTVAL (operands[3])"
14749   "shld{l}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
14750   [(set_attr "type" "ishift")
14751    (set_attr "length_immediate" "1")
14752    (set_attr "mode" "SI")])
14755 (define_insn_and_split "*x86_shld_shrd_1_nozext"
14756   [(set (match_operand:SI 0 "nonimmediate_operand")
14757         (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
14758                              (match_operand:QI 2 "const_0_to_31_operand"))
14759                (lshiftrt:SI
14760                    (match_operand:SI 1 "nonimmediate_operand")
14761                    (match_operand:QI 3 "const_0_to_31_operand"))))
14762    (clobber (reg:CC FLAGS_REG))]
14763   "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
14764    && ix86_pre_reload_split ()"
14765   "#"
14766   "&& 1"
14767   [(const_int 0)]
14769   if (rtx_equal_p (operands[4], operands[0]))
14770     {
14771       operands[1] = force_reg (SImode, operands[1]);
14772       emit_insn (gen_x86_shld_1 (operands[0], operands[1], operands[2], operands[3]));
14773     }
14774   else if (rtx_equal_p (operands[1], operands[0]))
14775     {
14776       operands[4] = force_reg (SImode, operands[4]);
14777       emit_insn (gen_x86_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
14778     }
14779   else if (TARGET_APX_NDD)
14780     {
14781      rtx tmp = gen_reg_rtx (SImode);
14782      if (MEM_P (operands[4]))
14783        {
14784          operands[1] = force_reg (SImode, operands[1]);
14785          emit_insn (gen_x86_shld_ndd_1 (tmp, operands[4], operands[1],
14786                                         operands[2], operands[3]));
14787        }
14788      else if (MEM_P (operands[1]))
14789        emit_insn (gen_x86_shrd_ndd_1 (tmp, operands[1], operands[4],
14790                                       operands[3], operands[2]));
14791      else
14792        emit_insn (gen_x86_shld_ndd_1 (tmp, operands[4], operands[1],
14793                                       operands[2], operands[3]));
14794      emit_move_insn (operands[0], tmp);
14795     }
14796  else
14797    {
14798      operands[1] = force_reg (SImode, operands[1]);
14799      rtx tmp = gen_reg_rtx (SImode);
14800      emit_move_insn (tmp, operands[4]);
14801      emit_insn (gen_x86_shld_1 (tmp, operands[1], operands[2], operands[3]));
14802      emit_move_insn (operands[0], tmp);
14803    }
14804    DONE;
14807 (define_insn_and_split "*x86_shld_2"
14808   [(set (match_operand:SI 0 "nonimmediate_operand")
14809         (ior:SI (ashift:SI (match_dup 0)
14810                            (match_operand:QI 2 "nonmemory_operand"))
14811                 (lshiftrt:SI (match_operand:SI 1 "register_operand")
14812                              (minus:QI (const_int 32) (match_dup 2)))))
14813    (clobber (reg:CC FLAGS_REG))]
14814   "TARGET_64BIT && ix86_pre_reload_split ()"
14815   "#"
14816   "&& 1"
14817   [(parallel [(set (match_dup 0)
14818                    (ior:SI (ashift:SI (match_dup 0)
14819                                       (and:QI (match_dup 2) (const_int 31)))
14820                            (subreg:SI
14821                              (lshiftrt:DI
14822                                (zero_extend:DI (match_dup 1))
14823                                  (minus:QI (const_int 32)
14824                                            (and:QI (match_dup 2)
14825                                                    (const_int 31)))) 0)))
14826               (clobber (reg:CC FLAGS_REG))])])
14828 (define_insn_and_split "*x86_shld_ndd_2"
14829   [(set (match_operand:SI 0 "nonimmediate_operand")
14830         (ior:SI (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
14831                            (match_operand:QI 3 "nonmemory_operand"))
14832                 (lshiftrt:SI (match_operand:SI 2 "register_operand")
14833                              (minus:QI (const_int 32) (match_dup 3)))))
14834    (clobber (reg:CC FLAGS_REG))]
14835   "TARGET_APX_NDD
14836    && ix86_pre_reload_split ()"
14837   "#"
14838   "&& 1"
14839   [(parallel [(set (match_dup 4)
14840                    (ior:SI (ashift:SI (match_dup 1)
14841                                       (and:QI (match_dup 3) (const_int 31)))
14842                            (subreg:SI
14843                              (lshiftrt:DI
14844                                (zero_extend:DI (match_dup 2))
14845                                  (minus:QI (const_int 32)
14846                                            (and:QI (match_dup 3)
14847                                                    (const_int 31)))) 0)))
14848               (clobber (reg:CC FLAGS_REG))
14849               (set (match_dup 0) (match_dup 4))])]
14851   operands[4] = gen_reg_rtx (SImode);
14852   emit_move_insn (operands[4], operands[0]);
14855 (define_expand "@x86_shift<mode>_adj_1"
14856   [(set (reg:CCZ FLAGS_REG)
14857         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
14858                              (match_dup 4))
14859                      (const_int 0)))
14860    (set (match_operand:SWI48 0 "register_operand")
14861         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
14862                             (match_operand:SWI48 1 "register_operand")
14863                             (match_dup 0)))
14864    (set (match_dup 1)
14865         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
14866                             (match_operand:SWI48 3 "register_operand")
14867                             (match_dup 1)))]
14868   "TARGET_CMOVE"
14869   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
14871 (define_expand "@x86_shift<mode>_adj_2"
14872   [(use (match_operand:SWI48 0 "register_operand"))
14873    (use (match_operand:SWI48 1 "register_operand"))
14874    (use (match_operand:QI 2 "register_operand"))]
14875   ""
14877   rtx_code_label *label = gen_label_rtx ();
14878   rtx tmp;
14880   emit_insn (gen_testqi_ccz_1 (operands[2],
14881                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
14883   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
14884   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
14885   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
14886                               gen_rtx_LABEL_REF (VOIDmode, label),
14887                               pc_rtx);
14888   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
14889   JUMP_LABEL (tmp) = label;
14891   emit_move_insn (operands[0], operands[1]);
14892   ix86_expand_clear (operands[1]);
14894   emit_label (label);
14895   LABEL_NUSES (label) = 1;
14897   DONE;
14900 ;; Avoid useless masking of count operand.
14901 (define_insn_and_split "*ashl<mode>3_mask"
14902   [(set (match_operand:SWI48 0 "nonimmediate_operand")
14903         (ashift:SWI48
14904           (match_operand:SWI48 1 "nonimmediate_operand")
14905           (subreg:QI
14906             (and
14907               (match_operand 2 "int248_register_operand" "c,r")
14908               (match_operand 3 "const_int_operand")) 0)))
14909    (clobber (reg:CC FLAGS_REG))]
14910   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
14911    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14912       == GET_MODE_BITSIZE (<MODE>mode)-1
14913    && ix86_pre_reload_split ()"
14914   "#"
14915   "&& 1"
14916   [(parallel
14917      [(set (match_dup 0)
14918            (ashift:SWI48 (match_dup 1)
14919                          (match_dup 2)))
14920       (clobber (reg:CC FLAGS_REG))])]
14922   operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14923   operands[2] = gen_lowpart (QImode, operands[2]);
14925   [(set_attr "isa" "*,bmi2")])
14927 (define_insn_and_split "*ashl<mode>3_mask_1"
14928   [(set (match_operand:SWI48 0 "nonimmediate_operand")
14929         (ashift:SWI48
14930           (match_operand:SWI48 1 "nonimmediate_operand")
14931           (and:QI
14932             (match_operand:QI 2 "register_operand" "c,r")
14933             (match_operand:QI 3 "const_int_operand"))))
14934    (clobber (reg:CC FLAGS_REG))]
14935   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
14936    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14937       == GET_MODE_BITSIZE (<MODE>mode)-1
14938    && ix86_pre_reload_split ()"
14939   "#"
14940   "&& 1"
14941   [(parallel
14942      [(set (match_dup 0)
14943            (ashift:SWI48 (match_dup 1)
14944                          (match_dup 2)))
14945       (clobber (reg:CC FLAGS_REG))])]
14946   ""
14947   [(set_attr "isa" "*,bmi2")])
14949 (define_insn "*bmi2_ashl<mode>3_1"
14950   [(set (match_operand:SWI48 0 "register_operand" "=r")
14951         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14952                       (match_operand:SWI48 2 "register_operand" "r")))]
14953   "TARGET_BMI2"
14954   "shlx\t{%2, %1, %0|%0, %1, %2}"
14955   [(set_attr "type" "ishiftx")
14956    (set_attr "mode" "<MODE>")])
14958 (define_insn "*ashl<mode>3_1"
14959   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,?k,r")
14960         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm,k,rm")
14961                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r,<KS>,c<S>")))
14962    (clobber (reg:CC FLAGS_REG))]
14963   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands, TARGET_APX_NDD)"
14965   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
14966   switch (get_attr_type (insn))
14967     {
14968     case TYPE_LEA:
14969     case TYPE_ISHIFTX:
14970     case TYPE_MSKLOG:
14971       return "#";
14973     case TYPE_ALU:
14974       gcc_assert (operands[2] == const1_rtx);
14975       gcc_assert (rtx_equal_p (operands[0], operands[1]));
14976       return "add{<imodesuffix>}\t%0, %0";
14978     default:
14979       if (operands[2] == const1_rtx
14980           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14981           /* For NDD form instructions related to TARGET_SHIFT1, the $1
14982              immediate do not need to be omitted as assembler will map it
14983              to use shorter encoding. */
14984           && !use_ndd)
14985         return "sal{<imodesuffix>}\t%0";
14986       else
14987         return use_ndd ? "sal{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
14988                        : "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14989     }
14991   [(set_attr "isa" "*,*,bmi2,avx512bw,apx_ndd")
14992    (set (attr "type")
14993      (cond [(eq_attr "alternative" "1")
14994               (const_string "lea")
14995             (eq_attr "alternative" "2")
14996               (const_string "ishiftx")
14997             (eq_attr "alternative" "4")
14998               (const_string "ishift")
14999             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
15000                       (match_operand 0 "register_operand"))
15001                  (match_operand 2 "const1_operand"))
15002               (const_string "alu")
15003             (eq_attr "alternative" "3")
15004               (const_string "msklog")
15005            ]
15006            (const_string "ishift")))
15007    (set (attr "length_immediate")
15008      (if_then_else
15009        (ior (eq_attr "type" "alu")
15010             (and (eq_attr "type" "ishift")
15011                  (and (match_operand 2 "const1_operand")
15012                       (ior (match_test "TARGET_SHIFT1")
15013                            (match_test "optimize_function_for_size_p (cfun)")))))
15014        (const_string "0")
15015        (const_string "*")))
15016    (set_attr "mode" "<MODE>")])
15018 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15019 (define_split
15020   [(set (match_operand:SWI48 0 "register_operand")
15021         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15022                       (match_operand:QI 2 "register_operand")))
15023    (clobber (reg:CC FLAGS_REG))]
15024   "TARGET_BMI2 && reload_completed"
15025   [(set (match_dup 0)
15026         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
15027   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
15029 (define_insn "*bmi2_ashlsi3_1_zext"
15030   [(set (match_operand:DI 0 "register_operand" "=r")
15031         (zero_extend:DI
15032           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15033                      (match_operand:SI 2 "register_operand" "r"))))]
15034   "TARGET_64BIT && TARGET_BMI2"
15035   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
15036   [(set_attr "type" "ishiftx")
15037    (set_attr "mode" "SI")])
15039 (define_insn "*ashlsi3_1_zext"
15040   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
15041         (zero_extend:DI
15042           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm,rm")
15043                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r,cI"))))
15044    (clobber (reg:CC FLAGS_REG))]
15045   "TARGET_64BIT
15046    && ix86_binary_operator_ok (ASHIFT, SImode, operands, TARGET_APX_NDD)"
15048   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
15049   switch (get_attr_type (insn))
15050     {
15051     case TYPE_LEA:
15052     case TYPE_ISHIFTX:
15053       return "#";
15055     case TYPE_ALU:
15056       gcc_assert (operands[2] == const1_rtx);
15057       return "add{l}\t%k0, %k0";
15059     default:
15060       if (operands[2] == const1_rtx
15061           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
15062           && !use_ndd)
15063         return "sal{l}\t%k0";
15064       else
15065         return use_ndd ? "sal{l}\t{%2, %1, %k0|%k0, %1, %2}"
15066                        : "sal{l}\t{%2, %k0|%k0, %2}";
15067     }
15069   [(set_attr "isa" "*,*,bmi2,apx_ndd")
15070    (set (attr "type")
15071      (cond [(eq_attr "alternative" "1")
15072               (const_string "lea")
15073             (eq_attr "alternative" "2")
15074               (const_string "ishiftx")
15075             (eq_attr "alternative" "3")
15076               (const_string "ishift")
15077             (and (match_test "TARGET_DOUBLE_WITH_ADD")
15078                  (match_operand 2 "const1_operand"))
15079               (const_string "alu")
15080            ]
15081            (const_string "ishift")))
15082    (set (attr "length_immediate")
15083      (if_then_else
15084        (ior (eq_attr "type" "alu")
15085             (and (eq_attr "type" "ishift")
15086                  (and (match_operand 2 "const1_operand")
15087                       (ior (match_test "TARGET_SHIFT1")
15088                            (match_test "optimize_function_for_size_p (cfun)")))))
15089        (const_string "0")
15090        (const_string "*")))
15091    (set_attr "mode" "SI")])
15093 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15094 (define_split
15095   [(set (match_operand:DI 0 "register_operand")
15096         (zero_extend:DI
15097           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
15098                      (match_operand:QI 2 "register_operand"))))
15099    (clobber (reg:CC FLAGS_REG))]
15100   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
15101   [(set (match_dup 0)
15102         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
15103   "operands[2] = gen_lowpart (SImode, operands[2]);")
15105 (define_insn "*ashlhi3_1"
15106   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp,?k,r")
15107         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l,k,rm")
15108                    (match_operand:QI 2 "nonmemory_operand" "cI,M,Ww,cI")))
15109    (clobber (reg:CC FLAGS_REG))]
15110   "ix86_binary_operator_ok (ASHIFT, HImode, operands, TARGET_APX_NDD)"
15112   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
15113   switch (get_attr_type (insn))
15114     {
15115     case TYPE_LEA:
15116     case TYPE_MSKLOG:
15117       return "#";
15119     case TYPE_ALU:
15120       gcc_assert (operands[2] == const1_rtx);
15121       return "add{w}\t%0, %0";
15123     default:
15124       if (operands[2] == const1_rtx
15125           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
15126           && !use_ndd)
15127         return "sal{w}\t%0";
15128       else
15129         return use_ndd ? "sal{w}\t{%2, %1, %0|%0, %1, %2}"
15130                        : "sal{w}\t{%2, %0|%0, %2}";
15131     }
15133   [(set_attr "isa" "*,*,avx512f,apx_ndd")
15134    (set (attr "type")
15135      (cond [(eq_attr "alternative" "1")
15136               (const_string "lea")
15137             (eq_attr "alternative" "2")
15138               (const_string "msklog")
15139             (eq_attr "alternative" "3")
15140               (const_string "ishift")
15141             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
15142                       (match_operand 0 "register_operand"))
15143                  (match_operand 2 "const1_operand"))
15144               (const_string "alu")
15145            ]
15146            (const_string "ishift")))
15147    (set (attr "length_immediate")
15148      (if_then_else
15149        (ior (eq_attr "type" "alu")
15150             (and (eq_attr "type" "ishift")
15151                  (and (match_operand 2 "const1_operand")
15152                       (ior (match_test "TARGET_SHIFT1")
15153                            (match_test "optimize_function_for_size_p (cfun)")))))
15154        (const_string "0")
15155        (const_string "*")))
15156    (set_attr "mode" "HI,SI,HI,HI")])
15158 (define_insn "*ashlqi3_1"
15159   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp,?k,r")
15160         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l,k,rm")
15161                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M,Wb,cI")))
15162    (clobber (reg:CC FLAGS_REG))]
15163   "ix86_binary_operator_ok (ASHIFT, QImode, operands, TARGET_APX_NDD)"
15165   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
15166   switch (get_attr_type (insn))
15167     {
15168     case TYPE_LEA:
15169     case TYPE_MSKLOG:
15170       return "#";
15172     case TYPE_ALU:
15173       gcc_assert (operands[2] == const1_rtx);
15174       if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
15175         return "add{l}\t%k0, %k0";
15176       else
15177         return "add{b}\t%0, %0";
15179     default:
15180       if (operands[2] == const1_rtx
15181           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
15182           && !use_ndd)
15183         {
15184           if (get_attr_mode (insn) == MODE_SI)
15185             return "sal{l}\t%k0";
15186           else
15187             return "sal{b}\t%0";
15188         }
15189       else
15190         {
15191           if (get_attr_mode (insn) == MODE_SI)
15192             return "sal{l}\t{%2, %k0|%k0, %2}";
15193           else
15194             return use_ndd ? "sal{b}\t{%2, %1, %0|%0, %1, %2}"
15195                            : "sal{b}\t{%2, %0|%0, %2}";
15196         }
15197     }
15199   [(set_attr "isa" "*,*,*,avx512dq,apx_ndd")
15200    (set (attr "type")
15201      (cond [(eq_attr "alternative" "2")
15202               (const_string "lea")
15203             (eq_attr "alternative" "3")
15204               (const_string "msklog")
15205             (eq_attr "alternative" "4")
15206               (const_string "ishift")
15207             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
15208                       (match_operand 0 "register_operand"))
15209                  (match_operand 2 "const1_operand"))
15210               (const_string "alu")
15211            ]
15212            (const_string "ishift")))
15213    (set (attr "length_immediate")
15214      (if_then_else
15215        (ior (eq_attr "type" "alu")
15216             (and (eq_attr "type" "ishift")
15217                  (and (match_operand 2 "const1_operand")
15218                       (ior (match_test "TARGET_SHIFT1")
15219                            (match_test "optimize_function_for_size_p (cfun)")))))
15220        (const_string "0")
15221        (const_string "*")))
15222    (set_attr "mode" "QI,SI,SI,QI,QI")
15223    ;; Potential partial reg stall on alternative 1.
15224    (set (attr "preferred_for_speed")
15225      (cond [(eq_attr "alternative" "1,4")
15226               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
15227            (symbol_ref "true")))])
15229 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15230 (define_insn_and_split "*ashl<mode>3_1_slp"
15231   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15232         (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15233                       (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15234    (clobber (reg:CC FLAGS_REG))]
15235   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15237   if (which_alternative)
15238     return "#";
15240   switch (get_attr_type (insn))
15241     {
15242     case TYPE_ALU:
15243       gcc_assert (operands[2] == const1_rtx);
15244       return "add{<imodesuffix>}\t%0, %0";
15246     default:
15247       if (operands[2] == const1_rtx
15248           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15249         return "sal{<imodesuffix>}\t%0";
15250       else
15251         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
15252     }
15254   "&& reload_completed
15255    && !(rtx_equal_p (operands[0], operands[1]))"
15256   [(set (strict_low_part (match_dup 0)) (match_dup 1))
15257    (parallel
15258      [(set (strict_low_part (match_dup 0))
15259            (ashift:SWI12 (match_dup 0) (match_dup 2)))
15260       (clobber (reg:CC FLAGS_REG))])]
15261   ""
15262   [(set (attr "type")
15263      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
15264                  (match_operand 2 "const1_operand"))
15265               (const_string "alu")
15266            ]
15267            (const_string "ishift")))
15268    (set (attr "length_immediate")
15269      (if_then_else
15270        (ior (eq_attr "type" "alu")
15271             (and (eq_attr "type" "ishift")
15272                  (and (match_operand 2 "const1_operand")
15273                       (ior (match_test "TARGET_SHIFT1")
15274                            (match_test "optimize_function_for_size_p (cfun)")))))
15275        (const_string "0")
15276        (const_string "*")))
15277    (set_attr "mode" "<MODE>")])
15279 ;; Convert ashift to the lea pattern to avoid flags dependency.
15280 (define_split
15281   [(set (match_operand:SWI 0 "general_reg_operand")
15282         (ashift:SWI (match_operand:SWI 1 "index_reg_operand")
15283                     (match_operand 2 "const_0_to_3_operand")))
15284    (clobber (reg:CC FLAGS_REG))]
15285   "reload_completed
15286    && REGNO (operands[0]) != REGNO (operands[1])"
15287   [(set (match_dup 0)
15288         (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
15290   if (<MODE>mode != <LEAMODE>mode)
15291     {
15292       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
15293       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
15294     }
15295   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
15298 ;; Convert ashift to the lea pattern to avoid flags dependency.
15299 (define_split
15300   [(set (match_operand:DI 0 "general_reg_operand")
15301         (zero_extend:DI
15302           (ashift:SI (match_operand:SI 1 "index_reg_operand")
15303                      (match_operand 2 "const_0_to_3_operand"))))
15304    (clobber (reg:CC FLAGS_REG))]
15305   "TARGET_64BIT && reload_completed
15306    && REGNO (operands[0]) != REGNO (operands[1])"
15307   [(set (match_dup 0)
15308         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
15310   operands[1] = gen_lowpart (SImode, operands[1]);
15311   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
15314 ;; This pattern can't accept a variable shift count, since shifts by
15315 ;; zero don't affect the flags.  We assume that shifts by constant
15316 ;; zero are optimized away.
15317 (define_insn "*ashl<mode>3_cmp"
15318   [(set (reg FLAGS_REG)
15319         (compare
15320           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm")
15321                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>,<S>"))
15322           (const_int 0)))
15323    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
15324         (ashift:SWI (match_dup 1) (match_dup 2)))]
15325   "(optimize_function_for_size_p (cfun)
15326     || !TARGET_PARTIAL_FLAG_REG_STALL
15327     || (operands[2] == const1_rtx
15328         && (TARGET_SHIFT1
15329             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
15330    && ix86_match_ccmode (insn, CCGOCmode)
15331    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands, TARGET_APX_NDD)"
15333   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
15334   switch (get_attr_type (insn))
15335     {
15336     case TYPE_ALU:
15337       gcc_assert (operands[2] == const1_rtx);
15338       return "add{<imodesuffix>}\t%0, %0";
15340     default:
15341       if (operands[2] == const1_rtx
15342           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
15343           && !use_ndd)
15344         return "sal{<imodesuffix>}\t%0";
15345       else
15346         return use_ndd ? "sal{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
15347                        : "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
15348     }
15350   [(set_attr "isa" "*,apx_ndd")
15351    (set (attr "type")
15352      (cond [(eq_attr "alternative" "1")
15353               (const_string "ishift")
15354             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
15355                       (match_operand 0 "register_operand"))
15356                  (match_operand 2 "const1_operand"))
15357               (const_string "alu")
15358            ]
15359            (const_string "ishift")))
15360    (set (attr "length_immediate")
15361      (if_then_else
15362        (ior (eq_attr "type" "alu")
15363             (and (eq_attr "type" "ishift")
15364                  (and (match_operand 2 "const1_operand")
15365                       (ior (match_test "TARGET_SHIFT1")
15366                            (match_test "optimize_function_for_size_p (cfun)")))))
15367        (const_string "0")
15368        (const_string "*")))
15369    (set_attr "mode" "<MODE>")])
15371 (define_insn "*ashlsi3_cmp_zext"
15372   [(set (reg FLAGS_REG)
15373         (compare
15374           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15375                      (match_operand:QI 2 "const_1_to_31_operand"))
15376           (const_int 0)))
15377    (set (match_operand:DI 0 "register_operand" "=r,r")
15378         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
15379   "TARGET_64BIT
15380    && (optimize_function_for_size_p (cfun)
15381        || !TARGET_PARTIAL_FLAG_REG_STALL
15382        || (operands[2] == const1_rtx
15383            && (TARGET_SHIFT1
15384                || TARGET_DOUBLE_WITH_ADD)))
15385    && ix86_match_ccmode (insn, CCGOCmode)
15386    && ix86_binary_operator_ok (ASHIFT, SImode, operands, TARGET_APX_NDD)"
15388   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
15389   switch (get_attr_type (insn))
15390     {
15391     case TYPE_ALU:
15392       gcc_assert (operands[2] == const1_rtx);
15393       return "add{l}\t%k0, %k0";
15395     default:
15396       if (operands[2] == const1_rtx
15397           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
15398           && !use_ndd)
15399         return "sal{l}\t%k0";
15400       else
15401         return use_ndd ? "sal{l}\t{%2, %1, %k0|%k0, %1, %2}"
15402                        : "sal{l}\t{%2, %k0|%k0, %2}";
15403     }
15405   [(set_attr "isa" "*,apx_ndd")
15406    (set (attr "type")
15407      (cond [(eq_attr "alternative" "1")
15408               (const_string "ishift")
15409             (and (match_test "TARGET_DOUBLE_WITH_ADD")
15410                  (match_operand 2 "const1_operand"))
15411               (const_string "alu")
15412            ]
15413            (const_string "ishift")))
15414    (set (attr "length_immediate")
15415      (if_then_else
15416        (ior (eq_attr "type" "alu")
15417             (and (eq_attr "type" "ishift")
15418                  (and (match_operand 2 "const1_operand")
15419                       (ior (match_test "TARGET_SHIFT1")
15420                            (match_test "optimize_function_for_size_p (cfun)")))))
15421        (const_string "0")
15422        (const_string "*")))
15423    (set_attr "mode" "SI")])
15425 (define_insn "*ashl<mode>3_cconly"
15426   [(set (reg FLAGS_REG)
15427         (compare
15428           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm")
15429                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>,<S>"))
15430           (const_int 0)))
15431    (clobber (match_scratch:SWI 0 "=<r>,r"))]
15432   "(optimize_function_for_size_p (cfun)
15433     || !TARGET_PARTIAL_FLAG_REG_STALL
15434     || (operands[2] == const1_rtx
15435         && (TARGET_SHIFT1
15436             || TARGET_DOUBLE_WITH_ADD)))
15437    && ix86_match_ccmode (insn, CCGOCmode)"
15439   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
15440   switch (get_attr_type (insn))
15441     {
15442     case TYPE_ALU:
15443       gcc_assert (operands[2] == const1_rtx);
15444       return "add{<imodesuffix>}\t%0, %0";
15446   default:
15447       if (operands[2] == const1_rtx
15448           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
15449           && !use_ndd)
15450         return "sal{<imodesuffix>}\t%0";
15451       else
15452         return use_ndd ? "sal{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
15453                        : "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
15454     }
15456   [(set_attr "isa" "*,apx_ndd")
15457    (set (attr "type")
15458      (cond [(eq_attr "alternative" "1")
15459               (const_string "ishift")
15460             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
15461                       (match_operand 0 "register_operand"))
15462                  (match_operand 2 "const1_operand"))
15463               (const_string "alu")
15464            ]
15465            (const_string "ishift")))
15466    (set (attr "length_immediate")
15467      (if_then_else
15468        (ior (eq_attr "type" "alu")
15469             (and (eq_attr "type" "ishift")
15470                  (and (match_operand 2 "const1_operand")
15471                       (ior (match_test "TARGET_SHIFT1")
15472                            (match_test "optimize_function_for_size_p (cfun)")))))
15473        (const_string "0")
15474        (const_string "*")))
15475    (set_attr "mode" "<MODE>")])
15477 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15478 (define_insn_and_split "*ashlqi_ext<mode>_1"
15479   [(set (zero_extract:SWI248
15480           (match_operand 0 "int248_register_operand" "+Q,&Q")
15481           (const_int 8)
15482           (const_int 8))
15483         (subreg:SWI248
15484           (ashift:QI
15485             (subreg:QI
15486               (match_operator:SWI248 3 "extract_operator"
15487                 [(match_operand 1 "int248_register_operand" "0,!Q")
15488                  (const_int 8)
15489                  (const_int 8)]) 0)
15490             (match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
15491    (clobber (reg:CC FLAGS_REG))]
15492   ""
15494   if (which_alternative)
15495     return "#";
15497   switch (get_attr_type (insn))
15498     {
15499     case TYPE_ALU:
15500       gcc_assert (operands[2] == const1_rtx);
15501       return "add{b}\t%h0, %h0";
15503     default:
15504       if (operands[2] == const1_rtx
15505           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15506         return "sal{b}\t%h0";
15507       else
15508         return "sal{b}\t{%2, %h0|%h0, %2}";
15509     }
15511   "reload_completed
15512    && !(rtx_equal_p (operands[0], operands[1]))"
15513   [(set (zero_extract:SWI248
15514           (match_dup 0) (const_int 8) (const_int 8))
15515         (zero_extract:SWI248
15516           (match_dup 1) (const_int 8) (const_int 8)))
15517    (parallel
15518      [(set (zero_extract:SWI248
15519              (match_dup 0) (const_int 8) (const_int 8))
15520            (subreg:SWI248
15521              (ashift:QI
15522                (subreg:QI
15523                  (match_op_dup 3
15524                    [(match_dup 0) (const_int 8) (const_int 8)]) 0)
15525                (match_dup 2)) 0))
15526       (clobber (reg:CC FLAGS_REG))])]
15527   ""
15528   [(set (attr "type")
15529      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
15530                  (match_operand 2 "const1_operand"))
15531               (const_string "alu")
15532            ]
15533            (const_string "ishift")))
15534    (set (attr "length_immediate")
15535      (if_then_else
15536        (ior (eq_attr "type" "alu")
15537             (and (eq_attr "type" "ishift")
15538                  (and (match_operand 2 "const1_operand")
15539                       (ior (match_test "TARGET_SHIFT1")
15540                            (match_test "optimize_function_for_size_p (cfun)")))))
15541        (const_string "0")
15542        (const_string "*")))
15543    (set_attr "mode" "QI")])
15545 ;; See comment above `ashl<mode>3' about how this works.
15547 (define_expand "<insn><mode>3"
15548   [(set (match_operand:SDWIM 0 "<shift_operand>")
15549         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
15550                            (match_operand:QI 2 "nonmemory_operand")))]
15551   ""
15553   ix86_expand_binary_operator (<CODE>, <MODE>mode, operands, TARGET_APX_NDD);
15554   DONE;
15557 ;; Avoid useless masking of count operand.
15558 (define_insn_and_split "*<insn><mode>3_mask"
15559   [(set (match_operand:SWI48 0 "nonimmediate_operand")
15560         (any_shiftrt:SWI48
15561           (match_operand:SWI48 1 "nonimmediate_operand")
15562           (subreg:QI
15563             (and
15564               (match_operand 2 "int248_register_operand" "c,r")
15565               (match_operand 3 "const_int_operand")) 0)))
15566    (clobber (reg:CC FLAGS_REG))]
15567   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15568    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15569       == GET_MODE_BITSIZE (<MODE>mode)-1
15570    && ix86_pre_reload_split ()"
15571   "#"
15572   "&& 1"
15573   [(parallel
15574      [(set (match_dup 0)
15575            (any_shiftrt:SWI48 (match_dup 1)
15576                               (match_dup 2)))
15577       (clobber (reg:CC FLAGS_REG))])]
15579   operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15580   operands[2] = gen_lowpart (QImode, operands[2]);
15582   [(set_attr "isa" "*,bmi2")])
15584 (define_insn_and_split "*<insn><mode>3_mask_1"
15585   [(set (match_operand:SWI48 0 "nonimmediate_operand")
15586         (any_shiftrt:SWI48
15587           (match_operand:SWI48 1 "nonimmediate_operand")
15588           (and:QI
15589             (match_operand:QI 2 "register_operand" "c,r")
15590             (match_operand:QI 3 "const_int_operand"))))
15591    (clobber (reg:CC FLAGS_REG))]
15592   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15593    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15594       == GET_MODE_BITSIZE (<MODE>mode)-1
15595    && ix86_pre_reload_split ()"
15596   "#"
15597   "&& 1"
15598   [(parallel
15599      [(set (match_dup 0)
15600            (any_shiftrt:SWI48 (match_dup 1)
15601                               (match_dup 2)))
15602       (clobber (reg:CC FLAGS_REG))])]
15603   ""
15604   [(set_attr "isa" "*,bmi2")])
15606 (define_insn_and_split "*<insn><dwi>3_doubleword_mask"
15607   [(set (match_operand:<DWI> 0 "register_operand")
15608         (any_shiftrt:<DWI>
15609           (match_operand:<DWI> 1 "register_operand")
15610           (subreg:QI
15611             (and
15612               (match_operand 2 "int248_register_operand" "c")
15613               (match_operand 3 "const_int_operand")) 0)))
15614    (clobber (reg:CC FLAGS_REG))]
15615   "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
15616     || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
15617          == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
15618    && ix86_pre_reload_split ()"
15619   "#"
15620   "&& 1"
15621   [(parallel
15622      [(set (match_dup 4)
15623            (ior:DWIH (lshiftrt:DWIH (match_dup 4)
15624                        (and:QI (match_dup 2) (match_dup 8)))
15625                      (subreg:DWIH
15626                        (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
15627                          (minus:QI (match_dup 9)
15628                                    (and:QI (match_dup 2) (match_dup 8)))) 0)))
15629       (clobber (reg:CC FLAGS_REG))])
15630    (parallel
15631      [(set (match_dup 6)
15632            (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
15633       (clobber (reg:CC FLAGS_REG))])]
15635   if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
15636     {
15637       operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15638       operands[2] = gen_lowpart (QImode, operands[2]);
15639       emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
15640                                               operands[2]));
15641       DONE;
15642     }
15644   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
15646   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
15647   operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
15649   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
15650       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
15651     {
15652       rtx xops[3];
15653       xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
15654       xops[1] = operands[2];
15655       xops[2] = GEN_INT (INTVAL (operands[3])
15656                          & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
15657       ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
15658       operands[2] = xops[0];
15659     }
15661   operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15662   operands[2] = gen_lowpart (QImode, operands[2]);
15664   if (!rtx_equal_p (operands[4], operands[5]))
15665     emit_move_insn (operands[4], operands[5]);
15668 (define_insn_and_split "*<insn><dwi>3_doubleword_mask_1"
15669   [(set (match_operand:<DWI> 0 "register_operand")
15670         (any_shiftrt:<DWI>
15671           (match_operand:<DWI> 1 "register_operand")
15672           (and:QI
15673             (match_operand:QI 2 "register_operand" "c")
15674             (match_operand:QI 3 "const_int_operand"))))
15675    (clobber (reg:CC FLAGS_REG))]
15676   "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
15677     || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
15678          == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
15679    && ix86_pre_reload_split ()"
15680   "#"
15681   "&& 1"
15682   [(parallel
15683      [(set (match_dup 4)
15684            (ior:DWIH (lshiftrt:DWIH (match_dup 4)
15685                        (and:QI (match_dup 2) (match_dup 8)))
15686                      (subreg:DWIH
15687                        (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
15688                          (minus:QI (match_dup 9)
15689                                    (and:QI (match_dup 2) (match_dup 8)))) 0)))
15690       (clobber (reg:CC FLAGS_REG))])
15691    (parallel
15692      [(set (match_dup 6)
15693            (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
15694       (clobber (reg:CC FLAGS_REG))])]
15696   if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
15697     {
15698       emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
15699                                               operands[2]));
15700       DONE;
15701     }
15703   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
15705   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
15706   operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
15708   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
15709       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
15710     {
15711       rtx tem = gen_reg_rtx (QImode);
15712       emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
15713       operands[2] = tem;
15714     }
15716   if (!rtx_equal_p (operands[4], operands[5]))
15717     emit_move_insn (operands[4], operands[5]);
15720 (define_insn_and_split "<insn><mode>3_doubleword"
15721   [(set (match_operand:DWI 0 "register_operand" "=&r,&r")
15722         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0,r")
15723                          (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
15724    (clobber (reg:CC FLAGS_REG))]
15725   ""
15726   "#"
15727   "epilogue_completed"
15728   [(const_int 0)]
15730   if (TARGET_APX_NDD
15731       && !rtx_equal_p (operands[0], operands[1]))
15732     ix86_split_rshift_ndd (<CODE>, operands, NULL_RTX);
15733   else
15734     ix86_split_<insn> (operands, NULL_RTX, <MODE>mode);
15735   DONE;
15737   [(set_attr "type" "multi")
15738    (set_attr "isa" "*,apx_ndd")])
15740 ;; By default we don't ask for a scratch register, because when DWImode
15741 ;; values are manipulated, registers are already at a premium.  But if
15742 ;; we have one handy, we won't turn it away.
15744 (define_peephole2
15745   [(match_scratch:DWIH 3 "r")
15746    (parallel [(set (match_operand:<DWI> 0 "register_operand")
15747                    (any_shiftrt:<DWI>
15748                      (match_operand:<DWI> 1 "register_operand")
15749                      (match_operand:QI 2 "nonmemory_operand")))
15750               (clobber (reg:CC FLAGS_REG))])
15751    (match_dup 3)]
15752   "TARGET_CMOVE"
15753   [(const_int 0)]
15755   if (TARGET_APX_NDD
15756       && !rtx_equal_p (operands[0], operands[1]))
15757     ix86_split_rshift_ndd (<CODE>, operands, operands[3]);
15758   else
15759     ix86_split_<insn> (operands, operands[3], <DWI>mode);
15760   DONE;
15763 ;; Split truncations of double word right shifts into x86_shrd_1.
15764 (define_insn_and_split "<insn><dwi>3_doubleword_lowpart"
15765   [(set (match_operand:DWIH 0 "register_operand" "=&r")
15766         (subreg:DWIH
15767           (any_shiftrt:<DWI> (match_operand:<DWI> 1 "register_operand" "r")
15768                              (match_operand:QI 2 "const_int_operand")) 0))
15769    (clobber (reg:CC FLAGS_REG))]
15770   "UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
15771   "#"
15772   "&& reload_completed"
15773   [(parallel
15774       [(set (match_dup 0)
15775             (ior:DWIH (lshiftrt:DWIH (match_dup 0) (match_dup 2))
15776                       (subreg:DWIH
15777                         (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
15778                                       (match_dup 4)) 0)))
15779        (clobber (reg:CC FLAGS_REG))])]
15781   split_double_mode (<DWI>mode, &operands[1], 1, &operands[1], &operands[3]);
15782   operands[4] = GEN_INT ((<MODE_SIZE> * BITS_PER_UNIT) - INTVAL (operands[2]));
15783   if (!rtx_equal_p (operands[0], operands[1]))
15784     emit_move_insn (operands[0], operands[1]);
15787 (define_insn "x86_64_shrd"
15788   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
15789         (ior:DI (lshiftrt:DI (match_dup 0)
15790                   (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
15791                           (const_int 63)))
15792                 (subreg:DI
15793                   (ashift:TI
15794                     (zero_extend:TI
15795                       (match_operand:DI 1 "register_operand" "r"))
15796                     (minus:QI (const_int 64)
15797                               (and:QI (match_dup 2) (const_int 63)))) 0)))
15798    (clobber (reg:CC FLAGS_REG))]
15799   "TARGET_64BIT"
15800   "shrd{q}\t{%2, %1, %0|%0, %1, %2}"
15801   [(set_attr "type" "ishift")
15802    (set_attr "prefix_0f" "1")
15803    (set_attr "mode" "DI")
15804    (set_attr "athlon_decode" "vector")
15805    (set_attr "amdfam10_decode" "vector")
15806    (set_attr "bdver1_decode" "vector")])
15808 (define_insn "x86_64_shrd_ndd"
15809   [(set (match_operand:DI 0 "register_operand" "=r")
15810         (ior:DI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "rm")
15811                   (and:QI (match_operand:QI 3 "nonmemory_operand" "Jc")
15812                           (const_int 63)))
15813                 (subreg:DI
15814                   (ashift:TI
15815                     (zero_extend:TI
15816                       (match_operand:DI 2 "register_operand" "r"))
15817                     (minus:QI (const_int 64)
15818                               (and:QI (match_dup 3) (const_int 63)))) 0)))
15819    (clobber (reg:CC FLAGS_REG))]
15820   "TARGET_APX_NDD"
15821   "shrd{q}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
15822   [(set_attr "type" "ishift")
15823    (set_attr "mode" "DI")])
15826 (define_insn "x86_64_shrd_1"
15827   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
15828         (ior:DI (lshiftrt:DI (match_dup 0)
15829                              (match_operand:QI 2 "const_0_to_63_operand"))
15830                 (subreg:DI
15831                   (ashift:TI
15832                     (zero_extend:TI
15833                       (match_operand:DI 1 "register_operand" "r"))
15834                     (match_operand:QI 3 "const_0_to_255_operand")) 0)))
15835    (clobber (reg:CC FLAGS_REG))]
15836   "TARGET_64BIT
15837    && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
15838   "shrd{q}\t{%2, %1, %0|%0, %1, %2}"
15839   [(set_attr "type" "ishift")
15840    (set_attr "prefix_0f" "1")
15841    (set_attr "length_immediate" "1")
15842    (set_attr "mode" "DI")
15843    (set_attr "athlon_decode" "vector")
15844    (set_attr "amdfam10_decode" "vector")
15845    (set_attr "bdver1_decode" "vector")])
15847 (define_insn "x86_64_shrd_ndd_1"
15848   [(set (match_operand:DI 0 "register_operand" "=r")
15849         (ior:DI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "rm")
15850                              (match_operand:QI 3 "const_0_to_63_operand"))
15851                 (subreg:DI
15852                   (ashift:TI
15853                     (zero_extend:TI
15854                       (match_operand:DI 2 "register_operand" "r"))
15855                     (match_operand:QI 4 "const_0_to_255_operand")) 0)))
15856    (clobber (reg:CC FLAGS_REG))]
15857   "TARGET_APX_NDD
15858    && INTVAL (operands[4]) == 64 - INTVAL (operands[3])"
15859   "shrd{q}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
15860   [(set_attr "type" "ishift")
15861    (set_attr "length_immediate" "1")
15862    (set_attr "mode" "DI")])
15865 (define_insn_and_split "*x86_64_shrd_shld_1_nozext"
15866   [(set (match_operand:DI 0 "nonimmediate_operand")
15867         (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
15868                              (match_operand:QI 2 "const_0_to_63_operand"))
15869                 (ashift:DI
15870                   (match_operand:DI 1 "nonimmediate_operand")
15871                   (match_operand:QI 3 "const_0_to_63_operand"))))
15872    (clobber (reg:CC FLAGS_REG))]
15873   "TARGET_64BIT
15874    && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
15875    && ix86_pre_reload_split ()"
15876   "#"
15877   "&& 1"
15878   [(const_int 0)]
15880   if (rtx_equal_p (operands[4], operands[0]))
15881     {
15882       operands[1] = force_reg (DImode, operands[1]);
15883       emit_insn (gen_x86_64_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
15884     }
15885   else if (rtx_equal_p (operands[1], operands[0]))
15886     {
15887       operands[4] = force_reg (DImode, operands[4]);
15888       emit_insn (gen_x86_64_shld_1 (operands[0], operands[4], operands[3], operands[2]));
15889     }
15890   else if (TARGET_APX_NDD)
15891     {
15892       rtx tmp = gen_reg_rtx (DImode);
15893       if (MEM_P (operands[4]))
15894         {
15895           operands[1] = force_reg (DImode, operands[1]);
15896           emit_insn (gen_x86_64_shrd_ndd_1 (tmp, operands[4], operands[1],
15897                                             operands[2], operands[3]));
15898         }
15899        else if (MEM_P (operands[1]))
15900          emit_insn (gen_x86_64_shld_ndd_1 (tmp, operands[1], operands[4],
15901                                            operands[3], operands[2]));
15902        else
15903          emit_insn (gen_x86_64_shrd_ndd_1 (tmp, operands[4], operands[1],
15904                                            operands[2], operands[3]));
15905        emit_move_insn (operands[0], tmp);
15906     }
15907   else
15908    {
15909      operands[1] = force_reg (DImode, operands[1]);
15910      rtx tmp = gen_reg_rtx (DImode);
15911      emit_move_insn (tmp, operands[4]);
15912      emit_insn (gen_x86_64_shrd_1 (tmp, operands[1], operands[2], operands[3]));
15913      emit_move_insn (operands[0], tmp);
15914    }
15915    DONE;
15918 (define_insn_and_split "*x86_64_shrd_2"
15919   [(set (match_operand:DI 0 "nonimmediate_operand")
15920         (ior:DI (lshiftrt:DI (match_dup 0)
15921                              (match_operand:QI 2 "nonmemory_operand"))
15922                 (ashift:DI (match_operand:DI 1 "register_operand")
15923                            (minus:QI (const_int 64) (match_dup 2)))))
15924    (clobber (reg:CC FLAGS_REG))]
15925   "TARGET_64BIT && ix86_pre_reload_split ()"
15926   "#"
15927   "&& 1"
15928   [(parallel [(set (match_dup 0)
15929                    (ior:DI (lshiftrt:DI (match_dup 0)
15930                                         (and:QI (match_dup 2) (const_int 63)))
15931                            (subreg:DI
15932                              (ashift:TI
15933                                (zero_extend:TI (match_dup 1))
15934                                  (minus:QI (const_int 64)
15935                                            (and:QI (match_dup 2)
15936                                                    (const_int 63)))) 0)))
15937               (clobber (reg:CC FLAGS_REG))])])
15939 (define_insn_and_split "*x86_64_shrd_ndd_2"
15940   [(set (match_operand:DI 0 "nonimmediate_operand")
15941         (ior:DI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand")
15942                              (match_operand:QI 3 "nonmemory_operand"))
15943                 (ashift:DI (match_operand:DI 2 "register_operand")
15944                            (minus:QI (const_int 64) (match_dup 2)))))
15945    (clobber (reg:CC FLAGS_REG))]
15946   "TARGET_APX_NDD
15947   && ix86_pre_reload_split ()"
15948   "#"
15949   "&& 1"
15950   [(parallel [(set (match_dup 4)
15951                    (ior:DI (lshiftrt:DI (match_dup 1)
15952                                         (and:QI (match_dup 3) (const_int 63)))
15953                            (subreg:DI
15954                              (ashift:TI
15955                                (zero_extend:TI (match_dup 2))
15956                                  (minus:QI (const_int 64)
15957                                            (and:QI (match_dup 3)
15958                                                    (const_int 63)))) 0)))
15959               (clobber (reg:CC FLAGS_REG))
15960               (set (match_dup 0) (match_dup 4))])]
15962   operands[4] = gen_reg_rtx (DImode);
15963   emit_move_insn (operands[4], operands[0]);
15966 (define_insn "x86_shrd"
15967   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
15968         (ior:SI (lshiftrt:SI (match_dup 0)
15969                   (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
15970                           (const_int 31)))
15971                 (subreg:SI
15972                   (ashift:DI
15973                     (zero_extend:DI
15974                       (match_operand:SI 1 "register_operand" "r"))
15975                     (minus:QI (const_int 32)
15976                               (and:QI (match_dup 2) (const_int 31)))) 0)))
15977    (clobber (reg:CC FLAGS_REG))]
15978   ""
15979   "shrd{l}\t{%2, %1, %0|%0, %1, %2}"
15980   [(set_attr "type" "ishift")
15981    (set_attr "prefix_0f" "1")
15982    (set_attr "mode" "SI")
15983    (set_attr "pent_pair" "np")
15984    (set_attr "athlon_decode" "vector")
15985    (set_attr "amdfam10_decode" "vector")
15986    (set_attr "bdver1_decode" "vector")])
15988 (define_insn "x86_shrd_ndd"
15989   [(set (match_operand:SI 0 "register_operand" "=r")
15990         (ior:SI (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15991                   (and:QI (match_operand:QI 3 "nonmemory_operand" "Ic")
15992                           (const_int 31)))
15993                 (subreg:SI
15994                   (ashift:DI
15995                     (zero_extend:DI
15996                       (match_operand:SI 2 "register_operand" "r"))
15997                     (minus:QI (const_int 32)
15998                               (and:QI (match_dup 3) (const_int 31)))) 0)))
15999    (clobber (reg:CC FLAGS_REG))]
16000   "TARGET_APX_NDD"
16001   "shrd{l}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
16002   [(set_attr "type" "ishift")
16003    (set_attr "mode" "SI")])
16005 (define_insn "x86_shrd_1"
16006   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
16007         (ior:SI (lshiftrt:SI (match_dup 0)
16008                              (match_operand:QI 2 "const_0_to_31_operand"))
16009                 (subreg:SI
16010                   (ashift:DI
16011                     (zero_extend:DI
16012                       (match_operand:SI 1 "register_operand" "r"))
16013                     (match_operand:QI 3 "const_0_to_63_operand")) 0)))
16014    (clobber (reg:CC FLAGS_REG))]
16015   "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
16016   "shrd{l}\t{%2, %1, %0|%0, %1, %2}"
16017   [(set_attr "type" "ishift")
16018    (set_attr "prefix_0f" "1")
16019    (set_attr "length_immediate" "1")
16020    (set_attr "mode" "SI")
16021    (set_attr "pent_pair" "np")
16022    (set_attr "athlon_decode" "vector")
16023    (set_attr "amdfam10_decode" "vector")
16024    (set_attr "bdver1_decode" "vector")])
16026 (define_insn "x86_shrd_ndd_1"
16027   [(set (match_operand:SI 0 "register_operand" "=r")
16028         (ior:SI (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
16029                              (match_operand:QI 3 "const_0_to_31_operand"))
16030                 (subreg:SI
16031                   (ashift:DI
16032                     (zero_extend:DI
16033                       (match_operand:SI 2 "register_operand" "r"))
16034                     (match_operand:QI 4 "const_0_to_63_operand")) 0)))
16035    (clobber (reg:CC FLAGS_REG))]
16036   "TARGET_APX_NDD
16037    && (INTVAL (operands[4]) == 32 - INTVAL (operands[3]))"
16038   "shrd{l}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
16039   [(set_attr "type" "ishift")
16040    (set_attr "length_immediate" "1")
16041    (set_attr "mode" "SI")])
16044 (define_insn_and_split "*x86_shrd_shld_1_nozext"
16045   [(set (match_operand:SI 0 "nonimmediate_operand")
16046         (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
16047                              (match_operand:QI 2 "const_0_to_31_operand"))
16048                (ashift:SI
16049                    (match_operand:SI 1 "nonimmediate_operand")
16050                    (match_operand:QI 3 "const_0_to_31_operand"))))
16051    (clobber (reg:CC FLAGS_REG))]
16052   "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
16053    && ix86_pre_reload_split ()"
16054   "#"
16055   "&& 1"
16056   [(const_int 0)]
16058   if (rtx_equal_p (operands[4], operands[0]))
16059     {
16060       operands[1] = force_reg (SImode, operands[1]);
16061       emit_insn (gen_x86_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
16062     }
16063   else if (rtx_equal_p (operands[1], operands[0]))
16064     {
16065       operands[4] = force_reg (SImode, operands[4]);
16066       emit_insn (gen_x86_shld_1 (operands[0], operands[4], operands[3], operands[2]));
16067     }
16068   else if (TARGET_APX_NDD)
16069     {
16070       rtx tmp = gen_reg_rtx (SImode);
16071       if (MEM_P (operands[4]))
16072         {
16073           operands[1] = force_reg (SImode, operands[1]);
16074           emit_insn (gen_x86_shrd_ndd_1 (tmp, operands[4], operands[1],
16075                                          operands[2], operands[3]));
16076         }
16077       else if (MEM_P (operands[1]))
16078         emit_insn (gen_x86_shld_ndd_1 (tmp, operands[1], operands[4],
16079                                        operands[3], operands[2]));
16080       else
16081         emit_insn (gen_x86_shrd_ndd_1 (tmp, operands[4], operands[1],
16082                                        operands[2], operands[3]));
16083       emit_move_insn (operands[0], tmp);
16084      }
16085    else
16086    {
16087      operands[1] = force_reg (SImode, operands[1]);
16088      rtx tmp = gen_reg_rtx (SImode);
16089      emit_move_insn (tmp, operands[4]);
16090      emit_insn (gen_x86_shrd_1 (tmp, operands[1], operands[2], operands[3]));
16091      emit_move_insn (operands[0], tmp);
16092    }
16093    DONE;
16096 (define_insn_and_split "*x86_shrd_2"
16097   [(set (match_operand:SI 0 "nonimmediate_operand")
16098         (ior:SI (lshiftrt:SI (match_dup 0)
16099                              (match_operand:QI 2 "nonmemory_operand"))
16100                 (ashift:SI (match_operand:SI 1 "register_operand")
16101                            (minus:QI (const_int 32) (match_dup 2)))))
16102    (clobber (reg:CC FLAGS_REG))]
16103   "TARGET_64BIT && ix86_pre_reload_split ()"
16104   "#"
16105   "&& 1"
16106   [(parallel [(set (match_dup 0)
16107                    (ior:SI (lshiftrt:SI (match_dup 0)
16108                                         (and:QI (match_dup 2) (const_int 31)))
16109                            (subreg:SI
16110                              (ashift:DI
16111                                (zero_extend:DI (match_dup 1))
16112                                  (minus:QI (const_int 32)
16113                                            (and:QI (match_dup 2)
16114                                                    (const_int 31)))) 0)))
16115               (clobber (reg:CC FLAGS_REG))])])
16117 (define_insn_and_split "*x86_shrd_ndd_2"
16118   [(set (match_operand:SI 0 "nonimmediate_operand")
16119         (ior:SI (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
16120                            (match_operand:QI 3 "nonmemory_operand"))
16121                 (ashift:SI (match_operand:SI 2 "register_operand")
16122                            (minus:QI (const_int 32) (match_dup 3)))))
16123    (clobber (reg:CC FLAGS_REG))]
16124   "TARGET_APX_NDD
16125    && ix86_pre_reload_split ()"
16126   "#"
16127   "&& 1"
16128   [(parallel [(set (match_dup 4)
16129                    (ior:SI (lshiftrt:SI (match_dup 1)
16130                                         (and:QI (match_dup 3) (const_int 31)))
16131                            (subreg:SI
16132                              (ashift:DI
16133                                (zero_extend:DI (match_dup 2))
16134                                  (minus:QI (const_int 32)
16135                                            (and:QI (match_dup 3)
16136                                                    (const_int 31)))) 0)))
16137               (clobber (reg:CC FLAGS_REG))
16138               (set (match_dup 0) (match_dup 4))])]
16140   operands[4] = gen_reg_rtx (SImode);
16141   emit_move_insn (operands[4], operands[0]);
16144 ;; Base name for insn mnemonic.
16145 (define_mode_attr cvt_mnemonic
16146   [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
16148 (define_insn "ashr<mode>3_cvt"
16149   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm,r")
16150         (ashiftrt:SWI48
16151           (match_operand:SWI48 1 "nonimmediate_operand" "*a,0,rm")
16152           (match_operand:QI 2 "const_int_operand")))
16153    (clobber (reg:CC FLAGS_REG))]
16154   "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
16155    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
16156    && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands, TARGET_APX_NDD)"
16157   "@
16158    <cvt_mnemonic>
16159    sar{<imodesuffix>}\t{%2, %0|%0, %2}
16160    sar{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
16161   [(set_attr "isa" "*,*,apx_ndd")
16162    (set_attr "type" "imovx,ishift,ishift")
16163    (set_attr "prefix_0f" "0,*,*")
16164    (set_attr "length_immediate" "0,*,*")
16165    (set_attr "modrm" "0,1,1")
16166    (set_attr "mode" "<MODE>")])
16168 (define_insn "*ashrsi3_cvt_zext"
16169   [(set (match_operand:DI 0 "register_operand" "=*d,r,r")
16170         (zero_extend:DI
16171           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0,rm")
16172                        (match_operand:QI 2 "const_int_operand"))))
16173    (clobber (reg:CC FLAGS_REG))]
16174   "TARGET_64BIT && INTVAL (operands[2]) == 31
16175    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
16176    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands, TARGET_APX_NDD)"
16177   "@
16178    {cltd|cdq}
16179    sar{l}\t{%2, %k0|%k0, %2}
16180    sar{l}\t{%2, %1, %k0|%k0, %1, %2}"
16181   [(set_attr "isa" "*,*,apx_ndd")
16182    (set_attr "type" "imovx,ishift,ishift")
16183    (set_attr "prefix_0f" "0,*,*")
16184    (set_attr "length_immediate" "0,*,*")
16185    (set_attr "modrm" "0,1,1")
16186    (set_attr "mode" "SI")])
16188 (define_expand "@x86_shift<mode>_adj_3"
16189   [(use (match_operand:SWI48 0 "register_operand"))
16190    (use (match_operand:SWI48 1 "register_operand"))
16191    (use (match_operand:QI 2 "register_operand"))]
16192   ""
16194   rtx_code_label *label = gen_label_rtx ();
16195   rtx tmp;
16197   emit_insn (gen_testqi_ccz_1 (operands[2],
16198                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
16200   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
16201   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
16202   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
16203                               gen_rtx_LABEL_REF (VOIDmode, label),
16204                               pc_rtx);
16205   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
16206   JUMP_LABEL (tmp) = label;
16208   emit_move_insn (operands[0], operands[1]);
16209   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
16210                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
16211   emit_label (label);
16212   LABEL_NUSES (label) = 1;
16214   DONE;
16217 (define_insn "*bmi2_<insn><mode>3_1"
16218   [(set (match_operand:SWI48 0 "register_operand" "=r")
16219         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
16220                            (match_operand:SWI48 2 "register_operand" "r")))]
16221   "TARGET_BMI2"
16222   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
16223   [(set_attr "type" "ishiftx")
16224    (set_attr "mode" "<MODE>")])
16226 (define_insn "*ashr<mode>3_1"
16227   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
16228         (ashiftrt:SWI48
16229           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,rm")
16230           (match_operand:QI 2 "nonmemory_operand" "c<S>,r,c<S>")))
16231    (clobber (reg:CC FLAGS_REG))]
16232   "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands, TARGET_APX_NDD)"
16234   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16235   switch (get_attr_type (insn))
16236     {
16237     case TYPE_ISHIFTX:
16238       return "#";
16240     default:
16241       if (operands[2] == const1_rtx
16242           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16243           && !use_ndd)
16244         return "sar{<imodesuffix>}\t%0";
16245       else
16246         return use_ndd ? "sar{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
16247                        : "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
16248     }
16250   [(set_attr "isa" "*,bmi2,apx_ndd")
16251    (set_attr "type" "ishift,ishiftx,ishift")
16252    (set (attr "length_immediate")
16253      (if_then_else
16254        (and (match_operand 2 "const1_operand")
16255             (ior (match_test "TARGET_SHIFT1")
16256                  (match_test "optimize_function_for_size_p (cfun)")))
16257        (const_string "0")
16258        (const_string "*")))
16259    (set_attr "mode" "<MODE>")])
16261 ;; Specialization of *lshr<mode>3_1 below, extracting the SImode
16262 ;; highpart of a DI to be extracted, but allowing it to be clobbered.
16263 (define_insn_and_split "*highpartdisi2"
16264   [(set (subreg:DI (match_operand:SI 0 "register_operand" "=r,x,?k,r") 0)
16265         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0,k,rm")
16266                      (const_int 32)))
16267    (clobber (reg:CC FLAGS_REG))]
16268   "TARGET_64BIT"
16269   "#"
16270   "&& reload_completed"
16271   [(parallel
16272     [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 32)))
16273      (clobber (reg:CC FLAGS_REG))])]
16275   if (SSE_REG_P (operands[0]))
16276     {
16277       rtx tmp = gen_rtx_REG (V4SImode, REGNO (operands[0]));
16278       emit_insn (gen_sse_shufps_v4si (tmp, tmp, tmp,
16279                                       const1_rtx, const1_rtx,
16280                                       GEN_INT (5), GEN_INT (5)));
16281       DONE;
16282     }
16283   operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
16285 [(set_attr "isa" "*,*,*,apx_ndd")])
16288 (define_insn "*lshr<mode>3_1"
16289   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,?k,r")
16290         (lshiftrt:SWI48
16291           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,k,rm")
16292           (match_operand:QI 2 "nonmemory_operand" "c<S>,r,<KS>,c<S>")))
16293    (clobber (reg:CC FLAGS_REG))]
16294   "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands, TARGET_APX_NDD)"
16296   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16297   switch (get_attr_type (insn))
16298     {
16299     case TYPE_ISHIFTX:
16300     case TYPE_MSKLOG:
16301       return "#";
16303     default:
16304       if (operands[2] == const1_rtx
16305           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16306           && !use_ndd)
16307         return "shr{<imodesuffix>}\t%0";
16308       else
16309         return use_ndd ? "shr{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
16310                        : "shr{<imodesuffix>}\t{%2, %0|%0, %2}";
16311     }
16313   [(set_attr "isa" "*,bmi2,avx512bw,apx_ndd")
16314    (set_attr "type" "ishift,ishiftx,msklog,ishift")
16315    (set (attr "length_immediate")
16316      (if_then_else
16317        (and (and (match_operand 2 "const1_operand")
16318                  (eq_attr "alternative" "0"))
16319             (ior (match_test "TARGET_SHIFT1")
16320                  (match_test "optimize_function_for_size_p (cfun)")))
16321        (const_string "0")
16322        (const_string "*")))
16323    (set_attr "mode" "<MODE>")])
16325 ;; Convert shift to the shiftx pattern to avoid flags dependency.
16326 (define_split
16327   [(set (match_operand:SWI48 0 "register_operand")
16328         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
16329                            (match_operand:QI 2 "register_operand")))
16330    (clobber (reg:CC FLAGS_REG))]
16331   "TARGET_BMI2 && reload_completed"
16332   [(set (match_dup 0)
16333         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
16334   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
16336 (define_insn "*bmi2_<insn>si3_1_zext"
16337   [(set (match_operand:DI 0 "register_operand" "=r")
16338         (zero_extend:DI
16339           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
16340                           (match_operand:SI 2 "register_operand" "r"))))]
16341   "TARGET_64BIT && TARGET_BMI2"
16342   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
16343   [(set_attr "type" "ishiftx")
16344    (set_attr "mode" "SI")])
16346 (define_insn "*<insn>si3_1_zext"
16347   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
16348         (zero_extend:DI
16349           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm,rm")
16350                           (match_operand:QI 2 "nonmemory_operand" "cI,r,cI"))))
16351    (clobber (reg:CC FLAGS_REG))]
16352   "TARGET_64BIT
16353    && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
16355   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16356   switch (get_attr_type (insn))
16357     {
16358     case TYPE_ISHIFTX:
16359       return "#";
16361     default:
16362       if (operands[2] == const1_rtx
16363           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16364           && !use_ndd)
16365         return "<shift>{l}\t%k0";
16366       else
16367         return use_ndd ? "<shift>{l}\t{%2, %1, %k0|%k0, %1, %2}"
16368                        : "<shift>{l}\t{%2, %k0|%k0, %2}";
16369     }
16371   [(set_attr "isa" "*,bmi2,apx_ndd")
16372    (set_attr "type" "ishift,ishiftx,ishift")
16373    (set (attr "length_immediate")
16374      (if_then_else
16375        (and (match_operand 2 "const1_operand")
16376             (ior (match_test "TARGET_SHIFT1")
16377                  (match_test "optimize_function_for_size_p (cfun)")))
16378        (const_string "0")
16379        (const_string "*")))
16380    (set_attr "mode" "SI")])
16382 ;; Convert shift to the shiftx pattern to avoid flags dependency.
16383 (define_split
16384   [(set (match_operand:DI 0 "register_operand")
16385         (zero_extend:DI
16386           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
16387                           (match_operand:QI 2 "register_operand"))))
16388    (clobber (reg:CC FLAGS_REG))]
16389   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
16390   [(set (match_dup 0)
16391         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
16392   "operands[2] = gen_lowpart (SImode, operands[2]);")
16394 (define_insn "*ashr<mode>3_1"
16395   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m, r")
16396         (ashiftrt:SWI12
16397           (match_operand:SWI12 1 "nonimmediate_operand" "0, rm")
16398           (match_operand:QI 2 "nonmemory_operand" "c<S>, c<S>")))
16399    (clobber (reg:CC FLAGS_REG))]
16400   "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands, TARGET_APX_NDD)"
16402   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16403   if (operands[2] == const1_rtx
16404       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16405       && !use_ndd)
16406     return "sar{<imodesuffix>}\t%0";
16407   else
16408     return use_ndd ? "sar{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
16409                    : "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
16411   [(set_attr "isa" "*, apx_ndd")
16412    (set_attr "type" "ishift")
16413    (set (attr "length_immediate")
16414      (if_then_else
16415        (and (match_operand 2 "const1_operand")
16416             (ior (match_test "TARGET_SHIFT1")
16417                  (match_test "optimize_function_for_size_p (cfun)")))
16418        (const_string "0")
16419        (const_string "*")))
16420    (set_attr "mode" "<MODE>")])
16422 (define_insn "*lshrqi3_1"
16423   [(set (match_operand:QI 0 "nonimmediate_operand"  "=qm,?k,r")
16424         (lshiftrt:QI
16425           (match_operand:QI 1 "nonimmediate_operand" "0, k, rm")
16426           (match_operand:QI 2 "nonmemory_operand"    "cI,Wb,cI")))
16427    (clobber (reg:CC FLAGS_REG))]
16428   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands, TARGET_APX_NDD)"
16430   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16431   switch (get_attr_type (insn))
16432     {
16433     case TYPE_ISHIFT:
16434       if (operands[2] == const1_rtx
16435           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16436           && !use_ndd)
16437         return "shr{b}\t%0";
16438       else
16439         return use_ndd ? "shr{b}\t{%2, %1, %0|%0, %1, %2}"
16440                        : "shr{b}\t{%2, %0|%0, %2}";
16441     case TYPE_MSKLOG:
16442       return "#";
16443     default:
16444       gcc_unreachable ();
16445     }
16447   [(set_attr "isa" "*,avx512dq,apx_ndd")
16448    (set_attr "type" "ishift,msklog,ishift")
16449    (set (attr "length_immediate")
16450      (if_then_else
16451        (and (and (match_operand 2 "const1_operand")
16452                  (eq_attr "alternative" "0"))
16453             (ior (match_test "TARGET_SHIFT1")
16454                  (match_test "optimize_function_for_size_p (cfun)")))
16455        (const_string "0")
16456        (const_string "*")))
16457    (set_attr "mode" "QI")])
16459 (define_insn "*lshrhi3_1"
16460   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm, ?k, r")
16461         (lshiftrt:HI
16462           (match_operand:HI 1 "nonimmediate_operand" "0, k, rm")
16463           (match_operand:QI 2 "nonmemory_operand" "cI, Ww, cI")))
16464    (clobber (reg:CC FLAGS_REG))]
16465   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands, TARGET_APX_NDD)"
16467   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16468   switch (get_attr_type (insn))
16469     {
16470     case TYPE_ISHIFT:
16471       if (operands[2] == const1_rtx
16472           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16473           && !use_ndd)
16474         return "shr{w}\t%0";
16475       else
16476         return use_ndd ? "shr{w}\t{%2, %1, %0|%0, %1, %2}"
16477                        : "shr{w}\t{%2, %0|%0, %2}";
16478     case TYPE_MSKLOG:
16479       return "#";
16480     default:
16481       gcc_unreachable ();
16482     }
16484   [(set_attr "isa" "*, avx512f, apx_ndd")
16485    (set_attr "type" "ishift,msklog,ishift")
16486    (set (attr "length_immediate")
16487      (if_then_else
16488        (and (and (match_operand 2 "const1_operand")
16489                  (eq_attr "alternative" "0"))
16490             (ior (match_test "TARGET_SHIFT1")
16491                  (match_test "optimize_function_for_size_p (cfun)")))
16492        (const_string "0")
16493        (const_string "*")))
16494    (set_attr "mode" "HI")])
16496 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
16497 (define_insn_and_split "*<insn><mode>3_1_slp"
16498   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
16499         (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
16500                            (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
16501    (clobber (reg:CC FLAGS_REG))]
16502   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
16504   if (which_alternative)
16505     return "#";
16507   if (operands[2] == const1_rtx
16508       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
16509     return "<shift>{<imodesuffix>}\t%0";
16510   else
16511     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
16513   "&& reload_completed
16514    && !(rtx_equal_p (operands[0], operands[1]))"
16515   [(set (strict_low_part (match_dup 0)) (match_dup 1))
16516    (parallel
16517      [(set (strict_low_part (match_dup 0))
16518            (any_shiftrt:SWI12 (match_dup 0) (match_dup 2)))
16519       (clobber (reg:CC FLAGS_REG))])]
16520   ""
16521   [(set_attr "type" "ishift")
16522    (set (attr "length_immediate")
16523      (if_then_else
16524        (and (match_operand 2 "const1_operand")
16525             (ior (match_test "TARGET_SHIFT1")
16526                  (match_test "optimize_function_for_size_p (cfun)")))
16527        (const_string "0")
16528        (const_string "*")))
16529    (set_attr "mode" "<MODE>")])
16531 ;; This pattern can't accept a variable shift count, since shifts by
16532 ;; zero don't affect the flags.  We assume that shifts by constant
16533 ;; zero are optimized away.
16534 (define_insn "*<insn><mode>3_cmp"
16535   [(set (reg FLAGS_REG)
16536         (compare
16537           (any_shiftrt:SWI
16538             (match_operand:SWI 1 "nonimmediate_operand" "0,rm")
16539             (match_operand:QI 2 "<shift_immediate_operand>" "<S>,<S>"))
16540           (const_int 0)))
16541    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
16542         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
16543   "(optimize_function_for_size_p (cfun)
16544     || !TARGET_PARTIAL_FLAG_REG_STALL
16545     || (operands[2] == const1_rtx
16546         && TARGET_SHIFT1))
16547    && ix86_match_ccmode (insn, CCGOCmode)
16548    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)"
16550   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16551   if (operands[2] == const1_rtx
16552       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16553       && !use_ndd)
16554     return "<shift>{<imodesuffix>}\t%0";
16555   else
16556     return use_ndd ? "<shift>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
16557                    : "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
16559   [(set_attr "isa" "*,apx_ndd")
16560    (set_attr "type" "ishift")
16561    (set (attr "length_immediate")
16562      (if_then_else
16563        (and (match_operand 2 "const1_operand")
16564             (ior (match_test "TARGET_SHIFT1")
16565                  (match_test "optimize_function_for_size_p (cfun)")))
16566        (const_string "0")
16567        (const_string "*")))
16568    (set_attr "mode" "<MODE>")])
16570 (define_insn "*<insn>si3_cmp_zext"
16571   [(set (reg FLAGS_REG)
16572         (compare
16573           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
16574                           (match_operand:QI 2 "const_1_to_31_operand"))
16575           (const_int 0)))
16576    (set (match_operand:DI 0 "register_operand" "=r,r")
16577         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
16578   "TARGET_64BIT
16579    && (optimize_function_for_size_p (cfun)
16580        || !TARGET_PARTIAL_FLAG_REG_STALL
16581        || (operands[2] == const1_rtx
16582            && TARGET_SHIFT1))
16583    && ix86_match_ccmode (insn, CCGOCmode)
16584    && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
16586   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16587   if (operands[2] == const1_rtx
16588       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16589       && !use_ndd)
16590     return "<shift>{l}\t%k0";
16591   else
16592     return use_ndd ? "<shift>{l}\t{%2, %1, %k0|%k0, %1, %2}"
16593                    : "<shift>{l}\t{%2, %k0|%k0, %2}";
16595   [(set_attr "isa" "*,apx_ndd")
16596    (set_attr "type" "ishift")
16597    (set (attr "length_immediate")
16598      (if_then_else
16599        (and (match_operand 2 "const1_operand")
16600             (ior (match_test "TARGET_SHIFT1")
16601                  (match_test "optimize_function_for_size_p (cfun)")))
16602        (const_string "0")
16603        (const_string "*")))
16604    (set_attr "mode" "SI")])
16606 (define_insn "*<insn><mode>3_cconly"
16607   [(set (reg FLAGS_REG)
16608         (compare
16609           (any_shiftrt:SWI
16610             (match_operand:SWI 1 "nonimmediate_operand" "0,rm")
16611             (match_operand:QI 2 "<shift_immediate_operand>" "<S>,<S>"))
16612           (const_int 0)))
16613    (clobber (match_scratch:SWI 0 "=<r>,r"))]
16614   "(optimize_function_for_size_p (cfun)
16615     || !TARGET_PARTIAL_FLAG_REG_STALL
16616     || (operands[2] == const1_rtx
16617         && TARGET_SHIFT1))
16618    && ix86_match_ccmode (insn, CCGOCmode)"
16620   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16621   if (operands[2] == const1_rtx
16622       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16623       && !use_ndd)
16624     return "<shift>{<imodesuffix>}\t%0";
16625   else
16626     return use_ndd
16627            ? "<shift>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
16628            : "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
16630   [(set_attr "isa" "*,apx_ndd")
16631    (set_attr "type" "ishift")
16632    (set (attr "length_immediate")
16633      (if_then_else
16634        (and (match_operand 2 "const1_operand")
16635             (ior (match_test "TARGET_SHIFT1")
16636                  (match_test "optimize_function_for_size_p (cfun)")))
16637        (const_string "0")
16638        (const_string "*")))
16639    (set_attr "mode" "<MODE>")])
16641 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
16642 (define_insn_and_split "*<insn>qi_ext<mode>_1"
16643   [(set (zero_extract:SWI248
16644           (match_operand 0 "int248_register_operand" "+Q,&Q")
16645           (const_int 8)
16646           (const_int 8))
16647         (subreg:SWI248
16648           (any_shiftrt:QI
16649             (subreg:QI
16650               (match_operator:SWI248 3 "extract_operator"
16651                 [(match_operand 1 "int248_register_operand" "0,!Q")
16652                  (const_int 8)
16653                  (const_int 8)]) 0)
16654             (match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
16655    (clobber (reg:CC FLAGS_REG))]
16656   ""
16658   if (which_alternative)
16659     return "#";
16661   if (operands[2] == const1_rtx
16662       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
16663     return "<shift>{b}\t%h0";
16664   else
16665     return "<shift>{b}\t{%2, %h0|%h0, %2}";
16667   "reload_completed
16668    && !(rtx_equal_p (operands[0], operands[1]))"
16669   [(set (zero_extract:SWI248
16670           (match_dup 0) (const_int 8) (const_int 8))
16671         (zero_extract:SWI248
16672           (match_dup 1) (const_int 8) (const_int 8)))
16673    (parallel
16674      [(set (zero_extract:SWI248
16675              (match_dup 0) (const_int 8) (const_int 8))
16676            (subreg:SWI248
16677              (any_shiftrt:QI
16678                (subreg:QI
16679                  (match_op_dup 3
16680                    [(match_dup 0) (const_int 8) (const_int 8)]) 0)
16681                (match_dup 2)) 0))
16682       (clobber (reg:CC FLAGS_REG))])]
16683   ""
16684   [(set_attr "type" "ishift")
16685    (set (attr "length_immediate")
16686      (if_then_else
16687        (and (match_operand 2 "const1_operand")
16688             (ior (match_test "TARGET_SHIFT1")
16689                  (match_test "optimize_function_for_size_p (cfun)")))
16690        (const_string "0")
16691        (const_string "*")))
16692    (set_attr "mode" "QI")])
16694 (define_insn_and_split "*extend<dwi>2_doubleword_highpart"
16695   [(set (match_operand:<DWI> 0 "register_operand" "=r")
16696         (ashiftrt:<DWI>
16697           (ashift:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")
16698                         (match_operand:QI 2 "const_int_operand"))
16699           (match_operand:QI 3 "const_int_operand")))
16700    (clobber (reg:CC FLAGS_REG))]
16701   "INTVAL (operands[2]) == INTVAL (operands[3])
16702    && UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
16703   "#"
16704   "&& reload_completed"
16705   [(parallel [(set (match_dup 4)
16706                    (ashift:DWIH (match_dup 4) (match_dup 2)))
16707               (clobber (reg:CC FLAGS_REG))])
16708    (parallel [(set (match_dup 4)
16709                    (ashiftrt:DWIH (match_dup 4) (match_dup 2)))
16710               (clobber (reg:CC FLAGS_REG))])]
16711   "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[4]);")
16713 (define_insn_and_split "*extendv2di2_highpart_stv"
16714   [(set (match_operand:V2DI 0 "register_operand" "=v")
16715         (ashiftrt:V2DI
16716           (ashift:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "vm")
16717                        (match_operand:QI 2 "const_int_operand"))
16718           (match_operand:QI 3 "const_int_operand")))]
16719   "!TARGET_64BIT && TARGET_STV && TARGET_AVX512VL
16720    && INTVAL (operands[2]) == INTVAL (operands[3])
16721    && UINTVAL (operands[2]) < 32"
16722   "#"
16723   "&& reload_completed"
16724   [(set (match_dup 0)
16725         (ashift:V2DI (match_dup 1) (match_dup 2)))
16726    (set (match_dup 0)
16727         (ashiftrt:V2DI (match_dup 0) (match_dup 2)))])
16729 ;; Rotate instructions
16731 (define_expand "<insn>ti3"
16732   [(set (match_operand:TI 0 "register_operand")
16733         (any_rotate:TI (match_operand:TI 1 "register_operand")
16734                        (match_operand:QI 2 "nonmemory_operand")))]
16735   "TARGET_64BIT"
16737   if (const_1_to_63_operand (operands[2], VOIDmode))
16738     emit_insn (gen_ix86_<insn>ti3_doubleword
16739                 (operands[0], operands[1], operands[2]));
16740   else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 64)
16741     {
16742       operands[1] = force_reg (TImode, operands[1]);
16743       emit_insn (gen_<insn>64ti2_doubleword (operands[0], operands[1]));
16744     }
16745   else
16746     {
16747       rtx amount = force_reg (QImode, operands[2]);
16748       rtx src_lo = gen_lowpart (DImode, operands[1]);
16749       rtx src_hi = gen_highpart (DImode, operands[1]);
16750       rtx tmp_lo = gen_reg_rtx (DImode);
16751       rtx tmp_hi = gen_reg_rtx (DImode);
16752       emit_move_insn (tmp_lo, src_lo);
16753       emit_move_insn (tmp_hi, src_hi);
16754       rtx (*shiftd) (rtx, rtx, rtx)
16755             = (<CODE> == ROTATE) ? gen_x86_64_shld : gen_x86_64_shrd;
16756       emit_insn (shiftd (tmp_lo, src_hi, amount));
16757       emit_insn (shiftd (tmp_hi, src_lo, amount));
16758       rtx dst_lo = gen_lowpart (DImode, operands[0]);
16759       rtx dst_hi = gen_highpart (DImode, operands[0]);
16760       emit_move_insn (dst_lo, tmp_lo);
16761       emit_move_insn (dst_hi, tmp_hi);
16762       emit_insn (gen_x86_shiftdi_adj_1 (dst_lo, dst_hi, amount, tmp_lo));
16763     }
16764   DONE;
16767 (define_expand "<insn>di3"
16768   [(set (match_operand:DI 0 "shiftdi_operand")
16769         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
16770                        (match_operand:QI 2 "nonmemory_operand")))]
16771  ""
16773   if (TARGET_64BIT)
16774     ix86_expand_binary_operator (<CODE>, DImode, operands, TARGET_APX_NDD);
16775   else if (const_1_to_31_operand (operands[2], VOIDmode))
16776     emit_insn (gen_ix86_<insn>di3_doubleword
16777                 (operands[0], operands[1], operands[2]));
16778   else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 32)
16779     {
16780       operands[1] = force_reg (DImode, operands[1]);
16781       emit_insn (gen_<insn>32di2_doubleword (operands[0], operands[1]));
16782     }
16783   else
16784     FAIL;
16786   DONE;
16789 (define_expand "<insn><mode>3"
16790   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
16791         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
16792                             (match_operand:QI 2 "nonmemory_operand")))]
16793   ""
16795   ix86_expand_binary_operator (<CODE>, <MODE>mode, operands, TARGET_APX_NDD);
16796   DONE;
16799 ;; Avoid useless masking of count operand.
16800 (define_insn_and_split "*<insn><mode>3_mask"
16801   [(set (match_operand:SWI 0 "nonimmediate_operand")
16802         (any_rotate:SWI
16803           (match_operand:SWI 1 "nonimmediate_operand")
16804           (subreg:QI
16805             (and
16806               (match_operand 2 "int248_register_operand" "c")
16807               (match_operand 3 "const_int_operand")) 0)))
16808    (clobber (reg:CC FLAGS_REG))]
16809   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
16810    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16811       == GET_MODE_BITSIZE (<MODE>mode)-1
16812    && ix86_pre_reload_split ()"
16813   "#"
16814   "&& 1"
16815   [(parallel
16816      [(set (match_dup 0)
16817            (any_rotate:SWI (match_dup 1)
16818                            (match_dup 2)))
16819       (clobber (reg:CC FLAGS_REG))])]
16821   operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
16822   operands[2] = gen_lowpart (QImode, operands[2]);
16825 (define_split
16826   [(set (match_operand:SWI 0 "register_operand")
16827         (any_rotate:SWI
16828           (match_operand:SWI 1 "const_int_operand")
16829           (subreg:QI
16830             (and
16831               (match_operand 2 "int248_register_operand")
16832               (match_operand 3 "const_int_operand")) 0)))]
16833  "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
16834    == GET_MODE_BITSIZE (<MODE>mode) - 1"
16835  [(set (match_dup 4) (match_dup 1))
16836   (set (match_dup 0)
16837        (any_rotate:SWI (match_dup 4)
16838                        (subreg:QI (match_dup 2) 0)))]
16839  "operands[4] = gen_reg_rtx (<MODE>mode);")
16841 (define_insn_and_split "*<insn><mode>3_mask_1"
16842   [(set (match_operand:SWI 0 "nonimmediate_operand")
16843         (any_rotate:SWI
16844           (match_operand:SWI 1 "nonimmediate_operand")
16845           (and:QI
16846             (match_operand:QI 2 "register_operand" "c")
16847             (match_operand:QI 3 "const_int_operand"))))
16848    (clobber (reg:CC FLAGS_REG))]
16849   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
16850    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16851       == GET_MODE_BITSIZE (<MODE>mode)-1
16852    && ix86_pre_reload_split ()"
16853   "#"
16854   "&& 1"
16855   [(parallel
16856      [(set (match_dup 0)
16857            (any_rotate:SWI (match_dup 1)
16858                            (match_dup 2)))
16859       (clobber (reg:CC FLAGS_REG))])])
16861 (define_split
16862   [(set (match_operand:SWI 0 "register_operand")
16863         (any_rotate:SWI
16864           (match_operand:SWI 1 "const_int_operand")
16865           (and:QI
16866             (match_operand:QI 2 "register_operand")
16867             (match_operand:QI 3 "const_int_operand"))))]
16868  "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
16869   == GET_MODE_BITSIZE (<MODE>mode) - 1"
16870  [(set (match_dup 4) (match_dup 1))
16871   (set (match_dup 0)
16872        (any_rotate:SWI (match_dup 4) (match_dup 2)))]
16873  "operands[4] = gen_reg_rtx (<MODE>mode);")
16875 ;; Implement rotation using two double-precision
16876 ;; shift instructions and a scratch register.
16878 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
16879  [(set (match_operand:<DWI> 0 "register_operand" "=r")
16880        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
16881                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
16882   (clobber (reg:CC FLAGS_REG))
16883   (clobber (match_scratch:DWIH 3 "=&r"))]
16884  ""
16885  "#"
16886  "reload_completed"
16887  [(set (match_dup 3) (match_dup 4))
16888   (parallel
16889    [(set (match_dup 4)
16890          (ior:DWIH (ashift:DWIH (match_dup 4)
16891                                 (and:QI (match_dup 2) (match_dup 6)))
16892                    (subreg:DWIH
16893                      (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
16894                                      (minus:QI (match_dup 7)
16895                                                (and:QI (match_dup 2)
16896                                                        (match_dup 6)))) 0)))
16897     (clobber (reg:CC FLAGS_REG))])
16898   (parallel
16899    [(set (match_dup 5)
16900          (ior:DWIH (ashift:DWIH (match_dup 5)
16901                                 (and:QI (match_dup 2) (match_dup 6)))
16902                    (subreg:DWIH
16903                      (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 3))
16904                                      (minus:QI (match_dup 7)
16905                                                (and:QI (match_dup 2)
16906                                                        (match_dup 6)))) 0)))
16907     (clobber (reg:CC FLAGS_REG))])]
16909   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
16910   operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
16912   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
16915 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
16916  [(set (match_operand:<DWI> 0 "register_operand" "=r")
16917        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
16918                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
16919   (clobber (reg:CC FLAGS_REG))
16920   (clobber (match_scratch:DWIH 3 "=&r"))]
16921  ""
16922  "#"
16923  "reload_completed"
16924  [(set (match_dup 3) (match_dup 4))
16925   (parallel
16926    [(set (match_dup 4)
16927          (ior:DWIH (lshiftrt:DWIH (match_dup 4)
16928                                   (and:QI (match_dup 2) (match_dup 6)))
16929                    (subreg:DWIH
16930                      (ashift:<DWI> (zero_extend:<DWI> (match_dup 5))
16931                                    (minus:QI (match_dup 7)
16932                                              (and:QI (match_dup 2)
16933                                                      (match_dup 6)))) 0)))
16934     (clobber (reg:CC FLAGS_REG))])
16935   (parallel
16936    [(set (match_dup 5)
16937          (ior:DWIH (lshiftrt:DWIH (match_dup 5)
16938                                   (and:QI (match_dup 2) (match_dup 6)))
16939                    (subreg:DWIH
16940                      (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
16941                                    (minus:QI (match_dup 7)
16942                                              (and:QI (match_dup 2)
16943                                                      (match_dup 6)))) 0)))
16944     (clobber (reg:CC FLAGS_REG))])]
16946   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
16947   operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
16949   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
16952 (define_insn_and_split "<insn>32di2_doubleword"
16953  [(set (match_operand:DI 0 "register_operand" "=r,r")
16954        (any_rotate:DI (match_operand:DI 1 "register_operand" "0,r")
16955                       (const_int 32)))]
16956  "!TARGET_64BIT"
16957  "#"
16958  "&& reload_completed"
16959  [(set (match_dup 0) (match_dup 3))
16960   (set (match_dup 2) (match_dup 1))]
16962   split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
16963   if (rtx_equal_p (operands[0], operands[1]))
16964     {
16965       emit_insn (gen_swapsi (operands[0], operands[2]));
16966       DONE;
16967     }
16970 (define_insn_and_split "<insn>64ti2_doubleword"
16971  [(set (match_operand:TI 0 "register_operand" "=r,r")
16972        (any_rotate:TI (match_operand:TI 1 "register_operand" "0,r")
16973                       (const_int 64)))]
16974  "TARGET_64BIT"
16975  "#"
16976  "&& reload_completed"
16977  [(set (match_dup 0) (match_dup 3))
16978   (set (match_dup 2) (match_dup 1))]
16980   split_double_mode (TImode, &operands[0], 2, &operands[0], &operands[2]);
16981   if (rtx_equal_p (operands[0], operands[1]))
16982     {
16983       emit_insn (gen_swapdi (operands[0], operands[2]));
16984       DONE;
16985     }
16988 (define_mode_attr rorx_immediate_operand
16989         [(SI "const_0_to_31_operand")
16990          (DI "const_0_to_63_operand")])
16992 (define_insn "*bmi2_rorx<mode>3_1"
16993   [(set (match_operand:SWI48 0 "register_operand" "=r")
16994         (rotatert:SWI48
16995           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
16996           (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
16997   "TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
16998   "rorx\t{%2, %1, %0|%0, %1, %2}"
16999   [(set_attr "type" "rotatex")
17000    (set_attr "mode" "<MODE>")])
17002 (define_insn "*<insn><mode>3_1"
17003   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
17004         (any_rotate:SWI48
17005           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,rm")
17006           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>,c<S>")))
17007    (clobber (reg:CC FLAGS_REG))]
17008   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)"
17010   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17011   switch (get_attr_type (insn))
17012     {
17013     case TYPE_ROTATEX:
17014       return "#";
17016     default:
17017       if (operands[2] == const1_rtx
17018           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17019           && !use_ndd)
17020         return "<rotate>{<imodesuffix>}\t%0";
17021       else
17022         return use_ndd ? "<rotate>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
17023                        : "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
17024     }
17026   [(set_attr "isa" "*,bmi2,apx_ndd")
17027    (set_attr "type" "rotate,rotatex,rotate")
17028    (set (attr "preferred_for_size")
17029      (cond [(eq_attr "alternative" "0")
17030               (symbol_ref "true")]
17031            (symbol_ref "false")))
17032    (set (attr "length_immediate")
17033      (if_then_else
17034        (and (eq_attr "type" "rotate")
17035             (and (match_operand 2 "const1_operand")
17036                  (ior (match_test "TARGET_SHIFT1")
17037                       (match_test "optimize_function_for_size_p (cfun)"))))
17038        (const_string "0")
17039        (const_string "*")))
17040    (set_attr "mode" "<MODE>")])
17042 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
17043 (define_split
17044   [(set (match_operand:SWI48 0 "register_operand")
17045         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17046                       (match_operand:QI 2 "const_int_operand")))
17047    (clobber (reg:CC FLAGS_REG))]
17048   "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
17049   [(set (match_dup 0)
17050         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
17052   int bitsize = GET_MODE_BITSIZE (<MODE>mode);
17054   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
17057 (define_split
17058   [(set (match_operand:SWI48 0 "register_operand")
17059         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17060                         (match_operand:QI 2 "const_int_operand")))
17061    (clobber (reg:CC FLAGS_REG))]
17062   "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
17063   [(set (match_dup 0)
17064         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
17066 (define_insn "*bmi2_rorxsi3_1_zext"
17067   [(set (match_operand:DI 0 "register_operand" "=r")
17068         (zero_extend:DI
17069           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
17070                        (match_operand:QI 2 "const_0_to_31_operand"))))]
17071   "TARGET_64BIT && TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
17072   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
17073   [(set_attr "type" "rotatex")
17074    (set_attr "mode" "SI")])
17076 (define_insn "*<insn>si3_1_zext"
17077   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
17078         (zero_extend:DI
17079           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm,rm")
17080                          (match_operand:QI 2 "nonmemory_operand" "cI,I,cI"))))
17081    (clobber (reg:CC FLAGS_REG))]
17082   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
17084   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17085   switch (get_attr_type (insn))
17086     {
17087     case TYPE_ROTATEX:
17088       return "#";
17090     default:
17091       if (operands[2] == const1_rtx
17092           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17093           && !use_ndd)
17094         return "<rotate>{l}\t%k0";
17095       else
17096         return use_ndd ? "<rotate>{l}\t{%2, %1, %k0|%k0, %1, %2}"
17097                        : "<rotate>{l}\t{%2, %k0|%k0, %2}";
17098     }
17100   [(set_attr "isa" "*,bmi2,apx_ndd")
17101    (set_attr "type" "rotate,rotatex,rotate")
17102    (set (attr "preferred_for_size")
17103      (cond [(eq_attr "alternative" "0")
17104               (symbol_ref "true")]
17105            (symbol_ref "false")))
17106    (set (attr "length_immediate")
17107      (if_then_else
17108        (and (eq_attr "type" "rotate")
17109             (and (match_operand 2 "const1_operand")
17110                  (ior (match_test "TARGET_SHIFT1")
17111                       (match_test "optimize_function_for_size_p (cfun)"))))
17112        (const_string "0")
17113        (const_string "*")))
17114    (set_attr "mode" "SI")])
17116 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
17117 (define_split
17118   [(set (match_operand:DI 0 "register_operand")
17119         (zero_extend:DI
17120           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
17121                      (match_operand:QI 2 "const_int_operand"))))
17122    (clobber (reg:CC FLAGS_REG))]
17123   "TARGET_64BIT && TARGET_BMI2 && reload_completed
17124    && !optimize_function_for_size_p (cfun)"
17125   [(set (match_dup 0)
17126         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
17128   int bitsize = GET_MODE_BITSIZE (SImode);
17130   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
17133 (define_split
17134   [(set (match_operand:DI 0 "register_operand")
17135         (zero_extend:DI
17136           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
17137                        (match_operand:QI 2 "const_int_operand"))))
17138    (clobber (reg:CC FLAGS_REG))]
17139   "TARGET_64BIT && TARGET_BMI2 && reload_completed
17140    && !optimize_function_for_size_p (cfun)"
17141   [(set (match_dup 0)
17142         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
17144 (define_insn "*<insn><mode>3_1"
17145   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m,r")
17146         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0,rm")
17147                           (match_operand:QI 2 "nonmemory_operand" "c<S>,c<S>")))
17148    (clobber (reg:CC FLAGS_REG))]
17149   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)"
17151   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17152   if (operands[2] == const1_rtx
17153       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17154       && !use_ndd)
17155     return "<rotate>{<imodesuffix>}\t%0";
17156   else
17157     return use_ndd
17158            ? "<rotate>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
17159            : "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
17161   [(set_attr "isa" "*,apx_ndd")
17162    (set_attr "type" "rotate")
17163    (set (attr "length_immediate")
17164      (if_then_else
17165        (and (match_operand 2 "const1_operand")
17166             (ior (match_test "TARGET_SHIFT1")
17167                  (match_test "optimize_function_for_size_p (cfun)")))
17168        (const_string "0")
17169        (const_string "*")))
17170    (set_attr "mode" "<MODE>")])
17172 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
17173 (define_insn_and_split "*<insn><mode>3_1_slp"
17174   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
17175         (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
17176                           (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
17177    (clobber (reg:CC FLAGS_REG))]
17178   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
17180   if (which_alternative)
17181     return "#";
17183   if (operands[2] == const1_rtx
17184       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
17185     return "<rotate>{<imodesuffix>}\t%0";
17186   else
17187     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
17189   "&& reload_completed
17190    && !(rtx_equal_p (operands[0], operands[1]))"
17191   [(set (strict_low_part (match_dup 0)) (match_dup 1))
17192    (parallel
17193      [(set (strict_low_part (match_dup 0))
17194            (any_rotate:SWI12 (match_dup 0) (match_dup 2)))
17195       (clobber (reg:CC FLAGS_REG))])]
17196   ""
17197   [(set_attr "type" "rotate")
17198    (set (attr "length_immediate")
17199      (if_then_else
17200        (and (match_operand 2 "const1_operand")
17201             (ior (match_test "TARGET_SHIFT1")
17202                  (match_test "optimize_function_for_size_p (cfun)")))
17203        (const_string "0")
17204        (const_string "*")))
17205    (set_attr "mode" "<MODE>")])
17207 (define_split
17208  [(set (match_operand:HI 0 "QIreg_operand")
17209        (any_rotate:HI (match_dup 0) (const_int 8)))
17210   (clobber (reg:CC FLAGS_REG))]
17211  "reload_completed
17212   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
17213  [(parallel [(set (strict_low_part (match_dup 0))
17214                   (bswap:HI (match_dup 0)))
17215              (clobber (reg:CC FLAGS_REG))])])
17217 ;; Rotations through carry flag
17218 (define_insn "rcrsi2"
17219   [(set (match_operand:SI 0 "register_operand" "=r,r")
17220         (plus:SI
17221           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
17222                        (const_int 1))
17223           (ashift:SI (ltu:SI (reg:CCC FLAGS_REG) (const_int 0))
17224                      (const_int 31))))
17225    (clobber (reg:CC FLAGS_REG))]
17226   ""
17227   "@
17228    rcr{l}\t%0
17229    rcr{l}\t{%1, %0|%0, %1}"
17230   [(set_attr "isa" "*,apx_ndd")
17231    (set_attr "type" "ishift1")
17232    (set_attr "memory" "none")
17233    (set_attr "length_immediate" "0")
17234    (set_attr "mode" "SI")])
17236 (define_insn "rcrdi2"
17237   [(set (match_operand:DI 0 "register_operand" "=r,r")
17238         (plus:DI
17239           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,rm")
17240                        (const_int 1))
17241           (ashift:DI (ltu:DI (reg:CCC FLAGS_REG) (const_int 0))
17242                      (const_int 63))))
17243    (clobber (reg:CC FLAGS_REG))]
17244   "TARGET_64BIT"
17245   "@
17246    rcr{q}\t%0
17247    rcr{q}\t{%1, %0|%0, %1}"
17248   [(set_attr "isa" "*,apx_ndd")
17249    (set_attr "type" "ishift1")
17250    (set_attr "length_immediate" "0")
17251    (set_attr "mode" "DI")])
17253 ;; Versions of sar and shr that set the carry flag.
17254 (define_insn "<insn><mode>3_carry"
17255   [(set (reg:CCC FLAGS_REG)
17256         (unspec:CCC [(and:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
17257                                 (const_int 1))
17258                      (const_int 0)] UNSPEC_CC_NE))
17259    (set (match_operand:SWI48 0 "register_operand" "=r,r")
17260         (any_shiftrt:SWI48 (match_dup 1) (const_int 1)))]
17261   ""
17263   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17264   if ((TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17265       && !use_ndd)
17266     return "<shift>{<imodesuffix>}\t%0";
17267   return use_ndd ? "<shift>{<imodesuffix>}\t{$1, %1, %0|%0, %1, 1}"
17268                  : "<shift>{<imodesuffix>}\t{$1, %0|%0, 1}";
17270   [(set_attr "isa" "*, apx_ndd")
17271    (set_attr "type" "ishift1")
17272    (set (attr "length_immediate")
17273      (if_then_else
17274        (ior (match_test "TARGET_SHIFT1")
17275             (match_test "optimize_function_for_size_p (cfun)"))
17276        (const_string "0")
17277        (const_string "*")))
17278    (set_attr "mode" "<MODE>")])
17280 ;; Bit set / bit test instructions
17282 ;; %%% bts, btr, btc
17284 ;; These instructions are *slow* when applied to memory.
17286 (define_code_attr btsc [(ior "bts") (xor "btc")])
17288 (define_insn "*<btsc><mode>"
17289   [(set (match_operand:SWI48 0 "register_operand" "=r")
17290         (any_or:SWI48
17291           (ashift:SWI48 (const_int 1)
17292                         (match_operand:QI 2 "register_operand" "r"))
17293           (match_operand:SWI48 1 "register_operand" "0")))
17294    (clobber (reg:CC FLAGS_REG))]
17295   "TARGET_USE_BT"
17296   "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
17297   [(set_attr "type" "alu1")
17298    (set_attr "prefix_0f" "1")
17299    (set_attr "znver1_decode" "double")
17300    (set_attr "mode" "<MODE>")])
17302 ;; Avoid useless masking of count operand.
17303 (define_insn_and_split "*<btsc><mode>_mask"
17304   [(set (match_operand:SWI48 0 "register_operand")
17305         (any_or:SWI48
17306           (ashift:SWI48
17307             (const_int 1)
17308             (subreg:QI
17309               (and
17310                 (match_operand 1 "int248_register_operand")
17311                 (match_operand 2 "const_int_operand")) 0))
17312           (match_operand:SWI48 3 "register_operand")))
17313    (clobber (reg:CC FLAGS_REG))]
17314   "TARGET_USE_BT
17315    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
17316       == GET_MODE_BITSIZE (<MODE>mode)-1
17317    && ix86_pre_reload_split ()"
17318   "#"
17319   "&& 1"
17320   [(parallel
17321      [(set (match_dup 0)
17322            (any_or:SWI48
17323              (ashift:SWI48 (const_int 1)
17324                            (match_dup 1))
17325              (match_dup 3)))
17326       (clobber (reg:CC FLAGS_REG))])]
17328   operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
17329   operands[1] = gen_lowpart (QImode, operands[1]);
17332 (define_insn_and_split "*<btsc><mode>_mask_1"
17333   [(set (match_operand:SWI48 0 "register_operand")
17334         (any_or:SWI48
17335           (ashift:SWI48
17336             (const_int 1)
17337             (and:QI
17338               (match_operand:QI 1 "register_operand")
17339               (match_operand:QI 2 "const_int_operand")))
17340           (match_operand:SWI48 3 "register_operand")))
17341    (clobber (reg:CC FLAGS_REG))]
17342   "TARGET_USE_BT
17343    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
17344       == GET_MODE_BITSIZE (<MODE>mode)-1
17345    && ix86_pre_reload_split ()"
17346   "#"
17347   "&& 1"
17348   [(parallel
17349      [(set (match_dup 0)
17350            (any_or:SWI48
17351              (ashift:SWI48 (const_int 1)
17352                            (match_dup 1))
17353              (match_dup 3)))
17354       (clobber (reg:CC FLAGS_REG))])])
17356 (define_insn "*btr<mode>"
17357   [(set (match_operand:SWI48 0 "register_operand" "=r")
17358         (and:SWI48
17359           (rotate:SWI48 (const_int -2)
17360                         (match_operand:QI 2 "register_operand" "r"))
17361         (match_operand:SWI48 1 "register_operand" "0")))
17362    (clobber (reg:CC FLAGS_REG))]
17363   "TARGET_USE_BT"
17364   "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
17365   [(set_attr "type" "alu1")
17366    (set_attr "prefix_0f" "1")
17367    (set_attr "znver1_decode" "double")
17368    (set_attr "mode" "<MODE>")])
17370 ;; Avoid useless masking of count operand.
17371 (define_insn_and_split "*btr<mode>_mask"
17372   [(set (match_operand:SWI48 0 "register_operand")
17373         (and:SWI48
17374           (rotate:SWI48
17375             (const_int -2)
17376             (subreg:QI
17377               (and
17378                 (match_operand 1 "int248_register_operand")
17379                 (match_operand 2 "const_int_operand")) 0))
17380           (match_operand:SWI48 3 "register_operand")))
17381    (clobber (reg:CC FLAGS_REG))]
17382   "TARGET_USE_BT
17383    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
17384       == GET_MODE_BITSIZE (<MODE>mode)-1
17385    && ix86_pre_reload_split ()"
17386   "#"
17387   "&& 1"
17388   [(parallel
17389      [(set (match_dup 0)
17390            (and:SWI48
17391              (rotate:SWI48 (const_int -2)
17392                            (match_dup 1))
17393              (match_dup 3)))
17394       (clobber (reg:CC FLAGS_REG))])]
17396   operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
17397   operands[1] = gen_lowpart (QImode, operands[1]);
17400 (define_insn_and_split "*btr<mode>_mask_1"
17401   [(set (match_operand:SWI48 0 "register_operand")
17402         (and:SWI48
17403           (rotate:SWI48
17404             (const_int -2)
17405             (and:QI
17406               (match_operand:QI 1 "register_operand")
17407               (match_operand:QI 2 "const_int_operand")))
17408           (match_operand:SWI48 3 "register_operand")))
17409    (clobber (reg:CC FLAGS_REG))]
17410   "TARGET_USE_BT
17411    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
17412       == GET_MODE_BITSIZE (<MODE>mode)-1
17413    && ix86_pre_reload_split ()"
17414   "#"
17415   "&& 1"
17416   [(parallel
17417      [(set (match_dup 0)
17418            (and:SWI48
17419              (rotate:SWI48 (const_int -2)
17420                            (match_dup 1))
17421              (match_dup 3)))
17422       (clobber (reg:CC FLAGS_REG))])])
17424 (define_insn_and_split "*btr<mode>_1"
17425   [(set (match_operand:SWI12 0 "register_operand")
17426         (and:SWI12
17427           (subreg:SWI12
17428             (rotate:SI (const_int -2)
17429                        (match_operand:QI 2 "register_operand")) 0)
17430           (match_operand:SWI12 1 "nonimmediate_operand")))
17431    (clobber (reg:CC FLAGS_REG))]
17432   "TARGET_USE_BT && ix86_pre_reload_split ()"
17433   "#"
17434   "&& 1"
17435   [(parallel
17436      [(set (match_dup 0)
17437            (and:SI (rotate:SI (const_int -2) (match_dup 2))
17438                    (match_dup 1)))
17439       (clobber (reg:CC FLAGS_REG))])]
17441   operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
17442   operands[1] = force_reg (<MODE>mode, operands[1]);
17443   operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
17446 (define_insn_and_split "*btr<mode>_2"
17447   [(set (zero_extract:HI
17448           (match_operand:SWI12 0 "nonimmediate_operand")
17449           (const_int 1)
17450           (match_operand:QI 1 "register_operand"))
17451         (const_int 0))
17452    (clobber (reg:CC FLAGS_REG))]
17453   "TARGET_USE_BT && ix86_pre_reload_split ()"
17454   "#"
17455   "&& MEM_P (operands[0])"
17456   [(set (match_dup 2) (match_dup 0))
17457    (parallel
17458      [(set (match_dup 3)
17459            (and:SI (rotate:SI (const_int -2) (match_dup 1))
17460                    (match_dup 4)))
17461       (clobber (reg:CC FLAGS_REG))])
17462    (set (match_dup 0) (match_dup 5))]
17464   operands[2] = gen_reg_rtx (<MODE>mode);
17465   operands[5] = gen_reg_rtx (<MODE>mode);
17466   operands[3] = lowpart_subreg (SImode, operands[5], <MODE>mode);
17467   operands[4] = lowpart_subreg (SImode, operands[2], <MODE>mode);
17470 (define_split
17471   [(set (zero_extract:HI
17472           (match_operand:SWI12 0 "register_operand")
17473           (const_int 1)
17474           (match_operand:QI 1 "register_operand"))
17475         (const_int 0))
17476    (clobber (reg:CC FLAGS_REG))]
17477   "TARGET_USE_BT && ix86_pre_reload_split ()"
17478   [(parallel
17479      [(set (match_dup 0)
17480            (and:SI (rotate:SI (const_int -2) (match_dup 1))
17481                    (match_dup 2)))
17482       (clobber (reg:CC FLAGS_REG))])]
17484   operands[2] = lowpart_subreg (SImode, operands[0], <MODE>mode);
17485   operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
17488 ;; These instructions are never faster than the corresponding
17489 ;; and/ior/xor operations when using immediate operand, so with
17490 ;; 32-bit there's no point.  But in 64-bit, we can't hold the
17491 ;; relevant immediates within the instruction itself, so operating
17492 ;; on bits in the high 32-bits of a register becomes easier.
17494 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
17495 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
17496 ;; negdf respectively, so they can never be disabled entirely.
17498 (define_insn "*btsq_imm"
17499   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
17500                          (const_int 1)
17501                          (match_operand:QI 1 "const_0_to_63_operand"))
17502         (const_int 1))
17503    (clobber (reg:CC FLAGS_REG))]
17504   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
17505   "bts{q}\t{%1, %0|%0, %1}"
17506   [(set_attr "type" "alu1")
17507    (set_attr "prefix_0f" "1")
17508    (set_attr "znver1_decode" "double")
17509    (set_attr "mode" "DI")])
17511 (define_insn "*btrq_imm"
17512   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
17513                          (const_int 1)
17514                          (match_operand:QI 1 "const_0_to_63_operand"))
17515         (const_int 0))
17516    (clobber (reg:CC FLAGS_REG))]
17517   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
17518   "btr{q}\t{%1, %0|%0, %1}"
17519   [(set_attr "type" "alu1")
17520    (set_attr "prefix_0f" "1")
17521    (set_attr "znver1_decode" "double")
17522    (set_attr "mode" "DI")])
17524 (define_insn "*btcq_imm"
17525   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
17526                          (const_int 1)
17527                          (match_operand:QI 1 "const_0_to_63_operand"))
17528         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
17529    (clobber (reg:CC FLAGS_REG))]
17530   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
17531   "btc{q}\t{%1, %0|%0, %1}"
17532   [(set_attr "type" "alu1")
17533    (set_attr "prefix_0f" "1")
17534    (set_attr "znver1_decode" "double")
17535    (set_attr "mode" "DI")])
17537 ;; Allow Nocona to avoid these instructions if a register is available.
17539 (define_peephole2
17540   [(match_scratch:DI 2 "r")
17541    (parallel [(set (zero_extract:DI
17542                      (match_operand:DI 0 "nonimmediate_operand")
17543                      (const_int 1)
17544                      (match_operand:QI 1 "const_0_to_63_operand"))
17545                    (const_int 1))
17546               (clobber (reg:CC FLAGS_REG))])]
17547   "TARGET_64BIT && !TARGET_USE_BT"
17548   [(parallel [(set (match_dup 0)
17549                    (ior:DI (match_dup 0) (match_dup 3)))
17550               (clobber (reg:CC FLAGS_REG))])]
17552   int i = INTVAL (operands[1]);
17554   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
17556   if (!x86_64_immediate_operand (operands[3], DImode))
17557     {
17558       emit_move_insn (operands[2], operands[3]);
17559       operands[3] = operands[2];
17560     }
17563 (define_peephole2
17564   [(match_scratch:DI 2 "r")
17565    (parallel [(set (zero_extract:DI
17566                      (match_operand:DI 0 "nonimmediate_operand")
17567                      (const_int 1)
17568                      (match_operand:QI 1 "const_0_to_63_operand"))
17569                    (const_int 0))
17570               (clobber (reg:CC FLAGS_REG))])]
17571   "TARGET_64BIT && !TARGET_USE_BT"
17572   [(parallel [(set (match_dup 0)
17573                    (and:DI (match_dup 0) (match_dup 3)))
17574               (clobber (reg:CC FLAGS_REG))])]
17576   int i = INTVAL (operands[1]);
17578   operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
17580   if (!x86_64_immediate_operand (operands[3], DImode))
17581     {
17582       emit_move_insn (operands[2], operands[3]);
17583       operands[3] = operands[2];
17584     }
17587 (define_peephole2
17588   [(match_scratch:DI 2 "r")
17589    (parallel [(set (zero_extract:DI
17590                      (match_operand:DI 0 "nonimmediate_operand")
17591                      (const_int 1)
17592                      (match_operand:QI 1 "const_0_to_63_operand"))
17593               (not:DI (zero_extract:DI
17594                         (match_dup 0) (const_int 1) (match_dup 1))))
17595               (clobber (reg:CC FLAGS_REG))])]
17596   "TARGET_64BIT && !TARGET_USE_BT"
17597   [(parallel [(set (match_dup 0)
17598                    (xor:DI (match_dup 0) (match_dup 3)))
17599               (clobber (reg:CC FLAGS_REG))])]
17601   int i = INTVAL (operands[1]);
17603   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
17605   if (!x86_64_immediate_operand (operands[3], DImode))
17606     {
17607       emit_move_insn (operands[2], operands[3]);
17608       operands[3] = operands[2];
17609     }
17612 ;; %%% bt
17614 (define_insn "*bt<mode>"
17615   [(set (reg:CCC FLAGS_REG)
17616         (compare:CCC
17617           (zero_extract:SWI48
17618             (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
17619             (const_int 1)
17620             (match_operand:QI 1 "nonmemory_operand" "q<S>,<S>"))
17621           (const_int 0)))]
17622   ""
17624   switch (get_attr_mode (insn))
17625     {
17626     case MODE_SI:
17627       return "bt{l}\t{%k1, %k0|%k0, %k1}";
17629     case MODE_DI:
17630       return "bt{q}\t{%q1, %0|%0, %q1}";
17632     default:
17633       gcc_unreachable ();
17634     }
17636   [(set_attr "type" "alu1")
17637    (set_attr "prefix_0f" "1")
17638    (set (attr "mode")
17639         (if_then_else
17640           (and (match_test "CONST_INT_P (operands[1])")
17641                (match_test "INTVAL (operands[1]) < 32"))
17642           (const_string "SI")
17643           (const_string "<MODE>")))])
17645 (define_insn_and_split "*bt<SWI48:mode>_mask"
17646   [(set (reg:CCC FLAGS_REG)
17647         (compare:CCC
17648           (zero_extract:SWI48
17649             (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
17650             (const_int 1)
17651             (subreg:QI
17652               (and:SWI248
17653                 (match_operand:SWI248 1 "register_operand")
17654                 (match_operand 2 "const_int_operand")) 0))
17655           (const_int 0)))]
17656   "TARGET_USE_BT
17657    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
17658       == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
17659    && ix86_pre_reload_split ()"
17660   "#"
17661   "&& 1"
17662   [(set (reg:CCC FLAGS_REG)
17663         (compare:CCC
17664          (zero_extract:SWI48 (match_dup 0) (const_int 1) (match_dup 1))
17665          (const_int 0)))]
17666   "operands[1] = gen_lowpart (QImode, operands[1]);")
17668 (define_insn_and_split "*jcc_bt<mode>"
17669   [(set (pc)
17670         (if_then_else (match_operator 0 "bt_comparison_operator"
17671                         [(zero_extract:SWI48
17672                            (match_operand:SWI48 1 "nonimmediate_operand")
17673                            (const_int 1)
17674                            (match_operand:QI 2 "nonmemory_operand"))
17675                          (const_int 0)])
17676                       (label_ref (match_operand 3))
17677                       (pc)))
17678    (clobber (reg:CC FLAGS_REG))]
17679   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
17680    && (CONST_INT_P (operands[2])
17681        ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
17682           && INTVAL (operands[2])
17683                >= (optimize_function_for_size_p (cfun) ? 8 : 32))
17684        : !memory_operand (operands[1], <MODE>mode))
17685    && ix86_pre_reload_split ()"
17686   "#"
17687   "&& 1"
17688   [(set (reg:CCC FLAGS_REG)
17689         (compare:CCC
17690           (zero_extract:SWI48
17691             (match_dup 1)
17692             (const_int 1)
17693             (match_dup 2))
17694           (const_int 0)))
17695    (set (pc)
17696         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
17697                       (label_ref (match_dup 3))
17698                       (pc)))]
17700   operands[0] = shallow_copy_rtx (operands[0]);
17701   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
17704 ;; Avoid useless masking of bit offset operand.
17705 (define_insn_and_split "*jcc_bt<mode>_mask"
17706   [(set (pc)
17707         (if_then_else (match_operator 0 "bt_comparison_operator"
17708                         [(zero_extract:SWI48
17709                            (match_operand:SWI48 1 "register_operand")
17710                            (const_int 1)
17711                            (and:QI
17712                              (match_operand:QI 2 "register_operand")
17713                              (match_operand 3 "const_int_operand")))
17714                          (const_int 0)])
17715                       (label_ref (match_operand 4))
17716                       (pc)))
17717    (clobber (reg:CC FLAGS_REG))]
17718   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
17719    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
17720       == GET_MODE_BITSIZE (<MODE>mode)-1
17721    && ix86_pre_reload_split ()"
17722   "#"
17723   "&& 1"
17724   [(set (reg:CCC FLAGS_REG)
17725         (compare:CCC
17726           (zero_extract:SWI48
17727             (match_dup 1)
17728             (const_int 1)
17729             (match_dup 2))
17730           (const_int 0)))
17731    (set (pc)
17732         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
17733                       (label_ref (match_dup 4))
17734                       (pc)))]
17736   operands[0] = shallow_copy_rtx (operands[0]);
17737   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
17740 ;; Avoid useless masking of bit offset operand.
17741 (define_insn_and_split "*jcc_bt<SWI48:mode>_mask_1"
17742   [(set (pc)
17743         (if_then_else (match_operator 0 "bt_comparison_operator"
17744                         [(zero_extract:SWI48
17745                            (match_operand:SWI48 1 "register_operand")
17746                            (const_int 1)
17747                            (subreg:QI
17748                              (and:SWI248
17749                                (match_operand:SWI248 2 "register_operand")
17750                                (match_operand 3 "const_int_operand")) 0))
17751                          (const_int 0)])
17752                       (label_ref (match_operand 4))
17753                       (pc)))
17754    (clobber (reg:CC FLAGS_REG))]
17755   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
17756    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
17757       == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
17758    && ix86_pre_reload_split ()"
17759   "#"
17760   "&& 1"
17761   [(set (reg:CCC FLAGS_REG)
17762         (compare:CCC
17763           (zero_extract:SWI48
17764             (match_dup 1)
17765             (const_int 1)
17766             (match_dup 2))
17767           (const_int 0)))
17768    (set (pc)
17769         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
17770                       (label_ref (match_dup 4))
17771                       (pc)))]
17773   operands[0] = shallow_copy_rtx (operands[0]);
17774   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
17775   operands[2] = gen_lowpart (QImode, operands[2]);
17778 ;; Help combine recognize bt followed by cmov
17779 (define_split
17780   [(set (match_operand:SWI248 0 "register_operand")
17781         (if_then_else:SWI248
17782          (match_operator 5 "bt_comparison_operator"
17783           [(zero_extract:SWI48
17784             (match_operand:SWI48 1 "register_operand")
17785             (const_int 1)
17786             (match_operand:QI 2 "register_operand"))
17787            (const_int 0)])
17788          (match_operand:SWI248 3 "nonimmediate_operand")
17789          (match_operand:SWI248 4 "nonimmediate_operand")))]
17790   "TARGET_USE_BT && TARGET_CMOVE
17791    && !(MEM_P (operands[3]) && MEM_P (operands[4]))
17792    && ix86_pre_reload_split ()"
17793   [(set (reg:CCC FLAGS_REG)
17794         (compare:CCC
17795          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
17796          (const_int 0)))
17797    (set (match_dup 0)
17798         (if_then_else:SWI248 (eq (reg:CCC FLAGS_REG) (const_int 0))
17799                              (match_dup 3)
17800                              (match_dup 4)))]
17802   if (GET_CODE (operands[5]) == EQ)
17803     std::swap (operands[3], operands[4]);
17806 ;; Help combine recognize bt followed by setc
17807 (define_insn_and_split "*bt<mode>_setcqi"
17808   [(set (subreg:SWI48 (match_operand:QI 0 "register_operand") 0)
17809         (zero_extract:SWI48
17810          (match_operand:SWI48 1 "register_operand")
17811          (const_int 1)
17812          (match_operand:QI 2 "register_operand")))
17813    (clobber (reg:CC FLAGS_REG))]
17814   "TARGET_USE_BT && ix86_pre_reload_split ()"
17815   "#"
17816   "&& 1"
17817   [(set (reg:CCC FLAGS_REG)
17818         (compare:CCC
17819          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
17820          (const_int 0)))
17821    (set (match_dup 0)
17822         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))])
17824 ;; Help combine recognize bt followed by setnc
17825 (define_insn_and_split "*bt<mode>_setncqi"
17826   [(set (match_operand:QI 0 "register_operand")
17827         (and:QI
17828          (not:QI
17829           (subreg:QI
17830            (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
17831                            (match_operand:QI 2 "register_operand")) 0))
17832          (const_int 1)))
17833    (clobber (reg:CC FLAGS_REG))]
17834   "TARGET_USE_BT && ix86_pre_reload_split ()"
17835   "#"
17836   "&& 1"
17837   [(set (reg:CCC FLAGS_REG)
17838         (compare:CCC
17839          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
17840          (const_int 0)))
17841    (set (match_dup 0)
17842         (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
17844 (define_insn_and_split "*bt<mode>_setnc<mode>"
17845   [(set (match_operand:SWI48 0 "register_operand")
17846         (and:SWI48
17847          (not:SWI48
17848           (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
17849                           (match_operand:QI 2 "register_operand")))
17850          (const_int 1)))
17851    (clobber (reg:CC FLAGS_REG))]
17852   "TARGET_USE_BT && ix86_pre_reload_split ()"
17853   "#"
17854   "&& 1"
17855   [(set (reg:CCC FLAGS_REG)
17856         (compare:CCC
17857          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
17858          (const_int 0)))
17859    (set (match_dup 3)
17860         (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
17861    (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
17862   "operands[3] = gen_reg_rtx (QImode);")
17864 ;; Help combine recognize bt followed by setnc (PR target/110588)
17865 (define_insn_and_split "*bt<mode>_setncqi_2"
17866   [(set (match_operand:QI 0 "register_operand")
17867         (eq:QI
17868           (zero_extract:SWI48
17869             (match_operand:SWI48 1 "register_operand")
17870             (const_int 1)
17871             (match_operand:QI 2 "register_operand"))
17872           (const_int 0)))
17873    (clobber (reg:CC FLAGS_REG))]
17874   "TARGET_USE_BT && ix86_pre_reload_split ()"
17875   "#"
17876   "&& 1"
17877   [(set (reg:CCC FLAGS_REG)
17878         (compare:CCC
17879          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
17880          (const_int 0)))
17881    (set (match_dup 0)
17882         (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
17884 ;; Help combine recognize bt followed by setc
17885 (define_insn_and_split "*bt<mode>_setc<mode>_mask"
17886   [(set (match_operand:SWI48 0 "register_operand")
17887         (zero_extract:SWI48
17888           (match_operand:SWI48 1 "register_operand")
17889           (const_int 1)
17890           (subreg:QI
17891             (and:SWI48
17892               (match_operand:SWI48 2 "register_operand")
17893               (match_operand 3 "const_int_operand")) 0)))
17894    (clobber (reg:CC FLAGS_REG))]
17895   "TARGET_USE_BT
17896    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
17897       == GET_MODE_BITSIZE (<MODE>mode)-1
17898    && ix86_pre_reload_split ()"
17899   "#"
17900   "&& 1"
17901   [(set (reg:CCC FLAGS_REG)
17902         (compare:CCC
17903          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
17904          (const_int 0)))
17905    (set (match_dup 3)
17906         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))
17907    (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
17909   operands[2] = gen_lowpart (QImode, operands[2]);
17910   operands[3] = gen_reg_rtx (QImode);
17913 ;; Store-flag instructions.
17915 (define_split
17916   [(set (match_operand:QI 0 "nonimmediate_operand")
17917         (match_operator:QI 1 "add_comparison_operator"
17918           [(not:SWI (match_operand:SWI 2 "register_operand"))
17919            (match_operand:SWI 3 "nonimmediate_operand")]))]
17920   ""
17921   [(set (reg:CCC FLAGS_REG)
17922         (compare:CCC
17923           (plus:SWI (match_dup 2) (match_dup 3))
17924           (match_dup 2)))
17925    (set (match_dup 0)
17926         (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))])
17928 (define_split
17929   [(set (match_operand:QI 0 "nonimmediate_operand")
17930         (match_operator:QI 1 "shr_comparison_operator"
17931           [(match_operand:DI 2 "register_operand")
17932            (match_operand 3 "const_int_operand")]))]
17933   "TARGET_64BIT
17934    && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
17935   [(set (reg:CCZ FLAGS_REG)
17936         (compare:CCZ
17937           (lshiftrt:DI (match_dup 2) (match_dup 4))
17938           (const_int 0)))
17939    (set (match_dup 0)
17940         (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))]
17942   enum rtx_code new_code;
17944   operands[1] = shallow_copy_rtx (operands[1]);
17945   switch (GET_CODE (operands[1]))
17946     {
17947     case GTU: new_code = NE; break;
17948     case LEU: new_code = EQ; break;
17949     default: gcc_unreachable ();
17950     }
17951   PUT_CODE (operands[1], new_code);
17953   operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
17956 ;; For all sCOND expanders, also expand the compare or test insn that
17957 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
17959 (define_insn_and_split "*setcc_di_1"
17960   [(set (match_operand:DI 0 "register_operand" "=q")
17961         (match_operator:DI 1 "ix86_comparison_operator"
17962           [(reg FLAGS_REG) (const_int 0)]))]
17963   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
17964   "#"
17965   "&& reload_completed"
17966   [(set (match_dup 2) (match_dup 1))
17967    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
17969   operands[1] = shallow_copy_rtx (operands[1]);
17970   PUT_MODE (operands[1], QImode);
17971   operands[2] = gen_lowpart (QImode, operands[0]);
17974 (define_insn_and_split "*setcc_<mode>_1_and"
17975   [(set (match_operand:SWI24 0 "register_operand" "=q")
17976         (match_operator:SWI24 1 "ix86_comparison_operator"
17977           [(reg FLAGS_REG) (const_int 0)]))
17978    (clobber (reg:CC FLAGS_REG))]
17979   "!TARGET_PARTIAL_REG_STALL
17980    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
17981   "#"
17982   "&& reload_completed"
17983   [(set (match_dup 2) (match_dup 1))
17984    (parallel [(set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))
17985               (clobber (reg:CC FLAGS_REG))])]
17987   operands[1] = shallow_copy_rtx (operands[1]);
17988   PUT_MODE (operands[1], QImode);
17989   operands[2] = gen_lowpart (QImode, operands[0]);
17992 (define_insn_and_split "*setcc_<mode>_1_movzbl"
17993   [(set (match_operand:SWI24 0 "register_operand" "=q")
17994         (match_operator:SWI24 1 "ix86_comparison_operator"
17995           [(reg FLAGS_REG) (const_int 0)]))]
17996   "!TARGET_PARTIAL_REG_STALL
17997    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
17998   "#"
17999   "&& reload_completed"
18000   [(set (match_dup 2) (match_dup 1))
18001    (set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))]
18003   operands[1] = shallow_copy_rtx (operands[1]);
18004   PUT_MODE (operands[1], QImode);
18005   operands[2] = gen_lowpart (QImode, operands[0]);
18008 (define_insn "*setcc_qi"
18009   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18010         (match_operator:QI 1 "ix86_comparison_operator"
18011           [(reg FLAGS_REG) (const_int 0)]))]
18012   ""
18013   "set%C1\t%0"
18014   [(set_attr "type" "setcc")
18015    (set_attr "mode" "QI")])
18017 (define_insn "*setcc_qi_slp"
18018   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
18019         (match_operator:QI 1 "ix86_comparison_operator"
18020           [(reg FLAGS_REG) (const_int 0)]))]
18021   ""
18022   "set%C1\t%0"
18023   [(set_attr "type" "setcc")
18024    (set_attr "mode" "QI")])
18026 ;; In general it is not safe to assume too much about CCmode registers,
18027 ;; so simplify-rtx stops when it sees a second one.  Under certain
18028 ;; conditions this is safe on x86, so help combine not create
18030 ;;      seta    %al
18031 ;;      testb   %al, %al
18032 ;;      sete    %al
18034 (define_split
18035   [(set (match_operand:QI 0 "nonimmediate_operand")
18036         (ne:QI (match_operator 1 "ix86_comparison_operator"
18037                  [(reg FLAGS_REG) (const_int 0)])
18038             (const_int 0)))]
18039   ""
18040   [(set (match_dup 0) (match_dup 1))]
18042   operands[1] = shallow_copy_rtx (operands[1]);
18043   PUT_MODE (operands[1], QImode);
18046 (define_split
18047   [(set (strict_low_part (match_operand:QI 0 "register_operand"))
18048         (ne:QI (match_operator 1 "ix86_comparison_operator"
18049                  [(reg FLAGS_REG) (const_int 0)])
18050             (const_int 0)))]
18051   ""
18052   [(set (match_dup 0) (match_dup 1))]
18054   operands[1] = shallow_copy_rtx (operands[1]);
18055   PUT_MODE (operands[1], QImode);
18058 (define_split
18059   [(set (match_operand:QI 0 "nonimmediate_operand")
18060         (eq:QI (match_operator 1 "ix86_comparison_operator"
18061                  [(reg FLAGS_REG) (const_int 0)])
18062             (const_int 0)))]
18063   ""
18064   [(set (match_dup 0) (match_dup 1))]
18066   operands[1] = shallow_copy_rtx (operands[1]);
18067   PUT_MODE (operands[1], QImode);
18068   PUT_CODE (operands[1],
18069             ix86_reverse_condition (GET_CODE (operands[1]),
18070                                     GET_MODE (XEXP (operands[1], 0))));
18072   /* Make sure that (a) the CCmode we have for the flags is strong
18073      enough for the reversed compare or (b) we have a valid FP compare.  */
18074   if (! ix86_comparison_operator (operands[1], VOIDmode))
18075     FAIL;
18078 (define_split
18079   [(set (strict_low_part (match_operand:QI 0 "register_operand"))
18080         (eq:QI (match_operator 1 "ix86_comparison_operator"
18081                  [(reg FLAGS_REG) (const_int 0)])
18082             (const_int 0)))]
18083   ""
18084   [(set (match_dup 0) (match_dup 1))]
18086   operands[1] = shallow_copy_rtx (operands[1]);
18087   PUT_MODE (operands[1], QImode);
18088   PUT_CODE (operands[1],
18089             ix86_reverse_condition (GET_CODE (operands[1]),
18090                                     GET_MODE (XEXP (operands[1], 0))));
18092   /* Make sure that (a) the CCmode we have for the flags is strong
18093      enough for the reversed compare or (b) we have a valid FP compare.  */
18094   if (! ix86_comparison_operator (operands[1], VOIDmode))
18095     FAIL;
18098 ;; Eliminate redundant compare between set{z,nz} and j{z,nz}:
18099 ;; setz %al; test %al,%al; jz <...> -> setz %al; jnz <...> and
18100 ;; setnz %al, test %al,%al; jz <...> -> setnz %al; jz <...>.
18101 (define_peephole2
18102   [(set (match_operand:QI 0 "nonimmediate_operand")
18103         (match_operator:QI 1 "bt_comparison_operator"
18104           [(reg:CCZ FLAGS_REG) (const_int 0)]))
18105    (set (reg:CCZ FLAGS_REG)
18106         (compare:CCZ (match_dup 0) (const_int 0)))
18107    (set (pc)
18108         (if_then_else (match_operator 2 "bt_comparison_operator"
18109                         [(reg:CCZ FLAGS_REG) (const_int 0)])
18110                       (match_operand 3)
18111                       (pc)))]
18112   "peep2_regno_dead_p (3, FLAGS_REG)"
18113   [(set (match_dup 0)
18114         (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))
18115    (set (pc)
18116         (if_then_else (match_dup 2)
18117                       (match_dup 3)
18118                       (pc)))]
18120   if (GET_CODE (operands[1]) == EQ)
18121     {
18122       operands[2] = shallow_copy_rtx (operands[2]);
18123       PUT_CODE (operands[2], reverse_condition (GET_CODE (operands[2])));
18124     }
18127 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
18128 ;; subsequent logical operations are used to imitate conditional moves.
18129 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
18130 ;; it directly.
18132 (define_insn "setcc_<mode>_sse"
18133   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
18134         (match_operator:MODEF 3 "sse_comparison_operator"
18135           [(match_operand:MODEF 1 "register_operand" "0,x")
18136            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xjm")]))]
18137   "SSE_FLOAT_MODE_P (<MODE>mode)"
18138   "@
18139    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
18140    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18141   [(set_attr "isa" "noavx,avx")
18142    (set_attr "addr" "*,gpr16")
18143    (set_attr "type" "ssecmp")
18144    (set_attr "length_immediate" "1")
18145    (set_attr "prefix" "orig,vex")
18146    (set_attr "mode" "<MODE>")])
18148 (define_insn "setcc_hf_mask"
18149   [(set (match_operand:QI 0 "register_operand" "=k")
18150         (unspec:QI
18151           [(match_operand:HF 1 "register_operand" "v")
18152            (match_operand:HF 2 "nonimmediate_operand" "vm")
18153            (match_operand:SI 3 "const_0_to_31_operand")]
18154           UNSPEC_PCMP))]
18155   "TARGET_AVX512FP16"
18156   "vcmpsh\t{%3, %2, %1, %0|%0, %1, %2, %3}"
18157   [(set_attr "type" "ssecmp")
18158    (set_attr "prefix" "evex")
18159    (set_attr "mode" "HF")])
18162 ;; Basic conditional jump instructions.
18164 (define_split
18165   [(set (pc)
18166         (if_then_else
18167           (match_operator 1 "add_comparison_operator"
18168             [(not:SWI (match_operand:SWI 2 "register_operand"))
18169              (match_operand:SWI 3 "nonimmediate_operand")])
18170           (label_ref (match_operand 0))
18171           (pc)))]
18172   ""
18173   [(set (reg:CCC FLAGS_REG)
18174         (compare:CCC
18175           (plus:SWI (match_dup 2) (match_dup 3))
18176           (match_dup 2)))
18177    (set (pc)
18178         (if_then_else (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)])
18179                       (label_ref (match_operand 0))
18180                       (pc)))])
18182 (define_split
18183   [(set (pc)
18184         (if_then_else
18185           (match_operator 1 "shr_comparison_operator"
18186             [(match_operand:DI 2 "register_operand")
18187              (match_operand 3 "const_int_operand")])
18188           (label_ref (match_operand 0))
18189           (pc)))]
18190   "TARGET_64BIT
18191    && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
18192   [(set (reg:CCZ FLAGS_REG)
18193         (compare:CCZ
18194           (lshiftrt:DI (match_dup 2) (match_dup 4))
18195           (const_int 0)))
18196    (set (pc)
18197         (if_then_else (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)])
18198                       (label_ref (match_operand 0))
18199                       (pc)))]
18201   enum rtx_code new_code;
18203   operands[1] = shallow_copy_rtx (operands[1]);
18204   switch (GET_CODE (operands[1]))
18205     {
18206     case GTU: new_code = NE; break;
18207     case LEU: new_code = EQ; break;
18208     default: gcc_unreachable ();
18209     }
18210   PUT_CODE (operands[1], new_code);
18212   operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
18215 ;; We ignore the overflow flag for signed branch instructions.
18217 (define_insn "*jcc"
18218   [(set (pc)
18219         (if_then_else (match_operator 1 "ix86_comparison_operator"
18220                                       [(reg FLAGS_REG) (const_int 0)])
18221                       (label_ref (match_operand 0))
18222                       (pc)))]
18223   ""
18224   "%!%+j%C1\t%l0"
18225   [(set_attr "type" "ibr")
18226    (set_attr "modrm" "0")
18227    (set (attr "length")
18228         (if_then_else
18229           (and (ge (minus (match_dup 0) (pc))
18230                    (const_int -126))
18231                (lt (minus (match_dup 0) (pc))
18232                    (const_int 128)))
18233           (const_int 2)
18234           (const_int 6)))])
18236 ;; In general it is not safe to assume too much about CCmode registers,
18237 ;; so simplify-rtx stops when it sees a second one.  Under certain
18238 ;; conditions this is safe on x86, so help combine not create
18240 ;;      seta    %al
18241 ;;      testb   %al, %al
18242 ;;      je      Lfoo
18244 (define_split
18245   [(set (pc)
18246         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
18247                                       [(reg FLAGS_REG) (const_int 0)])
18248                           (const_int 0))
18249                       (label_ref (match_operand 1))
18250                       (pc)))]
18251   ""
18252   [(set (pc)
18253         (if_then_else (match_dup 0)
18254                       (label_ref (match_dup 1))
18255                       (pc)))]
18257   operands[0] = shallow_copy_rtx (operands[0]);
18258   PUT_MODE (operands[0], VOIDmode);
18261 (define_split
18262   [(set (pc)
18263         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
18264                                       [(reg FLAGS_REG) (const_int 0)])
18265                           (const_int 0))
18266                       (label_ref (match_operand 1))
18267                       (pc)))]
18268   ""
18269   [(set (pc)
18270         (if_then_else (match_dup 0)
18271                       (label_ref (match_dup 1))
18272                       (pc)))]
18274   operands[0] = shallow_copy_rtx (operands[0]);
18275   PUT_MODE (operands[0], VOIDmode);
18276   PUT_CODE (operands[0],
18277             ix86_reverse_condition (GET_CODE (operands[0]),
18278                                     GET_MODE (XEXP (operands[0], 0))));
18280   /* Make sure that (a) the CCmode we have for the flags is strong
18281      enough for the reversed compare or (b) we have a valid FP compare.  */
18282   if (! ix86_comparison_operator (operands[0], VOIDmode))
18283     FAIL;
18286 ;; Unconditional and other jump instructions
18288 (define_insn "jump"
18289   [(set (pc)
18290         (label_ref (match_operand 0)))]
18291   ""
18292   "%!jmp\t%l0"
18293   [(set_attr "type" "ibr")
18294    (set_attr "modrm" "0")
18295    (set (attr "length")
18296         (if_then_else
18297           (and (ge (minus (match_dup 0) (pc))
18298                    (const_int -126))
18299                (lt (minus (match_dup 0) (pc))
18300                    (const_int 128)))
18301           (const_int 2)
18302           (const_int 5)))])
18304 (define_expand "indirect_jump"
18305   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
18306   ""
18308   if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
18309     operands[0] = convert_memory_address (word_mode, operands[0]);
18310   cfun->machine->has_local_indirect_jump = true;
18313 (define_insn "*indirect_jump"
18314   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
18315   ""
18316   "* return ix86_output_indirect_jmp (operands[0]);"
18317   [(set (attr "type")
18318      (if_then_else (match_test "(cfun->machine->indirect_branch_type
18319                                  != indirect_branch_keep)")
18320         (const_string "multi")
18321         (const_string "ibr")))
18322    (set_attr "length_immediate" "0")])
18324 (define_expand "tablejump"
18325   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
18326               (use (label_ref (match_operand 1)))])]
18327   ""
18329   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
18330      relative.  Convert the relative address to an absolute address.  */
18331   if (flag_pic)
18332     {
18333       rtx op0, op1;
18334       enum rtx_code code;
18336       /* We can't use @GOTOFF for text labels on VxWorks;
18337          see gotoff_operand.  */
18338       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
18339         {
18340           code = PLUS;
18341           op0 = operands[0];
18342           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
18343         }
18344       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
18345         {
18346           code = PLUS;
18347           op0 = operands[0];
18348           op1 = pic_offset_table_rtx;
18349         }
18350       else
18351         {
18352           code = MINUS;
18353           op0 = pic_offset_table_rtx;
18354           op1 = operands[0];
18355         }
18357       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
18358                                          OPTAB_DIRECT);
18359     }
18361   if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
18362     operands[0] = convert_memory_address (word_mode, operands[0]);
18363   cfun->machine->has_local_indirect_jump = true;
18366 (define_insn "*tablejump_1"
18367   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
18368    (use (label_ref (match_operand 1)))]
18369   ""
18370   "* return ix86_output_indirect_jmp (operands[0]);"
18371   [(set (attr "type")
18372      (if_then_else (match_test "(cfun->machine->indirect_branch_type
18373                                  != indirect_branch_keep)")
18374         (const_string "multi")
18375         (const_string "ibr")))
18376    (set_attr "length_immediate" "0")])
18378 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
18380 (define_peephole2
18381   [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
18382    (set (match_operand:QI 1 "register_operand")
18383         (match_operator:QI 2 "ix86_comparison_operator"
18384           [(reg FLAGS_REG) (const_int 0)]))
18385    (set (match_operand 3 "any_QIreg_operand")
18386         (zero_extend (match_dup 1)))]
18387   "(peep2_reg_dead_p (3, operands[1])
18388     || operands_match_p (operands[1], operands[3]))
18389    && ! reg_overlap_mentioned_p (operands[3], operands[0])
18390    && peep2_regno_dead_p (0, FLAGS_REG)"
18391   [(set (match_dup 4) (match_dup 0))
18392    (set (strict_low_part (match_dup 5))
18393         (match_dup 2))]
18395   operands[5] = gen_lowpart (QImode, operands[3]);
18396   ix86_expand_clear (operands[3]);
18399 (define_peephole2
18400   [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
18401               (match_operand 4)])
18402    (set (match_operand:QI 1 "register_operand")
18403         (match_operator:QI 2 "ix86_comparison_operator"
18404           [(reg FLAGS_REG) (const_int 0)]))
18405    (set (match_operand 3 "any_QIreg_operand")
18406         (zero_extend (match_dup 1)))]
18407   "(peep2_reg_dead_p (3, operands[1])
18408     || operands_match_p (operands[1], operands[3]))
18409    && ! reg_overlap_mentioned_p (operands[3], operands[0])
18410    && ! reg_overlap_mentioned_p (operands[3], operands[4])
18411    && ! reg_set_p (operands[3], operands[4])
18412    && peep2_regno_dead_p (0, FLAGS_REG)"
18413   [(parallel [(set (match_dup 5) (match_dup 0))
18414               (match_dup 4)])
18415    (set (strict_low_part (match_dup 6))
18416         (match_dup 2))]
18418   operands[6] = gen_lowpart (QImode, operands[3]);
18419   ix86_expand_clear (operands[3]);
18422 (define_peephole2
18423   [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
18424    (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
18425               (match_operand 5)])
18426    (set (match_operand:QI 2 "register_operand")
18427         (match_operator:QI 3 "ix86_comparison_operator"
18428           [(reg FLAGS_REG) (const_int 0)]))
18429    (set (match_operand 4 "any_QIreg_operand")
18430         (zero_extend (match_dup 2)))]
18431   "(peep2_reg_dead_p (4, operands[2])
18432     || operands_match_p (operands[2], operands[4]))
18433    && ! reg_overlap_mentioned_p (operands[4], operands[0])
18434    && ! reg_overlap_mentioned_p (operands[4], operands[1])
18435    && ! reg_overlap_mentioned_p (operands[4], operands[5])
18436    && ! reg_set_p (operands[4], operands[5])
18437    && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
18438    && peep2_regno_dead_p (0, FLAGS_REG)"
18439   [(set (match_dup 6) (match_dup 0))
18440    (parallel [(set (match_dup 7) (match_dup 1))
18441               (match_dup 5)])
18442    (set (strict_low_part (match_dup 8))
18443         (match_dup 3))]
18445   operands[8] = gen_lowpart (QImode, operands[4]);
18446   ix86_expand_clear (operands[4]);
18449 ;; Similar, but match zero extend with andsi3.
18451 (define_peephole2
18452   [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
18453    (set (match_operand:QI 1 "register_operand")
18454         (match_operator:QI 2 "ix86_comparison_operator"
18455           [(reg FLAGS_REG) (const_int 0)]))
18456    (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
18457                    (and:SI (match_dup 3) (const_int 255)))
18458               (clobber (reg:CC FLAGS_REG))])]
18459   "REGNO (operands[1]) == REGNO (operands[3])
18460    && ! reg_overlap_mentioned_p (operands[3], operands[0])
18461    && peep2_regno_dead_p (0, FLAGS_REG)"
18462   [(set (match_dup 4) (match_dup 0))
18463    (set (strict_low_part (match_dup 5))
18464         (match_dup 2))]
18466   operands[5] = gen_lowpart (QImode, operands[3]);
18467   ix86_expand_clear (operands[3]);
18470 (define_peephole2
18471   [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
18472               (match_operand 4)])
18473    (set (match_operand:QI 1 "register_operand")
18474         (match_operator:QI 2 "ix86_comparison_operator"
18475           [(reg FLAGS_REG) (const_int 0)]))
18476    (parallel [(set (match_operand 3 "any_QIreg_operand")
18477                    (zero_extend (match_dup 1)))
18478               (clobber (reg:CC FLAGS_REG))])]
18479   "(peep2_reg_dead_p (3, operands[1])
18480     || operands_match_p (operands[1], operands[3]))
18481    && ! reg_overlap_mentioned_p (operands[3], operands[0])
18482    && ! reg_overlap_mentioned_p (operands[3], operands[4])
18483    && ! reg_set_p (operands[3], operands[4])
18484    && peep2_regno_dead_p (0, FLAGS_REG)"
18485   [(parallel [(set (match_dup 5) (match_dup 0))
18486               (match_dup 4)])
18487    (set (strict_low_part (match_dup 6))
18488         (match_dup 2))]
18490   operands[6] = gen_lowpart (QImode, operands[3]);
18491   ix86_expand_clear (operands[3]);
18494 (define_peephole2
18495   [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
18496    (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
18497               (match_operand 5)])
18498    (set (match_operand:QI 2 "register_operand")
18499         (match_operator:QI 3 "ix86_comparison_operator"
18500           [(reg FLAGS_REG) (const_int 0)]))
18501    (parallel [(set (match_operand 4 "any_QIreg_operand")
18502                    (zero_extend (match_dup 2)))
18503               (clobber (reg:CC FLAGS_REG))])]
18504   "(peep2_reg_dead_p (4, operands[2])
18505     || operands_match_p (operands[2], operands[4]))
18506    && ! reg_overlap_mentioned_p (operands[4], operands[0])
18507    && ! reg_overlap_mentioned_p (operands[4], operands[1])
18508    && ! reg_overlap_mentioned_p (operands[4], operands[5])
18509    && ! reg_set_p (operands[4], operands[5])
18510    && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
18511    && peep2_regno_dead_p (0, FLAGS_REG)"
18512   [(set (match_dup 6) (match_dup 0))
18513    (parallel [(set (match_dup 7) (match_dup 1))
18514               (match_dup 5)])
18515    (set (strict_low_part (match_dup 8))
18516         (match_dup 3))]
18518   operands[8] = gen_lowpart (QImode, operands[4]);
18519   ix86_expand_clear (operands[4]);
18522 ;; Call instructions.
18524 ;; The predicates normally associated with named expanders are not properly
18525 ;; checked for calls.  This is a bug in the generic code, but it isn't that
18526 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
18528 ;; P6 processors will jump to the address after the decrement when %esp
18529 ;; is used as a call operand, so they will execute return address as a code.
18530 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
18532 ;; Register constraint for call instruction.
18533 (define_mode_attr c [(SI "l") (DI "r")])
18535 ;; Call subroutine returning no value.
18537 (define_expand "call"
18538   [(call (match_operand:QI 0)
18539          (match_operand 1))
18540    (use (match_operand 2))]
18541   ""
18543   ix86_expand_call (NULL, operands[0], operands[1],
18544                     operands[2], NULL, false);
18545   DONE;
18548 (define_expand "sibcall"
18549   [(call (match_operand:QI 0)
18550          (match_operand 1))
18551    (use (match_operand 2))]
18552   ""
18554   ix86_expand_call (NULL, operands[0], operands[1],
18555                     operands[2], NULL, true);
18556   DONE;
18559 (define_insn "*call"
18560   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
18561          (match_operand 1))]
18562   "!SIBLING_CALL_P (insn)"
18563   "* return ix86_output_call_insn (insn, operands[0]);"
18564   [(set_attr "type" "call")])
18566 ;; This covers both call and sibcall since only GOT slot is allowed.
18567 (define_insn "*call_got_x32"
18568   [(call (mem:QI (zero_extend:DI
18569                    (match_operand:SI 0 "GOT_memory_operand" "Bg")))
18570          (match_operand 1))]
18571   "TARGET_X32"
18573   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
18574   return ix86_output_call_insn (insn, fnaddr);
18576   [(set_attr "type" "call")])
18578 ;; Since sibcall never returns, we can only use call-clobbered register
18579 ;; as GOT base.
18580 (define_insn "*sibcall_GOT_32"
18581   [(call (mem:QI
18582            (mem:SI (plus:SI
18583                      (match_operand:SI 0 "register_no_elim_operand" "U")
18584                      (match_operand:SI 1 "GOT32_symbol_operand"))))
18585          (match_operand 2))]
18586   "!TARGET_MACHO
18587   && !TARGET_64BIT
18588   && !TARGET_INDIRECT_BRANCH_REGISTER
18589   && SIBLING_CALL_P (insn)"
18591   rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
18592   fnaddr = gen_const_mem (SImode, fnaddr);
18593   return ix86_output_call_insn (insn, fnaddr);
18595   [(set_attr "type" "call")])
18597 (define_insn "*sibcall"
18598   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
18599          (match_operand 1))]
18600   "SIBLING_CALL_P (insn)"
18601   "* return ix86_output_call_insn (insn, operands[0]);"
18602   [(set_attr "type" "call")])
18604 (define_insn "*sibcall_memory"
18605   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
18606          (match_operand 1))
18607    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
18608   "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
18609   "* return ix86_output_call_insn (insn, operands[0]);"
18610   [(set_attr "type" "call")])
18612 (define_peephole2
18613   [(set (match_operand:W 0 "register_operand")
18614         (match_operand:W 1 "memory_operand"))
18615    (call (mem:QI (match_dup 0))
18616          (match_operand 3))]
18617   "!TARGET_X32
18618    && !TARGET_INDIRECT_BRANCH_REGISTER
18619    && SIBLING_CALL_P (peep2_next_insn (1))
18620    && !reg_mentioned_p (operands[0],
18621                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
18622   [(parallel [(call (mem:QI (match_dup 1))
18623                     (match_dup 3))
18624               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
18626 (define_peephole2
18627   [(set (match_operand:W 0 "register_operand")
18628         (match_operand:W 1 "memory_operand"))
18629    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
18630    (call (mem:QI (match_dup 0))
18631          (match_operand 3))]
18632   "!TARGET_X32
18633    && !TARGET_INDIRECT_BRANCH_REGISTER
18634    && SIBLING_CALL_P (peep2_next_insn (2))
18635    && !reg_mentioned_p (operands[0],
18636                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
18637   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
18638    (parallel [(call (mem:QI (match_dup 1))
18639                     (match_dup 3))
18640               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
18642 (define_expand "call_pop"
18643   [(parallel [(call (match_operand:QI 0)
18644                     (match_operand:SI 1))
18645               (set (reg:SI SP_REG)
18646                    (plus:SI (reg:SI SP_REG)
18647                             (match_operand:SI 3)))])]
18648   "!TARGET_64BIT"
18650   ix86_expand_call (NULL, operands[0], operands[1],
18651                     operands[2], operands[3], false);
18652   DONE;
18655 (define_insn "*call_pop"
18656   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
18657          (match_operand 1))
18658    (set (reg:SI SP_REG)
18659         (plus:SI (reg:SI SP_REG)
18660                  (match_operand:SI 2 "immediate_operand" "i")))]
18661   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18662   "* return ix86_output_call_insn (insn, operands[0]);"
18663   [(set_attr "type" "call")])
18665 (define_insn "*sibcall_pop"
18666   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
18667          (match_operand 1))
18668    (set (reg:SI SP_REG)
18669         (plus:SI (reg:SI SP_REG)
18670                  (match_operand:SI 2 "immediate_operand" "i")))]
18671   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18672   "* return ix86_output_call_insn (insn, operands[0]);"
18673   [(set_attr "type" "call")])
18675 (define_insn "*sibcall_pop_memory"
18676   [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
18677          (match_operand 1))
18678    (set (reg:SI SP_REG)
18679         (plus:SI (reg:SI SP_REG)
18680                  (match_operand:SI 2 "immediate_operand" "i")))
18681    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
18682   "!TARGET_64BIT"
18683   "* return ix86_output_call_insn (insn, operands[0]);"
18684   [(set_attr "type" "call")])
18686 (define_peephole2
18687   [(set (match_operand:SI 0 "register_operand")
18688         (match_operand:SI 1 "memory_operand"))
18689    (parallel [(call (mem:QI (match_dup 0))
18690                     (match_operand 3))
18691               (set (reg:SI SP_REG)
18692                    (plus:SI (reg:SI SP_REG)
18693                             (match_operand:SI 4 "immediate_operand")))])]
18694   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
18695    && !reg_mentioned_p (operands[0],
18696                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
18697   [(parallel [(call (mem:QI (match_dup 1))
18698                     (match_dup 3))
18699               (set (reg:SI SP_REG)
18700                    (plus:SI (reg:SI SP_REG)
18701                             (match_dup 4)))
18702               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
18704 (define_peephole2
18705   [(set (match_operand:SI 0 "register_operand")
18706         (match_operand:SI 1 "memory_operand"))
18707    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
18708    (parallel [(call (mem:QI (match_dup 0))
18709                     (match_operand 3))
18710               (set (reg:SI SP_REG)
18711                    (plus:SI (reg:SI SP_REG)
18712                             (match_operand:SI 4 "immediate_operand")))])]
18713   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
18714    && !reg_mentioned_p (operands[0],
18715                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
18716   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
18717    (parallel [(call (mem:QI (match_dup 1))
18718                     (match_dup 3))
18719               (set (reg:SI SP_REG)
18720                    (plus:SI (reg:SI SP_REG)
18721                             (match_dup 4)))
18722               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
18724 ;; Combining simple memory jump instruction
18726 (define_peephole2
18727   [(set (match_operand:W 0 "register_operand")
18728         (match_operand:W 1 "memory_operand"))
18729    (set (pc) (match_dup 0))]
18730   "!TARGET_X32
18731    && !TARGET_INDIRECT_BRANCH_REGISTER
18732    && peep2_reg_dead_p (2, operands[0])"
18733   [(set (pc) (match_dup 1))])
18735 ;; Call subroutine, returning value in operand 0
18737 (define_expand "call_value"
18738   [(set (match_operand 0)
18739         (call (match_operand:QI 1)
18740               (match_operand 2)))
18741    (use (match_operand 3))]
18742   ""
18744   ix86_expand_call (operands[0], operands[1], operands[2],
18745                     operands[3], NULL, false);
18746   DONE;
18749 (define_expand "sibcall_value"
18750   [(set (match_operand 0)
18751         (call (match_operand:QI 1)
18752               (match_operand 2)))
18753    (use (match_operand 3))]
18754   ""
18756   ix86_expand_call (operands[0], operands[1], operands[2],
18757                     operands[3], NULL, true);
18758   DONE;
18761 (define_insn "*call_value"
18762   [(set (match_operand 0)
18763         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
18764               (match_operand 2)))]
18765   "!SIBLING_CALL_P (insn)"
18766   "* return ix86_output_call_insn (insn, operands[1]);"
18767   [(set_attr "type" "callv")])
18769 ;; This covers both call and sibcall since only GOT slot is allowed.
18770 (define_insn "*call_value_got_x32"
18771   [(set (match_operand 0)
18772         (call (mem:QI
18773                 (zero_extend:DI
18774                   (match_operand:SI 1 "GOT_memory_operand" "Bg")))
18775               (match_operand 2)))]
18776   "TARGET_X32"
18778   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
18779   return ix86_output_call_insn (insn, fnaddr);
18781   [(set_attr "type" "callv")])
18783 ;; Since sibcall never returns, we can only use call-clobbered register
18784 ;; as GOT base.
18785 (define_insn "*sibcall_value_GOT_32"
18786   [(set (match_operand 0)
18787         (call (mem:QI
18788                 (mem:SI (plus:SI
18789                           (match_operand:SI 1 "register_no_elim_operand" "U")
18790                           (match_operand:SI 2 "GOT32_symbol_operand"))))
18791          (match_operand 3)))]
18792   "!TARGET_MACHO
18793    && !TARGET_64BIT
18794    && !TARGET_INDIRECT_BRANCH_REGISTER
18795    && SIBLING_CALL_P (insn)"
18797   rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
18798   fnaddr = gen_const_mem (SImode, fnaddr);
18799   return ix86_output_call_insn (insn, fnaddr);
18801   [(set_attr "type" "callv")])
18803 (define_insn "*sibcall_value"
18804   [(set (match_operand 0)
18805         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
18806               (match_operand 2)))]
18807   "SIBLING_CALL_P (insn)"
18808   "* return ix86_output_call_insn (insn, operands[1]);"
18809   [(set_attr "type" "callv")])
18811 (define_insn "*sibcall_value_memory"
18812   [(set (match_operand 0)
18813         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
18814               (match_operand 2)))
18815    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
18816   "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
18817   "* return ix86_output_call_insn (insn, operands[1]);"
18818   [(set_attr "type" "callv")])
18820 (define_peephole2
18821   [(set (match_operand:W 0 "register_operand")
18822         (match_operand:W 1 "memory_operand"))
18823    (set (match_operand 2)
18824    (call (mem:QI (match_dup 0))
18825                  (match_operand 3)))]
18826   "!TARGET_X32
18827    && !TARGET_INDIRECT_BRANCH_REGISTER
18828    && SIBLING_CALL_P (peep2_next_insn (1))
18829    && !reg_mentioned_p (operands[0],
18830                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
18831   [(parallel [(set (match_dup 2)
18832                    (call (mem:QI (match_dup 1))
18833                          (match_dup 3)))
18834               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
18836 (define_peephole2
18837   [(set (match_operand:W 0 "register_operand")
18838         (match_operand:W 1 "memory_operand"))
18839    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
18840    (set (match_operand 2)
18841         (call (mem:QI (match_dup 0))
18842               (match_operand 3)))]
18843   "!TARGET_X32
18844    && !TARGET_INDIRECT_BRANCH_REGISTER
18845    && SIBLING_CALL_P (peep2_next_insn (2))
18846    && !reg_mentioned_p (operands[0],
18847                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
18848   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
18849    (parallel [(set (match_dup 2)
18850                    (call (mem:QI (match_dup 1))
18851                          (match_dup 3)))
18852               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
18854 (define_expand "call_value_pop"
18855   [(parallel [(set (match_operand 0)
18856                    (call (match_operand:QI 1)
18857                          (match_operand:SI 2)))
18858               (set (reg:SI SP_REG)
18859                    (plus:SI (reg:SI SP_REG)
18860                             (match_operand:SI 4)))])]
18861   "!TARGET_64BIT"
18863   ix86_expand_call (operands[0], operands[1], operands[2],
18864                     operands[3], operands[4], false);
18865   DONE;
18868 (define_insn "*call_value_pop"
18869   [(set (match_operand 0)
18870         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
18871               (match_operand 2)))
18872    (set (reg:SI SP_REG)
18873         (plus:SI (reg:SI SP_REG)
18874                  (match_operand:SI 3 "immediate_operand" "i")))]
18875   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18876   "* return ix86_output_call_insn (insn, operands[1]);"
18877   [(set_attr "type" "callv")])
18879 (define_insn "*sibcall_value_pop"
18880   [(set (match_operand 0)
18881         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
18882               (match_operand 2)))
18883    (set (reg:SI SP_REG)
18884         (plus:SI (reg:SI SP_REG)
18885                  (match_operand:SI 3 "immediate_operand" "i")))]
18886   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18887   "* return ix86_output_call_insn (insn, operands[1]);"
18888   [(set_attr "type" "callv")])
18890 (define_insn "*sibcall_value_pop_memory"
18891   [(set (match_operand 0)
18892         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
18893               (match_operand 2)))
18894    (set (reg:SI SP_REG)
18895         (plus:SI (reg:SI SP_REG)
18896                  (match_operand:SI 3 "immediate_operand" "i")))
18897    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
18898   "!TARGET_64BIT"
18899   "* return ix86_output_call_insn (insn, operands[1]);"
18900   [(set_attr "type" "callv")])
18902 (define_peephole2
18903   [(set (match_operand:SI 0 "register_operand")
18904         (match_operand:SI 1 "memory_operand"))
18905    (parallel [(set (match_operand 2)
18906                    (call (mem:QI (match_dup 0))
18907                          (match_operand 3)))
18908               (set (reg:SI SP_REG)
18909                    (plus:SI (reg:SI SP_REG)
18910                             (match_operand:SI 4 "immediate_operand")))])]
18911   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
18912    && !reg_mentioned_p (operands[0],
18913                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
18914   [(parallel [(set (match_dup 2)
18915                    (call (mem:QI (match_dup 1))
18916                          (match_dup 3)))
18917               (set (reg:SI SP_REG)
18918                    (plus:SI (reg:SI SP_REG)
18919                             (match_dup 4)))
18920               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
18922 (define_peephole2
18923   [(set (match_operand:SI 0 "register_operand")
18924         (match_operand:SI 1 "memory_operand"))
18925    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
18926    (parallel [(set (match_operand 2)
18927                    (call (mem:QI (match_dup 0))
18928                          (match_operand 3)))
18929               (set (reg:SI SP_REG)
18930                    (plus:SI (reg:SI SP_REG)
18931                             (match_operand:SI 4 "immediate_operand")))])]
18932   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
18933    && !reg_mentioned_p (operands[0],
18934                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
18935   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
18936    (parallel [(set (match_dup 2)
18937                    (call (mem:QI (match_dup 1))
18938                          (match_dup 3)))
18939               (set (reg:SI SP_REG)
18940                    (plus:SI (reg:SI SP_REG)
18941                             (match_dup 4)))
18942               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
18944 ;; Call subroutine returning any type.
18946 (define_expand "untyped_call"
18947   [(parallel [(call (match_operand 0)
18948                     (const_int 0))
18949               (match_operand 1)
18950               (match_operand 2)])]
18951   ""
18953   int i;
18955   /* In order to give reg-stack an easier job in validating two
18956      coprocessor registers as containing a possible return value,
18957      simply pretend the untyped call returns a complex long double
18958      value. 
18960      We can't use SSE_REGPARM_MAX here since callee is unprototyped
18961      and should have the default ABI.  */
18963   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
18964                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
18965                     operands[0], const0_rtx,
18966                     GEN_INT ((TARGET_64BIT
18967                               ? (ix86_abi == SYSV_ABI
18968                                  ? X86_64_SSE_REGPARM_MAX
18969                                  : X86_64_MS_SSE_REGPARM_MAX)
18970                               : X86_32_SSE_REGPARM_MAX)
18971                              - 1),
18972                     NULL, false);
18974   for (i = 0; i < XVECLEN (operands[2], 0); i++)
18975     {
18976       rtx set = XVECEXP (operands[2], 0, i);
18977       emit_move_insn (SET_DEST (set), SET_SRC (set));
18978     }
18980   /* The optimizer does not know that the call sets the function value
18981      registers we stored in the result block.  We avoid problems by
18982      claiming that all hard registers are used and clobbered at this
18983      point.  */
18984   emit_insn (gen_blockage ());
18986   DONE;
18989 ;; Prologue and epilogue instructions
18991 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
18992 ;; all of memory.  This blocks insns from being moved across this point.
18994 (define_insn "blockage"
18995   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
18996   ""
18997   ""
18998   [(set_attr "length" "0")])
19000 ;; Do not schedule instructions accessing memory across this point.
19002 (define_expand "memory_blockage"
19003   [(set (match_dup 0)
19004         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
19005   ""
19007   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19008   MEM_VOLATILE_P (operands[0]) = 1;
19011 (define_insn "*memory_blockage"
19012   [(set (match_operand:BLK 0)
19013         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
19014   ""
19015   ""
19016   [(set_attr "length" "0")])
19018 ;; As USE insns aren't meaningful after reload, this is used instead
19019 ;; to prevent deleting instructions setting registers for PIC code
19020 (define_insn "prologue_use"
19021   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
19022   ""
19023   ""
19024   [(set_attr "length" "0")])
19026 ;; Insn emitted into the body of a function to return from a function.
19027 ;; This is only done if the function's epilogue is known to be simple.
19028 ;; See comments for ix86_can_use_return_insn_p in i386.cc.
19030 (define_expand "return"
19031   [(simple_return)]
19032   "ix86_can_use_return_insn_p ()"
19034   if (crtl->args.pops_args)
19035     {
19036       rtx popc = GEN_INT (crtl->args.pops_args);
19037       emit_jump_insn (gen_simple_return_pop_internal (popc));
19038       DONE;
19039     }
19042 ;; We need to disable this for TARGET_SEH, as otherwise
19043 ;; shrink-wrapped prologue gets enabled too.  This might exceed
19044 ;; the maximum size of prologue in unwind information.
19045 ;; Also disallow shrink-wrapping if using stack slot to pass the
19046 ;; static chain pointer - the first instruction has to be pushl %esi
19047 ;; and it can't be moved around, as we use alternate entry points
19048 ;; in that case.
19049 ;; Also disallow for ms_hook_prologue functions which have frame
19050 ;; pointer set up in function label which is correctly handled in
19051 ;; ix86_expand_{prologue|epligoue}() only.
19053 (define_expand "simple_return"
19054   [(simple_return)]
19055   "!TARGET_SEH && !ix86_static_chain_on_stack && !ix86_function_ms_hook_prologue (cfun->decl)"
19057   if (crtl->args.pops_args)
19058     {
19059       rtx popc = GEN_INT (crtl->args.pops_args);
19060       emit_jump_insn (gen_simple_return_pop_internal (popc));
19061       DONE;
19062     }
19065 (define_insn "simple_return_internal"
19066   [(simple_return)]
19067   "reload_completed"
19068   "* return ix86_output_function_return (false);"
19069   [(set_attr "length" "1")
19070    (set_attr "atom_unit" "jeu")
19071    (set_attr "length_immediate" "0")
19072    (set_attr "modrm" "0")])
19074 (define_insn "interrupt_return"
19075   [(simple_return)
19076    (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
19077   "reload_completed"
19079   return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret";
19082 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
19083 ;; instruction Athlon and K8 have.
19085 (define_insn "simple_return_internal_long"
19086   [(simple_return)
19087    (unspec [(const_int 0)] UNSPEC_REP)]
19088   "reload_completed"
19089   "* return ix86_output_function_return (true);"
19090   [(set_attr "length" "2")
19091    (set_attr "atom_unit" "jeu")
19092    (set_attr "length_immediate" "0")
19093    (set_attr "prefix_rep" "1")
19094    (set_attr "modrm" "0")])
19096 (define_insn_and_split "simple_return_pop_internal"
19097   [(simple_return)
19098    (use (match_operand:SI 0 "const_int_operand"))]
19099   "reload_completed"
19100   "ret\t%0"
19101   "&& cfun->machine->function_return_type != indirect_branch_keep"
19102   [(const_int 0)]
19103   "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
19104   [(set_attr "length" "3")
19105    (set_attr "atom_unit" "jeu")
19106    (set_attr "length_immediate" "2")
19107    (set_attr "modrm" "0")])
19109 (define_expand "simple_return_indirect_internal"
19110   [(parallel
19111      [(simple_return)
19112       (use (match_operand 0 "register_operand"))])])
19114 (define_insn "*simple_return_indirect_internal<mode>"
19115   [(simple_return)
19116    (use (match_operand:W 0 "register_operand" "r"))]
19117   "reload_completed"
19118   "* return ix86_output_indirect_function_return (operands[0]);"
19119   [(set (attr "type")
19120      (if_then_else (match_test "(cfun->machine->indirect_branch_type
19121                                  != indirect_branch_keep)")
19122         (const_string "multi")
19123         (const_string "ibr")))
19124    (set_attr "length_immediate" "0")])
19126 (define_insn "nop"
19127   [(const_int 0)]
19128   ""
19129   "nop"
19130   [(set_attr "length" "1")
19131    (set_attr "length_immediate" "0")
19132    (set_attr "modrm" "0")])
19134 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
19135 (define_insn "nops"
19136   [(unspec_volatile [(match_operand 0 "const_int_operand")]
19137                     UNSPECV_NOPS)]
19138   "reload_completed"
19140   int num = INTVAL (operands[0]);
19142   gcc_assert (IN_RANGE (num, 1, 8));
19144   while (num--)
19145     fputs ("\tnop\n", asm_out_file);
19147   return "";
19149   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
19150    (set_attr "length_immediate" "0")
19151    (set_attr "modrm" "0")])
19153 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
19154 ;; branch prediction penalty for the third jump in a 16-byte
19155 ;; block on K8.
19157 (define_insn "pad"
19158   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
19159   ""
19161 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
19162   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
19163 #else
19164   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
19165      The align insn is used to avoid 3 jump instructions in the row to improve
19166      branch prediction and the benefits hardly outweigh the cost of extra 8
19167      nops on the average inserted by full alignment pseudo operation.  */
19168 #endif
19169   return "";
19171   [(set_attr "length" "16")])
19173 (define_expand "prologue"
19174   [(const_int 0)]
19175   ""
19176   "ix86_expand_prologue (); DONE;")
19178 (define_expand "set_got"
19179   [(parallel
19180      [(set (match_operand:SI 0 "register_operand")
19181            (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
19182       (clobber (reg:CC FLAGS_REG))])]
19183   "!TARGET_64BIT"
19185   if (flag_pic && !TARGET_VXWORKS_RTP)
19186     ix86_pc_thunk_call_expanded = true;
19189 (define_insn "*set_got"
19190   [(set (match_operand:SI 0 "register_operand" "=r")
19191         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
19192    (clobber (reg:CC FLAGS_REG))]
19193   "!TARGET_64BIT"
19194   "* return output_set_got (operands[0], NULL_RTX);"
19195   [(set_attr "type" "multi")
19196    (set_attr "length" "12")])
19198 (define_expand "set_got_labelled"
19199   [(parallel
19200      [(set (match_operand:SI 0 "register_operand")
19201            (unspec:SI [(label_ref (match_operand 1))]
19202                       UNSPEC_SET_GOT))
19203       (clobber (reg:CC FLAGS_REG))])]
19204   "!TARGET_64BIT"
19206   if (flag_pic && !TARGET_VXWORKS_RTP)
19207     ix86_pc_thunk_call_expanded = true;
19210 (define_insn "*set_got_labelled"
19211   [(set (match_operand:SI 0 "register_operand" "=r")
19212         (unspec:SI [(label_ref (match_operand 1))]
19213          UNSPEC_SET_GOT))
19214    (clobber (reg:CC FLAGS_REG))]
19215   "!TARGET_64BIT"
19216   "* return output_set_got (operands[0], operands[1]);"
19217   [(set_attr "type" "multi")
19218    (set_attr "length" "12")])
19220 (define_insn "set_got_rex64"
19221   [(set (match_operand:DI 0 "register_operand" "=r")
19222         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
19223   "TARGET_64BIT"
19224   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
19225   [(set_attr "type" "lea")
19226    (set_attr "length_address" "4")
19227    (set_attr "mode" "DI")])
19229 (define_insn "set_rip_rex64"
19230   [(set (match_operand:DI 0 "register_operand" "=r")
19231         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
19232   "TARGET_64BIT"
19233   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
19234   [(set_attr "type" "lea")
19235    (set_attr "length_address" "4")
19236    (set_attr "mode" "DI")])
19238 (define_insn "set_got_offset_rex64"
19239   [(set (match_operand:DI 0 "register_operand" "=r")
19240         (unspec:DI
19241           [(label_ref (match_operand 1))]
19242           UNSPEC_SET_GOT_OFFSET))]
19243   "TARGET_LP64"
19244   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
19245   [(set_attr "type" "imov")
19246    (set_attr "length_immediate" "0")
19247    (set_attr "length_address" "8")
19248    (set_attr "mode" "DI")])
19250 (define_expand "epilogue"
19251   [(const_int 0)]
19252   ""
19253   "ix86_expand_epilogue (1); DONE;")
19255 (define_expand "sibcall_epilogue"
19256   [(const_int 0)]
19257   ""
19258   "ix86_expand_epilogue (0); DONE;")
19260 (define_expand "eh_return"
19261   [(use (match_operand 0 "register_operand"))]
19262   ""
19264   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
19266   /* Tricky bit: we write the address of the handler to which we will
19267      be returning into someone else's stack frame, one word below the
19268      stack address we wish to restore.  */
19269   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
19270   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
19271   /* Return address is always in word_mode.  */
19272   tmp = gen_rtx_MEM (word_mode, tmp);
19273   if (GET_MODE (ra) != word_mode)
19274     ra = convert_to_mode (word_mode, ra, 1);
19275   emit_move_insn (tmp, ra);
19277   emit_jump_insn (gen_eh_return_internal ());
19278   emit_barrier ();
19279   DONE;
19282 (define_insn_and_split "eh_return_internal"
19283   [(eh_return)]
19284   ""
19285   "#"
19286   "epilogue_completed"
19287   [(const_int 0)]
19288   "ix86_expand_epilogue (2); DONE;")
19290 (define_expand "@leave_<mode>"
19291   [(parallel
19292     [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
19293      (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
19294      (clobber (mem:BLK (scratch)))])]
19295   ""
19296   "operands[0] = GEN_INT (<MODE_SIZE>);")
19298 (define_insn "*leave"
19299   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
19300    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
19301    (clobber (mem:BLK (scratch)))]
19302   "!TARGET_64BIT"
19303   "leave"
19304   [(set_attr "type" "leave")])
19306 (define_insn "*leave_rex64"
19307   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
19308    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
19309    (clobber (mem:BLK (scratch)))]
19310   "TARGET_64BIT"
19311   "leave"
19312   [(set_attr "type" "leave")])
19314 ;; Handle -fsplit-stack.
19316 (define_expand "split_stack_prologue"
19317   [(const_int 0)]
19318   ""
19320   ix86_expand_split_stack_prologue ();
19321   DONE;
19324 ;; In order to support the call/return predictor, we use a return
19325 ;; instruction which the middle-end doesn't see.
19326 (define_insn "split_stack_return"
19327   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
19328                      UNSPECV_SPLIT_STACK_RETURN)]
19329   ""
19331   if (operands[0] == const0_rtx)
19332     return "ret";
19333   else
19334     return "ret\t%0";
19336   [(set_attr "atom_unit" "jeu")
19337    (set_attr "modrm" "0")
19338    (set (attr "length")
19339         (if_then_else (match_operand:SI 0 "const0_operand")
19340                       (const_int 1)
19341                       (const_int 3)))
19342    (set (attr "length_immediate")
19343         (if_then_else (match_operand:SI 0 "const0_operand")
19344                       (const_int 0)
19345                       (const_int 2)))])
19347 ;; If there are operand 0 bytes available on the stack, jump to
19348 ;; operand 1.
19350 (define_expand "split_stack_space_check"
19351   [(set (pc) (if_then_else
19352               (ltu (minus (reg SP_REG)
19353                           (match_operand 0 "register_operand"))
19354                    (match_dup 2))
19355               (label_ref (match_operand 1))
19356               (pc)))]
19357   ""
19359   rtx reg = gen_reg_rtx (Pmode);
19361   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
19363   operands[2] = ix86_split_stack_guard ();
19364   ix86_expand_branch (GEU, reg, operands[2], operands[1]);
19366   DONE;
19369 ;; Bit manipulation instructions.
19371 (define_expand "ffs<mode>2"
19372   [(set (match_dup 2) (const_int -1))
19373    (parallel [(set (match_dup 3) (match_dup 4))
19374               (set (match_operand:SWI48 0 "register_operand")
19375                    (ctz:SWI48
19376                      (match_operand:SWI48 1 "nonimmediate_operand")))])
19377    (set (match_dup 0) (if_then_else:SWI48
19378                         (eq (match_dup 3) (const_int 0))
19379                         (match_dup 2)
19380                         (match_dup 0)))
19381    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
19382               (clobber (reg:CC FLAGS_REG))])]
19383   ""
19385   machine_mode flags_mode;
19387   if (<MODE>mode == SImode && !TARGET_CMOVE)
19388     {
19389       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
19390       DONE;
19391     }
19393   flags_mode = TARGET_BMI ? CCCmode : CCZmode;
19395   operands[2] = gen_reg_rtx (<MODE>mode);
19396   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
19397   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
19400 (define_insn_and_split "ffssi2_no_cmove"
19401   [(set (match_operand:SI 0 "register_operand" "=r")
19402         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
19403    (clobber (match_scratch:SI 2 "=&q"))
19404    (clobber (reg:CC FLAGS_REG))]
19405   "!TARGET_CMOVE"
19406   "#"
19407   "&& reload_completed"
19408   [(parallel [(set (match_dup 4) (match_dup 5))
19409               (set (match_dup 0) (ctz:SI (match_dup 1)))])
19410    (set (strict_low_part (match_dup 3))
19411         (eq:QI (match_dup 4) (const_int 0)))
19412    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
19413               (clobber (reg:CC FLAGS_REG))])
19414    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
19415               (clobber (reg:CC FLAGS_REG))])
19416    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
19417               (clobber (reg:CC FLAGS_REG))])]
19419   machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
19421   operands[3] = gen_lowpart (QImode, operands[2]);
19422   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
19423   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
19425   ix86_expand_clear (operands[2]);
19428 (define_insn_and_split "*tzcnt<mode>_1"
19429   [(set (reg:CCC FLAGS_REG)
19430         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19431                      (const_int 0)))
19432    (set (match_operand:SWI48 0 "register_operand" "=r")
19433         (ctz:SWI48 (match_dup 1)))]
19434   "TARGET_BMI"
19435   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19436   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19437    && optimize_function_for_speed_p (cfun)
19438    && !reg_mentioned_p (operands[0], operands[1])"
19439   [(parallel
19440     [(set (reg:CCC FLAGS_REG)
19441           (compare:CCC (match_dup 1) (const_int 0)))
19442      (set (match_dup 0)
19443           (ctz:SWI48 (match_dup 1)))
19444      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
19445   "ix86_expand_clear (operands[0]);"
19446   [(set_attr "type" "alu1")
19447    (set_attr "prefix_0f" "1")
19448    (set_attr "prefix_rep" "1")
19449    (set_attr "btver2_decode" "double")
19450    (set_attr "mode" "<MODE>")])
19452 ; False dependency happens when destination is only updated by tzcnt,
19453 ; lzcnt or popcnt.  There is no false dependency when destination is
19454 ; also used in source.
19455 (define_insn "*tzcnt<mode>_1_falsedep"
19456   [(set (reg:CCC FLAGS_REG)
19457         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19458                      (const_int 0)))
19459    (set (match_operand:SWI48 0 "register_operand" "=r")
19460         (ctz:SWI48 (match_dup 1)))
19461    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
19462            UNSPEC_INSN_FALSE_DEP)]
19463   "TARGET_BMI"
19464   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19465   [(set_attr "type" "alu1")
19466    (set_attr "prefix_0f" "1")
19467    (set_attr "prefix_rep" "1")
19468    (set_attr "btver2_decode" "double")
19469    (set_attr "mode" "<MODE>")])
19471 (define_insn "*bsf<mode>_1"
19472   [(set (reg:CCZ FLAGS_REG)
19473         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19474                      (const_int 0)))
19475    (set (match_operand:SWI48 0 "register_operand" "=r")
19476         (ctz:SWI48 (match_dup 1)))]
19477   ""
19478   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
19479   [(set_attr "type" "alu1")
19480    (set_attr "prefix_0f" "1")
19481    (set_attr "btver2_decode" "double")
19482    (set_attr "znver1_decode" "vector")
19483    (set_attr "mode" "<MODE>")])
19485 (define_insn_and_split "ctz<mode>2"
19486   [(set (match_operand:SWI48 0 "register_operand" "=r")
19487         (ctz:SWI48
19488           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19489    (clobber (reg:CC FLAGS_REG))]
19490   ""
19492   if (TARGET_BMI)
19493     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19494   else if (optimize_function_for_size_p (cfun))
19495     ;
19496   else if (TARGET_CPU_P (GENERIC))
19497     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
19498     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
19500   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
19502   "(TARGET_BMI || TARGET_CPU_P (GENERIC))
19503    && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19504    && optimize_function_for_speed_p (cfun)
19505    && !reg_mentioned_p (operands[0], operands[1])"
19506   [(parallel
19507     [(set (match_dup 0)
19508           (ctz:SWI48 (match_dup 1)))
19509      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19510      (clobber (reg:CC FLAGS_REG))])]
19511   "ix86_expand_clear (operands[0]);"
19512   [(set_attr "type" "alu1")
19513    (set_attr "prefix_0f" "1")
19514    (set (attr "prefix_rep")
19515      (if_then_else
19516        (ior (match_test "TARGET_BMI")
19517             (and (not (match_test "optimize_function_for_size_p (cfun)"))
19518                  (match_test "TARGET_CPU_P (GENERIC)")))
19519        (const_string "1")
19520        (const_string "0")))
19521    (set_attr "mode" "<MODE>")])
19523 ; False dependency happens when destination is only updated by tzcnt,
19524 ; lzcnt or popcnt.  There is no false dependency when destination is
19525 ; also used in source.
19526 (define_insn "*ctz<mode>2_falsedep"
19527   [(set (match_operand:SWI48 0 "register_operand" "=r")
19528         (ctz:SWI48
19529           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19530    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
19531            UNSPEC_INSN_FALSE_DEP)
19532    (clobber (reg:CC FLAGS_REG))]
19533   ""
19535   if (TARGET_BMI)
19536     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19537   else if (TARGET_CPU_P (GENERIC))
19538     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
19539     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
19540   else
19541     gcc_unreachable ();
19543   [(set_attr "type" "alu1")
19544    (set_attr "prefix_0f" "1")
19545    (set_attr "prefix_rep" "1")
19546    (set_attr "mode" "<MODE>")])
19548 (define_insn_and_split "*ctzsi2_zext"
19549   [(set (match_operand:DI 0 "register_operand" "=r")
19550         (and:DI
19551           (subreg:DI
19552             (ctz:SI
19553               (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19554           (const_int 63)))
19555    (clobber (reg:CC FLAGS_REG))]
19556   "TARGET_BMI && TARGET_64BIT"
19557   "tzcnt{l}\t{%1, %k0|%k0, %1}"
19558   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19559    && optimize_function_for_speed_p (cfun)
19560    && !reg_mentioned_p (operands[0], operands[1])"
19561   [(parallel
19562     [(set (match_dup 0)
19563           (and:DI (subreg:DI (ctz:SI (match_dup 1)) 0) (const_int 63)))
19564      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19565      (clobber (reg:CC FLAGS_REG))])]
19566   "ix86_expand_clear (operands[0]);"
19567   [(set_attr "type" "alu1")
19568    (set_attr "prefix_0f" "1")
19569    (set_attr "prefix_rep" "1")
19570    (set_attr "mode" "SI")])
19572 ; False dependency happens when destination is only updated by tzcnt,
19573 ; lzcnt or popcnt.  There is no false dependency when destination is
19574 ; also used in source.
19575 (define_insn "*ctzsi2_zext_falsedep"
19576   [(set (match_operand:DI 0 "register_operand" "=r")
19577         (and:DI
19578           (subreg:DI
19579             (ctz:SI
19580               (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19581           (const_int 63)))
19582    (unspec [(match_operand:DI 2 "register_operand" "0")]
19583            UNSPEC_INSN_FALSE_DEP)
19584    (clobber (reg:CC FLAGS_REG))]
19585   "TARGET_BMI && TARGET_64BIT"
19586   "tzcnt{l}\t{%1, %k0|%k0, %1}"
19587   [(set_attr "type" "alu1")
19588    (set_attr "prefix_0f" "1")
19589    (set_attr "prefix_rep" "1")
19590    (set_attr "mode" "SI")])
19592 (define_insn_and_split "*ctzsidi2_<s>ext"
19593   [(set (match_operand:DI 0 "register_operand" "=r")
19594         (any_extend:DI
19595           (ctz:SI
19596             (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19597    (clobber (reg:CC FLAGS_REG))]
19598   "TARGET_64BIT"
19600   if (TARGET_BMI)
19601     return "tzcnt{l}\t{%1, %k0|%k0, %1}";
19602   else if (TARGET_CPU_P (GENERIC)
19603            && !optimize_function_for_size_p (cfun))
19604     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
19605     return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
19606   return "bsf{l}\t{%1, %k0|%k0, %1}";
19608   "(TARGET_BMI || TARGET_CPU_P (GENERIC))
19609    && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19610    && optimize_function_for_speed_p (cfun)
19611    && !reg_mentioned_p (operands[0], operands[1])"
19612   [(parallel
19613     [(set (match_dup 0)
19614           (any_extend:DI (ctz:SI (match_dup 1))))
19615      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19616      (clobber (reg:CC FLAGS_REG))])]
19617   "ix86_expand_clear (operands[0]);"
19618   [(set_attr "type" "alu1")
19619    (set_attr "prefix_0f" "1")
19620    (set (attr "prefix_rep")
19621      (if_then_else
19622        (ior (match_test "TARGET_BMI")
19623             (and (not (match_test "optimize_function_for_size_p (cfun)"))
19624                  (match_test "TARGET_CPU_P (GENERIC)")))
19625        (const_string "1")
19626        (const_string "0")))
19627    (set_attr "mode" "SI")])
19629 (define_insn "*ctzsidi2_<s>ext_falsedep"
19630   [(set (match_operand:DI 0 "register_operand" "=r")
19631         (any_extend:DI
19632           (ctz:SI
19633             (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19634    (unspec [(match_operand:DI 2 "register_operand" "0")]
19635            UNSPEC_INSN_FALSE_DEP)
19636    (clobber (reg:CC FLAGS_REG))]
19637   "TARGET_64BIT"
19639   if (TARGET_BMI)
19640     return "tzcnt{l}\t{%1, %k0|%k0, %1}";
19641   else if (TARGET_CPU_P (GENERIC))
19642     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
19643     return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
19644   else
19645     gcc_unreachable ();
19647   [(set_attr "type" "alu1")
19648    (set_attr "prefix_0f" "1")
19649    (set_attr "prefix_rep" "1")
19650    (set_attr "mode" "SI")])
19652 (define_insn "bsr_rex64"
19653   [(set (reg:CCZ FLAGS_REG)
19654         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
19655                      (const_int 0)))
19656    (set (match_operand:DI 0 "register_operand" "=r")
19657         (minus:DI (const_int 63)
19658                   (clz:DI (match_dup 1))))]
19659   "TARGET_64BIT"
19660   "bsr{q}\t{%1, %0|%0, %1}"
19661   [(set_attr "type" "alu1")
19662    (set_attr "prefix_0f" "1")
19663    (set_attr "znver1_decode" "vector")
19664    (set_attr "mode" "DI")])
19666 (define_insn "bsr_rex64_1"
19667   [(set (match_operand:DI 0 "register_operand" "=r")
19668         (minus:DI (const_int 63)
19669                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
19670    (clobber (reg:CC FLAGS_REG))]
19671   "!TARGET_LZCNT && TARGET_64BIT"
19672   "bsr{q}\t{%1, %0|%0, %1}"
19673   [(set_attr "type" "alu1")
19674    (set_attr "prefix_0f" "1")
19675    (set_attr "znver1_decode" "vector")
19676    (set_attr "mode" "DI")])
19678 (define_insn "bsr_rex64_1_zext"
19679   [(set (match_operand:DI 0 "register_operand" "=r")
19680         (zero_extend:DI
19681           (minus:SI (const_int 63)
19682                     (subreg:SI
19683                       (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
19684                       0))))
19685    (clobber (reg:CC FLAGS_REG))]
19686   "!TARGET_LZCNT && TARGET_64BIT"
19687   "bsr{q}\t{%1, %0|%0, %1}"
19688   [(set_attr "type" "alu1")
19689    (set_attr "prefix_0f" "1")
19690    (set_attr "znver1_decode" "vector")
19691    (set_attr "mode" "DI")])
19693 (define_insn "bsr"
19694   [(set (reg:CCZ FLAGS_REG)
19695         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
19696                      (const_int 0)))
19697    (set (match_operand:SI 0 "register_operand" "=r")
19698         (minus:SI (const_int 31)
19699                   (clz:SI (match_dup 1))))]
19700   ""
19701   "bsr{l}\t{%1, %0|%0, %1}"
19702   [(set_attr "type" "alu1")
19703    (set_attr "prefix_0f" "1")
19704    (set_attr "znver1_decode" "vector")
19705    (set_attr "mode" "SI")])
19707 (define_insn "bsr_1"
19708   [(set (match_operand:SI 0 "register_operand" "=r")
19709         (minus:SI (const_int 31)
19710                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19711    (clobber (reg:CC FLAGS_REG))]
19712   "!TARGET_LZCNT"
19713   "bsr{l}\t{%1, %0|%0, %1}"
19714   [(set_attr "type" "alu1")
19715    (set_attr "prefix_0f" "1")
19716    (set_attr "znver1_decode" "vector")
19717    (set_attr "mode" "SI")])
19719 (define_insn "bsr_zext_1"
19720   [(set (match_operand:DI 0 "register_operand" "=r")
19721         (zero_extend:DI
19722           (minus:SI
19723             (const_int 31)
19724             (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))))
19725    (clobber (reg:CC FLAGS_REG))]
19726   "!TARGET_LZCNT && TARGET_64BIT"
19727   "bsr{l}\t{%1, %k0|%k0, %1}"
19728   [(set_attr "type" "alu1")
19729    (set_attr "prefix_0f" "1")
19730    (set_attr "znver1_decode" "vector")
19731    (set_attr "mode" "SI")])
19733 ; As bsr is undefined behavior on zero and for other input
19734 ; values it is in range 0 to 63, we can optimize away sign-extends.
19735 (define_insn_and_split "*bsr_rex64_2"
19736   [(set (match_operand:DI 0 "register_operand")
19737         (xor:DI
19738           (sign_extend:DI
19739             (minus:SI
19740               (const_int 63)
19741               (subreg:SI (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
19742                          0)))
19743           (const_int 63)))
19744     (clobber (reg:CC FLAGS_REG))]
19745   "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
19746   "#"
19747   "&& 1"
19748   [(parallel [(set (reg:CCZ FLAGS_REG)
19749                    (compare:CCZ (match_dup 1) (const_int 0)))
19750               (set (match_dup 2)
19751                    (minus:DI (const_int 63) (clz:DI (match_dup 1))))])
19752    (parallel [(set (match_dup 0)
19753                    (zero_extend:DI (xor:SI (match_dup 3) (const_int 63))))
19754               (clobber (reg:CC FLAGS_REG))])]
19756   operands[2] = gen_reg_rtx (DImode);
19757   operands[3] = lowpart_subreg (SImode, operands[2], DImode);
19760 (define_insn_and_split "*bsr_2"
19761   [(set (match_operand:DI 0 "register_operand")
19762         (sign_extend:DI
19763           (xor:SI
19764             (minus:SI
19765               (const_int 31)
19766               (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
19767             (const_int 31))))
19768    (clobber (reg:CC FLAGS_REG))]
19769   "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
19770   "#"
19771   "&& 1"
19772   [(parallel [(set (reg:CCZ FLAGS_REG)
19773                    (compare:CCZ (match_dup 1) (const_int 0)))
19774               (set (match_dup 2)
19775                    (minus:SI (const_int 31) (clz:SI (match_dup 1))))])
19776    (parallel [(set (match_dup 0)
19777                    (zero_extend:DI (xor:SI (match_dup 2) (const_int 31))))
19778               (clobber (reg:CC FLAGS_REG))])]
19779   "operands[2] = gen_reg_rtx (SImode);")
19781 ; Splitters to optimize 64 - __builtin_clzl (x) or 32 - __builtin_clz (x).
19782 ; Again, as for !TARGET_LZCNT CLZ is UB at zero, CLZ is guaranteed to be
19783 ; in [0, 63] or [0, 31] range.
19784 (define_split
19785   [(set (match_operand:SI 0 "register_operand")
19786         (minus:SI
19787           (match_operand:SI 2 "const_int_operand")
19788           (xor:SI
19789             (minus:SI (const_int 63)
19790                       (subreg:SI
19791                         (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
19792                         0))
19793             (const_int 63))))]
19794   "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
19795   [(set (match_dup 3)
19796         (minus:DI (const_int 63) (clz:DI (match_dup 1))))
19797    (set (match_dup 0)
19798         (plus:SI (match_dup 5) (match_dup 4)))]
19800   operands[3] = gen_reg_rtx (DImode);
19801   operands[5] = lowpart_subreg (SImode, operands[3], DImode);
19802   if (INTVAL (operands[2]) == 63)
19803     {
19804       emit_insn (gen_bsr_rex64_1_zext (operands[3], operands[1]));
19805       emit_move_insn (operands[0], operands[5]);
19806       DONE;
19807     }
19808   operands[4] = gen_int_mode (UINTVAL (operands[2]) - 63, SImode);
19811 (define_split
19812   [(set (match_operand:SI 0 "register_operand")
19813         (minus:SI
19814           (match_operand:SI 2 "const_int_operand")
19815           (xor:SI
19816             (minus:SI (const_int 31)
19817                       (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
19818             (const_int 31))))]
19819   "!TARGET_LZCNT && ix86_pre_reload_split ()"
19820   [(set (match_dup 3)
19821         (minus:SI (const_int 31) (clz:SI (match_dup 1))))
19822    (set (match_dup 0)
19823         (plus:SI (match_dup 3) (match_dup 4)))]
19825   if (INTVAL (operands[2]) == 31)
19826     {
19827       emit_insn (gen_bsr_1 (operands[0], operands[1]));
19828       DONE;
19829     }
19830   operands[3] = gen_reg_rtx (SImode);
19831   operands[4] = gen_int_mode (UINTVAL (operands[2]) - 31, SImode);
19834 (define_split
19835   [(set (match_operand:DI 0 "register_operand")
19836         (minus:DI
19837           (match_operand:DI 2 "const_int_operand")
19838           (xor:DI
19839             (sign_extend:DI
19840               (minus:SI (const_int 63)
19841                         (subreg:SI
19842                           (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
19843                           0)))
19844             (const_int 63))))]
19845   "!TARGET_LZCNT
19846    && TARGET_64BIT
19847    && ix86_pre_reload_split ()
19848    && ((unsigned HOST_WIDE_INT)
19849        trunc_int_for_mode (UINTVAL (operands[2]) - 63, SImode)
19850        == UINTVAL (operands[2]) - 63)"
19851   [(set (match_dup 3)
19852         (minus:DI (const_int 63) (clz:DI (match_dup 1))))
19853    (set (match_dup 0)
19854         (plus:DI (match_dup 3) (match_dup 4)))]
19856   if (INTVAL (operands[2]) == 63)
19857     {
19858       emit_insn (gen_bsr_rex64_1 (operands[0], operands[1]));
19859       DONE;
19860     }
19861   operands[3] = gen_reg_rtx (DImode);
19862   operands[4] = GEN_INT (UINTVAL (operands[2]) - 63);
19865 (define_split
19866   [(set (match_operand:DI 0 "register_operand")
19867         (minus:DI
19868           (match_operand:DI 2 "const_int_operand")
19869           (sign_extend:DI
19870             (xor:SI
19871               (minus:SI (const_int 31)
19872                         (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
19873               (const_int 31)))))]
19874   "!TARGET_LZCNT
19875    && TARGET_64BIT
19876    && ix86_pre_reload_split ()
19877    && ((unsigned HOST_WIDE_INT)
19878        trunc_int_for_mode (UINTVAL (operands[2]) - 31, SImode)
19879        == UINTVAL (operands[2]) - 31)"
19880   [(set (match_dup 3)
19881         (zero_extend:DI (minus:SI (const_int 31) (clz:SI (match_dup 1)))))
19882    (set (match_dup 0)
19883         (plus:DI (match_dup 3) (match_dup 4)))]
19885   if (INTVAL (operands[2]) == 31)
19886     {
19887       emit_insn (gen_bsr_zext_1 (operands[0], operands[1]));
19888       DONE;
19889     }
19890   operands[3] = gen_reg_rtx (DImode);
19891   operands[4] = GEN_INT (UINTVAL (operands[2]) - 31);
19894 (define_expand "clz<mode>2"
19895   [(parallel
19896      [(set (reg:CCZ FLAGS_REG)
19897         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19898                      (const_int 0)))
19899       (set (match_dup 3) (minus:SWI48
19900                            (match_dup 2)
19901                            (clz:SWI48 (match_dup 1))))])
19902    (parallel
19903      [(set (match_operand:SWI48 0 "register_operand")
19904            (xor:SWI48 (match_dup 3) (match_dup 2)))
19905       (clobber (reg:CC FLAGS_REG))])]
19906   ""
19908   if (TARGET_LZCNT)
19909     {
19910       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
19911       DONE;
19912     }
19913   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
19914   operands[3] = gen_reg_rtx (<MODE>mode);
19917 (define_insn_and_split "clz<mode>2_lzcnt"
19918   [(set (match_operand:SWI48 0 "register_operand" "=r")
19919         (clz:SWI48
19920           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19921    (clobber (reg:CC FLAGS_REG))]
19922   "TARGET_LZCNT"
19923   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
19924   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19925    && optimize_function_for_speed_p (cfun)
19926    && !reg_mentioned_p (operands[0], operands[1])"
19927   [(parallel
19928     [(set (match_dup 0)
19929           (clz:SWI48 (match_dup 1)))
19930      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19931      (clobber (reg:CC FLAGS_REG))])]
19932   "ix86_expand_clear (operands[0]);"
19933   [(set_attr "prefix_rep" "1")
19934    (set_attr "type" "bitmanip")
19935    (set_attr "mode" "<MODE>")])
19937 ; False dependency happens when destination is only updated by tzcnt,
19938 ; lzcnt or popcnt.  There is no false dependency when destination is
19939 ; also used in source.
19940 (define_insn "*clz<mode>2_lzcnt_falsedep"
19941   [(set (match_operand:SWI48 0 "register_operand" "=r")
19942         (clz:SWI48
19943           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19944    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
19945            UNSPEC_INSN_FALSE_DEP)
19946    (clobber (reg:CC FLAGS_REG))]
19947   "TARGET_LZCNT"
19948   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
19949   [(set_attr "prefix_rep" "1")
19950    (set_attr "type" "bitmanip")
19951    (set_attr "mode" "<MODE>")])
19953 (define_insn_and_split "*clzsi2_lzcnt_zext"
19954   [(set (match_operand:DI 0 "register_operand" "=r")
19955         (and:DI
19956           (subreg:DI
19957             (clz:SI
19958               (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19959           (const_int 63)))
19960    (clobber (reg:CC FLAGS_REG))]
19961   "TARGET_LZCNT && TARGET_64BIT"
19962   "lzcnt{l}\t{%1, %k0|%k0, %1}"
19963   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19964    && optimize_function_for_speed_p (cfun)
19965    && !reg_mentioned_p (operands[0], operands[1])"
19966   [(parallel
19967     [(set (match_dup 0)
19968           (and:DI (subreg:DI (clz:SI (match_dup 1)) 0) (const_int 63)))
19969      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19970      (clobber (reg:CC FLAGS_REG))])]
19971   "ix86_expand_clear (operands[0]);"
19972   [(set_attr "prefix_rep" "1")
19973    (set_attr "type" "bitmanip")
19974    (set_attr "mode" "SI")])
19976 ; False dependency happens when destination is only updated by tzcnt,
19977 ; lzcnt or popcnt.  There is no false dependency when destination is
19978 ; also used in source.
19979 (define_insn "*clzsi2_lzcnt_zext_falsedep"
19980   [(set (match_operand:DI 0 "register_operand" "=r")
19981         (and:DI
19982           (subreg:DI
19983             (clz:SI
19984               (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 0)
19985           (const_int 63)))
19986    (unspec [(match_operand:DI 2 "register_operand" "0")]
19987            UNSPEC_INSN_FALSE_DEP)
19988    (clobber (reg:CC FLAGS_REG))]
19989   "TARGET_LZCNT"
19990   "lzcnt{l}\t{%1, %k0|%k0, %1}"
19991   [(set_attr "prefix_rep" "1")
19992    (set_attr "type" "bitmanip")
19993    (set_attr "mode" "SI")])
19995 (define_insn_and_split "*clzsi2_lzcnt_zext_2"
19996   [(set (match_operand:DI 0 "register_operand" "=r")
19997         (zero_extend:DI
19998           (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19999    (clobber (reg:CC FLAGS_REG))]
20000   "TARGET_LZCNT && TARGET_64BIT"
20001   "lzcnt{l}\t{%1, %k0|%k0, %1}"
20002   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
20003    && optimize_function_for_speed_p (cfun)
20004    && !reg_mentioned_p (operands[0], operands[1])"
20005   [(parallel
20006     [(set (match_dup 0)
20007           (zero_extend:DI (clz:SI (match_dup 1))))
20008      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
20009      (clobber (reg:CC FLAGS_REG))])]
20010   "ix86_expand_clear (operands[0]);"
20011   [(set_attr "prefix_rep" "1")
20012    (set_attr "type" "bitmanip")
20013    (set_attr "mode" "SI")])
20015 ; False dependency happens when destination is only updated by tzcnt,
20016 ; lzcnt or popcnt.  There is no false dependency when destination is
20017 ; also used in source.
20018 (define_insn "*clzsi2_lzcnt_zext_2_falsedep"
20019   [(set (match_operand:DI 0 "register_operand" "=r")
20020         (zero_extend:DI
20021           (clz:SI (match_operand:SWI48 1 "nonimmediate_operand" "rm"))))
20022    (unspec [(match_operand:DI 2 "register_operand" "0")]
20023            UNSPEC_INSN_FALSE_DEP)
20024    (clobber (reg:CC FLAGS_REG))]
20025   "TARGET_LZCNT"
20026   "lzcnt{l}\t{%1, %k0|%k0, %1}"
20027   [(set_attr "prefix_rep" "1")
20028    (set_attr "type" "bitmanip")
20029    (set_attr "mode" "SI")])
20031 (define_int_iterator LT_ZCNT
20032         [(UNSPEC_TZCNT "TARGET_BMI")
20033          (UNSPEC_LZCNT "TARGET_LZCNT")])
20035 (define_int_attr lt_zcnt
20036         [(UNSPEC_TZCNT "tzcnt")
20037          (UNSPEC_LZCNT "lzcnt")])
20039 (define_int_attr lt_zcnt_type
20040         [(UNSPEC_TZCNT "alu1")
20041          (UNSPEC_LZCNT "bitmanip")])
20043 ;; Version of lzcnt/tzcnt that is expanded from intrinsics.  This version
20044 ;; provides operand size as output when source operand is zero. 
20046 (define_insn_and_split "<lt_zcnt>_<mode>"
20047   [(set (match_operand:SWI48 0 "register_operand" "=r")
20048         (unspec:SWI48
20049           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
20050    (clobber (reg:CC FLAGS_REG))]
20051   ""
20052   "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
20053   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
20054    && optimize_function_for_speed_p (cfun)
20055    && !reg_mentioned_p (operands[0], operands[1])"
20056   [(parallel
20057     [(set (match_dup 0)
20058           (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
20059      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
20060      (clobber (reg:CC FLAGS_REG))])]
20061   "ix86_expand_clear (operands[0]);"
20062   [(set_attr "type" "<lt_zcnt_type>")
20063    (set_attr "prefix_0f" "1")
20064    (set_attr "prefix_rep" "1")
20065    (set_attr "mode" "<MODE>")])
20067 ; False dependency happens when destination is only updated by tzcnt,
20068 ; lzcnt or popcnt.  There is no false dependency when destination is
20069 ; also used in source.
20070 (define_insn "*<lt_zcnt>_<mode>_falsedep"
20071   [(set (match_operand:SWI48 0 "register_operand" "=r")
20072         (unspec:SWI48
20073           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
20074    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
20075            UNSPEC_INSN_FALSE_DEP)
20076    (clobber (reg:CC FLAGS_REG))]
20077   ""
20078   "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
20079   [(set_attr "type" "<lt_zcnt_type>")
20080    (set_attr "prefix_0f" "1")
20081    (set_attr "prefix_rep" "1")
20082    (set_attr "mode" "<MODE>")])
20084 (define_insn "<lt_zcnt>_hi"
20085   [(set (match_operand:HI 0 "register_operand" "=r")
20086         (unspec:HI
20087           [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
20088    (clobber (reg:CC FLAGS_REG))]
20089   ""
20090   "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
20091   [(set_attr "type" "<lt_zcnt_type>")
20092    (set_attr "prefix_0f" "1")
20093    (set_attr "prefix_rep" "1")
20094    (set_attr "mode" "HI")])
20096 ;; BMI instructions.
20098 (define_insn "bmi_bextr_<mode>"
20099   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
20100         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
20101                        (match_operand:SWI48 2 "register_operand" "r,r")]
20102                       UNSPEC_BEXTR))
20103    (clobber (reg:CC FLAGS_REG))]
20104   "TARGET_BMI"
20105   "bextr\t{%2, %1, %0|%0, %1, %2}"
20106   [(set_attr "type" "bitmanip")
20107    (set_attr "btver2_decode" "direct, double")
20108    (set_attr "mode" "<MODE>")])
20110 (define_insn "*bmi_bextr_<mode>_ccz"
20111   [(set (reg:CCZ FLAGS_REG)
20112         (compare:CCZ
20113           (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
20114                          (match_operand:SWI48 2 "register_operand" "r,r")]
20115                         UNSPEC_BEXTR)
20116           (const_int 0)))
20117    (clobber (match_scratch:SWI48 0 "=r,r"))]
20118   "TARGET_BMI"
20119   "bextr\t{%2, %1, %0|%0, %1, %2}"
20120   [(set_attr "type" "bitmanip")
20121    (set_attr "btver2_decode" "direct, double")
20122    (set_attr "mode" "<MODE>")])
20124 (define_insn "*bmi_blsi_<mode>"
20125   [(set (match_operand:SWI48 0 "register_operand" "=r")
20126         (and:SWI48
20127           (neg:SWI48
20128             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
20129           (match_dup 1)))
20130    (clobber (reg:CC FLAGS_REG))]
20131   "TARGET_BMI"
20132   "blsi\t{%1, %0|%0, %1}"
20133   [(set_attr "type" "bitmanip")
20134    (set_attr "btver2_decode" "double")
20135    (set_attr "mode" "<MODE>")])
20137 (define_insn "*bmi_blsi_<mode>_cmp"
20138   [(set (reg FLAGS_REG)
20139         (compare
20140           (and:SWI48
20141             (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
20142             (match_dup 1))
20143           (const_int 0)))
20144    (set (match_operand:SWI48 0 "register_operand" "=r")
20145         (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))]
20146    "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
20147    "blsi\t{%1, %0|%0, %1}"
20148   [(set_attr "type" "bitmanip")
20149    (set_attr "btver2_decode" "double")
20150    (set_attr "mode" "<MODE>")])
20152 (define_insn "*bmi_blsi_<mode>_ccno"
20153   [(set (reg FLAGS_REG)
20154         (compare
20155           (and:SWI48
20156             (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
20157             (match_dup 1))
20158           (const_int 0)))
20159    (clobber (match_scratch:SWI48 0 "=r"))]
20160    "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
20161    "blsi\t{%1, %0|%0, %1}"
20162   [(set_attr "type" "bitmanip")
20163    (set_attr "btver2_decode" "double")
20164    (set_attr "mode" "<MODE>")])
20166 (define_insn "*bmi_blsmsk_<mode>"
20167   [(set (match_operand:SWI48 0 "register_operand" "=r")
20168         (xor:SWI48
20169           (plus:SWI48
20170             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20171             (const_int -1))
20172           (match_dup 1)))
20173    (clobber (reg:CC FLAGS_REG))]
20174   "TARGET_BMI"
20175   "blsmsk\t{%1, %0|%0, %1}"
20176   [(set_attr "type" "bitmanip")
20177    (set_attr "btver2_decode" "double")
20178    (set_attr "mode" "<MODE>")])
20180 (define_insn "*bmi_blsr_<mode>"
20181   [(set (match_operand:SWI48 0 "register_operand" "=r")
20182         (and:SWI48
20183           (plus:SWI48
20184             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20185             (const_int -1))
20186           (match_dup 1)))
20187    (clobber (reg:CC FLAGS_REG))]
20188    "TARGET_BMI"
20189    "blsr\t{%1, %0|%0, %1}"
20190   [(set_attr "type" "bitmanip")
20191    (set_attr "btver2_decode" "double")
20192    (set_attr "mode" "<MODE>")])
20194 (define_insn "*bmi_blsr_<mode>_cmp"
20195   [(set (reg:CCZ FLAGS_REG)
20196         (compare:CCZ
20197           (and:SWI48
20198             (plus:SWI48
20199               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20200               (const_int -1))
20201             (match_dup 1))
20202           (const_int 0)))
20203    (set (match_operand:SWI48 0 "register_operand" "=r")
20204         (and:SWI48
20205           (plus:SWI48
20206             (match_dup 1)
20207             (const_int -1))
20208           (match_dup 1)))]
20209    "TARGET_BMI"
20210    "blsr\t{%1, %0|%0, %1}"
20211   [(set_attr "type" "bitmanip")
20212    (set_attr "btver2_decode" "double")
20213    (set_attr "mode" "<MODE>")])
20215 (define_insn "*bmi_blsr_<mode>_ccz"
20216   [(set (reg:CCZ FLAGS_REG)
20217         (compare:CCZ
20218           (and:SWI48
20219             (plus:SWI48
20220               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20221               (const_int -1))
20222             (match_dup 1))
20223           (const_int 0)))
20224    (clobber (match_scratch:SWI48 0 "=r"))]
20225    "TARGET_BMI"
20226    "blsr\t{%1, %0|%0, %1}"
20227   [(set_attr "type" "bitmanip")
20228    (set_attr "btver2_decode" "double")
20229    (set_attr "mode" "<MODE>")])
20231 ;; BMI2 instructions.
20232 (define_expand "bmi2_bzhi_<mode>3"
20233   [(parallel
20234     [(set (match_operand:SWI48 0 "register_operand")
20235           (if_then_else:SWI48
20236             (ne:QI (match_operand:QI 2 "register_operand")
20237                    (const_int 0))
20238             (zero_extract:SWI48
20239               (match_operand:SWI48 1 "nonimmediate_operand")
20240               (umin:QI (match_dup 2) (match_dup 3))
20241               (const_int 0))
20242             (const_int 0)))
20243      (clobber (reg:CC FLAGS_REG))])]
20244   "TARGET_BMI2"
20246   operands[2] = gen_lowpart (QImode, operands[2]);
20247   operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
20250 (define_insn "*bmi2_bzhi_<mode>3"
20251   [(set (match_operand:SWI48 0 "register_operand" "=r")
20252         (if_then_else:SWI48
20253           (ne:QI (match_operand:QI 2 "register_operand" "q")
20254                  (const_int 0))
20255           (zero_extract:SWI48
20256             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20257             (umin:QI (match_dup 2)
20258                      (match_operand:QI 3 "const_int_operand"))
20259             (const_int 0))
20260           (const_int 0)))
20261    (clobber (reg:CC FLAGS_REG))]
20262   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
20263   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
20264   [(set_attr "type" "bitmanip")
20265    (set_attr "prefix" "vex")
20266    (set_attr "mode" "<MODE>")])
20268 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
20269   [(set (reg:CCZ FLAGS_REG)
20270         (compare:CCZ
20271           (if_then_else:SWI48
20272             (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
20273             (zero_extract:SWI48
20274               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20275               (umin:QI (match_dup 2)
20276                        (match_operand:QI 3 "const_int_operand"))
20277               (const_int 0))
20278             (const_int 0))
20279         (const_int 0)))
20280    (clobber (match_scratch:SWI48 0 "=r"))]
20281   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
20282   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
20283   [(set_attr "type" "bitmanip")
20284    (set_attr "prefix" "vex")
20285    (set_attr "mode" "<MODE>")])
20287 (define_insn "*bmi2_bzhi_<mode>3_2"
20288   [(set (match_operand:SWI48 0 "register_operand" "=r")
20289         (and:SWI48
20290           (plus:SWI48
20291             (ashift:SWI48 (const_int 1)
20292                           (match_operand:QI 2 "register_operand" "r"))
20293             (const_int -1))
20294           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
20295    (clobber (reg:CC FLAGS_REG))]
20296   "TARGET_BMI2"
20297   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
20298   [(set_attr "type" "bitmanip")
20299    (set_attr "prefix" "vex")
20300    (set_attr "mode" "<MODE>")])
20302 (define_insn "*bmi2_bzhi_<mode>3_3"
20303   [(set (match_operand:SWI48 0 "register_operand" "=r")
20304         (and:SWI48
20305           (not:SWI48
20306             (ashift:SWI48 (const_int -1)
20307                           (match_operand:QI 2 "register_operand" "r")))
20308           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
20309    (clobber (reg:CC FLAGS_REG))]
20310   "TARGET_BMI2"
20311   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
20312   [(set_attr "type" "bitmanip")
20313    (set_attr "prefix" "vex")
20314    (set_attr "mode" "<MODE>")])
20316 (define_insn "*bmi2_bzhi_zero_extendsidi_4"
20317   [(set (match_operand:DI 0 "register_operand" "=r")
20318         (zero_extend:DI
20319           (and:SI
20320             (plus:SI
20321               (ashift:SI (const_int 1)
20322                          (match_operand:QI 2 "register_operand" "r"))
20323               (const_int -1))
20324             (match_operand:SI 1 "nonimmediate_operand" "rm"))))
20325    (clobber (reg:CC FLAGS_REG))]
20326   "TARGET_64BIT && TARGET_BMI2"
20327   "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
20328   [(set_attr "type" "bitmanip")
20329    (set_attr "prefix" "vex")
20330    (set_attr "mode" "DI")])
20332 (define_insn "*bmi2_bzhi_zero_extendsidi_5"
20333   [(set (match_operand:DI 0 "register_operand" "=r")
20334         (and:DI
20335           (zero_extend:DI
20336             (plus:SI
20337               (ashift:SI (const_int 1)
20338                          (match_operand:QI 2 "register_operand" "r"))
20339               (const_int -1)))
20340           (match_operand:DI 1 "nonimmediate_operand" "rm")))
20341    (clobber (reg:CC FLAGS_REG))]
20342   "TARGET_64BIT && TARGET_BMI2"
20343   "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
20344   [(set_attr "type" "bitmanip")
20345    (set_attr "prefix" "vex")
20346    (set_attr "mode" "DI")])
20348 (define_insn "bmi2_pdep_<mode>3"
20349   [(set (match_operand:SWI48 0 "register_operand" "=r")
20350         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
20351                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
20352                        UNSPEC_PDEP))]
20353   "TARGET_BMI2"
20354   "pdep\t{%2, %1, %0|%0, %1, %2}"
20355   [(set_attr "type" "bitmanip")
20356    (set_attr "prefix" "vex")
20357    (set_attr "mode" "<MODE>")])
20359 (define_insn "bmi2_pext_<mode>3"
20360   [(set (match_operand:SWI48 0 "register_operand" "=r")
20361         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
20362                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
20363                        UNSPEC_PEXT))]
20364   "TARGET_BMI2"
20365   "pext\t{%2, %1, %0|%0, %1, %2}"
20366   [(set_attr "type" "bitmanip")
20367    (set_attr "prefix" "vex")
20368    (set_attr "mode" "<MODE>")])
20370 ;; TBM instructions.
20371 (define_insn "@tbm_bextri_<mode>"
20372   [(set (match_operand:SWI48 0 "register_operand" "=r")
20373         (zero_extract:SWI48
20374           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20375           (match_operand:QI 2 "const_0_to_255_operand")
20376           (match_operand:QI 3 "const_0_to_255_operand")))
20377    (clobber (reg:CC FLAGS_REG))]
20378    "TARGET_TBM"
20380   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
20381   return "bextr\t{%2, %1, %0|%0, %1, %2}";
20383   [(set_attr "type" "bitmanip")
20384    (set_attr "mode" "<MODE>")])
20386 (define_insn "*tbm_blcfill_<mode>"
20387   [(set (match_operand:SWI48 0 "register_operand" "=r")
20388         (and:SWI48
20389           (plus:SWI48
20390             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20391             (const_int 1))
20392           (match_dup 1)))
20393    (clobber (reg:CC FLAGS_REG))]
20394    "TARGET_TBM"
20395    "blcfill\t{%1, %0|%0, %1}"
20396   [(set_attr "type" "bitmanip")
20397    (set_attr "mode" "<MODE>")])
20399 (define_insn "*tbm_blci_<mode>"
20400   [(set (match_operand:SWI48 0 "register_operand" "=r")
20401         (ior:SWI48
20402           (not:SWI48
20403             (plus:SWI48
20404               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20405               (const_int 1)))
20406           (match_dup 1)))
20407    (clobber (reg:CC FLAGS_REG))]
20408    "TARGET_TBM"
20409    "blci\t{%1, %0|%0, %1}"
20410   [(set_attr "type" "bitmanip")
20411    (set_attr "mode" "<MODE>")])
20413 (define_insn "*tbm_blcic_<mode>"
20414   [(set (match_operand:SWI48 0 "register_operand" "=r")
20415         (and:SWI48
20416           (plus:SWI48
20417             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20418             (const_int 1))
20419           (not:SWI48
20420             (match_dup 1))))
20421    (clobber (reg:CC FLAGS_REG))]
20422    "TARGET_TBM"
20423    "blcic\t{%1, %0|%0, %1}"
20424   [(set_attr "type" "bitmanip")
20425    (set_attr "mode" "<MODE>")])
20427 (define_insn "*tbm_blcmsk_<mode>"
20428   [(set (match_operand:SWI48 0 "register_operand" "=r")
20429         (xor:SWI48
20430           (plus:SWI48
20431             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20432             (const_int 1))
20433           (match_dup 1)))
20434    (clobber (reg:CC FLAGS_REG))]
20435    "TARGET_TBM"
20436    "blcmsk\t{%1, %0|%0, %1}"
20437   [(set_attr "type" "bitmanip")
20438    (set_attr "mode" "<MODE>")])
20440 (define_insn "*tbm_blcs_<mode>"
20441   [(set (match_operand:SWI48 0 "register_operand" "=r")
20442         (ior:SWI48
20443           (plus:SWI48
20444             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20445             (const_int 1))
20446           (match_dup 1)))
20447    (clobber (reg:CC FLAGS_REG))]
20448    "TARGET_TBM"
20449    "blcs\t{%1, %0|%0, %1}"
20450   [(set_attr "type" "bitmanip")
20451    (set_attr "mode" "<MODE>")])
20453 (define_insn "*tbm_blsfill_<mode>"
20454   [(set (match_operand:SWI48 0 "register_operand" "=r")
20455         (ior:SWI48
20456           (plus:SWI48
20457             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20458             (const_int -1))
20459           (match_dup 1)))
20460    (clobber (reg:CC FLAGS_REG))]
20461    "TARGET_TBM"
20462    "blsfill\t{%1, %0|%0, %1}"
20463   [(set_attr "type" "bitmanip")
20464    (set_attr "mode" "<MODE>")])
20466 (define_insn "*tbm_blsic_<mode>"
20467   [(set (match_operand:SWI48 0 "register_operand" "=r")
20468         (ior:SWI48
20469           (plus:SWI48
20470             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20471             (const_int -1))
20472           (not:SWI48
20473             (match_dup 1))))
20474    (clobber (reg:CC FLAGS_REG))]
20475    "TARGET_TBM"
20476    "blsic\t{%1, %0|%0, %1}"
20477   [(set_attr "type" "bitmanip")
20478    (set_attr "mode" "<MODE>")])
20480 (define_insn "*tbm_t1mskc_<mode>"
20481   [(set (match_operand:SWI48 0 "register_operand" "=r")
20482         (ior:SWI48
20483           (plus:SWI48
20484             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20485             (const_int 1))
20486           (not:SWI48
20487             (match_dup 1))))
20488    (clobber (reg:CC FLAGS_REG))]
20489    "TARGET_TBM"
20490    "t1mskc\t{%1, %0|%0, %1}"
20491   [(set_attr "type" "bitmanip")
20492    (set_attr "mode" "<MODE>")])
20494 (define_insn "*tbm_tzmsk_<mode>"
20495   [(set (match_operand:SWI48 0 "register_operand" "=r")
20496         (and:SWI48
20497           (plus:SWI48
20498             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20499             (const_int -1))
20500           (not:SWI48
20501             (match_dup 1))))
20502    (clobber (reg:CC FLAGS_REG))]
20503    "TARGET_TBM"
20504    "tzmsk\t{%1, %0|%0, %1}"
20505   [(set_attr "type" "bitmanip")
20506    (set_attr "mode" "<MODE>")])
20508 (define_insn_and_split "popcount<mode>2"
20509   [(set (match_operand:SWI48 0 "register_operand" "=r")
20510         (popcount:SWI48
20511           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
20512    (clobber (reg:CC FLAGS_REG))]
20513   "TARGET_POPCNT"
20515 #if TARGET_MACHO
20516   return "popcnt\t{%1, %0|%0, %1}";
20517 #else
20518   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
20519 #endif
20521   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
20522    && optimize_function_for_speed_p (cfun)
20523    && !reg_mentioned_p (operands[0], operands[1])"
20524   [(parallel
20525     [(set (match_dup 0)
20526           (popcount:SWI48 (match_dup 1)))
20527      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
20528      (clobber (reg:CC FLAGS_REG))])]
20529   "ix86_expand_clear (operands[0]);"
20530   [(set_attr "prefix_rep" "1")
20531    (set_attr "type" "bitmanip")
20532    (set_attr "mode" "<MODE>")])
20534 ; False dependency happens when destination is only updated by tzcnt,
20535 ; lzcnt or popcnt.  There is no false dependency when destination is
20536 ; also used in source.
20537 (define_insn "*popcount<mode>2_falsedep"
20538   [(set (match_operand:SWI48 0 "register_operand" "=r")
20539         (popcount:SWI48
20540           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
20541    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
20542            UNSPEC_INSN_FALSE_DEP)
20543    (clobber (reg:CC FLAGS_REG))]
20544   "TARGET_POPCNT"
20546 #if TARGET_MACHO
20547   return "popcnt\t{%1, %0|%0, %1}";
20548 #else
20549   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
20550 #endif
20552   [(set_attr "prefix_rep" "1")
20553    (set_attr "type" "bitmanip")
20554    (set_attr "mode" "<MODE>")])
20556 (define_insn_and_split "*popcountsi2_zext"
20557   [(set (match_operand:DI 0 "register_operand" "=r")
20558         (and:DI
20559           (subreg:DI
20560             (popcount:SI
20561               (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
20562           (const_int 63)))
20563    (clobber (reg:CC FLAGS_REG))]
20564   "TARGET_POPCNT && TARGET_64BIT"
20566 #if TARGET_MACHO
20567   return "popcnt\t{%1, %k0|%k0, %1}";
20568 #else
20569   return "popcnt{l}\t{%1, %k0|%k0, %1}";
20570 #endif
20572   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
20573    && optimize_function_for_speed_p (cfun)
20574    && !reg_mentioned_p (operands[0], operands[1])"
20575   [(parallel
20576     [(set (match_dup 0)
20577           (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63)))
20578      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
20579      (clobber (reg:CC FLAGS_REG))])]
20580   "ix86_expand_clear (operands[0]);"
20581   [(set_attr "prefix_rep" "1")
20582    (set_attr "type" "bitmanip")
20583    (set_attr "mode" "SI")])
20585 ; False dependency happens when destination is only updated by tzcnt,
20586 ; lzcnt or popcnt.  There is no false dependency when destination is
20587 ; also used in source.
20588 (define_insn "*popcountsi2_zext_falsedep"
20589   [(set (match_operand:DI 0 "register_operand" "=r")
20590         (and:DI
20591           (subreg:DI
20592             (popcount:SI
20593               (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
20594           (const_int 63)))
20595    (unspec [(match_operand:DI 2 "register_operand" "0")]
20596            UNSPEC_INSN_FALSE_DEP)
20597    (clobber (reg:CC FLAGS_REG))]
20598   "TARGET_POPCNT && TARGET_64BIT"
20600 #if TARGET_MACHO
20601   return "popcnt\t{%1, %k0|%k0, %1}";
20602 #else
20603   return "popcnt{l}\t{%1, %k0|%k0, %1}";
20604 #endif
20606   [(set_attr "prefix_rep" "1")
20607    (set_attr "type" "bitmanip")
20608    (set_attr "mode" "SI")])
20610 (define_insn_and_split "*popcountsi2_zext_2"
20611   [(set (match_operand:DI 0 "register_operand" "=r")
20612         (zero_extend:DI
20613           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
20614    (clobber (reg:CC FLAGS_REG))]
20615   "TARGET_POPCNT && TARGET_64BIT"
20617 #if TARGET_MACHO
20618   return "popcnt\t{%1, %k0|%k0, %1}";
20619 #else
20620   return "popcnt{l}\t{%1, %k0|%k0, %1}";
20621 #endif
20623   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
20624    && optimize_function_for_speed_p (cfun)
20625    && !reg_mentioned_p (operands[0], operands[1])"
20626   [(parallel
20627     [(set (match_dup 0)
20628           (zero_extend:DI (popcount:SI (match_dup 1))))
20629      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
20630      (clobber (reg:CC FLAGS_REG))])]
20631   "ix86_expand_clear (operands[0]);"
20632   [(set_attr "prefix_rep" "1")
20633    (set_attr "type" "bitmanip")
20634    (set_attr "mode" "SI")])
20636 ; False dependency happens when destination is only updated by tzcnt,
20637 ; lzcnt or popcnt.  There is no false dependency when destination is
20638 ; also used in source.
20639 (define_insn "*popcountsi2_zext_2_falsedep"
20640   [(set (match_operand:DI 0 "register_operand" "=r")
20641         (zero_extend:DI
20642           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
20643    (unspec [(match_operand:DI 2 "register_operand" "0")]
20644            UNSPEC_INSN_FALSE_DEP)
20645    (clobber (reg:CC FLAGS_REG))]
20646   "TARGET_POPCNT && TARGET_64BIT"
20648 #if TARGET_MACHO
20649   return "popcnt\t{%1, %k0|%k0, %1}";
20650 #else
20651   return "popcnt{l}\t{%1, %k0|%k0, %1}";
20652 #endif
20654   [(set_attr "prefix_rep" "1")
20655    (set_attr "type" "bitmanip")
20656    (set_attr "mode" "SI")])
20658 (define_insn_and_split "*popcounthi2_1"
20659   [(set (match_operand:SI 0 "register_operand")
20660         (popcount:SI
20661           (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
20662    (clobber (reg:CC FLAGS_REG))]
20663   "TARGET_POPCNT
20664    && ix86_pre_reload_split ()"
20665   "#"
20666   "&& 1"
20667   [(const_int 0)]
20669   rtx tmp = gen_reg_rtx (HImode);
20671   emit_insn (gen_popcounthi2 (tmp, operands[1]));
20672   emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
20673   DONE;
20676 (define_insn_and_split "*popcounthi2_2"
20677   [(set (match_operand:SI 0 "register_operand")
20678         (zero_extend:SI
20679           (popcount:HI (match_operand:HI 1 "nonimmediate_operand"))))
20680    (clobber (reg:CC FLAGS_REG))]
20681   "TARGET_POPCNT
20682    && ix86_pre_reload_split ()"
20683   "#"
20684   "&& 1"
20685   [(const_int 0)]
20687   rtx tmp = gen_reg_rtx (HImode);
20689   emit_insn (gen_popcounthi2 (tmp, operands[1]));
20690   emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
20691   DONE;
20694 (define_insn "popcounthi2"
20695   [(set (match_operand:HI 0 "register_operand" "=r")
20696         (popcount:HI
20697           (match_operand:HI 1 "nonimmediate_operand" "rm")))
20698    (clobber (reg:CC FLAGS_REG))]
20699   "TARGET_POPCNT"
20701 #if TARGET_MACHO
20702   return "popcnt\t{%1, %0|%0, %1}";
20703 #else
20704   return "popcnt{w}\t{%1, %0|%0, %1}";
20705 #endif
20707   [(set_attr "prefix_rep" "1")
20708    (set_attr "type" "bitmanip")
20709    (set_attr "mode" "HI")])
20711 (define_expand "bswapdi2"
20712   [(set (match_operand:DI 0 "register_operand")
20713         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
20714   "TARGET_64BIT"
20716   if (!TARGET_MOVBE)
20717     operands[1] = force_reg (DImode, operands[1]);
20720 (define_expand "bswapsi2"
20721   [(set (match_operand:SI 0 "register_operand")
20722         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
20723   ""
20725   if (TARGET_MOVBE)
20726     ;
20727   else if (TARGET_BSWAP)
20728     operands[1] = force_reg (SImode, operands[1]);
20729   else
20730     {
20731       rtx x = operands[0];
20733       emit_move_insn (x, operands[1]);
20734       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
20735       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
20736       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
20737       DONE;
20738     }
20741 (define_insn "*bswap<mode>2_movbe"
20742   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
20743         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
20744   "TARGET_MOVBE
20745    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
20746   "@
20747     bswap\t%0
20748     movbe{<imodesuffix>}\t{%1, %0|%0, %1}
20749     movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
20750   [(set_attr "type" "bitmanip,imov,imov")
20751    (set_attr "modrm" "0,1,1")
20752    (set_attr "prefix_0f" "*,1,1")
20753    (set_attr "prefix_extra" "*,1,1")
20754    (set_attr "mode" "<MODE>")])
20756 (define_insn "*bswap<mode>2"
20757   [(set (match_operand:SWI48 0 "register_operand" "=r")
20758         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
20759   "TARGET_BSWAP"
20760   "bswap\t%0"
20761   [(set_attr "type" "bitmanip")
20762    (set_attr "modrm" "0")
20763    (set_attr "mode" "<MODE>")])
20765 (define_expand "bswaphi2"
20766   [(set (match_operand:HI 0 "register_operand")
20767         (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
20768   "TARGET_MOVBE")
20770 (define_insn "*bswaphi2_movbe"
20771   [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
20772         (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
20773   "TARGET_MOVBE
20774    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
20775   "@
20776     xchg{b}\t{%h0, %b0|%b0, %h0}
20777     movbe{w}\t{%1, %0|%0, %1}
20778     movbe{w}\t{%1, %0|%0, %1}"
20779   [(set_attr "type" "imov")
20780    (set_attr "modrm" "*,1,1")
20781    (set_attr "prefix_0f" "*,1,1")
20782    (set_attr "prefix_extra" "*,1,1")
20783    (set_attr "pent_pair" "np,*,*")
20784    (set_attr "athlon_decode" "vector,*,*")
20785    (set_attr "amdfam10_decode" "double,*,*")
20786    (set_attr "bdver1_decode" "double,*,*")
20787    (set_attr "mode" "QI,HI,HI")])
20789 (define_peephole2
20790   [(set (match_operand:HI 0 "general_reg_operand")
20791         (bswap:HI (match_dup 0)))]
20792   "TARGET_MOVBE
20793    && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
20794    && peep2_regno_dead_p (0, FLAGS_REG)"
20795   [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
20796               (clobber (reg:CC FLAGS_REG))])])
20798 (define_insn "bswaphi_lowpart"
20799   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
20800         (bswap:HI (match_dup 0)))
20801    (clobber (reg:CC FLAGS_REG))]
20802   ""
20803   "@
20804     xchg{b}\t{%h0, %b0|%b0, %h0}
20805     rol{w}\t{$8, %0|%0, 8}"
20806   [(set (attr "preferred_for_size")
20807      (cond [(eq_attr "alternative" "0")
20808               (symbol_ref "true")]
20809            (symbol_ref "false")))
20810    (set (attr "preferred_for_speed")
20811      (cond [(eq_attr "alternative" "0")
20812               (symbol_ref "TARGET_USE_XCHGB")]
20813            (symbol_ref "!TARGET_USE_XCHGB")))
20814    (set_attr "length" "2,4")
20815    (set_attr "mode" "QI,HI")])
20817 (define_expand "paritydi2"
20818   [(set (match_operand:DI 0 "register_operand")
20819         (parity:DI (match_operand:DI 1 "register_operand")))]
20820   "! TARGET_POPCNT"
20822   rtx scratch = gen_reg_rtx (QImode);
20823   rtx hipart1 = gen_reg_rtx (SImode);
20824   rtx lopart1 = gen_reg_rtx (SImode);
20825   rtx xor1 = gen_reg_rtx (SImode);
20826   rtx shift2 = gen_reg_rtx (SImode);
20827   rtx hipart2 = gen_reg_rtx (HImode);
20828   rtx lopart2 = gen_reg_rtx (HImode);
20829   rtx xor2 = gen_reg_rtx (HImode);
20831   if (TARGET_64BIT)
20832     {
20833       rtx shift1 = gen_reg_rtx (DImode);
20834       emit_insn (gen_lshrdi3 (shift1, operands[1], GEN_INT (32)));
20835       emit_move_insn (hipart1, gen_lowpart (SImode, shift1));
20836     }
20837   else
20838     emit_move_insn (hipart1, gen_highpart (SImode, operands[1]));
20840   emit_move_insn (lopart1, gen_lowpart (SImode, operands[1]));
20841   emit_insn (gen_xorsi3 (xor1, hipart1, lopart1));
20843   emit_insn (gen_lshrsi3 (shift2, xor1, GEN_INT (16)));
20844   emit_move_insn (hipart2, gen_lowpart (HImode, shift2));
20845   emit_move_insn (lopart2, gen_lowpart (HImode, xor1));
20846   emit_insn (gen_xorhi3 (xor2, hipart2, lopart2));
20848   emit_insn (gen_parityhi2_cmp (xor2));
20850   ix86_expand_setcc (scratch, ORDERED,
20851                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
20853   if (TARGET_64BIT)
20854     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
20855   else
20856     {
20857       rtx tmp = gen_reg_rtx (SImode);
20859       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
20860       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
20861     }
20862   DONE;
20865 (define_expand "paritysi2"
20866   [(set (match_operand:SI 0 "register_operand")
20867         (parity:SI (match_operand:SI 1 "register_operand")))]
20868   "! TARGET_POPCNT"
20870   rtx scratch = gen_reg_rtx (QImode);
20871   rtx shift = gen_reg_rtx (SImode);
20872   rtx hipart = gen_reg_rtx (HImode);
20873   rtx lopart = gen_reg_rtx (HImode);
20874   rtx tmp = gen_reg_rtx (HImode);
20876   emit_insn (gen_lshrsi3 (shift, operands[1], GEN_INT (16)));
20877   emit_move_insn (hipart, gen_lowpart (HImode, shift));
20878   emit_move_insn (lopart, gen_lowpart (HImode, operands[1]));
20879   emit_insn (gen_xorhi3 (tmp, hipart, lopart));
20881   emit_insn (gen_parityhi2_cmp (tmp));
20883   ix86_expand_setcc (scratch, ORDERED,
20884                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
20886   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
20887   DONE;
20890 (define_expand "parityhi2"
20891   [(set (match_operand:HI 0 "register_operand")
20892         (parity:HI (match_operand:HI 1 "register_operand")))]
20893   "! TARGET_POPCNT"
20895   rtx scratch = gen_reg_rtx (QImode);
20896   rtx tmp = gen_reg_rtx (HImode);
20898   emit_move_insn (tmp, operands[1]);
20899   emit_insn (gen_parityhi2_cmp (tmp));
20901   ix86_expand_setcc (scratch, ORDERED,
20902                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
20904   emit_insn (gen_zero_extendqihi2 (operands[0], scratch));
20905   DONE;
20908 (define_expand "parityqi2"
20909   [(set (match_operand:QI 0 "register_operand")
20910         (parity:QI (match_operand:QI 1 "register_operand")))]
20911   "! TARGET_POPCNT"
20913   emit_insn (gen_parityqi2_cmp (operands[1]));
20915   ix86_expand_setcc (operands[0], ORDERED,
20916                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
20917   DONE;
20920 (define_insn "parityhi2_cmp"
20921   [(set (reg:CC FLAGS_REG)
20922         (unspec:CC [(match_operand:HI 0 "register_operand" "+Q")]
20923                    UNSPEC_PARITY))
20924    (clobber (match_dup 0))]
20925   ""
20926   "xor{b}\t{%h0, %b0|%b0, %h0}"
20927   [(set_attr "length" "2")
20928    (set_attr "mode" "QI")])
20930 (define_insn "parityqi2_cmp"
20931   [(set (reg:CC FLAGS_REG)
20932         (unspec:CC [(match_operand:QI 0 "register_operand" "q")]
20933                    UNSPEC_PARITY))]
20934   ""
20935   "test{b}\t%0, %0"
20936   [(set_attr "mode" "QI")])
20938 ;; Replace zero_extend:HI followed by parityhi2_cmp with parityqi2_cmp
20939 (define_peephole2
20940   [(set (match_operand:HI 0 "register_operand")
20941         (zero_extend:HI (match_operand:QI 1 "general_reg_operand")))
20942    (parallel [(set (reg:CC FLAGS_REG)
20943                    (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
20944               (clobber (match_dup 0))])]
20945   ""
20946   [(set (reg:CC FLAGS_REG)
20947         (unspec:CC [(match_dup 1)] UNSPEC_PARITY))])
20949 ;; Eliminate QImode popcount&1 using parity flag
20950 (define_peephole2
20951   [(set (match_operand:SI 0 "register_operand")
20952         (zero_extend:SI (match_operand:QI 1 "general_reg_operand")))
20953    (parallel [(set (match_operand:SI 2 "register_operand")
20954                    (popcount:SI (match_dup 0)))
20955               (clobber (reg:CC FLAGS_REG))])
20956    (set (reg:CCZ FLAGS_REG)
20957         (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
20958                              (const_int 1))
20959                      (const_int 0)))
20960    (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
20961                             [(reg:CCZ FLAGS_REG)
20962                              (const_int 0)])
20963                            (label_ref (match_operand 5))
20964                            (pc)))]
20965   "REGNO (operands[2]) == REGNO (operands[3])
20966    && peep2_reg_dead_p (3, operands[0])
20967    && peep2_reg_dead_p (3, operands[2])
20968    && peep2_regno_dead_p (4, FLAGS_REG)"
20969   [(set (reg:CC FLAGS_REG)
20970         (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
20971    (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
20972                                             (const_int 0)])
20973                            (label_ref (match_dup 5))
20974                            (pc)))]
20976   operands[4] = shallow_copy_rtx (operands[4]);
20977   PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
20980 ;; Eliminate HImode popcount&1 using parity flag
20981 (define_peephole2
20982   [(match_scratch:HI 0 "Q")
20983    (parallel [(set (match_operand:HI 1 "register_operand")
20984                    (popcount:HI
20985                     (match_operand:HI 2 "nonimmediate_operand")))
20986               (clobber (reg:CC FLAGS_REG))])
20987    (set (match_operand 3 "register_operand")
20988         (zero_extend (match_dup 1)))
20989    (set (reg:CCZ FLAGS_REG)
20990         (compare:CCZ (and:QI (match_operand:QI 4 "register_operand")
20991                              (const_int 1))
20992                      (const_int 0)))
20993    (set (pc) (if_then_else (match_operator 5 "bt_comparison_operator"
20994                             [(reg:CCZ FLAGS_REG)
20995                              (const_int 0)])
20996                            (label_ref (match_operand 6))
20997                            (pc)))]
20998   "REGNO (operands[3]) == REGNO (operands[4])
20999    && peep2_reg_dead_p (3, operands[1])
21000    && peep2_reg_dead_p (3, operands[3])
21001    && peep2_regno_dead_p (4, FLAGS_REG)"
21002   [(set (match_dup 0) (match_dup 2))
21003    (parallel [(set (reg:CC FLAGS_REG)
21004                    (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
21005               (clobber (match_dup 0))])
21006    (set (pc) (if_then_else (match_op_dup 5 [(reg:CC FLAGS_REG)
21007                                             (const_int 0)])
21008                            (label_ref (match_dup 6))
21009                            (pc)))]
21011   operands[5] = shallow_copy_rtx (operands[5]);
21012   PUT_CODE (operands[5], GET_CODE (operands[5]) == EQ ? UNORDERED : ORDERED);
21015 ;; Eliminate HImode popcount&1 using parity flag (variant 2)
21016 (define_peephole2
21017   [(match_scratch:HI 0 "Q")
21018    (parallel [(set (match_operand:HI 1 "register_operand")
21019                    (popcount:HI
21020                     (match_operand:HI 2 "nonimmediate_operand")))
21021               (clobber (reg:CC FLAGS_REG))])
21022    (set (reg:CCZ FLAGS_REG)
21023         (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
21024                              (const_int 1))
21025                      (const_int 0)))
21026    (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
21027                             [(reg:CCZ FLAGS_REG)
21028                              (const_int 0)])
21029                            (label_ref (match_operand 5))
21030                            (pc)))]
21031   "REGNO (operands[1]) == REGNO (operands[3])
21032    && peep2_reg_dead_p (2, operands[1])
21033    && peep2_reg_dead_p (2, operands[3])
21034    && peep2_regno_dead_p (3, FLAGS_REG)"
21035   [(set (match_dup 0) (match_dup 2))
21036    (parallel [(set (reg:CC FLAGS_REG)
21037                    (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
21038               (clobber (match_dup 0))])
21039    (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
21040                                             (const_int 0)])
21041                            (label_ref (match_dup 5))
21042                            (pc)))]
21044   operands[4] = shallow_copy_rtx (operands[4]);
21045   PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
21049 ;; Thread-local storage patterns for ELF.
21051 ;; Note that these code sequences must appear exactly as shown
21052 ;; in order to allow linker relaxation.
21054 (define_insn "*tls_global_dynamic_32_gnu"
21055   [(set (match_operand:SI 0 "register_operand" "=a")
21056         (unspec:SI
21057          [(match_operand:SI 1 "register_operand" "Yb")
21058           (match_operand 2 "tls_symbolic_operand")
21059           (match_operand 3 "constant_call_address_operand" "Bz")
21060           (reg:SI SP_REG)]
21061          UNSPEC_TLS_GD))
21062    (clobber (match_scratch:SI 4 "=d"))
21063    (clobber (match_scratch:SI 5 "=c"))
21064    (clobber (reg:CC FLAGS_REG))]
21065   "!TARGET_64BIT && TARGET_GNU_TLS"
21067   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
21068     output_asm_insn
21069       ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
21070   else
21071     output_asm_insn
21072       ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
21073   if (TARGET_SUN_TLS)
21074 #ifdef HAVE_AS_IX86_TLSGDPLT
21075     return "call\t%a2@tlsgdplt";
21076 #else
21077     return "call\t%p3@plt";
21078 #endif
21079   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
21080     return "call\t%P3";
21081   return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
21083   [(set_attr "type" "multi")
21084    (set_attr "length" "12")])
21086 (define_expand "tls_global_dynamic_32"
21087   [(parallel
21088     [(set (match_operand:SI 0 "register_operand")
21089           (unspec:SI [(match_operand:SI 2 "register_operand")
21090                       (match_operand 1 "tls_symbolic_operand")
21091                       (match_operand 3 "constant_call_address_operand")
21092                       (reg:SI SP_REG)]
21093                      UNSPEC_TLS_GD))
21094      (clobber (scratch:SI))
21095      (clobber (scratch:SI))
21096      (clobber (reg:CC FLAGS_REG))])]
21097   ""
21098   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
21100 (define_insn "*tls_global_dynamic_64_<mode>"
21101   [(set (match_operand:P 0 "register_operand" "=a")
21102         (call:P
21103          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
21104          (match_operand 3)))
21105    (unspec:P [(match_operand 1 "tls_symbolic_operand")
21106               (reg:P SP_REG)]
21107              UNSPEC_TLS_GD)]
21108   "TARGET_64BIT"
21110   if (!TARGET_X32)
21111     /* The .loc directive has effect for 'the immediately following assembly
21112        instruction'.  So for a sequence:
21113          .loc f l
21114          .byte x
21115          insn1
21116        the 'immediately following assembly instruction' is insn1.
21117        We want to emit an insn prefix here, but if we use .byte (as shown in
21118        'ELF Handling For Thread-Local Storage'), a preceding .loc will point
21119        inside the insn sequence, rather than to the start.  After relaxation
21120        of the sequence by the linker, the .loc might point inside an insn.
21121        Use data16 prefix instead, which doesn't have this problem.  */
21122     fputs ("\tdata16", asm_out_file);
21123   output_asm_insn
21124     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
21125   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
21126     fputs (ASM_SHORT "0x6666\n", asm_out_file);
21127   else
21128     fputs (ASM_BYTE "0x66\n", asm_out_file);
21129   fputs ("\trex64\n", asm_out_file);
21130   if (TARGET_SUN_TLS)
21131     return "call\t%p2@plt";
21132   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
21133     return "call\t%P2";
21134   return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
21136   [(set_attr "type" "multi")
21137    (set (attr "length")
21138         (symbol_ref "TARGET_X32 ? 15 : 16"))])
21140 (define_insn "*tls_global_dynamic_64_largepic"
21141   [(set (match_operand:DI 0 "register_operand" "=a")
21142         (call:DI
21143          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
21144                           (match_operand:DI 3 "immediate_operand" "i")))
21145          (match_operand 4)))
21146    (unspec:DI [(match_operand 1 "tls_symbolic_operand")
21147                (reg:DI SP_REG)]
21148               UNSPEC_TLS_GD)]
21149   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
21150    && GET_CODE (operands[3]) == CONST
21151    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
21152    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
21154   output_asm_insn
21155     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
21156   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
21157   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
21158   return "call\t{*%%rax|rax}";
21160   [(set_attr "type" "multi")
21161    (set_attr "length" "22")])
21163 (define_expand "@tls_global_dynamic_64_<mode>"
21164   [(parallel
21165     [(set (match_operand:P 0 "register_operand")
21166           (call:P
21167            (mem:QI (match_operand 2))
21168            (const_int 0)))
21169      (unspec:P [(match_operand 1 "tls_symbolic_operand")
21170                 (reg:P SP_REG)]
21171                UNSPEC_TLS_GD)])]
21172   "TARGET_64BIT"
21173   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
21175 (define_insn "*tls_local_dynamic_base_32_gnu"
21176   [(set (match_operand:SI 0 "register_operand" "=a")
21177         (unspec:SI
21178          [(match_operand:SI 1 "register_operand" "Yb")
21179           (match_operand 2 "constant_call_address_operand" "Bz")
21180           (reg:SI SP_REG)]
21181          UNSPEC_TLS_LD_BASE))
21182    (clobber (match_scratch:SI 3 "=d"))
21183    (clobber (match_scratch:SI 4 "=c"))
21184    (clobber (reg:CC FLAGS_REG))]
21185   "!TARGET_64BIT && TARGET_GNU_TLS"
21187   output_asm_insn
21188     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
21189   if (TARGET_SUN_TLS)
21190     {
21191       if (HAVE_AS_IX86_TLSLDMPLT)
21192         return "call\t%&@tlsldmplt";
21193       else
21194         return "call\t%p2@plt";
21195     }
21196   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
21197     return "call\t%P2";
21198   return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
21200   [(set_attr "type" "multi")
21201    (set_attr "length" "11")])
21203 (define_expand "tls_local_dynamic_base_32"
21204   [(parallel
21205      [(set (match_operand:SI 0 "register_operand")
21206            (unspec:SI
21207             [(match_operand:SI 1 "register_operand")
21208              (match_operand 2 "constant_call_address_operand")
21209              (reg:SI SP_REG)]
21210             UNSPEC_TLS_LD_BASE))
21211       (clobber (scratch:SI))
21212       (clobber (scratch:SI))
21213       (clobber (reg:CC FLAGS_REG))])]
21214   ""
21215   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
21217 (define_insn "*tls_local_dynamic_base_64_<mode>"
21218   [(set (match_operand:P 0 "register_operand" "=a")
21219         (call:P
21220          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
21221          (match_operand 2)))
21222    (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
21223   "TARGET_64BIT"
21225   output_asm_insn
21226     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
21227   if (TARGET_SUN_TLS)
21228     return "call\t%p1@plt";
21229   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
21230     return "call\t%P1";
21231   return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
21233   [(set_attr "type" "multi")
21234    (set_attr "length" "12")])
21236 (define_insn "*tls_local_dynamic_base_64_largepic"
21237   [(set (match_operand:DI 0 "register_operand" "=a")
21238         (call:DI
21239          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
21240                           (match_operand:DI 2 "immediate_operand" "i")))
21241          (match_operand 3)))
21242    (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
21243   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
21244    && GET_CODE (operands[2]) == CONST
21245    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
21246    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
21248   output_asm_insn
21249     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
21250   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
21251   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
21252   return "call\t{*%%rax|rax}";
21254   [(set_attr "type" "multi")
21255    (set_attr "length" "22")])
21257 (define_expand "@tls_local_dynamic_base_64_<mode>"
21258   [(parallel
21259      [(set (match_operand:P 0 "register_operand")
21260            (call:P
21261             (mem:QI (match_operand 1))
21262             (const_int 0)))
21263       (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
21264   "TARGET_64BIT"
21265   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
21267 ;; Local dynamic of a single variable is a lose.  Show combine how
21268 ;; to convert that back to global dynamic.
21270 (define_insn_and_split "*tls_local_dynamic_32_once"
21271   [(set (match_operand:SI 0 "register_operand" "=a")
21272         (plus:SI
21273          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
21274                      (match_operand 2 "constant_call_address_operand" "Bz")
21275                      (reg:SI SP_REG)]
21276                     UNSPEC_TLS_LD_BASE)
21277          (const:SI (unspec:SI
21278                     [(match_operand 3 "tls_symbolic_operand")]
21279                     UNSPEC_DTPOFF))))
21280    (clobber (match_scratch:SI 4 "=d"))
21281    (clobber (match_scratch:SI 5 "=c"))
21282    (clobber (reg:CC FLAGS_REG))]
21283   ""
21284   "#"
21285   ""
21286   [(parallel
21287      [(set (match_dup 0)
21288            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
21289                        (reg:SI SP_REG)]
21290                       UNSPEC_TLS_GD))
21291       (clobber (match_dup 4))
21292       (clobber (match_dup 5))
21293       (clobber (reg:CC FLAGS_REG))])])
21295 ;; Load and add the thread base pointer from %<tp_seg>:0.
21296 (define_expand "get_thread_pointer<mode>"
21297   [(set (match_operand:PTR 0 "register_operand")
21298         (unspec:PTR [(const_int 0)] UNSPEC_TP))]
21299   ""
21301   /* targetm is not visible in the scope of the condition.  */
21302   if (!targetm.have_tls)
21303     error ("%<__builtin_thread_pointer%> is not supported on this target");
21306 (define_insn_and_split "*load_tp_<mode>"
21307   [(set (match_operand:PTR 0 "register_operand" "=r")
21308         (unspec:PTR [(const_int 0)] UNSPEC_TP))]
21309   ""
21310   "#"
21311   ""
21312   [(set (match_dup 0)
21313         (match_dup 1))]
21315   addr_space_t as = DEFAULT_TLS_SEG_REG;
21317   operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
21318   set_mem_addr_space (operands[1], as);
21321 (define_insn_and_split "*load_tp_x32_zext"
21322   [(set (match_operand:DI 0 "register_operand" "=r")
21323         (zero_extend:DI
21324           (unspec:SI [(const_int 0)] UNSPEC_TP)))]
21325   "TARGET_X32"
21326   "#"
21327   "&& 1"
21328   [(set (match_dup 0)
21329         (zero_extend:DI (match_dup 1)))]
21331   addr_space_t as = DEFAULT_TLS_SEG_REG;
21333   operands[1] = gen_const_mem (SImode, const0_rtx);
21334   set_mem_addr_space (operands[1], as);
21337 (define_insn_and_split "*add_tp_<mode>"
21338   [(set (match_operand:PTR 0 "register_operand" "=r")
21339         (plus:PTR
21340           (unspec:PTR [(const_int 0)] UNSPEC_TP)
21341           (match_operand:PTR 1 "register_operand" "0")))
21342    (clobber (reg:CC FLAGS_REG))]
21343   ""
21344   "#"
21345   ""
21346   [(parallel
21347      [(set (match_dup 0)
21348            (plus:PTR (match_dup 1) (match_dup 2)))
21349       (clobber (reg:CC FLAGS_REG))])]
21351   addr_space_t as = DEFAULT_TLS_SEG_REG;
21353   operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
21354   set_mem_addr_space (operands[2], as);
21357 (define_insn_and_split "*add_tp_x32_zext"
21358   [(set (match_operand:DI 0 "register_operand" "=r")
21359         (zero_extend:DI
21360           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
21361                    (match_operand:SI 1 "register_operand" "0"))))
21362    (clobber (reg:CC FLAGS_REG))]
21363   "TARGET_X32"
21364   "#"
21365   "&& 1"
21366   [(parallel
21367      [(set (match_dup 0)
21368            (zero_extend:DI
21369              (plus:SI (match_dup 1) (match_dup 2))))
21370       (clobber (reg:CC FLAGS_REG))])]
21372   addr_space_t as = DEFAULT_TLS_SEG_REG;
21374   operands[2] = gen_const_mem (SImode, const0_rtx);
21375   set_mem_addr_space (operands[2], as);
21378 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
21379 ;; %rax as destination of the initial executable code sequence.
21380 (define_insn "tls_initial_exec_64_sun"
21381   [(set (match_operand:DI 0 "register_operand" "=a")
21382         (unspec:DI
21383          [(match_operand 1 "tls_symbolic_operand")]
21384          UNSPEC_TLS_IE_SUN))
21385    (clobber (reg:CC FLAGS_REG))]
21386   "TARGET_64BIT && TARGET_SUN_TLS"
21388   output_asm_insn
21389     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
21390   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
21392   [(set_attr "type" "multi")])
21394 ;; GNU2 TLS patterns can be split.
21396 (define_expand "tls_dynamic_gnu2_32"
21397   [(set (match_dup 3)
21398         (plus:SI (match_operand:SI 2 "register_operand")
21399                  (const:SI
21400                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
21401                              UNSPEC_TLSDESC))))
21402    (parallel
21403     [(set (match_operand:SI 0 "register_operand")
21404           (unspec:SI [(match_dup 1) (match_dup 3)
21405                       (match_dup 2) (reg:SI SP_REG)]
21406                       UNSPEC_TLSDESC))
21407      (clobber (reg:CC FLAGS_REG))])]
21408   "!TARGET_64BIT && TARGET_GNU2_TLS"
21410   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
21411   ix86_tls_descriptor_calls_expanded_in_cfun = true;
21414 (define_insn "*tls_dynamic_gnu2_lea_32"
21415   [(set (match_operand:SI 0 "register_operand" "=r")
21416         (plus:SI (match_operand:SI 1 "register_operand" "b")
21417                  (const:SI
21418                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
21419                               UNSPEC_TLSDESC))))]
21420   "!TARGET_64BIT && TARGET_GNU2_TLS"
21421   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
21422   [(set_attr "type" "lea")
21423    (set_attr "mode" "SI")
21424    (set_attr "length" "6")
21425    (set_attr "length_address" "4")])
21427 (define_insn "*tls_dynamic_gnu2_call_32"
21428   [(set (match_operand:SI 0 "register_operand" "=a")
21429         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
21430                     (match_operand:SI 2 "register_operand" "0")
21431                     ;; we have to make sure %ebx still points to the GOT
21432                     (match_operand:SI 3 "register_operand" "b")
21433                     (reg:SI SP_REG)]
21434                    UNSPEC_TLSDESC))
21435    (clobber (reg:CC FLAGS_REG))]
21436   "!TARGET_64BIT && TARGET_GNU2_TLS"
21437   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
21438   [(set_attr "type" "call")
21439    (set_attr "length" "2")
21440    (set_attr "length_address" "0")])
21442 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
21443   [(set (match_operand:SI 0 "register_operand" "=&a")
21444         (plus:SI
21445          (unspec:SI [(match_operand 3 "tls_modbase_operand")
21446                      (match_operand:SI 4)
21447                      (match_operand:SI 2 "register_operand" "b")
21448                      (reg:SI SP_REG)]
21449                     UNSPEC_TLSDESC)
21450          (const:SI (unspec:SI
21451                     [(match_operand 1 "tls_symbolic_operand")]
21452                     UNSPEC_DTPOFF))))
21453    (clobber (reg:CC FLAGS_REG))]
21454   "!TARGET_64BIT && TARGET_GNU2_TLS"
21455   "#"
21456   "&& 1"
21457   [(set (match_dup 0) (match_dup 5))]
21459   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
21460   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
21463 (define_expand "@tls_dynamic_gnu2_64_<mode>"
21464   [(set (match_dup 2)
21465         (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
21466                     UNSPEC_TLSDESC))
21467    (parallel
21468     [(set (match_operand:PTR 0 "register_operand")
21469           (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)]
21470                       UNSPEC_TLSDESC))
21471      (clobber (reg:CC FLAGS_REG))])]
21472   "TARGET_64BIT && TARGET_GNU2_TLS"
21474   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
21475   ix86_tls_descriptor_calls_expanded_in_cfun = true;
21478 (define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
21479   [(set (match_operand:PTR 0 "register_operand" "=r")
21480         (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
21481                     UNSPEC_TLSDESC))]
21482   "TARGET_64BIT && TARGET_GNU2_TLS"
21483   "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
21484   [(set_attr "type" "lea")
21485    (set_attr "mode" "<MODE>")
21486    (set_attr "length" "7")
21487    (set_attr "length_address" "4")])
21489 (define_insn "*tls_dynamic_gnu2_call_64_<mode>"
21490   [(set (match_operand:PTR 0 "register_operand" "=a")
21491         (unspec:PTR [(match_operand 1 "tls_symbolic_operand")
21492                    (match_operand:PTR 2 "register_operand" "0")
21493                    (reg:PTR SP_REG)]
21494                   UNSPEC_TLSDESC))
21495    (clobber (reg:CC FLAGS_REG))]
21496   "TARGET_64BIT && TARGET_GNU2_TLS"
21497   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
21498   [(set_attr "type" "call")
21499    (set_attr "length" "2")
21500    (set_attr "length_address" "0")])
21502 (define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
21503   [(set (match_operand:PTR 0 "register_operand" "=&a")
21504         (plus:PTR
21505          (unspec:PTR [(match_operand 2 "tls_modbase_operand")
21506                       (match_operand:PTR 3)
21507                       (reg:PTR SP_REG)]
21508                      UNSPEC_TLSDESC)
21509          (const:PTR (unspec:PTR
21510                      [(match_operand 1 "tls_symbolic_operand")]
21511                      UNSPEC_DTPOFF))))
21512    (clobber (reg:CC FLAGS_REG))]
21513   "TARGET_64BIT && TARGET_GNU2_TLS"
21514   "#"
21515   "&& 1"
21516   [(set (match_dup 0) (match_dup 4))]
21518   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
21519   emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1]));
21522 (define_split
21523   [(match_operand 0 "tls_address_pattern")]
21524   "TARGET_TLS_DIRECT_SEG_REFS"
21525   [(match_dup 0)]
21526   "operands[0] = ix86_rewrite_tls_address (operands[0]);")
21529 ;; These patterns match the binary 387 instructions for addM3, subM3,
21530 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
21531 ;; SFmode.  The first is the normal insn, the second the same insn but
21532 ;; with one operand a conversion, and the third the same insn but with
21533 ;; the other operand a conversion.  The conversion may be SFmode or
21534 ;; SImode if the target mode DFmode, but only SImode if the target mode
21535 ;; is SFmode.
21537 ;; Gcc is slightly more smart about handling normal two address instructions
21538 ;; so use special patterns for add and mull.
21540 (define_insn "*fop_xf_comm_i387"
21541   [(set (match_operand:XF 0 "register_operand" "=f")
21542         (match_operator:XF 3 "binary_fp_operator"
21543                         [(match_operand:XF 1 "register_operand" "%0")
21544                          (match_operand:XF 2 "register_operand" "f")]))]
21545   "TARGET_80387
21546    && COMMUTATIVE_ARITH_P (operands[3])"
21547   "* return output_387_binary_op (insn, operands);"
21548   [(set (attr "type")
21549         (if_then_else (match_operand:XF 3 "mult_operator")
21550            (const_string "fmul")
21551            (const_string "fop")))
21552    (set_attr "mode" "XF")])
21554 (define_insn "*fop_<mode>_comm"
21555   [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
21556         (match_operator:MODEF 3 "binary_fp_operator"
21557           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
21558            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
21559   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21560     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
21561    && COMMUTATIVE_ARITH_P (operands[3])
21562    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
21563   "* return output_387_binary_op (insn, operands);"
21564   [(set (attr "type")
21565         (if_then_else (eq_attr "alternative" "1,2")
21566            (if_then_else (match_operand:MODEF 3 "mult_operator")
21567               (const_string "ssemul")
21568               (const_string "sseadd"))
21569            (if_then_else (match_operand:MODEF 3 "mult_operator")
21570               (const_string "fmul")
21571               (const_string "fop"))))
21572    (set_attr "isa" "*,noavx,avx")
21573    (set_attr "prefix" "orig,orig,vex")
21574    (set_attr "mode" "<MODE>")
21575    (set (attr "enabled")
21576      (if_then_else
21577        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
21578        (if_then_else
21579          (eq_attr "alternative" "0")
21580          (symbol_ref "TARGET_MIX_SSE_I387
21581                       && X87_ENABLE_ARITH (<MODE>mode)")
21582          (const_string "*"))
21583        (if_then_else
21584          (eq_attr "alternative" "0")
21585          (symbol_ref "true")
21586          (symbol_ref "false"))))])
21588 (define_insn "*<insn>hf"
21589   [(set (match_operand:HF 0 "register_operand" "=v")
21590         (plusminusmultdiv:HF
21591           (match_operand:HF 1 "nonimmediate_operand" "<comm>v")
21592           (match_operand:HF 2 "nonimmediate_operand" "vm")))]
21593   "TARGET_AVX512FP16
21594    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
21595   "v<insn>sh\t{%2, %1, %0|%0, %1, %2}"
21596   [(set_attr "prefix" "evex")
21597    (set_attr "mode" "HF")])
21599 (define_insn "*rcpsf2_sse"
21600   [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
21601         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
21602                    UNSPEC_RCP))]
21603   "TARGET_SSE && TARGET_SSE_MATH"
21604   "@
21605    %vrcpss\t{%d1, %0|%0, %d1}
21606    %vrcpss\t{%d1, %0|%0, %d1}
21607    rcpss\t{%1, %d0|%d0, %1}
21608    vrcpss\t{%1, %d0|%d0, %1}"
21609   [(set_attr "isa" "*,*,noavx,avx")
21610    (set_attr "addr" "*,*,*,gpr16")
21611    (set_attr "type" "sse")
21612    (set_attr "atom_sse_attr" "rcp")
21613    (set_attr "btver2_sse_attr" "rcp")
21614    (set_attr "prefix" "maybe_vex")
21615    (set_attr "mode" "SF")
21616    (set_attr "avx_partial_xmm_update" "false,false,true,true")
21617    (set (attr "preferred_for_speed")
21618       (cond [(match_test "TARGET_AVX")
21619                (symbol_ref "true")
21620              (eq_attr "alternative" "1,2,3")
21621                (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
21622             ]
21623             (symbol_ref "true")))])
21625 (define_insn "rcphf2"
21626   [(set (match_operand:HF 0 "register_operand" "=v,v")
21627         (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
21628                    UNSPEC_RCP))]
21629   "TARGET_AVX512FP16"
21630   "@
21631    vrcpsh\t{%d1, %0|%0, %d1}
21632    vrcpsh\t{%1, %d0|%d0, %1}"
21633   [(set_attr "type" "sse")
21634    (set_attr "prefix" "evex")
21635    (set_attr "mode" "HF")
21636    (set_attr "avx_partial_xmm_update" "false,true")])
21638 (define_insn "*fop_xf_1_i387"
21639   [(set (match_operand:XF 0 "register_operand" "=f,f")
21640         (match_operator:XF 3 "binary_fp_operator"
21641                         [(match_operand:XF 1 "register_operand" "0,f")
21642                          (match_operand:XF 2 "register_operand" "f,0")]))]
21643   "TARGET_80387
21644    && !COMMUTATIVE_ARITH_P (operands[3])"
21645   "* return output_387_binary_op (insn, operands);"
21646   [(set (attr "type")
21647         (if_then_else (match_operand:XF 3 "div_operator")
21648            (const_string "fdiv")
21649            (const_string "fop")))
21650    (set_attr "mode" "XF")])
21652 (define_insn "*fop_<mode>_1"
21653   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
21654         (match_operator:MODEF 3 "binary_fp_operator"
21655           [(match_operand:MODEF 1
21656              "x87nonimm_ssenomem_operand" "0,fm,0,v")
21657            (match_operand:MODEF 2
21658              "nonimmediate_operand"       "fm,0,xm,vm")]))]
21659   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21660     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
21661    && !COMMUTATIVE_ARITH_P (operands[3])
21662    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
21663   "* return output_387_binary_op (insn, operands);"
21664   [(set (attr "type")
21665         (if_then_else (eq_attr "alternative" "2,3")
21666            (if_then_else (match_operand:MODEF 3 "div_operator")
21667               (const_string "ssediv")
21668               (const_string "sseadd"))
21669            (if_then_else (match_operand:MODEF 3 "div_operator")
21670               (const_string "fdiv")
21671               (const_string "fop"))))
21672    (set_attr "isa" "*,*,noavx,avx")
21673    (set_attr "prefix" "orig,orig,orig,vex")
21674    (set_attr "mode" "<MODE>")
21675    (set (attr "enabled")
21676      (if_then_else
21677        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
21678        (if_then_else
21679          (eq_attr "alternative" "0,1")
21680          (symbol_ref "TARGET_MIX_SSE_I387
21681                       && X87_ENABLE_ARITH (<MODE>mode)")
21682          (const_string "*"))
21683        (if_then_else
21684          (eq_attr "alternative" "0,1")
21685          (symbol_ref "true")
21686          (symbol_ref "false"))))])
21688 (define_insn "*fop_<X87MODEF:mode>_2_i387"
21689   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
21690         (match_operator:X87MODEF 3 "binary_fp_operator"
21691           [(float:X87MODEF
21692              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
21693            (match_operand:X87MODEF 2 "register_operand" "0")]))]
21694   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
21695    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
21696    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
21697        || optimize_function_for_size_p (cfun))"
21698   "* return output_387_binary_op (insn, operands);"
21699   [(set (attr "type")
21700         (cond [(match_operand:X87MODEF 3 "mult_operator")
21701                  (const_string "fmul")
21702                (match_operand:X87MODEF 3 "div_operator")
21703                  (const_string "fdiv")
21704               ]
21705               (const_string "fop")))
21706    (set_attr "fp_int_src" "true")
21707    (set_attr "mode" "<SWI24:MODE>")])
21709 (define_insn "*fop_<X87MODEF:mode>_3_i387"
21710   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
21711         (match_operator:X87MODEF 3 "binary_fp_operator"
21712           [(match_operand:X87MODEF 1 "register_operand" "0")
21713            (float:X87MODEF
21714              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
21715   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
21716    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
21717    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
21718        || optimize_function_for_size_p (cfun))"
21719   "* return output_387_binary_op (insn, operands);"
21720   [(set (attr "type")
21721         (cond [(match_operand:X87MODEF 3 "mult_operator")
21722                  (const_string "fmul")
21723                (match_operand:X87MODEF 3 "div_operator")
21724                  (const_string "fdiv")
21725               ]
21726               (const_string "fop")))
21727    (set_attr "fp_int_src" "true")
21728    (set_attr "mode" "<SWI24:MODE>")])
21730 (define_insn "*fop_xf_4_i387"
21731   [(set (match_operand:XF 0 "register_operand" "=f,f")
21732         (match_operator:XF 3 "binary_fp_operator"
21733            [(float_extend:XF
21734               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
21735             (match_operand:XF 2 "register_operand" "0,f")]))]
21736   "TARGET_80387"
21737   "* return output_387_binary_op (insn, operands);"
21738   [(set (attr "type")
21739         (cond [(match_operand:XF 3 "mult_operator")
21740                  (const_string "fmul")
21741                (match_operand:XF 3 "div_operator")
21742                  (const_string "fdiv")
21743               ]
21744               (const_string "fop")))
21745    (set_attr "mode" "<MODE>")])
21747 (define_insn "*fop_df_4_i387"
21748   [(set (match_operand:DF 0 "register_operand" "=f,f")
21749         (match_operator:DF 3 "binary_fp_operator"
21750            [(float_extend:DF
21751              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
21752             (match_operand:DF 2 "register_operand" "0,f")]))]
21753   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
21754    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
21755   "* return output_387_binary_op (insn, operands);"
21756   [(set (attr "type")
21757         (cond [(match_operand:DF 3 "mult_operator")
21758                  (const_string "fmul")
21759                (match_operand:DF 3 "div_operator")
21760                  (const_string "fdiv")
21761               ]
21762               (const_string "fop")))
21763    (set_attr "mode" "SF")])
21765 (define_insn "*fop_xf_5_i387"
21766   [(set (match_operand:XF 0 "register_operand" "=f,f")
21767         (match_operator:XF 3 "binary_fp_operator"
21768           [(match_operand:XF 1 "register_operand" "0,f")
21769            (float_extend:XF
21770              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
21771   "TARGET_80387"
21772   "* return output_387_binary_op (insn, operands);"
21773   [(set (attr "type")
21774         (cond [(match_operand:XF 3 "mult_operator")
21775                  (const_string "fmul")
21776                (match_operand:XF 3 "div_operator")
21777                  (const_string "fdiv")
21778               ]
21779               (const_string "fop")))
21780    (set_attr "mode" "<MODE>")])
21782 (define_insn "*fop_df_5_i387"
21783   [(set (match_operand:DF 0 "register_operand" "=f,f")
21784         (match_operator:DF 3 "binary_fp_operator"
21785           [(match_operand:DF 1 "register_operand" "0,f")
21786            (float_extend:DF
21787             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
21788   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
21789    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
21790   "* return output_387_binary_op (insn, operands);"
21791   [(set (attr "type")
21792         (cond [(match_operand:DF 3 "mult_operator")
21793                  (const_string "fmul")
21794                (match_operand:DF 3 "div_operator")
21795                  (const_string "fdiv")
21796               ]
21797               (const_string "fop")))
21798    (set_attr "mode" "SF")])
21800 (define_insn "*fop_xf_6_i387"
21801   [(set (match_operand:XF 0 "register_operand" "=f,f")
21802         (match_operator:XF 3 "binary_fp_operator"
21803           [(float_extend:XF
21804              (match_operand:MODEF 1 "register_operand" "0,f"))
21805            (float_extend:XF
21806              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
21807   "TARGET_80387"
21808   "* return output_387_binary_op (insn, operands);"
21809   [(set (attr "type")
21810         (cond [(match_operand:XF 3 "mult_operator")
21811                  (const_string "fmul")
21812                (match_operand:XF 3 "div_operator")
21813                  (const_string "fdiv")
21814               ]
21815               (const_string "fop")))
21816    (set_attr "mode" "<MODE>")])
21818 (define_insn "*fop_df_6_i387"
21819   [(set (match_operand:DF 0 "register_operand" "=f,f")
21820         (match_operator:DF 3 "binary_fp_operator"
21821           [(float_extend:DF
21822             (match_operand:SF 1 "register_operand" "0,f"))
21823            (float_extend:DF
21824             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
21825   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
21826    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
21827   "* return output_387_binary_op (insn, operands);"
21828   [(set (attr "type")
21829         (cond [(match_operand:DF 3 "mult_operator")
21830                  (const_string "fmul")
21831                (match_operand:DF 3 "div_operator")
21832                  (const_string "fdiv")
21833               ]
21834               (const_string "fop")))
21835    (set_attr "mode" "SF")])
21837 ;; FPU special functions.
21839 ;; This pattern implements a no-op XFmode truncation for
21840 ;; all fancy i386 XFmode math functions.
21842 (define_insn "truncxf<mode>2_i387_noop_unspec"
21843   [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
21844         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
21845         UNSPEC_TRUNC_NOOP))]
21846   "TARGET_USE_FANCY_MATH_387"
21847   "* return output_387_reg_move (insn, operands);"
21848   [(set_attr "type" "fmov")
21849    (set_attr "mode" "<MODE>")])
21851 (define_insn "sqrtxf2"
21852   [(set (match_operand:XF 0 "register_operand" "=f")
21853         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
21854   "TARGET_USE_FANCY_MATH_387"
21855   "fsqrt"
21856   [(set_attr "type" "fpspc")
21857    (set_attr "mode" "XF")
21858    (set_attr "athlon_decode" "direct")
21859    (set_attr "amdfam10_decode" "direct")
21860    (set_attr "bdver1_decode" "direct")])
21862 (define_insn "*rsqrtsf2_sse"
21863   [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
21864         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
21865                    UNSPEC_RSQRT))]
21866   "TARGET_SSE && TARGET_SSE_MATH"
21867   "@
21868    %vrsqrtss\t{%d1, %0|%0, %d1}
21869    %vrsqrtss\t{%d1, %0|%0, %d1}
21870    rsqrtss\t{%1, %d0|%d0, %1}
21871    vrsqrtss\t{%1, %d0|%d0, %1}"
21872   [(set_attr "isa" "*,*,noavx,avx")
21873    (set_attr "addr" "*,*,*,gpr16")
21874    (set_attr "type" "sse")
21875    (set_attr "atom_sse_attr" "rcp")
21876    (set_attr "btver2_sse_attr" "rcp")
21877    (set_attr "prefix" "maybe_vex")
21878    (set_attr "mode" "SF")
21879    (set_attr "avx_partial_xmm_update" "false,false,true,true")
21880    (set (attr "preferred_for_speed")
21881       (cond [(match_test "TARGET_AVX")
21882                (symbol_ref "true")
21883              (eq_attr "alternative" "1,2,3")
21884                (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
21885             ]
21886             (symbol_ref "true")))])
21888 (define_expand "rsqrtsf2"
21889   [(set (match_operand:SF 0 "register_operand")
21890         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
21891                    UNSPEC_RSQRT))]
21892   "TARGET_SSE && TARGET_SSE_MATH"
21894   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
21895   DONE;
21898 (define_insn "rsqrthf2"
21899   [(set (match_operand:HF 0 "register_operand" "=v,v")
21900         (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
21901                    UNSPEC_RSQRT))]
21902   "TARGET_AVX512FP16"
21903   "@
21904    vrsqrtsh\t{%d1, %0|%0, %d1}
21905    vrsqrtsh\t{%1, %d0|%d0, %1}"
21906   [(set_attr "type" "sse")
21907    (set_attr "prefix" "evex")
21908    (set_attr "avx_partial_xmm_update" "false,true")
21909    (set_attr "mode" "HF")])
21911 (define_insn "sqrthf2"
21912   [(set (match_operand:HF 0 "register_operand" "=v,v")
21913         (sqrt:HF
21914           (match_operand:HF 1 "nonimmediate_operand" "v,m")))]
21915   "TARGET_AVX512FP16"
21916   "@
21917    vsqrtsh\t{%d1, %0|%0, %d1}
21918    vsqrtsh\t{%1, %d0|%d0, %1}"
21919   [(set_attr "type" "sse")
21920    (set_attr "prefix" "evex")
21921    (set_attr "avx_partial_xmm_update" "false,true")
21922    (set_attr "mode" "HF")])
21924 (define_insn "*sqrt<mode>2_sse"
21925   [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
21926         (sqrt:MODEF
21927           (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
21928   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
21929   "@
21930    %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
21931    %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
21932    %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
21933   [(set_attr "type" "sse")
21934    (set_attr "atom_sse_attr" "sqrt")
21935    (set_attr "btver2_sse_attr" "sqrt")
21936    (set_attr "prefix" "maybe_vex")
21937    (set_attr "avx_partial_xmm_update" "false,false,true")
21938    (set_attr "mode" "<MODE>")
21939    (set (attr "preferred_for_speed")
21940       (cond [(match_test "TARGET_AVX")
21941                (symbol_ref "true")
21942              (eq_attr "alternative" "1,2")
21943                (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
21944             ]
21945             (symbol_ref "true")))])
21947 (define_expand "sqrt<mode>2"
21948   [(set (match_operand:MODEF 0 "register_operand")
21949         (sqrt:MODEF
21950           (match_operand:MODEF 1 "nonimmediate_operand")))]
21951   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
21952    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
21954   if (<MODE>mode == SFmode
21955       && TARGET_SSE && TARGET_SSE_MATH
21956       && TARGET_RECIP_SQRT
21957       && !optimize_function_for_size_p (cfun)
21958       && flag_finite_math_only && !flag_trapping_math
21959       && flag_unsafe_math_optimizations)
21960     {
21961       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
21962       DONE;
21963     }
21965   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
21966     {
21967       rtx op0 = gen_reg_rtx (XFmode);
21968       rtx op1 = gen_reg_rtx (XFmode);
21970       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21971       emit_insn (gen_sqrtxf2 (op0, op1));
21972       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21973       DONE;
21974    }
21977 (define_expand "hypot<mode>3"
21978   [(use (match_operand:MODEF 0 "register_operand"))
21979    (use (match_operand:MODEF 1 "general_operand"))
21980    (use (match_operand:MODEF 2 "general_operand"))]
21981   "TARGET_USE_FANCY_MATH_387
21982    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21983        || TARGET_MIX_SSE_I387)
21984    && flag_finite_math_only
21985    && flag_unsafe_math_optimizations"
21987   rtx op0 = gen_reg_rtx (XFmode);
21988   rtx op1 = gen_reg_rtx (XFmode);
21989   rtx op2 = gen_reg_rtx (XFmode);
21991   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21992   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21994   emit_insn (gen_mulxf3 (op1, op1, op1));
21995   emit_insn (gen_mulxf3 (op2, op2, op2));
21996   emit_insn (gen_addxf3 (op0, op2, op1));
21997   emit_insn (gen_sqrtxf2 (op0, op0));
21999   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22000   DONE;
22003 (define_insn "x86_fnstsw_1"
22004   [(set (match_operand:HI 0 "register_operand" "=a")
22005         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
22006   "TARGET_80387"
22007   "fnstsw\t%0"
22008   [(set_attr "length" "2")
22009    (set_attr "mode" "SI")
22010    (set_attr "unit" "i387")])
22012 (define_insn "fpremxf4_i387"
22013   [(set (match_operand:XF 0 "register_operand" "=f")
22014         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
22015                     (match_operand:XF 3 "register_operand" "1")]
22016                    UNSPEC_FPREM_F))
22017    (set (match_operand:XF 1 "register_operand" "=f")
22018         (unspec:XF [(match_dup 2) (match_dup 3)]
22019                    UNSPEC_FPREM_U))
22020    (set (reg:CCFP FPSR_REG)
22021         (unspec:CCFP [(match_dup 2) (match_dup 3)]
22022                      UNSPEC_C2_FLAG))]
22023   "TARGET_USE_FANCY_MATH_387"
22024   "fprem"
22025   [(set_attr "type" "fpspc")
22026    (set_attr "znver1_decode" "vector")
22027    (set_attr "mode" "XF")])
22029 (define_expand "fmodxf3"
22030   [(use (match_operand:XF 0 "register_operand"))
22031    (use (match_operand:XF 1 "general_operand"))
22032    (use (match_operand:XF 2 "general_operand"))]
22033   "TARGET_USE_FANCY_MATH_387"
22035   rtx_code_label *label = gen_label_rtx ();
22037   rtx op1 = gen_reg_rtx (XFmode);
22038   rtx op2 = gen_reg_rtx (XFmode);
22040   emit_move_insn (op2, operands[2]);
22041   emit_move_insn (op1, operands[1]);
22043   emit_label (label);
22044   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
22045   ix86_emit_fp_unordered_jump (label);
22046   LABEL_NUSES (label) = 1;
22048   emit_move_insn (operands[0], op1);
22049   DONE;
22052 (define_expand "fmod<mode>3"
22053   [(use (match_operand:MODEF 0 "register_operand"))
22054    (use (match_operand:MODEF 1 "general_operand"))
22055    (use (match_operand:MODEF 2 "general_operand"))]
22056   "TARGET_USE_FANCY_MATH_387"
22058   rtx (*gen_truncxf) (rtx, rtx);
22060   rtx_code_label *label = gen_label_rtx ();
22062   rtx op1 = gen_reg_rtx (XFmode);
22063   rtx op2 = gen_reg_rtx (XFmode);
22065   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
22066   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22068   emit_label (label);
22069   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
22070   ix86_emit_fp_unordered_jump (label);
22071   LABEL_NUSES (label) = 1;
22073   /* Truncate the result properly for strict SSE math.  */
22074   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22075       && !TARGET_MIX_SSE_I387)
22076     gen_truncxf = gen_truncxf<mode>2;
22077   else
22078     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
22080   emit_insn (gen_truncxf (operands[0], op1));
22081   DONE;
22084 (define_insn "fprem1xf4_i387"
22085   [(set (match_operand:XF 0 "register_operand" "=f")
22086         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
22087                     (match_operand:XF 3 "register_operand" "1")]
22088                    UNSPEC_FPREM1_F))
22089    (set (match_operand:XF 1 "register_operand" "=f")
22090         (unspec:XF [(match_dup 2) (match_dup 3)]
22091                    UNSPEC_FPREM1_U))
22092    (set (reg:CCFP FPSR_REG)
22093         (unspec:CCFP [(match_dup 2) (match_dup 3)]
22094                      UNSPEC_C2_FLAG))]
22095   "TARGET_USE_FANCY_MATH_387"
22096   "fprem1"
22097   [(set_attr "type" "fpspc")
22098    (set_attr "znver1_decode" "vector")
22099    (set_attr "mode" "XF")])
22101 (define_expand "remainderxf3"
22102   [(use (match_operand:XF 0 "register_operand"))
22103    (use (match_operand:XF 1 "general_operand"))
22104    (use (match_operand:XF 2 "general_operand"))]
22105   "TARGET_USE_FANCY_MATH_387"
22107   rtx_code_label *label = gen_label_rtx ();
22109   rtx op1 = gen_reg_rtx (XFmode);
22110   rtx op2 = gen_reg_rtx (XFmode);
22112   emit_move_insn (op2, operands[2]);
22113   emit_move_insn (op1, operands[1]);
22115   emit_label (label);
22116   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
22117   ix86_emit_fp_unordered_jump (label);
22118   LABEL_NUSES (label) = 1;
22120   emit_move_insn (operands[0], op1);
22121   DONE;
22124 (define_expand "remainder<mode>3"
22125   [(use (match_operand:MODEF 0 "register_operand"))
22126    (use (match_operand:MODEF 1 "general_operand"))
22127    (use (match_operand:MODEF 2 "general_operand"))]
22128   "TARGET_USE_FANCY_MATH_387"
22130   rtx (*gen_truncxf) (rtx, rtx);
22132   rtx_code_label *label = gen_label_rtx ();
22134   rtx op1 = gen_reg_rtx (XFmode);
22135   rtx op2 = gen_reg_rtx (XFmode);
22137   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
22138   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22140   emit_label (label);
22142   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
22143   ix86_emit_fp_unordered_jump (label);
22144   LABEL_NUSES (label) = 1;
22146   /* Truncate the result properly for strict SSE math.  */
22147   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22148       && !TARGET_MIX_SSE_I387)
22149     gen_truncxf = gen_truncxf<mode>2;
22150   else
22151     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
22153   emit_insn (gen_truncxf (operands[0], op1));
22154   DONE;
22157 (define_int_iterator SINCOS
22158         [UNSPEC_SIN
22159          UNSPEC_COS])
22161 (define_int_attr sincos
22162         [(UNSPEC_SIN "sin")
22163          (UNSPEC_COS "cos")])
22165 (define_insn "<sincos>xf2"
22166   [(set (match_operand:XF 0 "register_operand" "=f")
22167         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
22168                    SINCOS))]
22169   "TARGET_USE_FANCY_MATH_387
22170    && flag_unsafe_math_optimizations"
22171   "f<sincos>"
22172   [(set_attr "type" "fpspc")
22173    (set_attr "znver1_decode" "vector")
22174    (set_attr "mode" "XF")])
22176 (define_expand "<sincos><mode>2"
22177   [(set (match_operand:MODEF 0 "register_operand")
22178         (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
22179                       SINCOS))]
22180   "TARGET_USE_FANCY_MATH_387
22181    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22182        || TARGET_MIX_SSE_I387)
22183    && flag_unsafe_math_optimizations"
22185   rtx op0 = gen_reg_rtx (XFmode);
22186   rtx op1 = gen_reg_rtx (XFmode);
22188   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22189   emit_insn (gen_<sincos>xf2 (op0, op1));
22190   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22191   DONE;
22194 (define_insn "sincosxf3"
22195   [(set (match_operand:XF 0 "register_operand" "=f")
22196         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
22197                    UNSPEC_SINCOS_COS))
22198    (set (match_operand:XF 1 "register_operand" "=f")
22199         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
22200   "TARGET_USE_FANCY_MATH_387
22201    && flag_unsafe_math_optimizations"
22202   "fsincos"
22203   [(set_attr "type" "fpspc")
22204    (set_attr "znver1_decode" "vector")
22205    (set_attr "mode" "XF")])
22207 (define_expand "sincos<mode>3"
22208   [(use (match_operand:MODEF 0 "register_operand"))
22209    (use (match_operand:MODEF 1 "register_operand"))
22210    (use (match_operand:MODEF 2 "general_operand"))]
22211   "TARGET_USE_FANCY_MATH_387
22212    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22213        || TARGET_MIX_SSE_I387)
22214    && flag_unsafe_math_optimizations"
22216   rtx op0 = gen_reg_rtx (XFmode);
22217   rtx op1 = gen_reg_rtx (XFmode);
22218   rtx op2 = gen_reg_rtx (XFmode);
22220   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
22221   emit_insn (gen_sincosxf3 (op0, op1, op2));
22222   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22223   emit_insn (gen_truncxf<mode>2 (operands[1], op1));
22224   DONE;
22227 (define_insn "fptanxf4_i387"
22228   [(set (match_operand:SF 0 "register_operand" "=f")
22229         (match_operand:SF 3 "const1_operand"))
22230    (set (match_operand:XF 1 "register_operand" "=f")
22231         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
22232                    UNSPEC_TAN))]
22233   "TARGET_USE_FANCY_MATH_387
22234    && flag_unsafe_math_optimizations"
22235   "fptan"
22236   [(set_attr "type" "fpspc")
22237    (set_attr "znver1_decode" "vector")
22238    (set_attr "mode" "XF")])
22240 (define_expand "tanxf2"
22241   [(use (match_operand:XF 0 "register_operand"))
22242    (use (match_operand:XF 1 "register_operand"))]
22243   "TARGET_USE_FANCY_MATH_387
22244    && flag_unsafe_math_optimizations"
22246   rtx one = gen_reg_rtx (SFmode);
22247   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
22248                                 CONST1_RTX (SFmode)));
22249   DONE;
22252 (define_expand "tan<mode>2"
22253   [(use (match_operand:MODEF 0 "register_operand"))
22254    (use (match_operand:MODEF 1 "general_operand"))]
22255   "TARGET_USE_FANCY_MATH_387
22256    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22257        || TARGET_MIX_SSE_I387)
22258    && flag_unsafe_math_optimizations"
22260   rtx op0 = gen_reg_rtx (XFmode);
22261   rtx op1 = gen_reg_rtx (XFmode);
22263   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22264   emit_insn (gen_tanxf2 (op0, op1));
22265   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22266   DONE;
22269 (define_insn "atan2xf3"
22270   [(set (match_operand:XF 0 "register_operand" "=f")
22271         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
22272                     (match_operand:XF 1 "register_operand" "f")]
22273                    UNSPEC_FPATAN))
22274    (clobber (match_scratch:XF 3 "=1"))]
22275   "TARGET_USE_FANCY_MATH_387
22276    && flag_unsafe_math_optimizations"
22277   "fpatan"
22278   [(set_attr "type" "fpspc")
22279    (set_attr "znver1_decode" "vector")
22280    (set_attr "mode" "XF")])
22282 (define_expand "atan2<mode>3"
22283   [(use (match_operand:MODEF 0 "register_operand"))
22284    (use (match_operand:MODEF 1 "general_operand"))
22285    (use (match_operand:MODEF 2 "general_operand"))]
22286   "TARGET_USE_FANCY_MATH_387
22287    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22288        || TARGET_MIX_SSE_I387)
22289    && flag_unsafe_math_optimizations"
22291   rtx op0 = gen_reg_rtx (XFmode);
22292   rtx op1 = gen_reg_rtx (XFmode);
22293   rtx op2 = gen_reg_rtx (XFmode);
22295   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
22296   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22298   emit_insn (gen_atan2xf3 (op0, op1, op2));
22299   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22300   DONE;
22303 (define_expand "atanxf2"
22304   [(parallel [(set (match_operand:XF 0 "register_operand")
22305                    (unspec:XF [(match_dup 2)
22306                                (match_operand:XF 1 "register_operand")]
22307                               UNSPEC_FPATAN))
22308               (clobber (scratch:XF))])]
22309   "TARGET_USE_FANCY_MATH_387
22310    && flag_unsafe_math_optimizations"
22311   "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
22313 (define_expand "atan<mode>2"
22314   [(use (match_operand:MODEF 0 "register_operand"))
22315    (use (match_operand:MODEF 1 "general_operand"))]
22316   "TARGET_USE_FANCY_MATH_387
22317    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22318        || TARGET_MIX_SSE_I387)
22319    && flag_unsafe_math_optimizations"
22321   rtx op0 = gen_reg_rtx (XFmode);
22322   rtx op1 = gen_reg_rtx (XFmode);
22324   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22325   emit_insn (gen_atanxf2 (op0, op1));
22326   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22327   DONE;
22330 (define_expand "asinxf2"
22331   [(set (match_dup 2)
22332         (mult:XF (match_operand:XF 1 "register_operand")
22333                  (match_dup 1)))
22334    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
22335    (set (match_dup 5) (sqrt:XF (match_dup 4)))
22336    (parallel [(set (match_operand:XF 0 "register_operand")
22337                    (unspec:XF [(match_dup 5) (match_dup 1)]
22338                               UNSPEC_FPATAN))
22339               (clobber (scratch:XF))])]
22340   "TARGET_USE_FANCY_MATH_387
22341    && flag_unsafe_math_optimizations"
22343   int i;
22345   for (i = 2; i < 6; i++)
22346     operands[i] = gen_reg_rtx (XFmode);
22348   emit_move_insn (operands[3], CONST1_RTX (XFmode));
22351 (define_expand "asin<mode>2"
22352   [(use (match_operand:MODEF 0 "register_operand"))
22353    (use (match_operand:MODEF 1 "general_operand"))]
22354   "TARGET_USE_FANCY_MATH_387
22355    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22356        || TARGET_MIX_SSE_I387)
22357    && flag_unsafe_math_optimizations"
22359   rtx op0 = gen_reg_rtx (XFmode);
22360   rtx op1 = gen_reg_rtx (XFmode);
22362   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22363   emit_insn (gen_asinxf2 (op0, op1));
22364   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22365   DONE;
22368 (define_expand "acosxf2"
22369   [(set (match_dup 2)
22370         (mult:XF (match_operand:XF 1 "register_operand")
22371                  (match_dup 1)))
22372    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
22373    (set (match_dup 5) (sqrt:XF (match_dup 4)))
22374    (parallel [(set (match_operand:XF 0 "register_operand")
22375                    (unspec:XF [(match_dup 1) (match_dup 5)]
22376                               UNSPEC_FPATAN))
22377               (clobber (scratch:XF))])]
22378   "TARGET_USE_FANCY_MATH_387
22379    && flag_unsafe_math_optimizations"
22381   int i;
22383   for (i = 2; i < 6; i++)
22384     operands[i] = gen_reg_rtx (XFmode);
22386   emit_move_insn (operands[3], CONST1_RTX (XFmode));
22389 (define_expand "acos<mode>2"
22390   [(use (match_operand:MODEF 0 "register_operand"))
22391    (use (match_operand:MODEF 1 "general_operand"))]
22392   "TARGET_USE_FANCY_MATH_387
22393    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22394        || TARGET_MIX_SSE_I387)
22395    && flag_unsafe_math_optimizations"
22397   rtx op0 = gen_reg_rtx (XFmode);
22398   rtx op1 = gen_reg_rtx (XFmode);
22400   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22401   emit_insn (gen_acosxf2 (op0, op1));
22402   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22403   DONE;
22406 (define_expand "sinhxf2"
22407   [(use (match_operand:XF 0 "register_operand"))
22408    (use (match_operand:XF 1 "register_operand"))]
22409   "TARGET_USE_FANCY_MATH_387
22410    && flag_finite_math_only
22411    && flag_unsafe_math_optimizations"
22413   ix86_emit_i387_sinh (operands[0], operands[1]);
22414   DONE;
22417 (define_expand "sinh<mode>2"
22418   [(use (match_operand:MODEF 0 "register_operand"))
22419    (use (match_operand:MODEF 1 "general_operand"))]
22420   "TARGET_USE_FANCY_MATH_387
22421    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22422        || TARGET_MIX_SSE_I387)
22423    && flag_finite_math_only
22424    && flag_unsafe_math_optimizations"
22426   rtx op0 = gen_reg_rtx (XFmode);
22427   rtx op1 = gen_reg_rtx (XFmode);
22429   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22430   emit_insn (gen_sinhxf2 (op0, op1));
22431   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22432   DONE;
22435 (define_expand "coshxf2"
22436   [(use (match_operand:XF 0 "register_operand"))
22437    (use (match_operand:XF 1 "register_operand"))]
22438   "TARGET_USE_FANCY_MATH_387
22439    && flag_unsafe_math_optimizations"
22441   ix86_emit_i387_cosh (operands[0], operands[1]);
22442   DONE;
22445 (define_expand "cosh<mode>2"
22446   [(use (match_operand:MODEF 0 "register_operand"))
22447    (use (match_operand:MODEF 1 "general_operand"))]
22448   "TARGET_USE_FANCY_MATH_387
22449    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22450        || TARGET_MIX_SSE_I387)
22451    && flag_unsafe_math_optimizations"
22453   rtx op0 = gen_reg_rtx (XFmode);
22454   rtx op1 = gen_reg_rtx (XFmode);
22456   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22457   emit_insn (gen_coshxf2 (op0, op1));
22458   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22459   DONE;
22462 (define_expand "tanhxf2"
22463   [(use (match_operand:XF 0 "register_operand"))
22464    (use (match_operand:XF 1 "register_operand"))]
22465   "TARGET_USE_FANCY_MATH_387
22466    && flag_unsafe_math_optimizations"
22468   ix86_emit_i387_tanh (operands[0], operands[1]);
22469   DONE;
22472 (define_expand "tanh<mode>2"
22473   [(use (match_operand:MODEF 0 "register_operand"))
22474    (use (match_operand:MODEF 1 "general_operand"))]
22475   "TARGET_USE_FANCY_MATH_387
22476    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22477        || TARGET_MIX_SSE_I387)
22478    && flag_unsafe_math_optimizations"
22480   rtx op0 = gen_reg_rtx (XFmode);
22481   rtx op1 = gen_reg_rtx (XFmode);
22483   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22484   emit_insn (gen_tanhxf2 (op0, op1));
22485   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22486   DONE;
22489 (define_expand "asinhxf2"
22490   [(use (match_operand:XF 0 "register_operand"))
22491    (use (match_operand:XF 1 "register_operand"))]
22492   "TARGET_USE_FANCY_MATH_387
22493    && flag_finite_math_only
22494    && flag_unsafe_math_optimizations"
22496   ix86_emit_i387_asinh (operands[0], operands[1]);
22497   DONE;
22500 (define_expand "asinh<mode>2"
22501   [(use (match_operand:MODEF 0 "register_operand"))
22502    (use (match_operand:MODEF 1 "general_operand"))]
22503   "TARGET_USE_FANCY_MATH_387
22504    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22505        || TARGET_MIX_SSE_I387)
22506    && flag_finite_math_only
22507    && flag_unsafe_math_optimizations"
22509   rtx op0 = gen_reg_rtx (XFmode);
22510   rtx op1 = gen_reg_rtx (XFmode);
22512   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22513   emit_insn (gen_asinhxf2 (op0, op1));
22514   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22515   DONE;
22518 (define_expand "acoshxf2"
22519   [(use (match_operand:XF 0 "register_operand"))
22520    (use (match_operand:XF 1 "register_operand"))]
22521   "TARGET_USE_FANCY_MATH_387
22522    && flag_unsafe_math_optimizations"
22524   ix86_emit_i387_acosh (operands[0], operands[1]);
22525   DONE;
22528 (define_expand "acosh<mode>2"
22529   [(use (match_operand:MODEF 0 "register_operand"))
22530    (use (match_operand:MODEF 1 "general_operand"))]
22531   "TARGET_USE_FANCY_MATH_387
22532    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22533        || TARGET_MIX_SSE_I387)
22534    && flag_unsafe_math_optimizations"
22536   rtx op0 = gen_reg_rtx (XFmode);
22537   rtx op1 = gen_reg_rtx (XFmode);
22539   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22540   emit_insn (gen_acoshxf2 (op0, op1));
22541   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22542   DONE;
22545 (define_expand "atanhxf2"
22546   [(use (match_operand:XF 0 "register_operand"))
22547    (use (match_operand:XF 1 "register_operand"))]
22548   "TARGET_USE_FANCY_MATH_387
22549    && flag_unsafe_math_optimizations"
22551   ix86_emit_i387_atanh (operands[0], operands[1]);
22552   DONE;
22555 (define_expand "atanh<mode>2"
22556   [(use (match_operand:MODEF 0 "register_operand"))
22557    (use (match_operand:MODEF 1 "general_operand"))]
22558   "TARGET_USE_FANCY_MATH_387
22559    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22560        || TARGET_MIX_SSE_I387)
22561    && flag_unsafe_math_optimizations"
22563   rtx op0 = gen_reg_rtx (XFmode);
22564   rtx op1 = gen_reg_rtx (XFmode);
22566   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22567   emit_insn (gen_atanhxf2 (op0, op1));
22568   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22569   DONE;
22572 (define_insn "fyl2xxf3_i387"
22573   [(set (match_operand:XF 0 "register_operand" "=f")
22574         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
22575                     (match_operand:XF 2 "register_operand" "f")]
22576                    UNSPEC_FYL2X))
22577    (clobber (match_scratch:XF 3 "=2"))]
22578   "TARGET_USE_FANCY_MATH_387
22579    && flag_unsafe_math_optimizations"
22580   "fyl2x"
22581   [(set_attr "type" "fpspc")
22582    (set_attr "znver1_decode" "vector")
22583    (set_attr "mode" "XF")])
22585 (define_expand "logxf2"
22586   [(parallel [(set (match_operand:XF 0 "register_operand")
22587                    (unspec:XF [(match_operand:XF 1 "register_operand")
22588                                (match_dup 2)] UNSPEC_FYL2X))
22589               (clobber (scratch:XF))])]
22590   "TARGET_USE_FANCY_MATH_387
22591    && flag_unsafe_math_optimizations"
22593   operands[2]
22594     = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
22597 (define_expand "log<mode>2"
22598   [(use (match_operand:MODEF 0 "register_operand"))
22599    (use (match_operand:MODEF 1 "general_operand"))]
22600   "TARGET_USE_FANCY_MATH_387
22601    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22602        || TARGET_MIX_SSE_I387)
22603    && flag_unsafe_math_optimizations"
22605   rtx op0 = gen_reg_rtx (XFmode);
22606   rtx op1 = gen_reg_rtx (XFmode);
22608   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22609   emit_insn (gen_logxf2 (op0, op1));
22610   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22611   DONE;
22614 (define_expand "log10xf2"
22615   [(parallel [(set (match_operand:XF 0 "register_operand")
22616                    (unspec:XF [(match_operand:XF 1 "register_operand")
22617                                (match_dup 2)] UNSPEC_FYL2X))
22618               (clobber (scratch:XF))])]
22619   "TARGET_USE_FANCY_MATH_387
22620    && flag_unsafe_math_optimizations"
22622   operands[2]
22623     = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
22626 (define_expand "log10<mode>2"
22627   [(use (match_operand:MODEF 0 "register_operand"))
22628    (use (match_operand:MODEF 1 "general_operand"))]
22629   "TARGET_USE_FANCY_MATH_387
22630    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22631        || TARGET_MIX_SSE_I387)
22632    && flag_unsafe_math_optimizations"
22634   rtx op0 = gen_reg_rtx (XFmode);
22635   rtx op1 = gen_reg_rtx (XFmode);
22637   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22638   emit_insn (gen_log10xf2 (op0, op1));
22639   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22640   DONE;
22643 (define_expand "log2xf2"
22644   [(parallel [(set (match_operand:XF 0 "register_operand")
22645                    (unspec:XF [(match_operand:XF 1 "register_operand")
22646                                (match_dup 2)] UNSPEC_FYL2X))
22647               (clobber (scratch:XF))])]
22648   "TARGET_USE_FANCY_MATH_387
22649    && flag_unsafe_math_optimizations"
22650   "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
22652 (define_expand "log2<mode>2"
22653   [(use (match_operand:MODEF 0 "register_operand"))
22654    (use (match_operand:MODEF 1 "general_operand"))]
22655   "TARGET_USE_FANCY_MATH_387
22656    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22657        || TARGET_MIX_SSE_I387)
22658    && flag_unsafe_math_optimizations"
22660   rtx op0 = gen_reg_rtx (XFmode);
22661   rtx op1 = gen_reg_rtx (XFmode);
22663   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22664   emit_insn (gen_log2xf2 (op0, op1));
22665   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22666   DONE;
22669 (define_insn "fyl2xp1xf3_i387"
22670   [(set (match_operand:XF 0 "register_operand" "=f")
22671         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
22672                     (match_operand:XF 2 "register_operand" "f")]
22673                    UNSPEC_FYL2XP1))
22674    (clobber (match_scratch:XF 3 "=2"))]
22675   "TARGET_USE_FANCY_MATH_387
22676    && flag_unsafe_math_optimizations"
22677   "fyl2xp1"
22678   [(set_attr "type" "fpspc")
22679    (set_attr "znver1_decode" "vector")
22680    (set_attr "mode" "XF")])
22682 (define_expand "log1pxf2"
22683   [(use (match_operand:XF 0 "register_operand"))
22684    (use (match_operand:XF 1 "register_operand"))]
22685   "TARGET_USE_FANCY_MATH_387
22686    && flag_unsafe_math_optimizations"
22688   ix86_emit_i387_log1p (operands[0], operands[1]);
22689   DONE;
22692 (define_expand "log1p<mode>2"
22693   [(use (match_operand:MODEF 0 "register_operand"))
22694    (use (match_operand:MODEF 1 "general_operand"))]
22695   "TARGET_USE_FANCY_MATH_387
22696    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22697        || TARGET_MIX_SSE_I387)
22698    && flag_unsafe_math_optimizations"
22700   rtx op0 = gen_reg_rtx (XFmode);
22701   rtx op1 = gen_reg_rtx (XFmode);
22703   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22704   emit_insn (gen_log1pxf2 (op0, op1));
22705   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22706   DONE;
22709 (define_insn "fxtractxf3_i387"
22710   [(set (match_operand:XF 0 "register_operand" "=f")
22711         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
22712                    UNSPEC_XTRACT_FRACT))
22713    (set (match_operand:XF 1 "register_operand" "=f")
22714         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
22715   "TARGET_USE_FANCY_MATH_387
22716    && flag_unsafe_math_optimizations"
22717   "fxtract"
22718   [(set_attr "type" "fpspc")
22719    (set_attr "znver1_decode" "vector")
22720    (set_attr "mode" "XF")])
22722 (define_expand "logbxf2"
22723   [(parallel [(set (match_dup 2)
22724                    (unspec:XF [(match_operand:XF 1 "register_operand")]
22725                               UNSPEC_XTRACT_FRACT))
22726               (set (match_operand:XF 0 "register_operand")
22727                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
22728   "TARGET_USE_FANCY_MATH_387
22729    && flag_unsafe_math_optimizations"
22730   "operands[2] = gen_reg_rtx (XFmode);")
22732 (define_expand "logb<mode>2"
22733   [(use (match_operand:MODEF 0 "register_operand"))
22734    (use (match_operand:MODEF 1 "general_operand"))]
22735   "TARGET_USE_FANCY_MATH_387
22736    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22737        || TARGET_MIX_SSE_I387)
22738    && flag_unsafe_math_optimizations"
22740   rtx op0 = gen_reg_rtx (XFmode);
22741   rtx op1 = gen_reg_rtx (XFmode);
22743   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22744   emit_insn (gen_logbxf2 (op0, op1));
22745   emit_insn (gen_truncxf<mode>2 (operands[0], op1));
22746   DONE;
22749 (define_expand "ilogbxf2"
22750   [(use (match_operand:SI 0 "register_operand"))
22751    (use (match_operand:XF 1 "register_operand"))]
22752   "TARGET_USE_FANCY_MATH_387
22753    && flag_unsafe_math_optimizations"
22755   rtx op0, op1;
22757   if (optimize_insn_for_size_p ())
22758     FAIL;
22760   op0 = gen_reg_rtx (XFmode);
22761   op1 = gen_reg_rtx (XFmode);
22763   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
22764   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
22765   DONE;
22768 (define_expand "ilogb<mode>2"
22769   [(use (match_operand:SI 0 "register_operand"))
22770    (use (match_operand:MODEF 1 "general_operand"))]
22771   "TARGET_USE_FANCY_MATH_387
22772    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22773        || TARGET_MIX_SSE_I387)
22774    && flag_unsafe_math_optimizations"
22776   rtx op0, op1, op2;
22778   if (optimize_insn_for_size_p ())
22779     FAIL;
22781   op0 = gen_reg_rtx (XFmode);
22782   op1 = gen_reg_rtx (XFmode);
22783   op2 = gen_reg_rtx (XFmode);
22785   emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
22786   emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
22787   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
22788   DONE;
22791 (define_insn "*f2xm1xf2_i387"
22792   [(set (match_operand:XF 0 "register_operand" "=f")
22793         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
22794                    UNSPEC_F2XM1))]
22795   "TARGET_USE_FANCY_MATH_387
22796    && flag_unsafe_math_optimizations"
22797   "f2xm1"
22798   [(set_attr "type" "fpspc")
22799    (set_attr "znver1_decode" "vector")
22800    (set_attr "mode" "XF")])
22802 (define_insn "fscalexf4_i387"
22803   [(set (match_operand:XF 0 "register_operand" "=f")
22804         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
22805                     (match_operand:XF 3 "register_operand" "1")]
22806                    UNSPEC_FSCALE_FRACT))
22807    (set (match_operand:XF 1 "register_operand" "=f")
22808         (unspec:XF [(match_dup 2) (match_dup 3)]
22809                    UNSPEC_FSCALE_EXP))]
22810   "TARGET_USE_FANCY_MATH_387
22811    && flag_unsafe_math_optimizations"
22812   "fscale"
22813   [(set_attr "type" "fpspc")
22814    (set_attr "znver1_decode" "vector")
22815    (set_attr "mode" "XF")])
22817 (define_expand "expNcorexf3"
22818   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
22819                                (match_operand:XF 2 "register_operand")))
22820    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
22821    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
22822    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
22823    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
22824    (parallel [(set (match_operand:XF 0 "register_operand")
22825                    (unspec:XF [(match_dup 8) (match_dup 4)]
22826                               UNSPEC_FSCALE_FRACT))
22827               (set (match_dup 9)
22828                    (unspec:XF [(match_dup 8) (match_dup 4)]
22829                               UNSPEC_FSCALE_EXP))])]
22830   "TARGET_USE_FANCY_MATH_387
22831    && flag_unsafe_math_optimizations"
22833   int i;
22835   for (i = 3; i < 10; i++)
22836     operands[i] = gen_reg_rtx (XFmode);
22838   emit_move_insn (operands[7], CONST1_RTX (XFmode));
22841 (define_expand "expxf2"
22842   [(use (match_operand:XF 0 "register_operand"))
22843    (use (match_operand:XF 1 "register_operand"))]
22844   "TARGET_USE_FANCY_MATH_387
22845    && flag_unsafe_math_optimizations"
22847   rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
22849   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
22850   DONE;
22853 (define_expand "exp<mode>2"
22854   [(use (match_operand:MODEF 0 "register_operand"))
22855    (use (match_operand:MODEF 1 "general_operand"))]
22856   "TARGET_USE_FANCY_MATH_387
22857    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22858        || TARGET_MIX_SSE_I387)
22859    && flag_unsafe_math_optimizations"
22861   rtx op0 = gen_reg_rtx (XFmode);
22862   rtx op1 = gen_reg_rtx (XFmode);
22864   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22865   emit_insn (gen_expxf2 (op0, op1));
22866   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22867   DONE;
22870 (define_expand "exp10xf2"
22871   [(use (match_operand:XF 0 "register_operand"))
22872    (use (match_operand:XF 1 "register_operand"))]
22873   "TARGET_USE_FANCY_MATH_387
22874    && flag_unsafe_math_optimizations"
22876   rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
22878   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
22879   DONE;
22882 (define_expand "exp10<mode>2"
22883   [(use (match_operand:MODEF 0 "register_operand"))
22884    (use (match_operand:MODEF 1 "general_operand"))]
22885   "TARGET_USE_FANCY_MATH_387
22886    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22887        || TARGET_MIX_SSE_I387)
22888    && flag_unsafe_math_optimizations"
22890   rtx op0 = gen_reg_rtx (XFmode);
22891   rtx op1 = gen_reg_rtx (XFmode);
22893   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22894   emit_insn (gen_exp10xf2 (op0, op1));
22895   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22896   DONE;
22899 (define_expand "exp2xf2"
22900   [(use (match_operand:XF 0 "register_operand"))
22901    (use (match_operand:XF 1 "register_operand"))]
22902   "TARGET_USE_FANCY_MATH_387
22903    && flag_unsafe_math_optimizations"
22905   rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
22907   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
22908   DONE;
22911 (define_expand "exp2<mode>2"
22912   [(use (match_operand:MODEF 0 "register_operand"))
22913    (use (match_operand:MODEF 1 "general_operand"))]
22914   "TARGET_USE_FANCY_MATH_387
22915    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22916        || TARGET_MIX_SSE_I387)
22917    && flag_unsafe_math_optimizations"
22919   rtx op0 = gen_reg_rtx (XFmode);
22920   rtx op1 = gen_reg_rtx (XFmode);
22922   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22923   emit_insn (gen_exp2xf2 (op0, op1));
22924   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22925   DONE;
22928 (define_expand "expm1xf2"
22929   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
22930                                (match_dup 2)))
22931    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
22932    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
22933    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
22934    (parallel [(set (match_dup 7)
22935                    (unspec:XF [(match_dup 6) (match_dup 4)]
22936                               UNSPEC_FSCALE_FRACT))
22937               (set (match_dup 8)
22938                    (unspec:XF [(match_dup 6) (match_dup 4)]
22939                               UNSPEC_FSCALE_EXP))])
22940    (parallel [(set (match_dup 10)
22941                    (unspec:XF [(match_dup 9) (match_dup 8)]
22942                               UNSPEC_FSCALE_FRACT))
22943               (set (match_dup 11)
22944                    (unspec:XF [(match_dup 9) (match_dup 8)]
22945                               UNSPEC_FSCALE_EXP))])
22946    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
22947    (set (match_operand:XF 0 "register_operand")
22948         (plus:XF (match_dup 12) (match_dup 7)))]
22949   "TARGET_USE_FANCY_MATH_387
22950    && flag_unsafe_math_optimizations"
22952   int i;
22954   for (i = 2; i < 13; i++)
22955     operands[i] = gen_reg_rtx (XFmode);
22957   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
22958   emit_move_insn (operands[9], CONST1_RTX (XFmode));
22961 (define_expand "expm1<mode>2"
22962   [(use (match_operand:MODEF 0 "register_operand"))
22963    (use (match_operand:MODEF 1 "general_operand"))]
22964   "TARGET_USE_FANCY_MATH_387
22965    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22966        || TARGET_MIX_SSE_I387)
22967    && flag_unsafe_math_optimizations"
22969   rtx op0 = gen_reg_rtx (XFmode);
22970   rtx op1 = gen_reg_rtx (XFmode);
22972   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22973   emit_insn (gen_expm1xf2 (op0, op1));
22974   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22975   DONE;
22978 (define_insn "avx512f_scalef<mode>2"
22979   [(set (match_operand:MODEF 0 "register_operand" "=v")
22980         (unspec:MODEF
22981           [(match_operand:MODEF 1 "register_operand" "v")
22982            (match_operand:MODEF 2 "nonimmediate_operand" "vm")]
22983           UNSPEC_SCALEF))]
22984   "TARGET_AVX512F"
22985   "vscalef<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
22986   [(set_attr "prefix" "evex")
22987    (set_attr "mode"  "<MODE>")])
22989 (define_expand "ldexpxf3"
22990   [(match_operand:XF 0 "register_operand")
22991    (match_operand:XF 1 "register_operand")
22992    (match_operand:SI 2 "register_operand")]
22993   "TARGET_USE_FANCY_MATH_387
22994    && flag_unsafe_math_optimizations"
22996   rtx tmp1 = gen_reg_rtx (XFmode);
22997   rtx tmp2 = gen_reg_rtx (XFmode);
22999   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
23000   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
23001                                  operands[1], tmp1));
23002   DONE;
23005 (define_expand "ldexp<mode>3"
23006   [(use (match_operand:MODEF 0 "register_operand"))
23007    (use (match_operand:MODEF 1 "general_operand"))
23008    (use (match_operand:SI 2 "register_operand"))]
23009   "((TARGET_USE_FANCY_MATH_387
23010      && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23011          || TARGET_MIX_SSE_I387))
23012     || (TARGET_AVX512F && TARGET_SSE_MATH))
23013    && flag_unsafe_math_optimizations"
23015   /* Prefer avx512f version.  */
23016   if (TARGET_AVX512F && TARGET_SSE_MATH)
23017    {
23018      rtx op2 = gen_reg_rtx (<MODE>mode);
23019      operands[1] = force_reg (<MODE>mode, operands[1]);
23021      emit_insn (gen_floatsi<mode>2 (op2, operands[2]));
23022      emit_insn (gen_avx512f_scalef<mode>2 (operands[0], operands[1], op2));
23023    }
23024   else
23025     {
23026       rtx op0 = gen_reg_rtx (XFmode);
23027       rtx op1 = gen_reg_rtx (XFmode);
23029       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23030       emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
23031       emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23032   }
23033   DONE;
23036 (define_expand "scalbxf3"
23037   [(parallel [(set (match_operand:XF 0 " register_operand")
23038                    (unspec:XF [(match_operand:XF 1 "register_operand")
23039                                (match_operand:XF 2 "register_operand")]
23040                               UNSPEC_FSCALE_FRACT))
23041               (set (match_dup 3)
23042                    (unspec:XF [(match_dup 1) (match_dup 2)]
23043                               UNSPEC_FSCALE_EXP))])]
23044   "TARGET_USE_FANCY_MATH_387
23045    && flag_unsafe_math_optimizations"
23046   "operands[3] = gen_reg_rtx (XFmode);")
23048 (define_expand "scalb<mode>3"
23049   [(use (match_operand:MODEF 0 "register_operand"))
23050    (use (match_operand:MODEF 1 "general_operand"))
23051    (use (match_operand:MODEF 2 "general_operand"))]
23052   "TARGET_USE_FANCY_MATH_387
23053    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23054        || TARGET_MIX_SSE_I387)
23055    && flag_unsafe_math_optimizations"
23057   rtx op0 = gen_reg_rtx (XFmode);
23058   rtx op1 = gen_reg_rtx (XFmode);
23059   rtx op2 = gen_reg_rtx (XFmode);
23061   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23062   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
23063   emit_insn (gen_scalbxf3 (op0, op1, op2));
23064   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23065   DONE;
23068 (define_expand "significandxf2"
23069   [(parallel [(set (match_operand:XF 0 "register_operand")
23070                    (unspec:XF [(match_operand:XF 1 "register_operand")]
23071                               UNSPEC_XTRACT_FRACT))
23072               (set (match_dup 2)
23073                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
23074   "TARGET_USE_FANCY_MATH_387
23075    && flag_unsafe_math_optimizations"
23076   "operands[2] = gen_reg_rtx (XFmode);")
23078 (define_expand "significand<mode>2"
23079   [(use (match_operand:MODEF 0 "register_operand"))
23080    (use (match_operand:MODEF 1 "general_operand"))]
23081   "TARGET_USE_FANCY_MATH_387
23082    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23083        || TARGET_MIX_SSE_I387)
23084    && flag_unsafe_math_optimizations"
23086   rtx op0 = gen_reg_rtx (XFmode);
23087   rtx op1 = gen_reg_rtx (XFmode);
23089   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23090   emit_insn (gen_significandxf2 (op0, op1));
23091   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23092   DONE;
23096 (define_insn "sse4_1_round<mode>2"
23097   [(set (match_operand:MODEFH 0 "register_operand" "=x,x,x,v,v")
23098         (unspec:MODEFH
23099           [(match_operand:MODEFH 1 "nonimmediate_operand" "0,x,jm,v,m")
23100            (match_operand:SI 2 "const_0_to_15_operand")]
23101           UNSPEC_ROUND))]
23102   "TARGET_SSE4_1"
23103   "@
23104    %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
23105    %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
23106    %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
23107    vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
23108    vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
23109   [(set_attr "type" "ssecvt")
23110    (set_attr "prefix_extra" "1,1,1,*,*")
23111    (set_attr "length_immediate" "1")
23112    (set_attr "addr" "*,*,gpr16,*,*")
23113    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
23114    (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
23115    (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
23116    (set_attr "mode" "<MODE>")
23117    (set (attr "preferred_for_speed")
23118       (cond [(match_test "TARGET_AVX")
23119                (symbol_ref "true")
23120              (eq_attr "alternative" "1,2")
23121                (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
23122             ]
23123             (symbol_ref "true")))])
23125 (define_insn "rintxf2"
23126   [(set (match_operand:XF 0 "register_operand" "=f")
23127         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
23128                    UNSPEC_FRNDINT))]
23129   "TARGET_USE_FANCY_MATH_387"
23130   "frndint"
23131   [(set_attr "type" "fpspc")
23132    (set_attr "znver1_decode" "vector")
23133    (set_attr "mode" "XF")])
23135 (define_expand "rinthf2"
23136   [(match_operand:HF 0 "register_operand")
23137    (match_operand:HF 1 "nonimmediate_operand")]
23138   "TARGET_AVX512FP16"
23140   emit_insn (gen_sse4_1_roundhf2 (operands[0],
23141                                   operands[1],
23142                                   GEN_INT (ROUND_MXCSR)));
23143   DONE;
23146 (define_expand "rint<mode>2"
23147   [(use (match_operand:MODEF 0 "register_operand"))
23148    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
23149   "TARGET_USE_FANCY_MATH_387
23150    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
23152   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23153     {
23154       if (TARGET_SSE4_1)
23155         emit_insn (gen_sse4_1_round<mode>2
23156                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
23157       else
23158         ix86_expand_rint (operands[0], operands[1]);
23159     }
23160   else
23161     {
23162       rtx op0 = gen_reg_rtx (XFmode);
23163       rtx op1 = gen_reg_rtx (XFmode);
23165       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23166       emit_insn (gen_rintxf2 (op0, op1));
23167       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
23168     }
23169   DONE;
23172 (define_expand "nearbyintxf2"
23173   [(set (match_operand:XF 0 "register_operand")
23174         (unspec:XF [(match_operand:XF 1 "register_operand")]
23175                    UNSPEC_FRNDINT))]
23176   "TARGET_USE_FANCY_MATH_387
23177    && !flag_trapping_math")
23179 (define_expand "nearbyinthf2"
23180   [(match_operand:HF 0 "register_operand")
23181    (match_operand:HF 1 "nonimmediate_operand")]
23182   "TARGET_AVX512FP16"
23184   emit_insn (gen_sse4_1_roundhf2 (operands[0],
23185                                   operands[1],
23186                                   GEN_INT (ROUND_MXCSR | ROUND_NO_EXC)));
23187   DONE;
23190 (define_expand "nearbyint<mode>2"
23191   [(use (match_operand:MODEF 0 "register_operand"))
23192    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
23193   "(TARGET_USE_FANCY_MATH_387
23194     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23195           || TARGET_MIX_SSE_I387)
23196     && !flag_trapping_math)
23197    || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
23199   if (TARGET_SSE4_1 && TARGET_SSE_MATH)
23200     emit_insn (gen_sse4_1_round<mode>2
23201                (operands[0], operands[1], GEN_INT (ROUND_MXCSR
23202                                                    | ROUND_NO_EXC)));
23203   else
23204     {
23205       rtx op0 = gen_reg_rtx (XFmode);
23206       rtx op1 = gen_reg_rtx (XFmode);
23208       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23209       emit_insn (gen_nearbyintxf2 (op0, op1));
23210       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
23211     }
23212   DONE;
23215 (define_expand "roundhf2"
23216   [(match_operand:HF 0 "register_operand")
23217    (match_operand:HF 1 "register_operand")]
23218   "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
23220   ix86_expand_round_sse4 (operands[0], operands[1]);
23221   DONE;
23224 (define_expand "round<mode>2"
23225   [(match_operand:X87MODEF 0 "register_operand")
23226    (match_operand:X87MODEF 1 "nonimmediate_operand")]
23227   "(TARGET_USE_FANCY_MATH_387
23228     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23229         || TARGET_MIX_SSE_I387)
23230     && flag_unsafe_math_optimizations
23231     && (flag_fp_int_builtin_inexact || !flag_trapping_math))
23232    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23233        && !flag_trapping_math && !flag_rounding_math)"
23235   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23236       && !flag_trapping_math && !flag_rounding_math)
23237     {
23238       if (TARGET_SSE4_1)
23239         {
23240           operands[1] = force_reg (<MODE>mode, operands[1]);
23241           ix86_expand_round_sse4 (operands[0], operands[1]);
23242         }
23243       else if (TARGET_64BIT || (<MODE>mode != DFmode))
23244         ix86_expand_round (operands[0], operands[1]);
23245       else
23246         ix86_expand_rounddf_32 (operands[0], operands[1]);
23247     }
23248   else
23249     {
23250       operands[1] = force_reg (<MODE>mode, operands[1]);
23251       ix86_emit_i387_round (operands[0], operands[1]);
23252     }
23253   DONE;
23256 (define_insn "lrintxfdi2"
23257   [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
23258         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
23259                    UNSPEC_FIST))
23260    (clobber (match_scratch:XF 2 "=&f"))]
23261   "TARGET_USE_FANCY_MATH_387"
23262   "* return output_fix_trunc (insn, operands, false);"
23263   [(set_attr "type" "fpspc")
23264    (set_attr "mode" "DI")])
23266 (define_insn "lrintxf<mode>2"
23267   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
23268         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
23269                       UNSPEC_FIST))]
23270   "TARGET_USE_FANCY_MATH_387"
23271   "* return output_fix_trunc (insn, operands, false);"
23272   [(set_attr "type" "fpspc")
23273    (set_attr "mode" "<MODE>")])
23275 (define_expand "lroundhf<mode>2"
23276   [(set (match_operand:SWI248 0 "register_operand")
23277      (unspec:SWI248 [(match_operand:HF 1 "nonimmediate_operand")]
23278                    UNSPEC_FIX_NOTRUNC))]
23279   "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
23281   ix86_expand_lround (operands[0], operands[1]);
23282   DONE;
23285 (define_expand "lrinthf<mode>2"
23286   [(set (match_operand:SWI48 0 "register_operand")
23287      (unspec:SWI48 [(match_operand:HF 1 "nonimmediate_operand")]
23288                    UNSPEC_FIX_NOTRUNC))]
23289   "TARGET_AVX512FP16")
23291 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
23292   [(set (match_operand:SWI48 0 "register_operand")
23293      (unspec:SWI48 [(match_operand:MODEF 1 "nonimmediate_operand")]
23294                    UNSPEC_FIX_NOTRUNC))]
23295   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
23297 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
23298   [(match_operand:SWI248x 0 "nonimmediate_operand")
23299    (match_operand:X87MODEF 1 "register_operand")]
23300   "(TARGET_USE_FANCY_MATH_387
23301     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
23302         || TARGET_MIX_SSE_I387)
23303     && flag_unsafe_math_optimizations)
23304    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
23305        && <SWI248x:MODE>mode != HImode 
23306        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
23307        && !flag_trapping_math && !flag_rounding_math)"
23309   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
23310       && <SWI248x:MODE>mode != HImode
23311       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
23312       && !flag_trapping_math && !flag_rounding_math)
23313     ix86_expand_lround (operands[0], operands[1]);
23314   else
23315     ix86_emit_i387_round (operands[0], operands[1]);
23316   DONE;
23319 (define_int_iterator FRNDINT_ROUNDING
23320         [UNSPEC_FRNDINT_ROUNDEVEN
23321          UNSPEC_FRNDINT_FLOOR
23322          UNSPEC_FRNDINT_CEIL
23323          UNSPEC_FRNDINT_TRUNC])
23325 (define_int_iterator FIST_ROUNDING
23326         [UNSPEC_FIST_FLOOR
23327          UNSPEC_FIST_CEIL])
23329 ;; Base name for define_insn
23330 (define_int_attr rounding_insn
23331         [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
23332          (UNSPEC_FRNDINT_FLOOR "floor")
23333          (UNSPEC_FRNDINT_CEIL "ceil")
23334          (UNSPEC_FRNDINT_TRUNC "btrunc")
23335          (UNSPEC_FIST_FLOOR "floor")
23336          (UNSPEC_FIST_CEIL "ceil")])
23338 (define_int_attr rounding
23339         [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
23340          (UNSPEC_FRNDINT_FLOOR "floor")
23341          (UNSPEC_FRNDINT_CEIL "ceil")
23342          (UNSPEC_FRNDINT_TRUNC "trunc")
23343          (UNSPEC_FIST_FLOOR "floor")
23344          (UNSPEC_FIST_CEIL "ceil")])
23346 (define_int_attr ROUNDING
23347         [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
23348          (UNSPEC_FRNDINT_FLOOR "FLOOR")
23349          (UNSPEC_FRNDINT_CEIL "CEIL")
23350          (UNSPEC_FRNDINT_TRUNC "TRUNC")
23351          (UNSPEC_FIST_FLOOR "FLOOR")
23352          (UNSPEC_FIST_CEIL "CEIL")])
23354 ;; Rounding mode control word calculation could clobber FLAGS_REG.
23355 (define_insn_and_split "frndintxf2_<rounding>"
23356   [(set (match_operand:XF 0 "register_operand")
23357         (unspec:XF [(match_operand:XF 1 "register_operand")]
23358                    FRNDINT_ROUNDING))
23359    (clobber (reg:CC FLAGS_REG))]
23360   "TARGET_USE_FANCY_MATH_387
23361    && (flag_fp_int_builtin_inexact || !flag_trapping_math)
23362    && ix86_pre_reload_split ()"
23363   "#"
23364   "&& 1"
23365   [(const_int 0)]
23367   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
23369   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
23370   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
23372   emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
23373                                              operands[2], operands[3]));
23374   DONE;
23376   [(set_attr "type" "frndint")
23377    (set_attr "i387_cw" "<rounding>")
23378    (set_attr "mode" "XF")])
23380 (define_insn "frndintxf2_<rounding>_i387"
23381   [(set (match_operand:XF 0 "register_operand" "=f")
23382         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
23383                    FRNDINT_ROUNDING))
23384    (use (match_operand:HI 2 "memory_operand" "m"))
23385    (use (match_operand:HI 3 "memory_operand" "m"))]
23386   "TARGET_USE_FANCY_MATH_387
23387    && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
23388   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
23389   [(set_attr "type" "frndint")
23390    (set_attr "i387_cw" "<rounding>")
23391    (set_attr "mode" "XF")])
23393 (define_expand "<rounding_insn>xf2"
23394   [(parallel [(set (match_operand:XF 0 "register_operand")
23395                    (unspec:XF [(match_operand:XF 1 "register_operand")]
23396                               FRNDINT_ROUNDING))
23397               (clobber (reg:CC FLAGS_REG))])]
23398   "TARGET_USE_FANCY_MATH_387
23399    && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
23401 (define_expand "<rounding_insn>hf2"
23402   [(parallel [(set (match_operand:HF 0 "register_operand")
23403                    (unspec:HF [(match_operand:HF 1 "register_operand")]
23404                      FRNDINT_ROUNDING))
23405               (clobber (reg:CC FLAGS_REG))])]
23406   "TARGET_AVX512FP16"
23408   emit_insn (gen_sse4_1_roundhf2 (operands[0], operands[1],
23409                                   GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
23410   DONE;
23413 (define_expand "<rounding_insn><mode>2"
23414   [(parallel [(set (match_operand:MODEF 0 "register_operand")
23415                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
23416                                  FRNDINT_ROUNDING))
23417               (clobber (reg:CC FLAGS_REG))])]
23418   "(TARGET_USE_FANCY_MATH_387
23419     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23420         || TARGET_MIX_SSE_I387)
23421     && (flag_fp_int_builtin_inexact || !flag_trapping_math))
23422    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23423        && (TARGET_SSE4_1
23424            || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
23425                && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
23427   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23428       && (TARGET_SSE4_1
23429           || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
23430               && (flag_fp_int_builtin_inexact || !flag_trapping_math))))
23431     {
23432       if (TARGET_SSE4_1)
23433         emit_insn (gen_sse4_1_round<mode>2
23434                    (operands[0], operands[1],
23435                     GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
23436       else if (TARGET_64BIT || (<MODE>mode != DFmode))
23437         {
23438           if (ROUND_<ROUNDING> == ROUND_FLOOR)
23439             ix86_expand_floorceil (operands[0], operands[1], true);
23440           else if (ROUND_<ROUNDING> == ROUND_CEIL)
23441             ix86_expand_floorceil (operands[0], operands[1], false);
23442           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
23443             ix86_expand_trunc (operands[0], operands[1]);
23444           else
23445             gcc_unreachable ();
23446         }
23447       else
23448         {
23449           if (ROUND_<ROUNDING> == ROUND_FLOOR)
23450             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
23451           else if (ROUND_<ROUNDING> == ROUND_CEIL)
23452             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
23453           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
23454             ix86_expand_truncdf_32 (operands[0], operands[1]);
23455           else
23456             gcc_unreachable ();
23457         }
23458     }
23459   else
23460     {
23461       rtx op0 = gen_reg_rtx (XFmode);
23462       rtx op1 = gen_reg_rtx (XFmode);
23464       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23465       emit_insn (gen_frndintxf2_<rounding> (op0, op1));
23466       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
23467     }
23468   DONE;
23471 ;; Rounding mode control word calculation could clobber FLAGS_REG.
23472 (define_insn_and_split "*fist<mode>2_<rounding>_1"
23473   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
23474         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
23475                         FIST_ROUNDING))
23476    (clobber (reg:CC FLAGS_REG))]
23477   "TARGET_USE_FANCY_MATH_387
23478    && flag_unsafe_math_optimizations
23479    && ix86_pre_reload_split ()"
23480   "#"
23481   "&& 1"
23482   [(const_int 0)]
23484   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
23486   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
23487   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
23489   emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
23490                                          operands[2], operands[3]));
23491   DONE;
23493   [(set_attr "type" "fistp")
23494    (set_attr "i387_cw" "<rounding>")
23495    (set_attr "mode" "<MODE>")])
23497 (define_insn "fistdi2_<rounding>"
23498   [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
23499         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
23500                    FIST_ROUNDING))
23501    (use (match_operand:HI 2 "memory_operand" "m"))
23502    (use (match_operand:HI 3 "memory_operand" "m"))
23503    (clobber (match_scratch:XF 4 "=&f"))]
23504   "TARGET_USE_FANCY_MATH_387
23505    && flag_unsafe_math_optimizations"
23506   "* return output_fix_trunc (insn, operands, false);"
23507   [(set_attr "type" "fistp")
23508    (set_attr "i387_cw" "<rounding>")
23509    (set_attr "mode" "DI")])
23511 (define_insn "fist<mode>2_<rounding>"
23512   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
23513         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
23514                       FIST_ROUNDING))
23515    (use (match_operand:HI 2 "memory_operand" "m"))
23516    (use (match_operand:HI 3 "memory_operand" "m"))]
23517   "TARGET_USE_FANCY_MATH_387
23518    && flag_unsafe_math_optimizations"
23519   "* return output_fix_trunc (insn, operands, false);"
23520   [(set_attr "type" "fistp")
23521    (set_attr "i387_cw" "<rounding>")
23522    (set_attr "mode" "<MODE>")])
23524 (define_expand "l<rounding_insn>xf<mode>2"
23525   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
23526                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
23527                                    FIST_ROUNDING))
23528               (clobber (reg:CC FLAGS_REG))])]
23529   "TARGET_USE_FANCY_MATH_387
23530    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
23531    && flag_unsafe_math_optimizations")
23533 (define_expand "l<rounding_insn>hf<mode>2"
23534   [(set (match_operand:SWI48 0 "nonimmediate_operand")
23535         (unspec:SWI48 [(match_operand:HF 1 "register_operand")]
23536                     FIST_ROUNDING))]
23537   "TARGET_AVX512FP16"
23539   rtx tmp = gen_reg_rtx (HFmode);
23540   emit_insn (gen_sse4_1_roundhf2 (tmp, operands[1],
23541                                  GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
23542   emit_insn (gen_fix_trunchf<mode>2 (operands[0], tmp));
23543   DONE;
23546 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
23547   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
23548                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
23549                                  FIST_ROUNDING))
23550               (clobber (reg:CC FLAGS_REG))])]
23551   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
23552    && (TARGET_SSE4_1 || !flag_trapping_math)"
23554   if (TARGET_SSE4_1)
23555     {
23556       rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
23558       emit_insn (gen_sse4_1_round<MODEF:mode>2
23559                  (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
23560                                              | ROUND_NO_EXC)));
23561       emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
23562                  (operands[0], tmp));
23563     }
23564   else if (ROUND_<ROUNDING> == ROUND_FLOOR)
23565     ix86_expand_lfloorceil (operands[0], operands[1], true);
23566   else if (ROUND_<ROUNDING> == ROUND_CEIL)
23567     ix86_expand_lfloorceil (operands[0], operands[1], false);
23568   else
23569     gcc_unreachable ();
23571   DONE;
23574 (define_insn "fxam<mode>2_i387"
23575   [(set (match_operand:HI 0 "register_operand" "=a")
23576         (unspec:HI
23577           [(match_operand:X87MODEF 1 "register_operand" "f")]
23578           UNSPEC_FXAM))]
23579   "TARGET_USE_FANCY_MATH_387"
23580   "fxam\n\tfnstsw\t%0"
23581   [(set_attr "type" "multi")
23582    (set_attr "length" "4")
23583    (set_attr "unit" "i387")
23584    (set_attr "mode" "<MODE>")])
23586 (define_expand "signbittf2"
23587   [(use (match_operand:SI 0 "register_operand"))
23588    (use (match_operand:TF 1 "register_operand"))]
23589   "TARGET_SSE"
23591   if (TARGET_SSE4_1)
23592     {
23593       rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
23594       rtx scratch = gen_reg_rtx (QImode);
23596       emit_insn (gen_ptesttf2 (operands[1], mask));
23597         ix86_expand_setcc (scratch, NE,
23598                            gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
23600       emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
23601     }
23602   else
23603     {
23604       emit_insn (gen_sse_movmskps (operands[0],
23605                                    gen_lowpart (V4SFmode, operands[1])));
23606       emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
23607     }
23608   DONE;
23611 (define_expand "signbitxf2"
23612   [(use (match_operand:SI 0 "register_operand"))
23613    (use (match_operand:XF 1 "register_operand"))]
23614   "TARGET_USE_FANCY_MATH_387"
23616   rtx scratch = gen_reg_rtx (HImode);
23618   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
23619   emit_insn (gen_andsi3 (operands[0],
23620              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
23621   DONE;
23624 (define_insn "movmsk_df"
23625   [(set (match_operand:SI 0 "register_operand" "=r,jr")
23626         (unspec:SI
23627           [(match_operand:DF 1 "register_operand" "x,x")]
23628           UNSPEC_MOVMSK))]
23629   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
23630   "%vmovmskpd\t{%1, %0|%0, %1}"
23631   [(set_attr "isa" "noavx,avx")
23632    (set_attr "type" "ssemov")
23633    (set_attr "prefix" "maybe_evex")
23634    (set_attr "mode" "DF")])
23636 ;; Use movmskpd in SSE mode to avoid store forwarding stall
23637 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
23638 (define_expand "signbitdf2"
23639   [(use (match_operand:SI 0 "register_operand"))
23640    (use (match_operand:DF 1 "register_operand"))]
23641   "TARGET_USE_FANCY_MATH_387
23642    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
23644   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
23645     {
23646       emit_insn (gen_movmsk_df (operands[0], operands[1]));
23647       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
23648     }
23649   else
23650     {
23651       rtx scratch = gen_reg_rtx (HImode);
23653       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
23654       emit_insn (gen_andsi3 (operands[0],
23655                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
23656     }
23657   DONE;
23660 (define_expand "signbitsf2"
23661   [(use (match_operand:SI 0 "register_operand"))
23662    (use (match_operand:SF 1 "register_operand"))]
23663   "TARGET_USE_FANCY_MATH_387
23664    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
23666   rtx scratch = gen_reg_rtx (HImode);
23668   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
23669   emit_insn (gen_andsi3 (operands[0],
23670              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
23671   DONE;
23674 ;; Block operation instructions
23676 (define_insn "cld"
23677   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
23678   ""
23679   "cld"
23680   [(set_attr "length" "1")
23681    (set_attr "length_immediate" "0")
23682    (set_attr "modrm" "0")])
23684 (define_expand "cpymem<mode>"
23685   [(use (match_operand:BLK 0 "memory_operand"))
23686    (use (match_operand:BLK 1 "memory_operand"))
23687    (use (match_operand:SWI48 2 "nonmemory_operand"))
23688    (use (match_operand:SWI48 3 "const_int_operand"))
23689    (use (match_operand:SI 4 "const_int_operand"))
23690    (use (match_operand:SI 5 "const_int_operand"))
23691    (use (match_operand:SI 6 ""))
23692    (use (match_operand:SI 7 ""))
23693    (use (match_operand:SI 8 ""))]
23694   ""
23696  if (ix86_expand_set_or_cpymem (operands[0], operands[1],
23697                                 operands[2], NULL, operands[3],
23698                                 operands[4], operands[5],
23699                                 operands[6], operands[7],
23700                                 operands[8], false))
23701    DONE;
23702  else
23703    FAIL;
23706 ;; Most CPUs don't like single string operations
23707 ;; Handle this case here to simplify previous expander.
23709 (define_expand "strmov"
23710   [(set (match_dup 4) (match_operand 3 "memory_operand"))
23711    (set (match_operand 1 "memory_operand") (match_dup 4))
23712    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
23713               (clobber (reg:CC FLAGS_REG))])
23714    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
23715               (clobber (reg:CC FLAGS_REG))])]
23716   ""
23718   /* Can't use this for non-default address spaces.  */
23719   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
23720     FAIL;
23722   int piece_size = GET_MODE_SIZE (GET_MODE (operands[1]));
23724   /* If .md ever supports :P for Pmode, these can be directly
23725      in the pattern above.  */
23726   operands[5] = plus_constant (Pmode, operands[0], piece_size);
23727   operands[6] = plus_constant (Pmode, operands[2], piece_size);
23729   /* Can't use this if the user has appropriated esi or edi.  */
23730   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
23731       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
23732     {
23733       emit_insn (gen_strmov_singleop (operands[0], operands[1],
23734                                       operands[2], operands[3],
23735                                       operands[5], operands[6]));
23736       DONE;
23737     }
23739   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
23742 (define_expand "strmov_singleop"
23743   [(parallel [(set (match_operand 1 "memory_operand")
23744                    (match_operand 3 "memory_operand"))
23745               (set (match_operand 0 "register_operand")
23746                    (match_operand 4))
23747               (set (match_operand 2 "register_operand")
23748                    (match_operand 5))])]
23749   ""
23751   if (TARGET_CLD)
23752     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
23755 (define_insn "*strmovdi_rex_1"
23756   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
23757         (mem:DI (match_operand:P 3 "register_operand" "1")))
23758    (set (match_operand:P 0 "register_operand" "=D")
23759         (plus:P (match_dup 2)
23760                 (const_int 8)))
23761    (set (match_operand:P 1 "register_operand" "=S")
23762         (plus:P (match_dup 3)
23763                 (const_int 8)))]
23764   "TARGET_64BIT
23765    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
23766    && ix86_check_no_addr_space (insn)"
23767   "%^movsq"
23768   [(set_attr "type" "str")
23769    (set_attr "memory" "both")
23770    (set_attr "mode" "DI")])
23772 (define_insn "*strmovsi_1"
23773   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
23774         (mem:SI (match_operand:P 3 "register_operand" "1")))
23775    (set (match_operand:P 0 "register_operand" "=D")
23776         (plus:P (match_dup 2)
23777                 (const_int 4)))
23778    (set (match_operand:P 1 "register_operand" "=S")
23779         (plus:P (match_dup 3)
23780                 (const_int 4)))]
23781   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
23782    && ix86_check_no_addr_space (insn)"
23783   "%^movs{l|d}"
23784   [(set_attr "type" "str")
23785    (set_attr "memory" "both")
23786    (set_attr "mode" "SI")])
23788 (define_insn "*strmovhi_1"
23789   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
23790         (mem:HI (match_operand:P 3 "register_operand" "1")))
23791    (set (match_operand:P 0 "register_operand" "=D")
23792         (plus:P (match_dup 2)
23793                 (const_int 2)))
23794    (set (match_operand:P 1 "register_operand" "=S")
23795         (plus:P (match_dup 3)
23796                 (const_int 2)))]
23797   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
23798    && ix86_check_no_addr_space (insn)"
23799   "%^movsw"
23800   [(set_attr "type" "str")
23801    (set_attr "memory" "both")
23802    (set_attr "mode" "HI")])
23804 (define_insn "*strmovqi_1"
23805   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
23806         (mem:QI (match_operand:P 3 "register_operand" "1")))
23807    (set (match_operand:P 0 "register_operand" "=D")
23808         (plus:P (match_dup 2)
23809                 (const_int 1)))
23810    (set (match_operand:P 1 "register_operand" "=S")
23811         (plus:P (match_dup 3)
23812                 (const_int 1)))]
23813   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
23814    && ix86_check_no_addr_space (insn)"
23815   "%^movsb"
23816   [(set_attr "type" "str")
23817    (set_attr "memory" "both")
23818    (set (attr "prefix_rex")
23819         (if_then_else
23820           (match_test "<P:MODE>mode == DImode")
23821           (const_string "0")
23822           (const_string "*")))
23823    (set_attr "mode" "QI")])
23825 (define_expand "rep_mov"
23826   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
23827               (set (match_operand 0 "register_operand")
23828                    (match_operand 5))
23829               (set (match_operand 2 "register_operand")
23830                    (match_operand 6))
23831               (set (match_operand 1 "memory_operand")
23832                    (match_operand 3 "memory_operand"))
23833               (use (match_dup 4))])]
23834   ""
23836   if (TARGET_CLD)
23837     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
23840 (define_insn "*rep_movdi_rex64"
23841   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
23842    (set (match_operand:P 0 "register_operand" "=D")
23843         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
23844                           (const_int 3))
23845                 (match_operand:P 3 "register_operand" "0")))
23846    (set (match_operand:P 1 "register_operand" "=S")
23847         (plus:P (ashift:P (match_dup 5) (const_int 3))
23848                 (match_operand:P 4 "register_operand" "1")))
23849    (set (mem:BLK (match_dup 3))
23850         (mem:BLK (match_dup 4)))
23851    (use (match_dup 5))]
23852   "TARGET_64BIT
23853    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
23854    && ix86_check_no_addr_space (insn)"
23855   "%^rep{%;} movsq"
23856   [(set_attr "type" "str")
23857    (set_attr "prefix_rep" "1")
23858    (set_attr "memory" "both")
23859    (set_attr "mode" "DI")])
23861 (define_insn "*rep_movsi"
23862   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
23863    (set (match_operand:P 0 "register_operand" "=D")
23864         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
23865                           (const_int 2))
23866                  (match_operand:P 3 "register_operand" "0")))
23867    (set (match_operand:P 1 "register_operand" "=S")
23868         (plus:P (ashift:P (match_dup 5) (const_int 2))
23869                 (match_operand:P 4 "register_operand" "1")))
23870    (set (mem:BLK (match_dup 3))
23871         (mem:BLK (match_dup 4)))
23872    (use (match_dup 5))]
23873   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
23874    && ix86_check_no_addr_space (insn)"
23875   "%^rep{%;} movs{l|d}"
23876   [(set_attr "type" "str")
23877    (set_attr "prefix_rep" "1")
23878    (set_attr "memory" "both")
23879    (set_attr "mode" "SI")])
23881 (define_insn "*rep_movqi"
23882   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
23883    (set (match_operand:P 0 "register_operand" "=D")
23884         (plus:P (match_operand:P 3 "register_operand" "0")
23885                 (match_operand:P 5 "register_operand" "2")))
23886    (set (match_operand:P 1 "register_operand" "=S")
23887         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
23888    (set (mem:BLK (match_dup 3))
23889         (mem:BLK (match_dup 4)))
23890    (use (match_dup 5))]
23891   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
23892    && ix86_check_no_addr_space (insn)"
23893   "%^rep{%;} movsb"
23894   [(set_attr "type" "str")
23895    (set_attr "prefix_rep" "1")
23896    (set_attr "memory" "both")
23897    (set_attr "mode" "QI")])
23899 (define_expand "setmem<mode>"
23900    [(use (match_operand:BLK 0 "memory_operand"))
23901     (use (match_operand:SWI48 1 "nonmemory_operand"))
23902     (use (match_operand:QI 2 "nonmemory_operand"))
23903     (use (match_operand 3 "const_int_operand"))
23904     (use (match_operand:SI 4 "const_int_operand"))
23905     (use (match_operand:SI 5 "const_int_operand"))
23906     (use (match_operand:SI 6 ""))
23907     (use (match_operand:SI 7 ""))
23908     (use (match_operand:SI 8 ""))]
23909   ""
23911  if (ix86_expand_set_or_cpymem (operands[0], NULL,
23912                                 operands[1], operands[2],
23913                                 operands[3], operands[4],
23914                                 operands[5], operands[6],
23915                                 operands[7], operands[8], true))
23916    DONE;
23917  else
23918    FAIL;
23921 ;; Most CPUs don't like single string operations
23922 ;; Handle this case here to simplify previous expander.
23924 (define_expand "strset"
23925   [(set (match_operand 1 "memory_operand")
23926         (match_operand 2 "register_operand"))
23927    (parallel [(set (match_operand 0 "register_operand")
23928                    (match_dup 3))
23929               (clobber (reg:CC FLAGS_REG))])]
23930   ""
23932   /* Can't use this for non-default address spaces.  */
23933   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
23934     FAIL;
23936   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
23937     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
23939   /* If .md ever supports :P for Pmode, this can be directly
23940      in the pattern above.  */
23941   operands[3] = plus_constant (Pmode, operands[0],
23942                                GET_MODE_SIZE (GET_MODE (operands[2])));
23944   /* Can't use this if the user has appropriated eax or edi.  */
23945   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
23946       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
23947     {
23948       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
23949                                       operands[3]));
23950       DONE;
23951     }
23954 (define_expand "strset_singleop"
23955   [(parallel [(set (match_operand 1 "memory_operand")
23956                    (match_operand 2 "register_operand"))
23957               (set (match_operand 0 "register_operand")
23958                    (match_operand 3))
23959               (unspec [(const_int 0)] UNSPEC_STOS)])]
23960   ""
23962   if (TARGET_CLD)
23963     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
23966 (define_insn "*strsetdi_rex_1"
23967   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
23968         (match_operand:DI 2 "register_operand" "a"))
23969    (set (match_operand:P 0 "register_operand" "=D")
23970         (plus:P (match_dup 1)
23971                 (const_int 8)))
23972    (unspec [(const_int 0)] UNSPEC_STOS)]
23973   "TARGET_64BIT
23974    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
23975    && ix86_check_no_addr_space (insn)"
23976   "%^stosq"
23977   [(set_attr "type" "str")
23978    (set_attr "memory" "store")
23979    (set_attr "mode" "DI")])
23981 (define_insn "*strsetsi_1"
23982   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
23983         (match_operand:SI 2 "register_operand" "a"))
23984    (set (match_operand:P 0 "register_operand" "=D")
23985         (plus:P (match_dup 1)
23986                 (const_int 4)))
23987    (unspec [(const_int 0)] UNSPEC_STOS)]
23988   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
23989    && ix86_check_no_addr_space (insn)"
23990   "%^stos{l|d}"
23991   [(set_attr "type" "str")
23992    (set_attr "memory" "store")
23993    (set_attr "mode" "SI")])
23995 (define_insn "*strsethi_1"
23996   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
23997         (match_operand:HI 2 "register_operand" "a"))
23998    (set (match_operand:P 0 "register_operand" "=D")
23999         (plus:P (match_dup 1)
24000                 (const_int 2)))
24001    (unspec [(const_int 0)] UNSPEC_STOS)]
24002   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
24003    && ix86_check_no_addr_space (insn)"
24004   "%^stosw"
24005   [(set_attr "type" "str")
24006    (set_attr "memory" "store")
24007    (set_attr "mode" "HI")])
24009 (define_insn "*strsetqi_1"
24010   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
24011         (match_operand:QI 2 "register_operand" "a"))
24012    (set (match_operand:P 0 "register_operand" "=D")
24013         (plus:P (match_dup 1)
24014                 (const_int 1)))
24015    (unspec [(const_int 0)] UNSPEC_STOS)]
24016   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
24017    && ix86_check_no_addr_space (insn)"
24018   "%^stosb"
24019   [(set_attr "type" "str")
24020    (set_attr "memory" "store")
24021    (set (attr "prefix_rex")
24022         (if_then_else
24023           (match_test "<P:MODE>mode == DImode")
24024           (const_string "0")
24025           (const_string "*")))
24026    (set_attr "mode" "QI")])
24028 (define_expand "rep_stos"
24029   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
24030               (set (match_operand 0 "register_operand")
24031                    (match_operand 4))
24032               (set (match_operand 2 "memory_operand") (const_int 0))
24033               (use (match_operand 3 "register_operand"))
24034               (use (match_dup 1))])]
24035   ""
24037   if (TARGET_CLD)
24038     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
24041 (define_insn "*rep_stosdi_rex64"
24042   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
24043    (set (match_operand:P 0 "register_operand" "=D")
24044         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
24045                           (const_int 3))
24046                  (match_operand:P 3 "register_operand" "0")))
24047    (set (mem:BLK (match_dup 3))
24048         (const_int 0))
24049    (use (match_operand:DI 2 "register_operand" "a"))
24050    (use (match_dup 4))]
24051   "TARGET_64BIT
24052    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
24053    && ix86_check_no_addr_space (insn)"
24054   "%^rep{%;} stosq"
24055   [(set_attr "type" "str")
24056    (set_attr "prefix_rep" "1")
24057    (set_attr "memory" "store")
24058    (set_attr "mode" "DI")])
24060 (define_insn "*rep_stossi"
24061   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
24062    (set (match_operand:P 0 "register_operand" "=D")
24063         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
24064                           (const_int 2))
24065                  (match_operand:P 3 "register_operand" "0")))
24066    (set (mem:BLK (match_dup 3))
24067         (const_int 0))
24068    (use (match_operand:SI 2 "register_operand" "a"))
24069    (use (match_dup 4))]
24070   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
24071    && ix86_check_no_addr_space (insn)"
24072   "%^rep{%;} stos{l|d}"
24073   [(set_attr "type" "str")
24074    (set_attr "prefix_rep" "1")
24075    (set_attr "memory" "store")
24076    (set_attr "mode" "SI")])
24078 (define_insn "*rep_stosqi"
24079   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
24080    (set (match_operand:P 0 "register_operand" "=D")
24081         (plus:P (match_operand:P 3 "register_operand" "0")
24082                 (match_operand:P 4 "register_operand" "1")))
24083    (set (mem:BLK (match_dup 3))
24084         (const_int 0))
24085    (use (match_operand:QI 2 "register_operand" "a"))
24086    (use (match_dup 4))]
24087   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
24088    && ix86_check_no_addr_space (insn)"
24089   "%^rep{%;} stosb"
24090   [(set_attr "type" "str")
24091    (set_attr "prefix_rep" "1")
24092    (set_attr "memory" "store")
24093    (set (attr "prefix_rex")
24094         (if_then_else
24095           (match_test "<P:MODE>mode == DImode")
24096           (const_string "0")
24097           (const_string "*")))
24098    (set_attr "mode" "QI")])
24100 (define_expand "cmpmemsi"
24101   [(set (match_operand:SI 0 "register_operand" "")
24102         (compare:SI (match_operand:BLK 1 "memory_operand" "")
24103                     (match_operand:BLK 2 "memory_operand" "") ) )
24104    (use (match_operand 3 "general_operand"))
24105    (use (match_operand 4 "immediate_operand"))]
24106   ""
24108   if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
24109                                      operands[2], operands[3],
24110                                      operands[4], false))
24111     DONE;
24112   else
24113     FAIL;
24116 (define_expand "cmpstrnsi"
24117   [(set (match_operand:SI 0 "register_operand")
24118         (compare:SI (match_operand:BLK 1 "general_operand")
24119                     (match_operand:BLK 2 "general_operand")))
24120    (use (match_operand 3 "general_operand"))
24121    (use (match_operand 4 "immediate_operand"))]
24122   ""
24124   if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
24125                                      operands[2], operands[3],
24126                                      operands[4], true))
24127     DONE;
24128   else
24129     FAIL;
24132 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
24134 (define_expand "cmpintqi"
24135   [(set (match_dup 1)
24136         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
24137    (set (match_dup 2)
24138         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
24139    (parallel [(set (match_operand:QI 0 "register_operand")
24140                    (minus:QI (match_dup 1)
24141                              (match_dup 2)))
24142               (clobber (reg:CC FLAGS_REG))])]
24143   ""
24145   operands[1] = gen_reg_rtx (QImode);
24146   operands[2] = gen_reg_rtx (QImode);
24149 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
24150 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
24152 (define_expand "cmpstrnqi_nz_1"
24153   [(parallel [(set (reg:CC FLAGS_REG)
24154                    (compare:CC (match_operand 4 "memory_operand")
24155                                (match_operand 5 "memory_operand")))
24156               (use (match_operand 2 "register_operand"))
24157               (use (match_operand:SI 3 "immediate_operand"))
24158               (clobber (match_operand 0 "register_operand"))
24159               (clobber (match_operand 1 "register_operand"))
24160               (clobber (match_dup 2))])]
24161   ""
24163   if (TARGET_CLD)
24164     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
24167 (define_insn "*cmpstrnqi_nz_1"
24168   [(set (reg:CC FLAGS_REG)
24169         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
24170                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
24171    (use (match_operand:P 6 "register_operand" "2"))
24172    (use (match_operand:SI 3 "immediate_operand" "i"))
24173    (clobber (match_operand:P 0 "register_operand" "=S"))
24174    (clobber (match_operand:P 1 "register_operand" "=D"))
24175    (clobber (match_operand:P 2 "register_operand" "=c"))]
24176   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
24177    && ix86_check_no_addr_space (insn)"
24178   "%^repz{%;} cmpsb"
24179   [(set_attr "type" "str")
24180    (set_attr "mode" "QI")
24181    (set (attr "prefix_rex")
24182         (if_then_else
24183           (match_test "<P:MODE>mode == DImode")
24184           (const_string "0")
24185           (const_string "*")))
24186    (set_attr "prefix_rep" "1")])
24188 ;; The same, but the count is not known to not be zero.
24190 (define_expand "cmpstrnqi_1"
24191   [(parallel [(set (reg:CC FLAGS_REG)
24192                 (if_then_else:CC (ne (match_operand 2 "register_operand")
24193                                      (const_int 0))
24194                   (compare:CC (match_operand 4 "memory_operand")
24195                               (match_operand 5 "memory_operand"))
24196                   (reg:CC FLAGS_REG)))
24197               (use (match_operand:SI 3 "immediate_operand"))
24198               (clobber (match_operand 0 "register_operand"))
24199               (clobber (match_operand 1 "register_operand"))
24200               (clobber (match_dup 2))])]
24201   ""
24203   if (TARGET_CLD)
24204     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
24207 (define_insn "*cmpstrnqi_1"
24208   [(set (reg:CC FLAGS_REG)
24209         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
24210                              (const_int 0))
24211           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
24212                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
24213           (reg:CC FLAGS_REG)))
24214    (use (match_operand:SI 3 "immediate_operand" "i"))
24215    (clobber (match_operand:P 0 "register_operand" "=S"))
24216    (clobber (match_operand:P 1 "register_operand" "=D"))
24217    (clobber (match_operand:P 2 "register_operand" "=c"))]
24218   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
24219    && ix86_check_no_addr_space (insn)"
24220   "%^repz{%;} cmpsb"
24221   [(set_attr "type" "str")
24222    (set_attr "mode" "QI")
24223    (set (attr "prefix_rex")
24224         (if_then_else
24225           (match_test "<P:MODE>mode == DImode")
24226           (const_string "0")
24227           (const_string "*")))
24228    (set_attr "prefix_rep" "1")])
24230 (define_expand "strlen<mode>"
24231   [(set (match_operand:P 0 "register_operand")
24232         (unspec:P [(match_operand:BLK 1 "general_operand")
24233                    (match_operand:QI 2 "immediate_operand")
24234                    (match_operand 3 "immediate_operand")]
24235                   UNSPEC_SCAS))]
24236   ""
24238  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
24239    DONE;
24240  else
24241    FAIL;
24244 (define_expand "strlenqi_1"
24245   [(parallel [(set (match_operand 0 "register_operand")
24246                    (match_operand 2))
24247               (clobber (match_operand 1 "register_operand"))
24248               (clobber (reg:CC FLAGS_REG))])]
24249   ""
24251   if (TARGET_CLD)
24252     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
24255 (define_insn "*strlenqi_1"
24256   [(set (match_operand:P 0 "register_operand" "=&c")
24257         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
24258                    (match_operand:QI 2 "register_operand" "a")
24259                    (match_operand:P 3 "immediate_operand" "i")
24260                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
24261    (clobber (match_operand:P 1 "register_operand" "=D"))
24262    (clobber (reg:CC FLAGS_REG))]
24263   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
24264    && ix86_check_no_addr_space (insn)"
24265   "%^repnz{%;} scasb"
24266   [(set_attr "type" "str")
24267    (set_attr "mode" "QI")
24268    (set (attr "prefix_rex")
24269         (if_then_else
24270           (match_test "<P:MODE>mode == DImode")
24271           (const_string "0")
24272           (const_string "*")))
24273    (set_attr "prefix_rep" "1")])
24275 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
24276 ;; handled in combine, but it is not currently up to the task.
24277 ;; When used for their truth value, the cmpstrn* expanders generate
24278 ;; code like this:
24280 ;;   repz cmpsb
24281 ;;   seta       %al
24282 ;;   setb       %dl
24283 ;;   cmpb       %al, %dl
24284 ;;   jcc        label
24286 ;; The intermediate three instructions are unnecessary.
24288 ;; This one handles cmpstrn*_nz_1...
24289 (define_peephole2
24290   [(parallel[
24291      (set (reg:CC FLAGS_REG)
24292           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
24293                       (mem:BLK (match_operand 5 "register_operand"))))
24294      (use (match_operand 6 "register_operand"))
24295      (use (match_operand:SI 3 "immediate_operand"))
24296      (clobber (match_operand 0 "register_operand"))
24297      (clobber (match_operand 1 "register_operand"))
24298      (clobber (match_operand 2 "register_operand"))])
24299    (set (match_operand:QI 7 "register_operand")
24300         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
24301    (set (match_operand:QI 8 "register_operand")
24302         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
24303    (set (reg FLAGS_REG)
24304         (compare (match_dup 7) (match_dup 8)))
24305   ]
24306   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
24307   [(parallel[
24308      (set (reg:CC FLAGS_REG)
24309           (compare:CC (mem:BLK (match_dup 4))
24310                       (mem:BLK (match_dup 5))))
24311      (use (match_dup 6))
24312      (use (match_dup 3))
24313      (clobber (match_dup 0))
24314      (clobber (match_dup 1))
24315      (clobber (match_dup 2))])])
24317 ;; ...and this one handles cmpstrn*_1.
24318 (define_peephole2
24319   [(parallel[
24320      (set (reg:CC FLAGS_REG)
24321           (if_then_else:CC (ne (match_operand 6 "register_operand")
24322                                (const_int 0))
24323             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
24324                         (mem:BLK (match_operand 5 "register_operand")))
24325             (reg:CC FLAGS_REG)))
24326      (use (match_operand:SI 3 "immediate_operand"))
24327      (clobber (match_operand 0 "register_operand"))
24328      (clobber (match_operand 1 "register_operand"))
24329      (clobber (match_operand 2 "register_operand"))])
24330    (set (match_operand:QI 7 "register_operand")
24331         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
24332    (set (match_operand:QI 8 "register_operand")
24333         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
24334    (set (reg FLAGS_REG)
24335         (compare (match_dup 7) (match_dup 8)))
24336   ]
24337   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
24338   [(parallel[
24339      (set (reg:CC FLAGS_REG)
24340           (if_then_else:CC (ne (match_dup 6)
24341                                (const_int 0))
24342             (compare:CC (mem:BLK (match_dup 4))
24343                         (mem:BLK (match_dup 5)))
24344             (reg:CC FLAGS_REG)))
24345      (use (match_dup 3))
24346      (clobber (match_dup 0))
24347      (clobber (match_dup 1))
24348      (clobber (match_dup 2))])])
24350 ;; Conditional move instructions.
24352 (define_expand "mov<mode>cc"
24353   [(set (match_operand:SWIM 0 "register_operand")
24354         (if_then_else:SWIM (match_operand 1 "comparison_operator")
24355                            (match_operand:SWIM 2 "<general_operand>")
24356                            (match_operand:SWIM 3 "<general_operand>")))]
24357   ""
24358   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
24360 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
24361 ;; the register first winds up with `sbbl $0,reg', which is also weird.
24362 ;; So just document what we're doing explicitly.
24364 (define_expand "x86_mov<mode>cc_0_m1"
24365   [(parallel
24366     [(set (match_operand:SWI48 0 "register_operand")
24367           (if_then_else:SWI48
24368             (match_operator:SWI48 2 "ix86_carry_flag_operator"
24369              [(match_operand 1 "flags_reg_operand")
24370               (const_int 0)])
24371             (const_int -1)
24372             (const_int 0)))
24373      (clobber (reg:CC FLAGS_REG))])])
24375 (define_insn "*x86_mov<mode>cc_0_m1"
24376   [(set (match_operand:SWI48 0 "register_operand" "=r")
24377         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
24378                              [(reg FLAGS_REG) (const_int 0)])
24379           (const_int -1)
24380           (const_int 0)))
24381    (clobber (reg:CC FLAGS_REG))]
24382   ""
24383   "sbb{<imodesuffix>}\t%0, %0"
24384   [(set_attr "type" "alu1")
24385    (set_attr "use_carry" "1")
24386    (set_attr "pent_pair" "pu")
24387    (set_attr "mode" "<MODE>")
24388    (set_attr "length_immediate" "0")])
24390 (define_insn "*x86_mov<mode>cc_0_m1_se"
24391   [(set (match_operand:SWI48 0 "register_operand" "=r")
24392         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
24393                              [(reg FLAGS_REG) (const_int 0)])
24394                             (const_int 1)
24395                             (const_int 0)))
24396    (clobber (reg:CC FLAGS_REG))]
24397   ""
24398   "sbb{<imodesuffix>}\t%0, %0"
24399   [(set_attr "type" "alu1")
24400    (set_attr "use_carry" "1")
24401    (set_attr "pent_pair" "pu")
24402    (set_attr "mode" "<MODE>")
24403    (set_attr "length_immediate" "0")])
24405 (define_insn "*x86_mov<mode>cc_0_m1_neg"
24406   [(set (match_operand:SWI 0 "register_operand" "=<r>")
24407         (neg:SWI (match_operator 1 "ix86_carry_flag_operator"
24408                   [(reg FLAGS_REG) (const_int 0)])))
24409    (clobber (reg:CC FLAGS_REG))]
24410   ""
24411   "sbb{<imodesuffix>}\t%0, %0"
24412   [(set_attr "type" "alu1")
24413    (set_attr "use_carry" "1")
24414    (set_attr "pent_pair" "pu")
24415    (set_attr "mode" "<MODE>")
24416    (set_attr "length_immediate" "0")])
24418 (define_expand "x86_mov<mode>cc_0_m1_neg"
24419   [(parallel
24420     [(set (match_operand:SWI48 0 "register_operand")
24421           (neg:SWI48 (ltu:SWI48 (reg:CCC FLAGS_REG) (const_int 0))))
24422      (clobber (reg:CC FLAGS_REG))])])
24424 (define_split
24425   [(set (match_operand:SWI48 0 "register_operand")
24426         (neg:SWI48
24427           (leu:SWI48
24428             (match_operand 1 "int_nonimmediate_operand")
24429             (match_operand 2 "const_int_operand"))))]
24430   "x86_64_immediate_operand (operands[2], VOIDmode)
24431    && INTVAL (operands[2]) != -1
24432    && INTVAL (operands[2]) != 2147483647"
24433   [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
24434    (set (match_dup 0)
24435         (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))]
24436   "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
24438 (define_split
24439   [(set (match_operand:SWI 0 "register_operand")
24440         (neg:SWI
24441           (eq:SWI
24442             (match_operand 1 "int_nonimmediate_operand")
24443             (const_int 0))))]
24444   ""
24445   [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (const_int 1)))
24446    (set (match_dup 0)
24447         (neg:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))])
24449 (define_split
24450   [(set (match_operand:SWI 0 "register_operand")
24451         (neg:SWI
24452           (ne:SWI
24453             (match_operand 1 "int_nonimmediate_operand")
24454             (const_int 0))))]
24455   ""
24456   [(set (reg:CCC FLAGS_REG)
24457         (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
24458    (set (match_dup 0)
24459         (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))])
24461 (define_insn "*mov<mode>cc_noc"
24462   [(set (match_operand:SWI248 0 "register_operand" "=r,r,r,r")
24463         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
24464                                [(reg FLAGS_REG) (const_int 0)])
24465           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0,rm,r")
24466           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm,r,rm")))]
24467   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
24468   "@
24469    cmov%O2%C1\t{%2, %0|%0, %2}
24470    cmov%O2%c1\t{%3, %0|%0, %3}
24471    cmov%O2%C1\t{%2, %3, %0|%0, %3, %2}
24472    cmov%O2%c1\t{%3, %2, %0|%0, %2, %3}"
24473   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
24474    (set_attr "type" "icmov")
24475    (set_attr "mode" "<MODE>")])
24477 (define_insn "*movsicc_noc_zext"
24478   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
24479         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
24480                            [(reg FLAGS_REG) (const_int 0)])
24481           (zero_extend:DI
24482             (match_operand:SI 2 "nonimmediate_operand" "rm,0,rm,r"))
24483           (zero_extend:DI
24484             (match_operand:SI 3 "nonimmediate_operand" "0,rm,r,rm"))))]
24485   "TARGET_64BIT
24486    && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
24487   "@
24488    cmov%O2%C1\t{%2, %k0|%k0, %2}
24489    cmov%O2%c1\t{%3, %k0|%k0, %3}
24490    cmov%O2%C1\t{%2, %3, %k0|%k0, %3, %2}
24491    cmov%O2%c1\t{%3, %2, %k0|%k0, %2, %3}"
24492   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
24493    (set_attr "type" "icmov")
24494    (set_attr "mode" "SI")])
24496 (define_insn "*movsicc_noc_zext_1"
24497   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r")
24498         (zero_extend:DI
24499           (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
24500                              [(reg FLAGS_REG) (const_int 0)])
24501              (match_operand:SI 2 "nonimmediate_operand" "rm,0,rm,r")
24502              (match_operand:SI 3 "nonimmediate_operand" "0,rm,r,rm"))))]
24503   "TARGET_64BIT
24504    && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
24505   "@
24506    cmov%O2%C1\t{%2, %k0|%k0, %2}
24507    cmov%O2%c1\t{%3, %k0|%k0, %3}
24508    cmov%O2%C1\t{%2, %3, %k0|%k0, %3, %2}
24509    cmov%O2%c1\t{%3, %2, %k0|%k0, %2, %3}"
24510   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
24511    (set_attr "type" "icmov")
24512    (set_attr "mode" "SI")])
24515 ;; Don't do conditional moves with memory inputs.  This splitter helps
24516 ;; register starved x86_32 by forcing inputs into registers before reload.
24517 (define_split
24518   [(set (match_operand:SWI248 0 "register_operand")
24519         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
24520                                [(reg FLAGS_REG) (const_int 0)])
24521           (match_operand:SWI248 2 "nonimmediate_operand")
24522           (match_operand:SWI248 3 "nonimmediate_operand")))]
24523   "!TARGET_64BIT && TARGET_CMOVE
24524    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
24525    && (MEM_P (operands[2]) || MEM_P (operands[3]))
24526    && can_create_pseudo_p ()
24527    && optimize_insn_for_speed_p ()"
24528   [(set (match_dup 0)
24529         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
24531   operands[2] = force_reg (<MODE>mode, operands[2]);
24532   operands[3] = force_reg (<MODE>mode, operands[3]);
24535 (define_insn "*movqicc_noc"
24536   [(set (match_operand:QI 0 "register_operand" "=r,r,r")
24537         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
24538                            [(reg FLAGS_REG) (const_int 0)])
24539                       (match_operand:QI 2 "register_operand" "r,0,r")
24540                       (match_operand:QI 3 "register_operand" "0,r,r")))]
24541   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
24542   "#"
24543   [(set_attr "isa" "*,*,apx_ndd")
24544    (set_attr "type" "icmov")
24545    (set_attr "mode" "QI")])
24547 (define_split
24548   [(set (match_operand:SWI12 0 "register_operand")
24549         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
24550                               [(reg FLAGS_REG) (const_int 0)])
24551                       (match_operand:SWI12 2 "register_operand")
24552                       (match_operand:SWI12 3 "register_operand")))]
24553   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
24554    && reload_completed"
24555   [(set (match_dup 0)
24556         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
24558   operands[0] = gen_lowpart (SImode, operands[0]);
24559   operands[2] = gen_lowpart (SImode, operands[2]);
24560   operands[3] = gen_lowpart (SImode, operands[3]);
24563 ;; Don't do conditional moves with memory inputs
24564 (define_peephole2
24565   [(match_scratch:SWI248 4 "r")
24566    (set (match_operand:SWI248 0 "register_operand")
24567         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
24568                                [(reg FLAGS_REG) (const_int 0)])
24569           (match_operand:SWI248 2 "nonimmediate_operand")
24570           (match_operand:SWI248 3 "nonimmediate_operand")))]
24571   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
24572    && (MEM_P (operands[2]) || MEM_P (operands[3]))
24573    && optimize_insn_for_speed_p ()"
24574   [(set (match_dup 4) (match_dup 5))
24575    (set (match_dup 0)
24576         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
24578   if (MEM_P (operands[2]))
24579     {
24580       operands[5] = operands[2];
24581       operands[2] = operands[4];
24582     }
24583   else if (MEM_P (operands[3]))
24584     {
24585       operands[5] = operands[3];
24586       operands[3] = operands[4];
24587     }
24588   else
24589     gcc_unreachable ();
24592 (define_peephole2
24593   [(match_scratch:SI 4 "r")
24594    (set (match_operand:DI 0 "register_operand")
24595         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
24596                            [(reg FLAGS_REG) (const_int 0)])
24597           (zero_extend:DI
24598             (match_operand:SI 2 "nonimmediate_operand"))
24599           (zero_extend:DI
24600             (match_operand:SI 3 "nonimmediate_operand"))))]
24601   "TARGET_64BIT
24602    && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
24603    && (MEM_P (operands[2]) || MEM_P (operands[3]))
24604    && optimize_insn_for_speed_p ()"
24605   [(set (match_dup 4) (match_dup 5))
24606    (set (match_dup 0)
24607         (if_then_else:DI (match_dup 1)
24608           (zero_extend:DI (match_dup 2))
24609           (zero_extend:DI (match_dup 3))))]
24611   if (MEM_P (operands[2]))
24612     {
24613       operands[5] = operands[2];
24614       operands[2] = operands[4];
24615     }
24616   else if (MEM_P (operands[3]))
24617     {
24618       operands[5] = operands[3];
24619       operands[3] = operands[4];
24620     }
24621   else
24622     gcc_unreachable ();
24625 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#1).
24626 ;; mov r0,r1; dec r0; mov r2,r3; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
24627 (define_peephole2
24628  [(set (match_operand:SWI248 0 "general_reg_operand")
24629        (match_operand:SWI248 1 "general_reg_operand"))
24630   (parallel [(set (reg FLAGS_REG) (match_operand 5))
24631              (set (match_dup 0) (match_operand:SWI248 6))])
24632   (set (match_operand:SWI248 2 "general_reg_operand")
24633        (match_operand:SWI248 3 "general_gr_operand"))
24634   (set (match_dup 0)
24635        (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
24636                              [(reg FLAGS_REG) (const_int 0)])
24637         (match_dup 0)
24638         (match_dup 2)))]
24639  "TARGET_CMOVE
24640   && REGNO (operands[2]) != REGNO (operands[0])
24641   && REGNO (operands[2]) != REGNO (operands[1])
24642   && peep2_reg_dead_p (1, operands[1])
24643   && peep2_reg_dead_p (4, operands[2])
24644   && !reg_overlap_mentioned_p (operands[0], operands[3])"
24645  [(parallel [(set (match_dup 7) (match_dup 8))
24646              (set (match_dup 1) (match_dup 9))])
24647   (set (match_dup 0) (match_dup 3))
24648   (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
24649                                           (match_dup 1)
24650                                           (match_dup 0)))]
24652   operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
24653   operands[8]
24654     = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
24655   operands[9]
24656     = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
24659 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#2).
24660 ;; mov r2,r3; mov r0,r1; dec r0; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
24661 (define_peephole2
24662  [(set (match_operand:SWI248 2 "general_reg_operand")
24663        (match_operand:SWI248 3 "general_gr_operand"))
24664   (set (match_operand:SWI248 0 "general_reg_operand")
24665        (match_operand:SWI248 1 "general_reg_operand"))
24666   (parallel [(set (reg FLAGS_REG) (match_operand 5))
24667              (set (match_dup 0) (match_operand:SWI248 6))])
24668   (set (match_dup 0)
24669        (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
24670                              [(reg FLAGS_REG) (const_int 0)])
24671         (match_dup 0)
24672         (match_dup 2)))]
24673  "TARGET_CMOVE
24674   && REGNO (operands[2]) != REGNO (operands[0])
24675   && REGNO (operands[2]) != REGNO (operands[1])
24676   && peep2_reg_dead_p (2, operands[1])
24677   && peep2_reg_dead_p (4, operands[2])
24678   && !reg_overlap_mentioned_p (operands[0], operands[3])
24679   && !reg_mentioned_p (operands[2], operands[6])"
24680  [(parallel [(set (match_dup 7) (match_dup 8))
24681              (set (match_dup 1) (match_dup 9))])
24682   (set (match_dup 0) (match_dup 3))
24683   (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
24684                                           (match_dup 1)
24685                                           (match_dup 0)))]
24687   operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (2)), 0, 0));
24688   operands[8]
24689     = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
24690   operands[9]
24691     = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
24694 (define_insn "movhf_mask"
24695   [(set (match_operand:HF 0 "nonimmediate_operand" "=v,m,v")
24696         (unspec:HF
24697           [(match_operand:HF 1 "nonimmediate_operand" "m,v,v")
24698            (match_operand:HF 2 "nonimm_or_0_operand" "0C,0C,0C")
24699            (match_operand:QI 3 "register_operand" "Yk,Yk,Yk")]
24700           UNSPEC_MOVCC_MASK))]
24701   "TARGET_AVX512FP16"
24702   "@
24703    vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
24704    vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
24705    vmovsh\t{%d1, %0%{%3%}%N2|%0%{%3%}%N2, %d1}"
24706   [(set_attr "type" "ssemov")
24707    (set_attr "prefix" "evex")
24708    (set_attr "mode" "HF")])
24710 (define_expand "movhfcc"
24711   [(set (match_operand:HF 0 "register_operand")
24712         (if_then_else:HF
24713           (match_operand 1 "comparison_operator")
24714           (match_operand:HF 2 "register_operand")
24715           (match_operand:HF 3 "register_operand")))]
24716   "TARGET_AVX512FP16"
24717   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
24719 (define_expand "mov<mode>cc"
24720   [(set (match_operand:X87MODEF 0 "register_operand")
24721         (if_then_else:X87MODEF
24722           (match_operand 1 "comparison_operator")
24723           (match_operand:X87MODEF 2 "register_operand")
24724           (match_operand:X87MODEF 3 "register_operand")))]
24725   "(TARGET_80387 && TARGET_CMOVE)
24726    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
24727   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
24729 (define_insn "*movxfcc_1"
24730   [(set (match_operand:XF 0 "register_operand" "=f,f")
24731         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
24732                                 [(reg FLAGS_REG) (const_int 0)])
24733                       (match_operand:XF 2 "register_operand" "f,0")
24734                       (match_operand:XF 3 "register_operand" "0,f")))]
24735   "TARGET_80387 && TARGET_CMOVE"
24736   "@
24737    fcmov%F1\t{%2, %0|%0, %2}
24738    fcmov%f1\t{%3, %0|%0, %3}"
24739   [(set_attr "type" "fcmov")
24740    (set_attr "mode" "XF")])
24742 (define_insn "*movdfcc_1"
24743   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
24744         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
24745                                 [(reg FLAGS_REG) (const_int 0)])
24746                       (match_operand:DF 2 "nonimmediate_operand"
24747                                                "f ,0,rm,0 ,rm,0")
24748                       (match_operand:DF 3 "nonimmediate_operand"
24749                                                "0 ,f,0 ,rm,0, rm")))]
24750   "TARGET_80387 && TARGET_CMOVE
24751    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
24752   "@
24753    fcmov%F1\t{%2, %0|%0, %2}
24754    fcmov%f1\t{%3, %0|%0, %3}
24755    #
24756    #
24757    cmov%O2%C1\t{%2, %0|%0, %2}
24758    cmov%O2%c1\t{%3, %0|%0, %3}"
24759   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
24760    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
24761    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
24763 (define_split
24764   [(set (match_operand:DF 0 "general_reg_operand")
24765         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
24766                                 [(reg FLAGS_REG) (const_int 0)])
24767                       (match_operand:DF 2 "nonimmediate_operand")
24768                       (match_operand:DF 3 "nonimmediate_operand")))]
24769   "!TARGET_64BIT && reload_completed"
24770   [(set (match_dup 2)
24771         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
24772    (set (match_dup 3)
24773         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
24775   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
24776   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
24779 (define_insn "*movsfcc_1_387"
24780   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
24781         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
24782                                 [(reg FLAGS_REG) (const_int 0)])
24783                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
24784                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
24785   "TARGET_80387 && TARGET_CMOVE
24786    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
24787   "@
24788    fcmov%F1\t{%2, %0|%0, %2}
24789    fcmov%f1\t{%3, %0|%0, %3}
24790    cmov%O2%C1\t{%2, %0|%0, %2}
24791    cmov%O2%c1\t{%3, %0|%0, %3}"
24792   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
24793    (set_attr "mode" "SF,SF,SI,SI")])
24795 ;; Don't do conditional moves with memory inputs.  This splitter helps
24796 ;; register starved x86_32 by forcing inputs into registers before reload.
24797 (define_split
24798   [(set (match_operand:MODEF 0 "register_operand")
24799         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
24800                               [(reg FLAGS_REG) (const_int 0)])
24801           (match_operand:MODEF 2 "nonimmediate_operand")
24802           (match_operand:MODEF 3 "nonimmediate_operand")))]
24803   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
24804    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
24805    && (MEM_P (operands[2]) || MEM_P (operands[3]))
24806    && can_create_pseudo_p ()
24807    && optimize_insn_for_speed_p ()"
24808   [(set (match_dup 0)
24809         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
24811   operands[2] = force_reg (<MODE>mode, operands[2]);
24812   operands[3] = force_reg (<MODE>mode, operands[3]);
24815 ;; Don't do conditional moves with memory inputs
24816 (define_peephole2
24817   [(match_scratch:MODEF 4 "r")
24818    (set (match_operand:MODEF 0 "general_reg_operand")
24819         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
24820                               [(reg FLAGS_REG) (const_int 0)])
24821           (match_operand:MODEF 2 "nonimmediate_operand")
24822           (match_operand:MODEF 3 "nonimmediate_operand")))]
24823   "(<MODE>mode != DFmode || TARGET_64BIT)
24824    && TARGET_80387 && TARGET_CMOVE
24825    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
24826    && (MEM_P (operands[2]) || MEM_P (operands[3]))
24827    && optimize_insn_for_speed_p ()"
24828   [(set (match_dup 4) (match_dup 5))
24829    (set (match_dup 0)
24830         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
24832   if (MEM_P (operands[2]))
24833     {
24834       operands[5] = operands[2];
24835       operands[2] = operands[4];
24836     }
24837   else if (MEM_P (operands[3]))
24838     {
24839       operands[5] = operands[3];
24840       operands[3] = operands[4];
24841     }
24842   else
24843     gcc_unreachable ();
24846 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
24847 ;; the scalar versions to have only XMM registers as operands.
24849 ;; XOP conditional move
24850 (define_insn "*xop_pcmov_<mode>"
24851   [(set (match_operand:MODEF 0 "register_operand" "=x")
24852         (if_then_else:MODEF
24853           (match_operand:MODEF 1 "register_operand" "x")
24854           (match_operand:MODEF 2 "register_operand" "x")
24855           (match_operand:MODEF 3 "register_operand" "x")))]
24856   "TARGET_XOP"
24857   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
24858   [(set_attr "type" "sse4arg")
24859    (set_attr "mode" "TI")])
24861 ;; These versions of the min/max patterns are intentionally ignorant of
24862 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
24863 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
24864 ;; are undefined in this condition, we're certain this is correct.
24866 (define_insn "<code><mode>3"
24867   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
24868         (smaxmin:MODEF
24869           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
24870           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
24871   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
24872   "@
24873    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
24874    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
24875   [(set_attr "isa" "noavx,avx")
24876    (set_attr "prefix" "orig,vex")
24877    (set_attr "type" "sseadd")
24878    (set_attr "mode" "<MODE>")])
24880 (define_insn "<code>hf3"
24881   [(set (match_operand:HF 0 "register_operand" "=v")
24882         (smaxmin:HF
24883           (match_operand:HF 1 "nonimmediate_operand" "%v")
24884           (match_operand:HF 2 "nonimmediate_operand" "vm")))]
24885   "TARGET_AVX512FP16"
24886   "v<maxmin_float>sh\t{%2, %1, %0|%0, %1, %2}"
24887   [(set_attr "prefix" "evex")
24888    (set_attr "type" "sseadd")
24889    (set_attr "mode" "HF")])
24891 ;; These versions of the min/max patterns implement exactly the operations
24892 ;;   min = (op1 < op2 ? op1 : op2)
24893 ;;   max = (!(op1 < op2) ? op1 : op2)
24894 ;; Their operands are not commutative, and thus they may be used in the
24895 ;; presence of -0.0 and NaN.
24897 (define_insn "*ieee_s<ieee_maxmin>hf3"
24898   [(set (match_operand:HF 0 "register_operand" "=v")
24899         (unspec:HF
24900           [(match_operand:HF 1 "register_operand" "v")
24901            (match_operand:HF 2 "nonimmediate_operand" "vm")]
24902           IEEE_MAXMIN))]
24903   "TARGET_AVX512FP16"
24904   "v<ieee_maxmin>sh\t{%2, %1, %0|%0, %1, %2}"
24905   [(set_attr "prefix" "evex")
24906    (set_attr "type" "sseadd")
24907    (set_attr "mode" "HF")])
24909 (define_insn "*ieee_s<ieee_maxmin><mode>3"
24910   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
24911         (unspec:MODEF
24912           [(match_operand:MODEF 1 "register_operand" "0,v")
24913            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
24914           IEEE_MAXMIN))]
24915   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
24916   "@
24917    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
24918    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
24919   [(set_attr "isa" "noavx,avx")
24920    (set_attr "prefix" "orig,maybe_evex")
24921    (set_attr "type" "sseadd")
24922    (set_attr "mode" "<MODE>")])
24924 ;; Operands order in min/max instruction matters for signed zero and NANs.
24925 (define_insn_and_split "*ieee_max<mode>3_1"
24926   [(set (match_operand:MODEF 0 "register_operand")
24927         (unspec:MODEF
24928           [(match_operand:MODEF 1 "register_operand")
24929            (match_operand:MODEF 2 "register_operand")
24930            (lt:MODEF
24931              (match_operand:MODEF 3 "register_operand")
24932              (match_operand:MODEF 4 "register_operand"))]
24933           UNSPEC_BLENDV))]
24934   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
24935   && (rtx_equal_p (operands[1], operands[3])
24936       && rtx_equal_p (operands[2], operands[4]))
24937   && ix86_pre_reload_split ()"
24938   "#"
24939   "&& 1"
24940   [(set (match_dup 0)
24941         (unspec:MODEF
24942           [(match_dup 2)
24943            (match_dup 1)]
24944          UNSPEC_IEEE_MAX))])
24946 (define_insn_and_split "*ieee_min<mode>3_1"
24947   [(set (match_operand:MODEF 0 "register_operand")
24948         (unspec:MODEF
24949           [(match_operand:MODEF 1 "register_operand")
24950            (match_operand:MODEF 2 "register_operand")
24951            (lt:MODEF
24952              (match_operand:MODEF 3 "register_operand")
24953              (match_operand:MODEF 4 "register_operand"))]
24954           UNSPEC_BLENDV))]
24955   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
24956   && (rtx_equal_p (operands[1], operands[4])
24957       && rtx_equal_p (operands[2], operands[3]))
24958   && ix86_pre_reload_split ()"
24959   "#"
24960   "&& 1"
24961   [(set (match_dup 0)
24962         (unspec:MODEF
24963           [(match_dup 2)
24964            (match_dup 1)]
24965          UNSPEC_IEEE_MIN))])
24967 ;; Make two stack loads independent:
24968 ;;   fld aa              fld aa
24969 ;;   fld %st(0)     ->   fld bb
24970 ;;   fmul bb             fmul %st(1), %st
24972 ;; Actually we only match the last two instructions for simplicity.
24974 (define_peephole2
24975   [(set (match_operand 0 "fp_register_operand")
24976         (match_operand 1 "fp_register_operand"))
24977    (set (match_dup 0)
24978         (match_operator 2 "binary_fp_operator"
24979            [(match_dup 0)
24980             (match_operand 3 "memory_operand")]))]
24981   "REGNO (operands[0]) != REGNO (operands[1])"
24982   [(set (match_dup 0) (match_dup 3))
24983    (set (match_dup 0)
24984         (match_op_dup 2
24985           [(match_dup 5) (match_dup 4)]))]
24987   operands[4] = operands[0];
24988   operands[5] = operands[1];
24990   /* The % modifier is not operational anymore in peephole2's, so we have to
24991      swap the operands manually in the case of addition and multiplication. */
24992   if (COMMUTATIVE_ARITH_P (operands[2]))
24993     std::swap (operands[4], operands[5]);
24996 (define_peephole2
24997   [(set (match_operand 0 "fp_register_operand")
24998         (match_operand 1 "fp_register_operand"))
24999    (set (match_dup 0)
25000         (match_operator 2 "binary_fp_operator"
25001            [(match_operand 3 "memory_operand")
25002             (match_dup 0)]))]
25003   "REGNO (operands[0]) != REGNO (operands[1])"
25004   [(set (match_dup 0) (match_dup 3))
25005    (set (match_dup 0)
25006         (match_op_dup 2
25007           [(match_dup 4) (match_dup 5)]))]
25009   operands[4] = operands[0];
25010   operands[5] = operands[1];
25012   /* The % modifier is not operational anymore in peephole2's, so we have to
25013      swap the operands manually in the case of addition and multiplication. */
25014   if (COMMUTATIVE_ARITH_P (operands[2]))
25015     std::swap (operands[4], operands[5]);
25018 ;; Conditional addition patterns
25019 (define_expand "add<mode>cc"
25020   [(match_operand:SWI 0 "register_operand")
25021    (match_operand 1 "ordered_comparison_operator")
25022    (match_operand:SWI 2 "register_operand")
25023    (match_operand:SWI 3 "const_int_operand")]
25024   ""
25025   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
25027 ;; min/max patterns
25029 (define_code_attr maxmin_rel
25030   [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
25032 (define_expand "<code><mode>3"
25033   [(parallel
25034     [(set (match_operand:SDWIM 0 "register_operand")
25035           (maxmin:SDWIM
25036             (match_operand:SDWIM 1 "register_operand")
25037             (match_operand:SDWIM 2 "general_operand")))
25038      (clobber (reg:CC FLAGS_REG))])]
25039   "TARGET_CMOVE
25040    && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)")
25042 (define_insn_and_split "*<code><dwi>3_doubleword"
25043   [(set (match_operand:<DWI> 0 "register_operand")
25044         (maxmin:<DWI>
25045           (match_operand:<DWI> 1 "register_operand")
25046           (match_operand:<DWI> 2 "general_operand")))
25047    (clobber (reg:CC FLAGS_REG))]
25048   "TARGET_CMOVE
25049    && ix86_pre_reload_split ()"
25050   "#"
25051   "&& 1"
25052   [(set (match_dup 0)
25053         (if_then_else:DWIH (match_dup 6)
25054           (match_dup 1)
25055           (match_dup 2)))
25056    (set (match_dup 3)
25057         (if_then_else:DWIH (match_dup 6)
25058           (match_dup 4)
25059           (match_dup 5)))]
25061   operands[2] = force_reg (<DWI>mode, operands[2]);
25063   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
25065   rtx cmplo[2] = { operands[1], operands[2] };
25066   rtx cmphi[2] = { operands[4], operands[5] };
25068   enum rtx_code code = <maxmin_rel>;
25070   switch (code)
25071     {
25072     case LE: case LEU:
25073       std::swap (cmplo[0], cmplo[1]);
25074       std::swap (cmphi[0], cmphi[1]);
25075       code = swap_condition (code);
25076       /* FALLTHRU */
25078     case GE: case GEU:
25079       {
25080         bool uns = (code == GEU);
25081         rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
25082           = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
25084         emit_insn (gen_cmp_1 (<MODE>mode, cmplo[0], cmplo[1]));
25086         rtx tmp = gen_rtx_SCRATCH (<MODE>mode);
25087         emit_insn (sbb_insn (<MODE>mode, tmp, cmphi[0], cmphi[1]));
25089         rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
25090         operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
25092         break;
25093       }
25095     default:
25096       gcc_unreachable ();
25097     }
25100 (define_insn_and_split "*<code><mode>3_1"
25101   [(set (match_operand:SWI 0 "register_operand")
25102         (maxmin:SWI
25103           (match_operand:SWI 1 "register_operand")
25104           (match_operand:SWI 2 "general_operand")))
25105    (clobber (reg:CC FLAGS_REG))]
25106   "TARGET_CMOVE
25107    && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
25108    && ix86_pre_reload_split ()"
25109   "#"
25110   "&& 1"
25111   [(set (match_dup 0)
25112         (if_then_else:SWI (match_dup 3)
25113           (match_dup 1)
25114           (match_dup 2)))]
25116   machine_mode mode = <MODE>mode;
25117   rtx cmp_op = operands[2];
25119   operands[2] = force_reg (mode, cmp_op);
25121   enum rtx_code code = <maxmin_rel>;
25123   if (cmp_op == const1_rtx)
25124     {
25125       /* Convert smax (x, 1) into (x > 0 ? x : 1).
25126          Convert umax (x, 1) into (x != 0 ? x : 1).
25127          Convert ?min (x, 1) into (x <= 0 ? x : 1).  */
25128       cmp_op = const0_rtx;
25129       if (code == GE)
25130         code = GT;
25131       else if (code == GEU)
25132         code = NE;
25133     }
25134   /* Convert smin (x, -1) into (x < 0 ? x : -1).  */
25135   else if (cmp_op == constm1_rtx && code == LE)
25136     {
25137       cmp_op = const0_rtx;
25138       code = LT;
25139     }
25140   /* Convert smax (x, -1) into (x >= 0 ? x : -1).  */
25141   else if (cmp_op == constm1_rtx && code == GE)
25142     cmp_op = const0_rtx;
25143   else if (cmp_op != const0_rtx)
25144     cmp_op = operands[2];
25146   machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], cmp_op);
25147   rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
25149   rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], cmp_op);
25150   emit_insn (gen_rtx_SET (flags, tmp));
25152   operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
25155 ;; Avoid clearing a register between a flags setting comparison and its use,
25156 ;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
25157 (define_peephole2
25158   [(set (reg FLAGS_REG) (match_operand 0))
25159    (set (match_operand:SWI 1 "general_reg_operand") (const_int 0))]
25160   "peep2_regno_dead_p (0, FLAGS_REG)
25161    && !reg_overlap_mentioned_p (operands[1], operands[0])"
25162    [(set (match_dup 2) (match_dup 0))]
25164   operands[2] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
25165   ix86_expand_clear (operands[1]);
25168 ;; When optimizing for size, zeroing memory should use a register.
25169 (define_peephole2
25170   [(match_scratch:SWI48 0 "r")
25171    (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
25172    (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
25173    (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
25174    (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
25175   "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
25176   [(const_int 0)]
25178   ix86_expand_clear (operands[0]);
25179   emit_move_insn (operands[1], operands[0]);
25180   emit_move_insn (operands[2], operands[0]);
25181   emit_move_insn (operands[3], operands[0]);
25182   ix86_last_zero_store_uid
25183     = INSN_UID (emit_move_insn (operands[4], operands[0]));
25184   DONE;
25187 (define_peephole2
25188   [(match_scratch:SWI48 0 "r")
25189    (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
25190    (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
25191   "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
25192   [(const_int 0)]
25194   ix86_expand_clear (operands[0]);
25195   emit_move_insn (operands[1], operands[0]);
25196   ix86_last_zero_store_uid
25197     = INSN_UID (emit_move_insn (operands[2], operands[0]));
25198   DONE;
25201 (define_peephole2
25202   [(match_scratch:SWI48 0 "r")
25203    (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
25204   "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
25205   [(const_int 0)]
25207   ix86_expand_clear (operands[0]);
25208   ix86_last_zero_store_uid
25209     = INSN_UID (emit_move_insn (operands[1], operands[0]));
25210   DONE;
25213 (define_peephole2
25214   [(set (match_operand:SWI48 5 "memory_operand")
25215         (match_operand:SWI48 0 "general_reg_operand"))
25216    (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
25217    (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
25218    (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
25219    (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
25220   "optimize_insn_for_size_p ()
25221    && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
25222   [(const_int 0)]
25224   emit_move_insn (operands[5], operands[0]);
25225   emit_move_insn (operands[1], operands[0]);
25226   emit_move_insn (operands[2], operands[0]);
25227   emit_move_insn (operands[3], operands[0]);
25228   ix86_last_zero_store_uid
25229     = INSN_UID (emit_move_insn (operands[4], operands[0]));
25230   DONE;
25233 (define_peephole2
25234   [(set (match_operand:SWI48 3 "memory_operand")
25235         (match_operand:SWI48 0 "general_reg_operand"))
25236    (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
25237    (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
25238   "optimize_insn_for_size_p ()
25239    && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
25240   [(const_int 0)]
25242   emit_move_insn (operands[3], operands[0]);
25243   emit_move_insn (operands[1], operands[0]);
25244   ix86_last_zero_store_uid
25245     = INSN_UID (emit_move_insn (operands[2], operands[0]));
25246   DONE;
25249 (define_peephole2
25250   [(set (match_operand:SWI48 2 "memory_operand")
25251         (match_operand:SWI48 0 "general_reg_operand"))
25252    (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
25253   "optimize_insn_for_size_p ()
25254    && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
25255   [(const_int 0)]
25257   emit_move_insn (operands[2], operands[0]);
25258   ix86_last_zero_store_uid
25259     = INSN_UID (emit_move_insn (operands[1], operands[0]));
25260   DONE;
25263 ;; Reload dislikes loading constants directly into class_likely_spilled
25264 ;; hard registers.  Try to tidy things up here.
25265 (define_peephole2
25266   [(set (match_operand:SWI 0 "general_reg_operand")
25267         (match_operand:SWI 1 "x86_64_general_operand"))
25268    (set (match_operand:SWI 2 "general_reg_operand")
25269         (match_dup 0))]
25270   "peep2_reg_dead_p (2, operands[0])"
25271   [(set (match_dup 2) (match_dup 1))])
25273 ;; Misc patterns (?)
25275 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
25276 ;; Otherwise there will be nothing to keep
25278 ;; [(set (reg ebp) (reg esp))]
25279 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
25280 ;;  (clobber (eflags)]
25281 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
25283 ;; in proper program order.
25285 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
25286   [(set (match_operand:P 0 "register_operand" "=r,r")
25287         (plus:P (match_operand:P 1 "register_operand" "0,r")
25288                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
25289    (clobber (reg:CC FLAGS_REG))
25290    (clobber (mem:BLK (scratch)))]
25291   ""
25293   switch (get_attr_type (insn))
25294     {
25295     case TYPE_IMOV:
25296       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
25298     case TYPE_ALU:
25299       gcc_assert (rtx_equal_p (operands[0], operands[1]));
25300       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
25301         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
25303       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
25305     default:
25306       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
25307       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
25308     }
25310   [(set (attr "type")
25311         (cond [(and (eq_attr "alternative" "0")
25312                     (not (match_test "TARGET_OPT_AGU")))
25313                  (const_string "alu")
25314                (match_operand:<MODE> 2 "const0_operand")
25315                  (const_string "imov")
25316               ]
25317               (const_string "lea")))
25318    (set (attr "length_immediate")
25319         (cond [(eq_attr "type" "imov")
25320                  (const_string "0")
25321                (and (eq_attr "type" "alu")
25322                     (match_operand 2 "const128_operand"))
25323                  (const_string "1")
25324               ]
25325               (const_string "*")))
25326    (set_attr "mode" "<MODE>")])
25328 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
25329   [(set (match_operand:P 0 "register_operand" "=r")
25330         (minus:P (match_operand:P 1 "register_operand" "0")
25331                  (match_operand:P 2 "register_operand" "r")))
25332    (clobber (reg:CC FLAGS_REG))
25333    (clobber (mem:BLK (scratch)))]
25334   ""
25335   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
25336   [(set_attr "type" "alu")
25337    (set_attr "mode" "<MODE>")])
25339 (define_insn "@allocate_stack_worker_probe_<mode>"
25340   [(set (match_operand:P 0 "register_operand" "=a")
25341         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
25342                             UNSPECV_STACK_PROBE))
25343    (clobber (reg:CC FLAGS_REG))]
25344   "ix86_target_stack_probe ()"
25345   "call\t___chkstk_ms"
25346   [(set_attr "type" "multi")
25347    (set_attr "length" "5")])
25349 (define_expand "allocate_stack"
25350   [(match_operand 0 "register_operand")
25351    (match_operand 1 "general_operand")]
25352   "ix86_target_stack_probe ()"
25354   rtx x;
25356 #ifndef CHECK_STACK_LIMIT
25357 #define CHECK_STACK_LIMIT 0
25358 #endif
25360   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
25361       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
25362     x = operands[1];
25363   else
25364     {
25365       x = copy_to_mode_reg (Pmode, operands[1]);
25367       emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
25368     }
25370   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
25371                            stack_pointer_rtx, 0, OPTAB_DIRECT);
25373   if (x != stack_pointer_rtx)
25374     emit_move_insn (stack_pointer_rtx, x);
25376   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
25377   DONE;
25380 (define_expand "probe_stack"
25381   [(match_operand 0 "memory_operand")]
25382   ""
25384   emit_insn (gen_probe_stack_1
25385              (word_mode, operands[0], const0_rtx));
25386   DONE;
25389 ;; Use OR for stack probes, this is shorter.
25390 (define_insn "@probe_stack_1_<mode>"
25391   [(set (match_operand:W 0 "memory_operand" "=m")
25392         (unspec:W [(match_operand:W 1 "const0_operand")]
25393                   UNSPEC_PROBE_STACK))
25394    (clobber (reg:CC FLAGS_REG))]
25395   ""
25396   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
25397   [(set_attr "type" "alu1")
25398    (set_attr "mode" "<MODE>")
25399    (set_attr "length_immediate" "1")])
25400   
25401 (define_insn "@adjust_stack_and_probe_<mode>"
25402   [(set (match_operand:P 0 "register_operand" "=r")
25403         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
25404                             UNSPECV_PROBE_STACK_RANGE))
25405    (set (reg:P SP_REG)
25406         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand")))
25407    (clobber (reg:CC FLAGS_REG))
25408    (clobber (mem:BLK (scratch)))]
25409   ""
25410   "* return output_adjust_stack_and_probe (operands[0]);"
25411   [(set_attr "type" "multi")])
25413 (define_insn "@probe_stack_range_<mode>"
25414   [(set (match_operand:P 0 "register_operand" "=r")
25415         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
25416                             (match_operand:P 2 "const_int_operand")]
25417                             UNSPECV_PROBE_STACK_RANGE))
25418    (clobber (reg:CC FLAGS_REG))]
25419   ""
25420   "* return output_probe_stack_range (operands[0], operands[2]);"
25421   [(set_attr "type" "multi")])
25423 (define_expand "builtin_setjmp_receiver"
25424   [(label_ref (match_operand 0))]
25425   "!TARGET_64BIT && flag_pic"
25427 #if TARGET_MACHO
25428   if (TARGET_MACHO)
25429     {
25430       rtx xops[3];
25431       rtx_code_label *label_rtx = gen_label_rtx ();
25432       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
25433       xops[0] = xops[1] = pic_offset_table_rtx;
25434       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
25435       ix86_expand_binary_operator (MINUS, SImode, xops);
25436     }
25437   else
25438 #endif
25439     emit_insn (gen_set_got (pic_offset_table_rtx));
25440   DONE;
25443 (define_expand "save_stack_nonlocal"
25444   [(set (match_operand 0 "memory_operand")
25445         (match_operand 1 "register_operand"))]
25446   ""
25448   rtx stack_slot;
25450   if (flag_cf_protection & CF_RETURN)
25451     {
25452       /* Copy shadow stack pointer to the first slot
25453          and stack pointer to the second slot.  */
25454       rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
25455       stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
25457       rtx reg_ssp = force_reg (word_mode, const0_rtx);
25458       emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
25459       emit_move_insn (ssp_slot, reg_ssp);
25460     }
25461   else
25462     stack_slot = adjust_address (operands[0], Pmode, 0);
25463   emit_move_insn (stack_slot, operands[1]);
25464   DONE;
25467 (define_expand "restore_stack_nonlocal"
25468   [(set (match_operand 0 "register_operand" "")
25469         (match_operand 1 "memory_operand" ""))]
25470   ""
25472   rtx stack_slot;
25474   if (flag_cf_protection & CF_RETURN)
25475     {
25476       /* Restore shadow stack pointer from the first slot
25477          and stack pointer from the second slot.  */
25478       rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
25479       stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
25481       /* Get the current shadow stack pointer.  The code below will check if
25482          SHSTK feature is enabled.  If it is not enabled the RDSSP instruction
25483          is a NOP.  */
25484       rtx reg_ssp = force_reg (word_mode, const0_rtx);
25485       emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
25487       /* Compare through subtraction the saved and the current ssp
25488          to decide if ssp has to be adjusted.  */
25489       reg_ssp = expand_simple_binop (word_mode, MINUS,
25490                                      reg_ssp, ssp_slot,
25491                                      reg_ssp, 1, OPTAB_DIRECT);
25493       /* Compare and jump over adjustment code.  */
25494       rtx noadj_label = gen_label_rtx ();
25495       emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
25496                                word_mode, 1, noadj_label);
25498       /* Compute the number of frames to adjust.  */
25499       rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
25500       rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
25501                                             NULL_RTX, 1);
25503       reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
25504                                      GEN_INT (exact_log2 (UNITS_PER_WORD)),
25505                                      reg_adj, 1, OPTAB_DIRECT);
25507       /* Check if number of frames <= 255 so no loop is needed.  */
25508       rtx inc_label = gen_label_rtx ();
25509       emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
25510                                ptr_mode, 1, inc_label);
25512       /* Adjust the ssp in a loop.  */
25513       rtx loop_label = gen_label_rtx ();
25514       emit_label (loop_label);
25515       LABEL_NUSES (loop_label) = 1;
25517       rtx reg_255 = force_reg (word_mode, GEN_INT (255));
25518       emit_insn (gen_incssp (word_mode, reg_255));
25520       reg_adj = expand_simple_binop (ptr_mode, MINUS,
25521                                      reg_adj, GEN_INT (255),
25522                                      reg_adj, 1, OPTAB_DIRECT);
25524       /* Compare and jump to the loop label.  */
25525       emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
25526                                ptr_mode, 1, loop_label);
25528       emit_label (inc_label);
25529       LABEL_NUSES (inc_label) = 1;
25531       emit_insn (gen_incssp (word_mode, reg_ssp));
25533       emit_label (noadj_label);
25534       LABEL_NUSES (noadj_label) = 1;
25535     }
25536   else
25537     stack_slot = adjust_address (operands[1], Pmode, 0);
25538   emit_move_insn (operands[0], stack_slot);
25539   DONE;
25542 (define_expand "stack_protect_set"
25543   [(match_operand 0 "memory_operand")
25544    (match_operand 1 "memory_operand")]
25545   ""
25547   rtx scratch = gen_reg_rtx (word_mode);
25549   emit_insn (gen_stack_protect_set_1
25550              (ptr_mode, word_mode, operands[0], operands[1], scratch));
25551   DONE;
25554 (define_insn "@stack_protect_set_1_<PTR:mode>_<W:mode>"
25555   [(set (match_operand:PTR 0 "memory_operand" "=m")
25556         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
25557                     UNSPEC_SP_SET))
25558    (set (match_operand:W 2 "register_operand" "=&r") (const_int 0))
25559    (clobber (reg:CC FLAGS_REG))]
25560   ""
25562   output_asm_insn ("mov{<PTR:imodesuffix>}\t{%1, %<PTR:k>2|%<PTR:k>2, %1}",
25563                    operands);
25564   output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>2, %0|%0, %<PTR:k>2}",
25565                    operands);
25566   if (!TARGET_USE_MOV0 || optimize_insn_for_size_p ())
25567     return "xor{l}\t%k2, %k2";
25568   else
25569     return "mov{l}\t{$0, %k2|%k2, 0}";
25571   [(set_attr "type" "multi")])
25573 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
25574 ;; immediately followed by *mov{s,d}i_internal, where we can avoid
25575 ;; the xor{l} above.  We don't split this, so that scheduling or
25576 ;; anything else doesn't separate the *stack_protect_set* pattern from
25577 ;; the set of the register that overwrites the register with a new value.
25579 (define_peephole2
25580   [(parallel [(set (match_operand:PTR 0 "memory_operand")
25581                    (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
25582                                UNSPEC_SP_SET))
25583               (set (match_operand 2 "general_reg_operand") (const_int 0))
25584               (clobber (reg:CC FLAGS_REG))])
25585    (set (match_operand 3 "general_reg_operand")
25586         (match_operand 4 "const0_operand"))]
25587   "GET_MODE (operands[2]) == word_mode
25588    && GET_MODE_SIZE (GET_MODE (operands[3])) <= UNITS_PER_WORD
25589    && peep2_reg_dead_p (0, operands[3])
25590    && peep2_reg_dead_p (1, operands[2])"
25591   [(parallel [(set (match_dup 0)
25592                    (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25593               (set (match_dup 3) (const_int 0))
25594               (clobber (reg:CC FLAGS_REG))])]
25595   "operands[3] = gen_lowpart (word_mode, operands[3]);")
25597 (define_insn "*stack_protect_set_2_<mode>_si"
25598   [(set (match_operand:PTR 0 "memory_operand" "=m")
25599         (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
25600                     UNSPEC_SP_SET))
25601    (set (match_operand:SI 1 "register_operand" "=&r")
25602         (match_operand:SI 2 "general_operand" "g"))]
25603   "reload_completed"
25605   output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
25606   output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
25607   if (pic_32bit_operand (operands[2], SImode)
25608       || ix86_use_lea_for_mov (insn, operands + 1))
25609     return "lea{l}\t{%E2, %1|%1, %E2}";
25610   else
25611     return "mov{l}\t{%2, %1|%1, %2}";
25613   [(set_attr "type" "multi")
25614    (set_attr "length" "24")])
25616 (define_insn "*stack_protect_set_2_<mode>_di"
25617   [(set (match_operand:PTR 0 "memory_operand" "=m,m,m")
25618         (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m,m,m")]
25619                     UNSPEC_SP_SET))
25620    (set (match_operand:DI 1 "register_operand" "=&r,&r,&r")
25621         (match_operand:DI 2 "general_operand" "Z,rem,i"))]
25622   "TARGET_64BIT && reload_completed"
25624   output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
25625   output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
25626   if (pic_32bit_operand (operands[2], DImode))
25627     return "lea{q}\t{%E2, %1|%1, %E2}";
25628   else if (which_alternative == 0)
25629     return "mov{l}\t{%k2, %k1|%k1, %k2}";
25630   else if (which_alternative == 2)
25631     return "movabs{q}\t{%2, %1|%1, %2}";
25632   else if (ix86_use_lea_for_mov (insn, operands + 1))
25633     return "lea{q}\t{%E2, %1|%1, %E2}";
25634   else
25635     return "mov{q}\t{%2, %1|%1, %2}";
25637   [(set_attr "type" "multi")
25638    (set_attr "length" "24")])
25640 (define_peephole2
25641   [(parallel [(set (match_operand:PTR 0 "memory_operand")
25642                    (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
25643                                UNSPEC_SP_SET))
25644               (set (match_operand 2 "general_reg_operand") (const_int 0))
25645               (clobber (reg:CC FLAGS_REG))])
25646    (set (match_operand:SWI48 3 "general_reg_operand")
25647         (match_operand:SWI48 4 "general_gr_operand"))]
25648   "GET_MODE (operands[2]) == word_mode
25649    && peep2_reg_dead_p (0, operands[3])
25650    && peep2_reg_dead_p (1, operands[2])"
25651   [(parallel [(set (match_dup 0)
25652                    (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25653               (set (match_dup 3) (match_dup 4))])])
25655 (define_peephole2
25656   [(set (match_operand:SWI48 3 "general_reg_operand")
25657         (match_operand:SWI48 4 "general_gr_operand"))
25658    (parallel [(set (match_operand:PTR 0 "memory_operand")
25659                    (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
25660                                UNSPEC_SP_SET))
25661               (set (match_operand 2 "general_reg_operand") (const_int 0))
25662               (clobber (reg:CC FLAGS_REG))])]
25663   "GET_MODE (operands[2]) == word_mode
25664    && peep2_reg_dead_p (0, operands[3])
25665    && peep2_reg_dead_p (2, operands[2])
25666    && !reg_mentioned_p (operands[3], operands[0])
25667    && !reg_mentioned_p (operands[3], operands[1])"
25668   [(parallel [(set (match_dup 0)
25669                    (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25670               (set (match_dup 3) (match_dup 4))])])
25672 (define_insn "*stack_protect_set_3_<PTR:mode>_<SWI48:mode>"
25673   [(set (match_operand:PTR 0 "memory_operand" "=m")
25674         (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
25675                     UNSPEC_SP_SET))
25676    (set (match_operand:SWI48 1 "register_operand" "=&r")
25677         (match_operand:SWI48 2 "address_no_seg_operand" "Ts"))]
25678   ""
25680   output_asm_insn ("mov{<PTR:imodesuffix>}\t{%3, %<PTR:k>1|%<PTR:k>1, %3}",
25681                    operands);
25682   output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>1, %0|%0, %<PTR:k>1}",
25683                    operands);
25684   if (SImode_address_operand (operands[2], VOIDmode))
25685     {
25686       gcc_assert (TARGET_64BIT);
25687       return "lea{l}\t{%E2, %k1|%k1, %E2}";
25688     }
25689   else
25690     return "lea{<SWI48:imodesuffix>}\t{%E2, %1|%1, %E2}";
25692   [(set_attr "type" "multi")
25693    (set_attr "length" "24")])
25695 (define_peephole2
25696   [(parallel [(set (match_operand:PTR 0 "memory_operand")
25697                    (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
25698                                UNSPEC_SP_SET))
25699               (set (match_operand 2 "general_reg_operand") (const_int 0))
25700               (clobber (reg:CC FLAGS_REG))])
25701    (set (match_operand:SWI48 3 "general_reg_operand")
25702         (match_operand:SWI48 4 "address_no_seg_operand"))]
25703   "GET_MODE (operands[2]) == word_mode
25704    && peep2_reg_dead_p (0, operands[3])
25705    && peep2_reg_dead_p (1, operands[2])"
25706   [(parallel [(set (match_dup 0)
25707                    (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25708               (set (match_dup 3) (match_dup 4))])])
25710 (define_insn "*stack_protect_set_4z_<mode>_di"
25711   [(set (match_operand:PTR 0 "memory_operand" "=m")
25712         (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
25713                     UNSPEC_SP_SET))
25714    (set (match_operand:DI 1 "register_operand" "=&r")
25715         (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))]
25716   "TARGET_64BIT && reload_completed"
25718   output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
25719   output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
25720   if (ix86_use_lea_for_mov (insn, operands + 1))
25721     return "lea{l}\t{%E2, %k1|%k1, %E2}";
25722   else
25723     return "mov{l}\t{%2, %k1|%k1, %2}";
25725   [(set_attr "type" "multi")
25726    (set_attr "length" "24")])
25728 (define_insn "*stack_protect_set_4s_<mode>_di"
25729   [(set (match_operand:PTR 0 "memory_operand" "=m")
25730         (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
25731                     UNSPEC_SP_SET))
25732    (set (match_operand:DI 1 "register_operand" "=&r")
25733         (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))]
25734   "TARGET_64BIT && reload_completed"
25736   output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
25737   output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
25738   return "movs{lq|x}\t{%2, %1|%1, %2}";
25740   [(set_attr "type" "multi")
25741    (set_attr "length" "24")])
25743 (define_peephole2
25744   [(parallel [(set (match_operand:PTR 0 "memory_operand")
25745                    (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
25746                                UNSPEC_SP_SET))
25747               (set (match_operand 2 "general_reg_operand") (const_int 0))
25748               (clobber (reg:CC FLAGS_REG))])
25749    (set (match_operand:DI 3 "general_reg_operand")
25750         (any_extend:DI
25751           (match_operand:SI 4 "nonimmediate_gr_operand")))]
25752   "TARGET_64BIT
25753    && GET_MODE (operands[2]) == word_mode
25754    && peep2_reg_dead_p (0, operands[3])
25755    && peep2_reg_dead_p (1, operands[2])"
25756   [(parallel [(set (match_dup 0)
25757                    (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25758               (set (match_dup 3)
25759                    (any_extend:DI (match_dup 4)))])])
25761 (define_expand "stack_protect_test"
25762   [(match_operand 0 "memory_operand")
25763    (match_operand 1 "memory_operand")
25764    (match_operand 2)]
25765   ""
25767   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
25769   emit_insn (gen_stack_protect_test_1
25770              (ptr_mode, flags, operands[0], operands[1]));
25772   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
25773                                   flags, const0_rtx, operands[2]));
25774   DONE;
25777 (define_insn "@stack_protect_test_1_<mode>"
25778   [(set (match_operand:CCZ 0 "flags_reg_operand")
25779         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
25780                      (match_operand:PTR 2 "memory_operand" "m")]
25781                     UNSPEC_SP_TEST))
25782    (clobber (match_scratch:PTR 3 "=&r"))]
25783   ""
25785   output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
25786   return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
25788   [(set_attr "type" "multi")])
25790 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
25791 ;; Do not split instructions with mask registers.
25792 (define_split
25793   [(set (match_operand 0 "general_reg_operand")
25794         (match_operator 3 "promotable_binary_operator"
25795            [(match_operand 1 "general_reg_operand")
25796             (match_operand 2 "aligned_operand")]))
25797    (clobber (reg:CC FLAGS_REG))]
25798   "! TARGET_PARTIAL_REG_STALL && reload_completed
25799    && ((GET_MODE (operands[0]) == HImode
25800         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
25801             /* ??? next two lines just !satisfies_constraint_K (...) */
25802             || !CONST_INT_P (operands[2])
25803             || satisfies_constraint_K (operands[2])))
25804        || (GET_MODE (operands[0]) == QImode
25805            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
25806   [(parallel [(set (match_dup 0)
25807                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
25808               (clobber (reg:CC FLAGS_REG))])]
25810   operands[0] = gen_lowpart (SImode, operands[0]);
25811   operands[1] = gen_lowpart (SImode, operands[1]);
25812   if (GET_CODE (operands[3]) != ASHIFT)
25813     operands[2] = gen_lowpart (SImode, operands[2]);
25814   operands[3] = shallow_copy_rtx (operands[3]);
25815   PUT_MODE (operands[3], SImode);
25818 ; Promote the QImode tests, as i386 has encoding of the AND
25819 ; instruction with 32-bit sign-extended immediate and thus the
25820 ; instruction size is unchanged, except in the %eax case for
25821 ; which it is increased by one byte, hence the ! optimize_size.
25822 (define_split
25823   [(set (match_operand 0 "flags_reg_operand")
25824         (match_operator 2 "compare_operator"
25825           [(and (match_operand 3 "aligned_operand")
25826                 (match_operand 4 "const_int_operand"))
25827            (const_int 0)]))
25828    (set (match_operand 1 "register_operand")
25829         (and (match_dup 3) (match_dup 4)))]
25830   "! TARGET_PARTIAL_REG_STALL && reload_completed
25831    && optimize_insn_for_speed_p ()
25832    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
25833        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
25834    /* Ensure that the operand will remain sign-extended immediate.  */
25835    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
25836   [(parallel [(set (match_dup 0)
25837                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
25838                                     (const_int 0)]))
25839               (set (match_dup 1)
25840                    (and:SI (match_dup 3) (match_dup 4)))])]
25842   operands[4]
25843     = gen_int_mode (INTVAL (operands[4])
25844                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
25845   operands[1] = gen_lowpart (SImode, operands[1]);
25846   operands[3] = gen_lowpart (SImode, operands[3]);
25849 ; Don't promote the QImode tests, as i386 doesn't have encoding of
25850 ; the TEST instruction with 32-bit sign-extended immediate and thus
25851 ; the instruction size would at least double, which is not what we
25852 ; want even with ! optimize_size.
25853 (define_split
25854   [(set (match_operand 0 "flags_reg_operand")
25855         (match_operator 1 "compare_operator"
25856           [(and (match_operand:HI 2 "aligned_operand")
25857                 (match_operand:HI 3 "const_int_operand"))
25858            (const_int 0)]))]
25859   "! TARGET_PARTIAL_REG_STALL && reload_completed
25860    && ! TARGET_FAST_PREFIX
25861    && optimize_insn_for_speed_p ()
25862    /* Ensure that the operand will remain sign-extended immediate.  */
25863    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
25864   [(set (match_dup 0)
25865         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
25866                          (const_int 0)]))]
25868   operands[3]
25869     = gen_int_mode (INTVAL (operands[3])
25870                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
25871   operands[2] = gen_lowpart (SImode, operands[2]);
25874 (define_split
25875   [(set (match_operand 0 "register_operand")
25876         (neg (match_operand 1 "register_operand")))
25877    (clobber (reg:CC FLAGS_REG))]
25878   "! TARGET_PARTIAL_REG_STALL && reload_completed
25879    && (GET_MODE (operands[0]) == HImode
25880        || (GET_MODE (operands[0]) == QImode
25881            && (TARGET_PROMOTE_QImode
25882                || optimize_insn_for_size_p ())))"
25883   [(parallel [(set (match_dup 0)
25884                    (neg:SI (match_dup 1)))
25885               (clobber (reg:CC FLAGS_REG))])]
25887   operands[0] = gen_lowpart (SImode, operands[0]);
25888   operands[1] = gen_lowpart (SImode, operands[1]);
25891 ;; Do not split instructions with mask regs.
25892 (define_split
25893   [(set (match_operand 0 "general_reg_operand")
25894         (not (match_operand 1 "general_reg_operand")))]
25895   "! TARGET_PARTIAL_REG_STALL && reload_completed
25896    && (GET_MODE (operands[0]) == HImode
25897        || (GET_MODE (operands[0]) == QImode
25898            && (TARGET_PROMOTE_QImode
25899                || optimize_insn_for_size_p ())))"
25900   [(set (match_dup 0)
25901         (not:SI (match_dup 1)))]
25903   operands[0] = gen_lowpart (SImode, operands[0]);
25904   operands[1] = gen_lowpart (SImode, operands[1]);
25907 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
25908 ;; transform a complex memory operation into two memory to register operations.
25910 ;; Don't push memory operands
25911 (define_peephole2
25912   [(set (match_operand:SWI 0 "push_operand")
25913         (match_operand:SWI 1 "memory_operand"))
25914    (match_scratch:SWI 2 "<r>")]
25915   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
25916    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
25917   [(set (match_dup 2) (match_dup 1))
25918    (set (match_dup 0) (match_dup 2))])
25920 ;; We need to handle SFmode only, because DFmode and XFmode are split to
25921 ;; SImode pushes.
25922 (define_peephole2
25923   [(set (match_operand:SF 0 "push_operand")
25924         (match_operand:SF 1 "memory_operand"))
25925    (match_scratch:SF 2 "r")]
25926   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
25927    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
25928   [(set (match_dup 2) (match_dup 1))
25929    (set (match_dup 0) (match_dup 2))])
25931 ;; Don't move an immediate directly to memory when the instruction
25932 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
25933 (define_peephole2
25934   [(match_scratch:SWI124 1 "<r>")
25935    (set (match_operand:SWI124 0 "memory_operand")
25936         (const_int 0))]
25937   "optimize_insn_for_speed_p ()
25938    && ((<MODE>mode == HImode
25939        && TARGET_LCP_STALL)
25940        || (!TARGET_USE_MOV0
25941           && TARGET_SPLIT_LONG_MOVES
25942           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
25943    && peep2_regno_dead_p (0, FLAGS_REG)"
25944   [(parallel [(set (match_dup 2) (const_int 0))
25945               (clobber (reg:CC FLAGS_REG))])
25946    (set (match_dup 0) (match_dup 1))]
25947   "operands[2] = gen_lowpart (SImode, operands[1]);")
25949 (define_peephole2
25950   [(match_scratch:SWI124 2 "<r>")
25951    (set (match_operand:SWI124 0 "memory_operand")
25952         (match_operand:SWI124 1 "immediate_operand"))]
25953   "optimize_insn_for_speed_p ()
25954    && ((<MODE>mode == HImode
25955        && TARGET_LCP_STALL)
25956        || (TARGET_SPLIT_LONG_MOVES
25957           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
25958   [(set (match_dup 2) (match_dup 1))
25959    (set (match_dup 0) (match_dup 2))])
25961 ;; Don't compare memory with zero, load and use a test instead.
25962 (define_peephole2
25963   [(set (match_operand 0 "flags_reg_operand")
25964         (match_operator 1 "compare_operator"
25965           [(match_operand:SI 2 "memory_operand")
25966            (const_int 0)]))
25967    (match_scratch:SI 3 "r")]
25968   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
25969   [(set (match_dup 3) (match_dup 2))
25970    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
25972 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
25973 ;; Don't split NOTs with a displacement operand, because resulting XOR
25974 ;; will not be pairable anyway.
25976 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
25977 ;; represented using a modRM byte.  The XOR replacement is long decoded,
25978 ;; so this split helps here as well.
25980 ;; Note: Can't do this as a regular split because we can't get proper
25981 ;; lifetime information then.
25983 (define_peephole2
25984   [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
25985         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
25986   "optimize_insn_for_speed_p ()
25987    && ((TARGET_NOT_UNPAIRABLE
25988         && (!MEM_P (operands[0])
25989             || !memory_displacement_operand (operands[0], <MODE>mode)))
25990        || (TARGET_NOT_VECTORMODE
25991            && long_memory_operand (operands[0], <MODE>mode)))
25992    && peep2_regno_dead_p (0, FLAGS_REG)"
25993   [(parallel [(set (match_dup 0)
25994                    (xor:SWI124 (match_dup 1) (const_int -1)))
25995               (clobber (reg:CC FLAGS_REG))])])
25997 ;; Non pairable "test imm, reg" instructions can be translated to
25998 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
25999 ;; byte opcode instead of two, have a short form for byte operands),
26000 ;; so do it for other CPUs as well.  Given that the value was dead,
26001 ;; this should not create any new dependencies.  Pass on the sub-word
26002 ;; versions if we're concerned about partial register stalls.
26004 (define_peephole2
26005   [(set (match_operand 0 "flags_reg_operand")
26006         (match_operator 1 "compare_operator"
26007           [(and:SI (match_operand:SI 2 "register_operand")
26008                    (match_operand:SI 3 "immediate_operand"))
26009            (const_int 0)]))]
26010   "ix86_match_ccmode (insn, CCNOmode)
26011    && (REGNO (operands[2]) != AX_REG
26012        || satisfies_constraint_K (operands[3]))
26013    && peep2_reg_dead_p (1, operands[2])"
26014   [(parallel
26015      [(set (match_dup 0)
26016            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
26017                             (const_int 0)]))
26018       (set (match_dup 2)
26019            (and:SI (match_dup 2) (match_dup 3)))])])
26021 ;; We don't need to handle HImode case, because it will be promoted to SImode
26022 ;; on ! TARGET_PARTIAL_REG_STALL
26024 (define_peephole2
26025   [(set (match_operand 0 "flags_reg_operand")
26026         (match_operator 1 "compare_operator"
26027           [(and:QI (match_operand:QI 2 "register_operand")
26028                    (match_operand:QI 3 "immediate_operand"))
26029            (const_int 0)]))]
26030   "! TARGET_PARTIAL_REG_STALL
26031    && ix86_match_ccmode (insn, CCNOmode)
26032    && REGNO (operands[2]) != AX_REG
26033    && peep2_reg_dead_p (1, operands[2])"
26034   [(parallel
26035      [(set (match_dup 0)
26036            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
26037                             (const_int 0)]))
26038       (set (match_dup 2)
26039            (and:QI (match_dup 2) (match_dup 3)))])])
26041 (define_peephole2
26042   [(set (match_operand 0 "flags_reg_operand")
26043         (match_operator 1 "compare_operator"
26044           [(and:QI
26045              (subreg:QI
26046                (match_operator:SWI248 4 "extract_operator"
26047                  [(match_operand 2 "int248_register_operand")
26048                   (const_int 8)
26049                   (const_int 8)]) 0)
26050              (match_operand 3 "const_int_operand"))
26051            (const_int 0)]))]
26052   "! TARGET_PARTIAL_REG_STALL
26053    && ix86_match_ccmode (insn, CCNOmode)
26054    && REGNO (operands[2]) != AX_REG
26055    && peep2_reg_dead_p (1, operands[2])"
26056   [(parallel
26057      [(set (match_dup 0)
26058            (match_op_dup 1
26059              [(and:QI
26060                 (subreg:QI
26061                   (match_op_dup 4 [(match_dup 2)
26062                                    (const_int 8)
26063                                    (const_int 8)]) 0)
26064                 (match_dup 3))
26065               (const_int 0)]))
26066       (set (zero_extract:SWI248 (match_dup 2)
26067                                 (const_int 8)
26068                                 (const_int 8))
26069            (subreg:SWI248
26070              (and:QI
26071                (subreg:QI
26072                  (match_op_dup 4 [(match_dup 2)
26073                                   (const_int 8)
26074                                   (const_int 8)]) 0)
26075                (match_dup 3)) 0))])])
26077 ;; Don't do logical operations with memory inputs.
26078 (define_peephole2
26079   [(match_scratch:SWI 2 "<r>")
26080    (parallel [(set (match_operand:SWI 0 "register_operand")
26081                    (match_operator:SWI 3 "arith_or_logical_operator"
26082                      [(match_dup 0)
26083                       (match_operand:SWI 1 "memory_operand")]))
26084               (clobber (reg:CC FLAGS_REG))])]
26085   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
26086   [(set (match_dup 2) (match_dup 1))
26087    (parallel [(set (match_dup 0)
26088                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
26089               (clobber (reg:CC FLAGS_REG))])])
26091 (define_peephole2
26092   [(match_scratch:SWI 2 "<r>")
26093    (parallel [(set (match_operand:SWI 0 "register_operand")
26094                    (match_operator:SWI 3 "arith_or_logical_operator"
26095                      [(match_operand:SWI 1 "memory_operand")
26096                       (match_dup 0)]))
26097               (clobber (reg:CC FLAGS_REG))])]
26098   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
26099   [(set (match_dup 2) (match_dup 1))
26100    (parallel [(set (match_dup 0)
26101                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
26102               (clobber (reg:CC FLAGS_REG))])])
26104 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when
26105 ;; the memory address refers to the destination of the load!
26107 (define_peephole2
26108   [(set (match_operand:SWI 0 "general_reg_operand")
26109         (match_operand:SWI 1 "general_reg_operand"))
26110    (parallel [(set (match_dup 0)
26111                    (match_operator:SWI 3 "commutative_operator"
26112                      [(match_dup 0)
26113                       (match_operand:SWI 2 "memory_operand")]))
26114               (clobber (reg:CC FLAGS_REG))])]
26115   "REGNO (operands[0]) != REGNO (operands[1])
26116    && (<MODE>mode != QImode
26117        || any_QIreg_operand (operands[1], QImode))"
26118   [(set (match_dup 0) (match_dup 4))
26119    (parallel [(set (match_dup 0)
26120                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
26121               (clobber (reg:CC FLAGS_REG))])]
26123   operands[4]
26124     = ix86_replace_reg_with_reg (operands[2], operands[0], operands[1]);
26127 (define_peephole2
26128   [(set (match_operand 0 "mmx_reg_operand")
26129         (match_operand 1 "mmx_reg_operand"))
26130    (set (match_dup 0)
26131         (match_operator 3 "commutative_operator"
26132           [(match_dup 0)
26133            (match_operand 2 "memory_operand")]))]
26134   "REGNO (operands[0]) != REGNO (operands[1])"
26135   [(set (match_dup 0) (match_dup 2))
26136    (set (match_dup 0)
26137         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
26139 (define_peephole2
26140   [(set (match_operand 0 "sse_reg_operand")
26141         (match_operand 1 "sse_reg_operand"))
26142    (set (match_dup 0)
26143         (match_operator 3 "commutative_operator"
26144           [(match_dup 0)
26145            (match_operand 2 "memory_operand")]))]
26146   "REGNO (operands[0]) != REGNO (operands[1])
26147    /* Punt if operands[1] is %[xy]mm16+ and AVX512BW is not enabled,
26148       as EVEX encoded vpadd[bw], vpmullw, vpmin[su][bw] and vpmax[su][bw]
26149       instructions require AVX512BW and AVX512VL, but with the original
26150       instructions it might require just AVX512VL.
26151       AVX512VL is implied from TARGET_HARD_REGNO_MODE_OK.  */
26152    && (!EXT_REX_SSE_REGNO_P (REGNO (operands[1]))
26153        || TARGET_AVX512BW
26154        || GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (operands[0]))) > 2
26155        || logic_operator (operands[3], VOIDmode))"
26156   [(set (match_dup 0) (match_dup 2))
26157    (set (match_dup 0)
26158         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
26160 ; Don't do logical operations with memory outputs
26162 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
26163 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
26164 ; the same decoder scheduling characteristics as the original.
26166 (define_peephole2
26167   [(match_scratch:SWI 2 "<r>")
26168    (parallel [(set (match_operand:SWI 0 "memory_operand")
26169                    (match_operator:SWI 3 "arith_or_logical_operator"
26170                      [(match_dup 0)
26171                       (match_operand:SWI 1 "<nonmemory_operand>")]))
26172               (clobber (reg:CC FLAGS_REG))])]
26173   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
26174   [(set (match_dup 2) (match_dup 0))
26175    (parallel [(set (match_dup 2)
26176                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
26177               (clobber (reg:CC FLAGS_REG))])
26178    (set (match_dup 0) (match_dup 2))])
26180 (define_peephole2
26181   [(match_scratch:SWI 2 "<r>")
26182    (parallel [(set (match_operand:SWI 0 "memory_operand")
26183                    (match_operator:SWI 3 "arith_or_logical_operator"
26184                      [(match_operand:SWI 1 "<nonmemory_operand>")
26185                       (match_dup 0)]))
26186               (clobber (reg:CC FLAGS_REG))])]
26187   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
26188   [(set (match_dup 2) (match_dup 0))
26189    (parallel [(set (match_dup 2)
26190                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
26191               (clobber (reg:CC FLAGS_REG))])
26192    (set (match_dup 0) (match_dup 2))])
26194 ;; Attempt to use arith or logical operations with memory outputs with
26195 ;; setting of flags.
26196 (define_peephole2
26197   [(set (match_operand:SWI 0 "register_operand")
26198         (match_operand:SWI 1 "memory_operand"))
26199    (parallel [(set (match_dup 0)
26200                    (match_operator:SWI 3 "plusminuslogic_operator"
26201                      [(match_dup 0)
26202                       (match_operand:SWI 2 "<nonmemory_operand>")]))
26203               (clobber (reg:CC FLAGS_REG))])
26204    (set (match_dup 1) (match_dup 0))
26205    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
26206   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
26207    && peep2_reg_dead_p (4, operands[0])
26208    && !reg_overlap_mentioned_p (operands[0], operands[1])
26209    && !reg_overlap_mentioned_p (operands[0], operands[2])
26210    && (<MODE>mode != QImode
26211        || immediate_operand (operands[2], QImode)
26212        || any_QIreg_operand (operands[2], QImode))
26213    && ix86_match_ccmode (peep2_next_insn (3),
26214                          (GET_CODE (operands[3]) == PLUS
26215                           || GET_CODE (operands[3]) == MINUS)
26216                          ? CCGOCmode : CCNOmode)"
26217   [(parallel [(set (match_dup 4) (match_dup 6))
26218               (set (match_dup 1) (match_dup 5))])]
26220   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
26221   operands[5]
26222     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
26223                       copy_rtx (operands[1]),
26224                       operands[2]);
26225   operands[6]
26226     = gen_rtx_COMPARE (GET_MODE (operands[4]),
26227                        copy_rtx (operands[5]),
26228                        const0_rtx);
26231 ;; Likewise for cmpelim optimized pattern.
26232 (define_peephole2
26233   [(set (match_operand:SWI 0 "register_operand")
26234         (match_operand:SWI 1 "memory_operand"))
26235    (parallel [(set (reg FLAGS_REG)
26236                    (compare (match_operator:SWI 3 "plusminuslogic_operator"
26237                               [(match_dup 0)
26238                                (match_operand:SWI 2 "<nonmemory_operand>")])
26239                             (const_int 0)))
26240               (set (match_dup 0) (match_dup 3))])
26241    (set (match_dup 1) (match_dup 0))]
26242   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
26243    && peep2_reg_dead_p (3, operands[0])
26244    && !reg_overlap_mentioned_p (operands[0], operands[1])
26245    && !reg_overlap_mentioned_p (operands[0], operands[2])
26246    && ix86_match_ccmode (peep2_next_insn (1),
26247                          (GET_CODE (operands[3]) == PLUS
26248                           || GET_CODE (operands[3]) == MINUS)
26249                          ? CCGOCmode : CCNOmode)"
26250   [(parallel [(set (match_dup 4) (match_dup 6))
26251               (set (match_dup 1) (match_dup 5))])]
26253   operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
26254   operands[5]
26255     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
26256                       copy_rtx (operands[1]), operands[2]);
26257   operands[6]
26258     = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
26259                        const0_rtx);
26262 ;; Likewise for instances where we have a lea pattern.
26263 (define_peephole2
26264   [(set (match_operand:SWI 0 "register_operand")
26265         (match_operand:SWI 1 "memory_operand"))
26266    (set (match_operand:<LEAMODE> 3 "register_operand")
26267         (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
26268                         (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
26269    (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
26270    (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
26271   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
26272    && REGNO (operands[4]) == REGNO (operands[0])
26273    && REGNO (operands[5]) == REGNO (operands[3])
26274    && peep2_reg_dead_p (4, operands[3])
26275    && ((REGNO (operands[0]) == REGNO (operands[3]))
26276        || peep2_reg_dead_p (2, operands[0]))
26277    && !reg_overlap_mentioned_p (operands[0], operands[1])
26278    && !reg_overlap_mentioned_p (operands[3], operands[1])
26279    && !reg_overlap_mentioned_p (operands[0], operands[2])
26280    && (<MODE>mode != QImode
26281        || immediate_operand (operands[2], QImode)
26282        || any_QIreg_operand (operands[2], QImode))
26283    && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
26284   [(parallel [(set (match_dup 6) (match_dup 8))
26285               (set (match_dup 1) (match_dup 7))])]
26287   operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
26288   operands[7]
26289     = gen_rtx_PLUS (<MODE>mode,
26290                     copy_rtx (operands[1]),
26291                     gen_lowpart (<MODE>mode, operands[2]));
26292   operands[8]
26293     = gen_rtx_COMPARE (GET_MODE (operands[6]),
26294                        copy_rtx (operands[7]),
26295                        const0_rtx);
26298 (define_peephole2
26299   [(parallel [(set (match_operand:SWI 0 "register_operand")
26300                    (match_operator:SWI 2 "plusminuslogic_operator"
26301                      [(match_dup 0)
26302                       (match_operand:SWI 1 "memory_operand")]))
26303               (clobber (reg:CC FLAGS_REG))])
26304    (set (match_dup 1) (match_dup 0))
26305    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
26306   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
26307    && COMMUTATIVE_ARITH_P (operands[2])
26308    && peep2_reg_dead_p (3, operands[0])
26309    && !reg_overlap_mentioned_p (operands[0], operands[1])
26310    && ix86_match_ccmode (peep2_next_insn (2),
26311                          GET_CODE (operands[2]) == PLUS
26312                          ? CCGOCmode : CCNOmode)"
26313   [(parallel [(set (match_dup 3) (match_dup 5))
26314               (set (match_dup 1) (match_dup 4))])]
26316   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
26317   operands[4]
26318     = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
26319                       copy_rtx (operands[1]),
26320                       operands[0]);
26321   operands[5]
26322     = gen_rtx_COMPARE (GET_MODE (operands[3]),
26323                        copy_rtx (operands[4]),
26324                        const0_rtx);
26327 ;; Likewise for cmpelim optimized pattern.
26328 (define_peephole2
26329   [(parallel [(set (reg FLAGS_REG)
26330                    (compare (match_operator:SWI 2 "plusminuslogic_operator"
26331                               [(match_operand:SWI 0 "register_operand")
26332                                (match_operand:SWI 1 "memory_operand")])
26333                             (const_int 0)))
26334               (set (match_dup 0) (match_dup 2))])
26335    (set (match_dup 1) (match_dup 0))]
26336   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
26337    && COMMUTATIVE_ARITH_P (operands[2])
26338    && peep2_reg_dead_p (2, operands[0])
26339    && !reg_overlap_mentioned_p (operands[0], operands[1])
26340    && ix86_match_ccmode (peep2_next_insn (0),
26341                          GET_CODE (operands[2]) == PLUS
26342                          ? CCGOCmode : CCNOmode)"
26343   [(parallel [(set (match_dup 3) (match_dup 5))
26344               (set (match_dup 1) (match_dup 4))])]
26346   operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
26347   operands[4]
26348     = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
26349                       copy_rtx (operands[1]), operands[0]);
26350   operands[5]
26351     = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
26352                        const0_rtx);
26355 (define_peephole2
26356   [(set (match_operand:SWI12 0 "register_operand")
26357         (match_operand:SWI12 1 "memory_operand"))
26358    (parallel [(set (match_operand:SI 4 "register_operand")
26359                    (match_operator:SI 3 "plusminuslogic_operator"
26360                      [(match_dup 4)
26361                       (match_operand:SI 2 "nonmemory_operand")]))
26362               (clobber (reg:CC FLAGS_REG))])
26363    (set (match_dup 1) (match_dup 0))
26364    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
26365   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
26366    && REGNO (operands[0]) == REGNO (operands[4])
26367    && peep2_reg_dead_p (4, operands[0])
26368    && (<MODE>mode != QImode
26369        || immediate_operand (operands[2], SImode)
26370        || any_QIreg_operand (operands[2], SImode))
26371    && !reg_overlap_mentioned_p (operands[0], operands[1])
26372    && !reg_overlap_mentioned_p (operands[0], operands[2])
26373    && ix86_match_ccmode (peep2_next_insn (3),
26374                          (GET_CODE (operands[3]) == PLUS
26375                           || GET_CODE (operands[3]) == MINUS)
26376                          ? CCGOCmode : CCNOmode)"
26377   [(parallel [(set (match_dup 5) (match_dup 7))
26378               (set (match_dup 1) (match_dup 6))])]
26380   operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
26381   operands[6]
26382     = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
26383                       copy_rtx (operands[1]),
26384                       gen_lowpart (<MODE>mode, operands[2]));
26385   operands[7]
26386     = gen_rtx_COMPARE (GET_MODE (operands[5]),
26387                        copy_rtx (operands[6]),
26388                        const0_rtx);
26391 ;; peephole2 comes before regcprop, so deal also with a case that
26392 ;; would be cleaned up by regcprop.
26393 (define_peephole2
26394   [(set (match_operand:SWI 0 "register_operand")
26395         (match_operand:SWI 1 "memory_operand"))
26396    (parallel [(set (match_dup 0)
26397                    (match_operator:SWI 3 "plusminuslogic_operator"
26398                      [(match_dup 0)
26399                       (match_operand:SWI 2 "<nonmemory_operand>")]))
26400               (clobber (reg:CC FLAGS_REG))])
26401    (set (match_operand:SWI 4 "register_operand") (match_dup 0))
26402    (set (match_dup 1) (match_dup 4))
26403    (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
26404   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
26405    && peep2_reg_dead_p (3, operands[0])
26406    && peep2_reg_dead_p (5, operands[4])
26407    && !reg_overlap_mentioned_p (operands[0], operands[1])
26408    && !reg_overlap_mentioned_p (operands[0], operands[2])
26409    && !reg_overlap_mentioned_p (operands[4], operands[1])
26410    && (<MODE>mode != QImode
26411        || immediate_operand (operands[2], QImode)
26412        || any_QIreg_operand (operands[2], QImode))
26413    && ix86_match_ccmode (peep2_next_insn (4),
26414                          (GET_CODE (operands[3]) == PLUS
26415                           || GET_CODE (operands[3]) == MINUS)
26416                          ? CCGOCmode : CCNOmode)"
26417   [(parallel [(set (match_dup 5) (match_dup 7))
26418               (set (match_dup 1) (match_dup 6))])]
26420   operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
26421   operands[6]
26422     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
26423                       copy_rtx (operands[1]),
26424                       operands[2]);
26425   operands[7]
26426     = gen_rtx_COMPARE (GET_MODE (operands[5]),
26427                        copy_rtx (operands[6]),
26428                        const0_rtx);
26431 (define_peephole2
26432   [(set (match_operand:SWI12 0 "register_operand")
26433         (match_operand:SWI12 1 "memory_operand"))
26434    (parallel [(set (match_operand:SI 4 "register_operand")
26435                    (match_operator:SI 3 "plusminuslogic_operator"
26436                      [(match_dup 4)
26437                       (match_operand:SI 2 "nonmemory_operand")]))
26438               (clobber (reg:CC FLAGS_REG))])
26439    (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
26440    (set (match_dup 1) (match_dup 5))
26441    (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
26442   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
26443    && REGNO (operands[0]) == REGNO (operands[4])
26444    && peep2_reg_dead_p (3, operands[0])
26445    && peep2_reg_dead_p (5, operands[5])
26446    && (<MODE>mode != QImode
26447        || immediate_operand (operands[2], SImode)
26448        || any_QIreg_operand (operands[2], SImode))
26449    && !reg_overlap_mentioned_p (operands[0], operands[1])
26450    && !reg_overlap_mentioned_p (operands[0], operands[2])
26451    && !reg_overlap_mentioned_p (operands[5], operands[1])
26452    && ix86_match_ccmode (peep2_next_insn (4),
26453                          (GET_CODE (operands[3]) == PLUS
26454                           || GET_CODE (operands[3]) == MINUS)
26455                          ? CCGOCmode : CCNOmode)"
26456   [(parallel [(set (match_dup 6) (match_dup 8))
26457               (set (match_dup 1) (match_dup 7))])]
26459   operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
26460   operands[7]
26461     = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
26462                       copy_rtx (operands[1]),
26463                       gen_lowpart (<MODE>mode, operands[2]));
26464   operands[8]
26465     = gen_rtx_COMPARE (GET_MODE (operands[6]),
26466                        copy_rtx (operands[7]),
26467                        const0_rtx);
26470 ;; Likewise for cmpelim optimized pattern.
26471 (define_peephole2
26472   [(set (match_operand:SWI 0 "register_operand")
26473         (match_operand:SWI 1 "memory_operand"))
26474    (parallel [(set (reg FLAGS_REG)
26475                    (compare (match_operator:SWI 3 "plusminuslogic_operator"
26476                               [(match_dup 0)
26477                                (match_operand:SWI 2 "<nonmemory_operand>")])
26478                             (const_int 0)))
26479               (set (match_dup 0) (match_dup 3))])
26480    (set (match_operand:SWI 4 "register_operand") (match_dup 0))
26481    (set (match_dup 1) (match_dup 4))]
26482   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
26483    && peep2_reg_dead_p (3, operands[0])
26484    && peep2_reg_dead_p (4, operands[4])
26485    && !reg_overlap_mentioned_p (operands[0], operands[1])
26486    && !reg_overlap_mentioned_p (operands[0], operands[2])
26487    && !reg_overlap_mentioned_p (operands[4], operands[1])
26488    && ix86_match_ccmode (peep2_next_insn (1),
26489                          (GET_CODE (operands[3]) == PLUS
26490                           || GET_CODE (operands[3]) == MINUS)
26491                          ? CCGOCmode : CCNOmode)"
26492   [(parallel [(set (match_dup 5) (match_dup 7))
26493               (set (match_dup 1) (match_dup 6))])]
26495   operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
26496   operands[6]
26497     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
26498                       copy_rtx (operands[1]), operands[2]);
26499   operands[7]
26500     = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
26501                        const0_rtx);
26504 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
26505 ;; into x = z; x ^= y; x != z
26506 (define_peephole2
26507   [(set (match_operand:SWI 0 "register_operand")
26508         (match_operand:SWI 1 "memory_operand"))
26509    (set (match_operand:SWI 3 "register_operand") (match_dup 0))
26510    (parallel [(set (match_operand:SWI 4 "register_operand")
26511                    (xor:SWI (match_dup 4)
26512                             (match_operand:SWI 2 "<nonmemory_operand>")))
26513               (clobber (reg:CC FLAGS_REG))])
26514    (set (match_dup 1) (match_dup 4))
26515    (set (reg:CCZ FLAGS_REG)
26516         (compare:CCZ (match_operand:SWI 5 "register_operand")
26517                      (match_operand:SWI 6 "<nonmemory_operand>")))]
26518   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
26519    && (REGNO (operands[4]) == REGNO (operands[0])
26520        || REGNO (operands[4]) == REGNO (operands[3]))
26521    && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
26522                              ? 3 : 0], operands[5])
26523        ? rtx_equal_p (operands[2], operands[6])
26524        : rtx_equal_p (operands[2], operands[5])
26525          && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
26526                                   ? 3 : 0], operands[6]))
26527    && peep2_reg_dead_p (4, operands[4])
26528    && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
26529                                     ? 3 : 0])
26530    && !reg_overlap_mentioned_p (operands[0], operands[1])
26531    && !reg_overlap_mentioned_p (operands[0], operands[2])
26532    && !reg_overlap_mentioned_p (operands[3], operands[0])
26533    && !reg_overlap_mentioned_p (operands[3], operands[1])
26534    && !reg_overlap_mentioned_p (operands[3], operands[2])
26535    && (<MODE>mode != QImode
26536        || immediate_operand (operands[2], QImode)
26537        || any_QIreg_operand (operands[2], QImode))"
26538   [(parallel [(set (match_dup 7) (match_dup 9))
26539               (set (match_dup 1) (match_dup 8))])]
26541   operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
26542   operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
26543                              operands[2]);
26544   operands[9]
26545     = gen_rtx_COMPARE (GET_MODE (operands[7]),
26546                        copy_rtx (operands[8]),
26547                        const0_rtx);
26550 (define_peephole2
26551   [(set (match_operand:SWI12 0 "register_operand")
26552         (match_operand:SWI12 1 "memory_operand"))
26553    (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
26554    (parallel [(set (match_operand:SI 4 "register_operand")
26555                    (xor:SI (match_dup 4)
26556                            (match_operand:SI 2 "<nonmemory_operand>")))
26557               (clobber (reg:CC FLAGS_REG))])
26558    (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
26559    (set (reg:CCZ FLAGS_REG)
26560         (compare:CCZ (match_operand:SWI12 6 "register_operand")
26561                      (match_operand:SWI12 7 "<nonmemory_operand>")))]
26562   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
26563    && (REGNO (operands[5]) == REGNO (operands[0])
26564        || REGNO (operands[5]) == REGNO (operands[3]))
26565    && REGNO (operands[5]) == REGNO (operands[4])
26566    && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
26567                              ? 3 : 0], operands[6])
26568        ? (REG_P (operands[2])
26569           ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
26570           : rtx_equal_p (operands[2], operands[7]))
26571        : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
26572                                 ? 3 : 0], operands[7])
26573           && REG_P (operands[2])
26574           && REGNO (operands[2]) == REGNO (operands[6])))
26575    && peep2_reg_dead_p (4, operands[5])
26576    && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
26577                                     ? 3 : 0])
26578    && !reg_overlap_mentioned_p (operands[0], operands[1])
26579    && !reg_overlap_mentioned_p (operands[0], operands[2])
26580    && !reg_overlap_mentioned_p (operands[3], operands[0])
26581    && !reg_overlap_mentioned_p (operands[3], operands[1])
26582    && !reg_overlap_mentioned_p (operands[3], operands[2])
26583    && (<MODE>mode != QImode
26584        || immediate_operand (operands[2], SImode)
26585        || any_QIreg_operand (operands[2], SImode))"
26586   [(parallel [(set (match_dup 8) (match_dup 10))
26587               (set (match_dup 1) (match_dup 9))])]
26589   operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
26590   operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
26591                              gen_lowpart (<MODE>mode, operands[2]));
26592   operands[10]
26593     = gen_rtx_COMPARE (GET_MODE (operands[8]),
26594                        copy_rtx (operands[9]),
26595                        const0_rtx);
26598 ;; Attempt to optimize away memory stores of values the memory already
26599 ;; has.  See PR79593.
26600 (define_peephole2
26601   [(set (match_operand 0 "register_operand")
26602         (match_operand 1 "memory_operand"))
26603    (set (match_operand 2 "memory_operand") (match_dup 0))]
26604   "!MEM_VOLATILE_P (operands[1])
26605    && !MEM_VOLATILE_P (operands[2])
26606    && rtx_equal_p (operands[1], operands[2])
26607    && !reg_overlap_mentioned_p (operands[0], operands[2])"
26608   [(set (match_dup 0) (match_dup 1))])
26610 ;; Attempt to always use XOR for zeroing registers (including FP modes).
26611 (define_peephole2
26612   [(set (match_operand 0 "general_reg_operand")
26613         (match_operand 1 "const0_operand"))]
26614   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
26615    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
26616    && peep2_regno_dead_p (0, FLAGS_REG)"
26617   [(parallel [(set (match_dup 0) (const_int 0))
26618               (clobber (reg:CC FLAGS_REG))])]
26619   "operands[0] = gen_lowpart (word_mode, operands[0]);")
26621 (define_peephole2
26622   [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
26623         (const_int 0))]
26624   "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
26625    && peep2_regno_dead_p (0, FLAGS_REG)"
26626   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
26627               (clobber (reg:CC FLAGS_REG))])])
26629 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
26630 (define_peephole2
26631   [(set (match_operand:SWI248 0 "general_reg_operand")
26632         (const_int -1))]
26633   "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
26634    && peep2_regno_dead_p (0, FLAGS_REG)"
26635   [(parallel [(set (match_dup 0) (const_int -1))
26636               (clobber (reg:CC FLAGS_REG))])]
26638   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
26639     operands[0] = gen_lowpart (SImode, operands[0]);
26642 ;; Attempt to convert simple lea to add/shift.
26643 ;; These can be created by move expanders.
26644 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
26645 ;; relevant lea instructions were already split.
26647 (define_peephole2
26648   [(set (match_operand:SWI48 0 "register_operand")
26649         (plus:SWI48 (match_dup 0)
26650                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
26651   "!TARGET_OPT_AGU
26652    && peep2_regno_dead_p (0, FLAGS_REG)"
26653   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
26654               (clobber (reg:CC FLAGS_REG))])])
26656 (define_peephole2
26657   [(set (match_operand:SWI48 0 "register_operand")
26658         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
26659                     (match_dup 0)))]
26660   "!TARGET_OPT_AGU
26661    && peep2_regno_dead_p (0, FLAGS_REG)"
26662   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
26663               (clobber (reg:CC FLAGS_REG))])])
26665 (define_peephole2
26666   [(set (match_operand:DI 0 "register_operand")
26667         (zero_extend:DI
26668           (plus:SI (match_operand:SI 1 "register_operand")
26669                    (match_operand:SI 2 "nonmemory_operand"))))]
26670   "TARGET_64BIT && !TARGET_OPT_AGU
26671    && REGNO (operands[0]) == REGNO (operands[1])
26672    && peep2_regno_dead_p (0, FLAGS_REG)"
26673   [(parallel [(set (match_dup 0)
26674                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
26675               (clobber (reg:CC FLAGS_REG))])])
26677 (define_peephole2
26678   [(set (match_operand:DI 0 "register_operand")
26679         (zero_extend:DI
26680           (plus:SI (match_operand:SI 1 "nonmemory_operand")
26681                    (match_operand:SI 2 "register_operand"))))]
26682   "TARGET_64BIT && !TARGET_OPT_AGU
26683    && REGNO (operands[0]) == REGNO (operands[2])
26684    && peep2_regno_dead_p (0, FLAGS_REG)"
26685   [(parallel [(set (match_dup 0)
26686                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
26687               (clobber (reg:CC FLAGS_REG))])])
26689 (define_peephole2
26690   [(set (match_operand:SWI48 0 "register_operand")
26691         (mult:SWI48 (match_dup 0)
26692                     (match_operand:SWI48 1 "const_int_operand")))]
26693   "pow2p_hwi (INTVAL (operands[1]))
26694    && peep2_regno_dead_p (0, FLAGS_REG)"
26695   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
26696               (clobber (reg:CC FLAGS_REG))])]
26697   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
26699 (define_peephole2
26700   [(set (match_operand:DI 0 "register_operand")
26701         (zero_extend:DI
26702           (mult:SI (match_operand:SI 1 "register_operand")
26703                    (match_operand:SI 2 "const_int_operand"))))]
26704   "TARGET_64BIT
26705    && pow2p_hwi (INTVAL (operands[2]))
26706    && REGNO (operands[0]) == REGNO (operands[1])
26707    && peep2_regno_dead_p (0, FLAGS_REG)"
26708   [(parallel [(set (match_dup 0)
26709                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
26710               (clobber (reg:CC FLAGS_REG))])]
26711   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
26713 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
26714 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
26715 ;; On many CPUs it is also faster, since special hardware to avoid esp
26716 ;; dependencies is present.
26718 ;; While some of these conversions may be done using splitters, we use
26719 ;; peepholes in order to allow combine_stack_adjustments pass to see
26720 ;; nonobfuscated RTL.
26722 ;; Convert prologue esp subtractions to push.
26723 ;; We need register to push.  In order to keep verify_flow_info happy we have
26724 ;; two choices
26725 ;; - use scratch and clobber it in order to avoid dependencies
26726 ;; - use already live register
26727 ;; We can't use the second way right now, since there is no reliable way how to
26728 ;; verify that given register is live.  First choice will also most likely in
26729 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
26730 ;; call clobbered registers are dead.  We may want to use base pointer as an
26731 ;; alternative when no register is available later.
26733 (define_peephole2
26734   [(match_scratch:W 1 "r")
26735    (parallel [(set (reg:P SP_REG)
26736                    (plus:P (reg:P SP_REG)
26737                            (match_operand:P 0 "const_int_operand")))
26738               (clobber (reg:CC FLAGS_REG))
26739               (clobber (mem:BLK (scratch)))])]
26740   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
26741    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
26742    && !ix86_red_zone_used"
26743   [(clobber (match_dup 1))
26744    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
26745               (clobber (mem:BLK (scratch)))])])
26747 (define_peephole2
26748   [(match_scratch:W 1 "r")
26749    (parallel [(set (reg:P SP_REG)
26750                    (plus:P (reg:P SP_REG)
26751                            (match_operand:P 0 "const_int_operand")))
26752               (clobber (reg:CC FLAGS_REG))
26753               (clobber (mem:BLK (scratch)))])]
26754   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
26755    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
26756    && !ix86_red_zone_used"
26757   [(clobber (match_dup 1))
26758    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
26759    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
26760               (clobber (mem:BLK (scratch)))])])
26762 ;; Convert esp subtractions to push.
26763 (define_peephole2
26764   [(match_scratch:W 1 "r")
26765    (parallel [(set (reg:P SP_REG)
26766                    (plus:P (reg:P SP_REG)
26767                            (match_operand:P 0 "const_int_operand")))
26768               (clobber (reg:CC FLAGS_REG))])]
26769   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
26770    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
26771    && !ix86_red_zone_used"
26772   [(clobber (match_dup 1))
26773    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
26775 (define_peephole2
26776   [(match_scratch:W 1 "r")
26777    (parallel [(set (reg:P SP_REG)
26778                    (plus:P (reg:P SP_REG)
26779                            (match_operand:P 0 "const_int_operand")))
26780               (clobber (reg:CC FLAGS_REG))])]
26781   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
26782    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
26783    && !ix86_red_zone_used"
26784   [(clobber (match_dup 1))
26785    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
26786    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
26788 ;; Convert epilogue deallocator to pop.
26789 (define_peephole2
26790   [(match_scratch:W 1 "r")
26791    (parallel [(set (reg:P SP_REG)
26792                    (plus:P (reg:P SP_REG)
26793                            (match_operand:P 0 "const_int_operand")))
26794               (clobber (reg:CC FLAGS_REG))
26795               (clobber (mem:BLK (scratch)))])]
26796   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
26797    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
26798   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
26799               (clobber (mem:BLK (scratch)))])])
26801 ;; Two pops case is tricky, since pop causes dependency
26802 ;; on destination register.  We use two registers if available.
26803 (define_peephole2
26804   [(match_scratch:W 1 "r")
26805    (match_scratch:W 2 "r")
26806    (parallel [(set (reg:P SP_REG)
26807                    (plus:P (reg:P SP_REG)
26808                            (match_operand:P 0 "const_int_operand")))
26809               (clobber (reg:CC FLAGS_REG))
26810               (clobber (mem:BLK (scratch)))])]
26811   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
26812    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
26813   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
26814               (clobber (mem:BLK (scratch)))])
26815    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
26817 (define_peephole2
26818   [(match_scratch:W 1 "r")
26819    (parallel [(set (reg:P SP_REG)
26820                    (plus:P (reg:P SP_REG)
26821                            (match_operand:P 0 "const_int_operand")))
26822               (clobber (reg:CC FLAGS_REG))
26823               (clobber (mem:BLK (scratch)))])]
26824   "optimize_insn_for_size_p ()
26825    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
26826   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
26827               (clobber (mem:BLK (scratch)))])
26828    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
26830 ;; Convert esp additions to pop.
26831 (define_peephole2
26832   [(match_scratch:W 1 "r")
26833    (parallel [(set (reg:P SP_REG)
26834                    (plus:P (reg:P SP_REG)
26835                            (match_operand:P 0 "const_int_operand")))
26836               (clobber (reg:CC FLAGS_REG))])]
26837   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
26838   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
26840 ;; Two pops case is tricky, since pop causes dependency
26841 ;; on destination register.  We use two registers if available.
26842 (define_peephole2
26843   [(match_scratch:W 1 "r")
26844    (match_scratch:W 2 "r")
26845    (parallel [(set (reg:P SP_REG)
26846                    (plus:P (reg:P SP_REG)
26847                            (match_operand:P 0 "const_int_operand")))
26848               (clobber (reg:CC FLAGS_REG))])]
26849   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
26850   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
26851    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
26853 (define_peephole2
26854   [(match_scratch:W 1 "r")
26855    (parallel [(set (reg:P SP_REG)
26856                    (plus:P (reg:P SP_REG)
26857                            (match_operand:P 0 "const_int_operand")))
26858               (clobber (reg:CC FLAGS_REG))])]
26859   "optimize_insn_for_size_p ()
26860    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
26861   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
26862    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
26864 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
26865 ;; required and register dies.  Similarly for 128 to -128.
26866 (define_peephole2
26867   [(set (match_operand 0 "flags_reg_operand")
26868         (match_operator 1 "compare_operator"
26869           [(match_operand 2 "register_operand")
26870            (match_operand 3 "const_int_operand")]))]
26871   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
26872      && incdec_operand (operands[3], GET_MODE (operands[3])))
26873     || (!TARGET_FUSE_CMP_AND_BRANCH
26874         && INTVAL (operands[3]) == 128))
26875    && ix86_match_ccmode (insn, CCGCmode)
26876    && peep2_reg_dead_p (1, operands[2])"
26877   [(parallel [(set (match_dup 0)
26878                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
26879               (clobber (match_dup 2))])])
26881 ;; Convert imul by three, five and nine into lea
26882 (define_peephole2
26883   [(parallel
26884     [(set (match_operand:SWI48 0 "register_operand")
26885           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
26886                       (match_operand:SWI48 2 "const359_operand")))
26887      (clobber (reg:CC FLAGS_REG))])]
26888   "!TARGET_PARTIAL_REG_STALL
26889    || <MODE>mode == SImode
26890    || optimize_function_for_size_p (cfun)"
26891   [(set (match_dup 0)
26892         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
26893                     (match_dup 1)))]
26894   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
26896 (define_peephole2
26897   [(parallel
26898     [(set (match_operand:SWI48 0 "register_operand")
26899           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
26900                       (match_operand:SWI48 2 "const359_operand")))
26901      (clobber (reg:CC FLAGS_REG))])]
26902   "optimize_insn_for_speed_p ()
26903    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
26904   [(set (match_dup 0) (match_dup 1))
26905    (set (match_dup 0)
26906         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
26907                     (match_dup 0)))]
26908   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
26910 ;; imul $32bit_imm, mem, reg is vector decoded, while
26911 ;; imul $32bit_imm, reg, reg is direct decoded.
26912 (define_peephole2
26913   [(match_scratch:SWI48 3 "r")
26914    (parallel [(set (match_operand:SWI48 0 "register_operand")
26915                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
26916                                (match_operand:SWI48 2 "immediate_operand")))
26917               (clobber (reg:CC FLAGS_REG))])]
26918   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
26919    && !satisfies_constraint_K (operands[2])"
26920   [(set (match_dup 3) (match_dup 1))
26921    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
26922               (clobber (reg:CC FLAGS_REG))])])
26924 (define_peephole2
26925   [(match_scratch:SI 3 "r")
26926    (parallel [(set (match_operand:DI 0 "register_operand")
26927                    (zero_extend:DI
26928                      (mult:SI (match_operand:SI 1 "memory_operand")
26929                               (match_operand:SI 2 "immediate_operand"))))
26930               (clobber (reg:CC FLAGS_REG))])]
26931   "TARGET_64BIT
26932    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
26933    && !satisfies_constraint_K (operands[2])"
26934   [(set (match_dup 3) (match_dup 1))
26935    (parallel [(set (match_dup 0)
26936                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
26937               (clobber (reg:CC FLAGS_REG))])])
26939 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
26940 ;; Convert it into imul reg, reg
26941 ;; It would be better to force assembler to encode instruction using long
26942 ;; immediate, but there is apparently no way to do so.
26943 (define_peephole2
26944   [(parallel [(set (match_operand:SWI248 0 "register_operand")
26945                    (mult:SWI248
26946                     (match_operand:SWI248 1 "nonimmediate_operand")
26947                     (match_operand:SWI248 2 "const_int_operand")))
26948               (clobber (reg:CC FLAGS_REG))])
26949    (match_scratch:SWI248 3 "r")]
26950   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
26951    && satisfies_constraint_K (operands[2])"
26952   [(set (match_dup 3) (match_dup 2))
26953    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
26954               (clobber (reg:CC FLAGS_REG))])]
26956   if (!rtx_equal_p (operands[0], operands[1]))
26957     emit_move_insn (operands[0], operands[1]);
26960 ;; After splitting up read-modify operations, array accesses with memory
26961 ;; operands might end up in form:
26962 ;;  sall    $2, %eax
26963 ;;  movl    4(%esp), %edx
26964 ;;  addl    %edx, %eax
26965 ;; instead of pre-splitting:
26966 ;;  sall    $2, %eax
26967 ;;  addl    4(%esp), %eax
26968 ;; Turn it into:
26969 ;;  movl    4(%esp), %edx
26970 ;;  leal    (%edx,%eax,4), %eax
26972 (define_peephole2
26973   [(match_scratch:W 5 "r")
26974    (parallel [(set (match_operand 0 "register_operand")
26975                    (ashift (match_operand 1 "register_operand")
26976                            (match_operand 2 "const_int_operand")))
26977                (clobber (reg:CC FLAGS_REG))])
26978    (parallel [(set (match_operand 3 "register_operand")
26979                    (plus (match_dup 0)
26980                          (match_operand 4 "x86_64_general_operand")))
26981                    (clobber (reg:CC FLAGS_REG))])]
26982   "IN_RANGE (INTVAL (operands[2]), 1, 3)
26983    /* Validate MODE for lea.  */
26984    && ((!TARGET_PARTIAL_REG_STALL
26985         && (GET_MODE (operands[0]) == QImode
26986             || GET_MODE (operands[0]) == HImode))
26987        || GET_MODE (operands[0]) == SImode
26988        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
26989    && (rtx_equal_p (operands[0], operands[3])
26990        || peep2_reg_dead_p (2, operands[0]))
26991    /* We reorder load and the shift.  */
26992    && !reg_overlap_mentioned_p (operands[0], operands[4])"
26993   [(set (match_dup 5) (match_dup 4))
26994    (set (match_dup 0) (match_dup 1))]
26996   machine_mode op1mode = GET_MODE (operands[1]);
26997   machine_mode mode = op1mode == DImode ? DImode : SImode;
26998   int scale = 1 << INTVAL (operands[2]);
26999   rtx index = gen_lowpart (word_mode, operands[1]);
27000   rtx base = gen_lowpart (word_mode, operands[5]);
27001   rtx dest = gen_lowpart (mode, operands[3]);
27003   operands[1] = gen_rtx_PLUS (word_mode, base,
27004                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
27005   if (mode != word_mode)
27006     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
27008   operands[5] = base;
27009   if (op1mode != word_mode)
27010     operands[5] = gen_lowpart (op1mode, operands[5]);
27012   operands[0] = dest;
27015 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
27016 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
27017 ;; caught for use by garbage collectors and the like.  Using an insn that
27018 ;; maps to SIGILL makes it more likely the program will rightfully die.
27019 ;; Keeping with tradition, "6" is in honor of #UD.
27020 (define_insn "trap"
27021   [(trap_if (const_int 1) (const_int 6))]
27022   ""
27024 #ifdef HAVE_AS_IX86_UD2
27025   return "ud2";
27026 #else
27027   return ASM_SHORT "0x0b0f";
27028 #endif
27030   [(set_attr "length" "2")])
27032 (define_insn "ud2"
27033   [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
27034   ""
27036 #ifdef HAVE_AS_IX86_UD2
27037   return "ud2";
27038 #else
27039   return ASM_SHORT "0x0b0f";
27040 #endif
27042   [(set_attr "length" "2")])
27044 (define_expand "prefetch"
27045   [(prefetch (match_operand 0 "address_operand")
27046              (match_operand:SI 1 "const_int_operand")
27047              (match_operand:SI 2 "const_int_operand"))]
27048   "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
27050   bool write = operands[1] != const0_rtx;
27051   int locality = INTVAL (operands[2]);
27053   gcc_assert (IN_RANGE (locality, 0, 3));
27055   /* Use 3dNOW prefetch in case we are asking for write prefetch not
27056      supported by SSE counterpart (non-SSE2 athlon machines) or the
27057      SSE prefetch is not available (K6 machines).  Otherwise use SSE
27058      prefetch as it allows specifying of locality.  */
27060   if (write)
27061     {
27062       if (TARGET_PREFETCHWT1)
27063         operands[2] = GEN_INT (MAX (locality, 2)); 
27064       else if (TARGET_PRFCHW)
27065         operands[2] = GEN_INT (3);
27066       else if (TARGET_3DNOW && !TARGET_SSE2)
27067         operands[2] = GEN_INT (3);
27068       else if (TARGET_PREFETCH_SSE)
27069         operands[1] = const0_rtx;
27070       else
27071         {
27072           gcc_assert (TARGET_3DNOW);
27073           operands[2] = GEN_INT (3);
27074         }
27075     }
27076   else
27077     {
27078       if (TARGET_PREFETCH_SSE)
27079         ;
27080       else
27081         {
27082           gcc_assert (TARGET_3DNOW);
27083           operands[2] = GEN_INT (3);
27084         }
27085     }
27088 (define_insn "*prefetch_sse"
27089   [(prefetch (match_operand 0 "address_operand" "p")
27090              (const_int 0)
27091              (match_operand:SI 1 "const_int_operand"))]
27092   "TARGET_PREFETCH_SSE"
27094   static const char * const patterns[4] = {
27095    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
27096   };
27098   int locality = INTVAL (operands[1]);
27099   gcc_assert (IN_RANGE (locality, 0, 3));
27101   return patterns[locality];
27103   [(set_attr "type" "sse")
27104    (set_attr "atom_sse_attr" "prefetch")
27105    (set (attr "length_address")
27106         (symbol_ref "memory_address_length (operands[0], false)"))
27107    (set_attr "memory" "none")])
27109 (define_insn "*prefetch_3dnow"
27110   [(prefetch (match_operand 0 "address_operand" "p")
27111              (match_operand:SI 1 "const_int_operand")
27112              (const_int 3))]
27113   "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
27115   if (operands[1] == const0_rtx)
27116     return "prefetch\t%a0";
27117   else
27118     return "prefetchw\t%a0";
27120   [(set_attr "type" "mmx")
27121    (set (attr "length_address")
27122         (symbol_ref "memory_address_length (operands[0], false)"))
27123    (set_attr "memory" "none")])
27125 (define_insn "*prefetch_prefetchwt1"
27126   [(prefetch (match_operand 0 "address_operand" "p")
27127              (const_int 1)
27128              (const_int 2))]
27129   "TARGET_PREFETCHWT1"
27130   "prefetchwt1\t%a0";
27131   [(set_attr "type" "sse")
27132    (set (attr "length_address")
27133         (symbol_ref "memory_address_length (operands[0], false)"))
27134    (set_attr "memory" "none")])
27136 (define_insn "prefetchi"
27137   [(unspec_volatile [(match_operand 0 "local_func_symbolic_operand" "p")
27138                      (match_operand:SI 1 "const_int_operand")]
27139                     UNSPECV_PREFETCHI)]
27140   "TARGET_PREFETCHI && TARGET_64BIT"
27142   static const char * const patterns[2] = {
27143     "prefetchit1\t%0", "prefetchit0\t%0"
27144   };
27146   int locality = INTVAL (operands[1]);
27147   gcc_assert (IN_RANGE (locality, 2, 3));
27149   return patterns[locality - 2];
27151   [(set_attr "type" "sse")
27152    (set (attr "length_address")
27153         (symbol_ref "memory_address_length (operands[0], false)"))
27154    (set_attr "memory" "none")])
27156 (define_insn "sse4_2_crc32<mode>"
27157   [(set (match_operand:SI 0 "register_operand" "=r")
27158         (unspec:SI
27159           [(match_operand:SI 1 "register_operand" "0")
27160            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
27161           UNSPEC_CRC32))]
27162   "TARGET_CRC32"
27163   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
27164   [(set_attr "type" "sselog1")
27165    (set_attr "prefix_rep" "1")
27166    (set_attr "prefix_extra" "1")
27167    (set (attr "prefix_data16")
27168      (if_then_else (match_operand:HI 2)
27169        (const_string "1")
27170        (const_string "*")))
27171    (set (attr "prefix_rex")
27172      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
27173        (const_string "1")
27174        (const_string "*")))
27175    (set_attr "mode" "SI")])
27177 (define_insn "sse4_2_crc32di"
27178   [(set (match_operand:DI 0 "register_operand" "=r")
27179         (zero_extend:DI
27180           (unspec:SI
27181             [(match_operand:SI 1 "register_operand" "0")
27182              (match_operand:DI 2 "nonimmediate_operand" "rm")]
27183           UNSPEC_CRC32)))]
27184   "TARGET_64BIT && TARGET_CRC32"
27185   "crc32{q}\t{%2, %0|%0, %2}"
27186   [(set_attr "type" "sselog1")
27187    (set_attr "prefix_rep" "1")
27188    (set_attr "prefix_extra" "1")
27189    (set_attr "mode" "DI")])
27191 (define_insn "rdpmc"
27192   [(set (match_operand:DI 0 "register_operand" "=A")
27193         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
27194                             UNSPECV_RDPMC))]
27195   "!TARGET_64BIT"
27196   "rdpmc"
27197   [(set_attr "type" "other")
27198    (set_attr "length" "2")])
27200 (define_insn "rdpmc_rex64"
27201   [(set (match_operand:DI 0 "register_operand" "=a")
27202         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
27203                             UNSPECV_RDPMC))
27204    (set (match_operand:DI 1 "register_operand" "=d")
27205         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
27206   "TARGET_64BIT"
27207   "rdpmc"
27208   [(set_attr "type" "other")
27209    (set_attr "length" "2")])
27211 (define_insn "rdtsc"
27212   [(set (match_operand:DI 0 "register_operand" "=A")
27213         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
27214   "!TARGET_64BIT"
27215   "rdtsc"
27216   [(set_attr "type" "other")
27217    (set_attr "length" "2")])
27219 (define_insn "rdtsc_rex64"
27220   [(set (match_operand:DI 0 "register_operand" "=a")
27221         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
27222    (set (match_operand:DI 1 "register_operand" "=d")
27223         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
27224   "TARGET_64BIT"
27225   "rdtsc"
27226   [(set_attr "type" "other")
27227    (set_attr "length" "2")])
27229 (define_insn "rdtscp"
27230   [(set (match_operand:DI 0 "register_operand" "=A")
27231         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
27232    (set (match_operand:SI 1 "register_operand" "=c")
27233         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
27234   "!TARGET_64BIT"
27235   "rdtscp"
27236   [(set_attr "type" "other")
27237    (set_attr "length" "3")])
27239 (define_insn "rdtscp_rex64"
27240   [(set (match_operand:DI 0 "register_operand" "=a")
27241         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
27242    (set (match_operand:DI 1 "register_operand" "=d")
27243         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
27244    (set (match_operand:SI 2 "register_operand" "=c")
27245         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
27246   "TARGET_64BIT"
27247   "rdtscp"
27248   [(set_attr "type" "other")
27249    (set_attr "length" "3")])
27251 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
27253 ;; FXSR, XSAVE and XSAVEOPT instructions
27255 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
27257 (define_insn "fxsave"
27258   [(set (match_operand:BLK 0 "memory_operand" "=m")
27259         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
27260   "TARGET_FXSR"
27261   "fxsave\t%0"
27262   [(set_attr "type" "other")
27263    (set_attr "memory" "store")
27264    (set (attr "length")
27265         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
27267 (define_insn "fxsave64"
27268   [(set (match_operand:BLK 0 "memory_operand" "=jm")
27269         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
27270   "TARGET_64BIT && TARGET_FXSR"
27271   "fxsave64\t%0"
27272   [(set_attr "type" "other")
27273    (set_attr "addr" "gpr16")
27274    (set_attr "memory" "store")
27275    (set (attr "length")
27276         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
27278 (define_insn "fxrstor"
27279   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
27280                     UNSPECV_FXRSTOR)]
27281   "TARGET_FXSR"
27282   "fxrstor\t%0"
27283   [(set_attr "type" "other")
27284    (set_attr "memory" "load")
27285    (set (attr "length")
27286         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
27288 (define_insn "fxrstor64"
27289   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "jm")]
27290                     UNSPECV_FXRSTOR64)]
27291   "TARGET_64BIT && TARGET_FXSR"
27292   "fxrstor64\t%0"
27293   [(set_attr "type" "other")
27294    (set_attr "addr" "gpr16")
27295    (set_attr "memory" "load")
27296    (set (attr "length")
27297         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
27299 (define_int_iterator ANY_XSAVE
27300         [UNSPECV_XSAVE
27301          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
27302          (UNSPECV_XSAVEC "TARGET_XSAVEC")
27303          (UNSPECV_XSAVES "TARGET_XSAVES")])
27305 (define_int_iterator ANY_XSAVE64
27306         [UNSPECV_XSAVE64
27307          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
27308          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
27309          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
27311 (define_int_attr xsave
27312         [(UNSPECV_XSAVE "xsave")
27313          (UNSPECV_XSAVE64 "xsave64")
27314          (UNSPECV_XSAVEOPT "xsaveopt")
27315          (UNSPECV_XSAVEOPT64 "xsaveopt64")
27316          (UNSPECV_XSAVEC "xsavec")
27317          (UNSPECV_XSAVEC64 "xsavec64")
27318          (UNSPECV_XSAVES "xsaves")
27319          (UNSPECV_XSAVES64 "xsaves64")])
27321 (define_int_iterator ANY_XRSTOR
27322         [UNSPECV_XRSTOR
27323          (UNSPECV_XRSTORS "TARGET_XSAVES")])
27325 (define_int_iterator ANY_XRSTOR64
27326         [UNSPECV_XRSTOR64
27327          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
27329 (define_int_attr xrstor
27330         [(UNSPECV_XRSTOR "xrstor")
27331          (UNSPECV_XRSTOR64 "xrstor")
27332          (UNSPECV_XRSTORS "xrstors")
27333          (UNSPECV_XRSTORS64 "xrstors")])
27335 (define_insn "<xsave>"
27336   [(set (match_operand:BLK 0 "memory_operand" "=m")
27337         (unspec_volatile:BLK
27338          [(match_operand:DI 1 "register_operand" "A")]
27339          ANY_XSAVE))]
27340   "!TARGET_64BIT && TARGET_XSAVE"
27341   "<xsave>\t%0"
27342   [(set_attr "type" "other")
27343    (set_attr "memory" "store")
27344    (set (attr "length")
27345         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
27347 (define_insn "<xsave>_rex64"
27348   [(set (match_operand:BLK 0 "memory_operand" "=jm")
27349         (unspec_volatile:BLK
27350          [(match_operand:SI 1 "register_operand" "a")
27351           (match_operand:SI 2 "register_operand" "d")]
27352          ANY_XSAVE))]
27353   "TARGET_64BIT && TARGET_XSAVE"
27354   "<xsave>\t%0"
27355   [(set_attr "type" "other")
27356    (set_attr "memory" "store")
27357    (set_attr "addr" "gpr16")
27358    (set (attr "length")
27359         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
27361 (define_insn "<xsave>"
27362   [(set (match_operand:BLK 0 "memory_operand" "=jm")
27363         (unspec_volatile:BLK
27364          [(match_operand:SI 1 "register_operand" "a")
27365           (match_operand:SI 2 "register_operand" "d")]
27366          ANY_XSAVE64))]
27367   "TARGET_64BIT && TARGET_XSAVE"
27368   "<xsave>\t%0"
27369   [(set_attr "type" "other")
27370    (set_attr "memory" "store")
27371    (set_attr "addr" "gpr16")
27372    (set (attr "length")
27373         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
27375 (define_insn "<xrstor>"
27376    [(unspec_volatile:BLK
27377      [(match_operand:BLK 0 "memory_operand" "m")
27378       (match_operand:DI 1 "register_operand" "A")]
27379      ANY_XRSTOR)]
27380   "!TARGET_64BIT && TARGET_XSAVE"
27381   "<xrstor>\t%0"
27382   [(set_attr "type" "other")
27383    (set_attr "memory" "load")
27384    (set (attr "length")
27385         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
27387 (define_insn "<xrstor>_rex64"
27388    [(unspec_volatile:BLK
27389      [(match_operand:BLK 0 "memory_operand" "jm")
27390       (match_operand:SI 1 "register_operand" "a")
27391       (match_operand:SI 2 "register_operand" "d")]
27392      ANY_XRSTOR)]
27393   "TARGET_64BIT && TARGET_XSAVE"
27394   "<xrstor>\t%0"
27395   [(set_attr "type" "other")
27396    (set_attr "memory" "load")
27397    (set_attr "addr" "gpr16")
27398    (set (attr "length")
27399         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
27401 (define_insn "<xrstor>64"
27402    [(unspec_volatile:BLK
27403      [(match_operand:BLK 0 "memory_operand" "jm")
27404       (match_operand:SI 1 "register_operand" "a")
27405       (match_operand:SI 2 "register_operand" "d")]
27406      ANY_XRSTOR64)]
27407   "TARGET_64BIT && TARGET_XSAVE"
27408   "<xrstor>64\t%0"
27409   [(set_attr "type" "other")
27410    (set_attr "memory" "load")
27411    (set_attr "addr" "gpr16")
27412    (set (attr "length")
27413         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
27415 (define_insn "xsetbv"
27416   [(unspec_volatile:SI
27417          [(match_operand:SI 0 "register_operand" "c")
27418           (match_operand:DI 1 "register_operand" "A")]
27419          UNSPECV_XSETBV)]
27420   "!TARGET_64BIT && TARGET_XSAVE"
27421   "xsetbv"
27422   [(set_attr "type" "other")])
27424 (define_insn "xsetbv_rex64"
27425   [(unspec_volatile:SI
27426          [(match_operand:SI 0 "register_operand" "c")
27427           (match_operand:SI 1 "register_operand" "a")
27428           (match_operand:SI 2 "register_operand" "d")]
27429          UNSPECV_XSETBV)]
27430   "TARGET_64BIT && TARGET_XSAVE"
27431   "xsetbv"
27432   [(set_attr "type" "other")])
27434 (define_insn "xgetbv"
27435   [(set (match_operand:DI 0 "register_operand" "=A")
27436         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
27437                             UNSPECV_XGETBV))]
27438   "!TARGET_64BIT && TARGET_XSAVE"
27439   "xgetbv"
27440   [(set_attr "type" "other")])
27442 (define_insn "xgetbv_rex64"
27443   [(set (match_operand:DI 0 "register_operand" "=a")
27444         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
27445                             UNSPECV_XGETBV))
27446    (set (match_operand:DI 1 "register_operand" "=d")
27447         (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
27448   "TARGET_64BIT && TARGET_XSAVE"
27449   "xgetbv"
27450   [(set_attr "type" "other")])
27452 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
27454 ;; Floating-point instructions for atomic compound assignments
27456 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
27458 ; Clobber all floating-point registers on environment save and restore
27459 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
27460 (define_insn "fnstenv"
27461   [(set (match_operand:BLK 0 "memory_operand" "=m")
27462         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
27463    (clobber (reg:XF ST0_REG))
27464    (clobber (reg:XF ST1_REG))
27465    (clobber (reg:XF ST2_REG))
27466    (clobber (reg:XF ST3_REG))
27467    (clobber (reg:XF ST4_REG))
27468    (clobber (reg:XF ST5_REG))
27469    (clobber (reg:XF ST6_REG))
27470    (clobber (reg:XF ST7_REG))]
27471   "TARGET_80387"
27472   "fnstenv\t%0"
27473   [(set_attr "type" "other")
27474    (set_attr "memory" "store")
27475    (set (attr "length")
27476         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
27478 (define_insn "fldenv"
27479   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
27480                     UNSPECV_FLDENV)
27481    (clobber (reg:XF ST0_REG))
27482    (clobber (reg:XF ST1_REG))
27483    (clobber (reg:XF ST2_REG))
27484    (clobber (reg:XF ST3_REG))
27485    (clobber (reg:XF ST4_REG))
27486    (clobber (reg:XF ST5_REG))
27487    (clobber (reg:XF ST6_REG))
27488    (clobber (reg:XF ST7_REG))]
27489   "TARGET_80387"
27490   "fldenv\t%0"
27491   [(set_attr "type" "other")
27492    (set_attr "memory" "load")
27493    (set (attr "length")
27494         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
27496 (define_insn "fnstsw"
27497   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
27498         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
27499   "TARGET_80387"
27500   "fnstsw\t%0"
27501   [(set_attr "type" "other,other")
27502    (set_attr "memory" "none,store")
27503    (set (attr "length")
27504         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
27506 (define_insn "fnclex"
27507   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
27508   "TARGET_80387"
27509   "fnclex"
27510   [(set_attr "type" "other")
27511    (set_attr "memory" "none")
27512    (set_attr "length" "2")])
27514 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
27516 ;; LWP instructions
27518 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
27520 (define_insn "@lwp_llwpcb<mode>"
27521   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
27522                     UNSPECV_LLWP_INTRINSIC)]
27523   "TARGET_LWP"
27524   "llwpcb\t%0"
27525   [(set_attr "type" "lwp")
27526    (set_attr "mode" "<MODE>")
27527    (set_attr "length" "5")])
27529 (define_insn "@lwp_slwpcb<mode>"
27530   [(set (match_operand:P 0 "register_operand" "=r")
27531         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
27532   "TARGET_LWP"
27533   "slwpcb\t%0"
27534   [(set_attr "type" "lwp")
27535    (set_attr "mode" "<MODE>")
27536    (set_attr "length" "5")])
27538 (define_insn "@lwp_lwpval<mode>"
27539   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
27540                      (match_operand:SI 1 "nonimmediate_operand" "rm")
27541                      (match_operand:SI 2 "const_int_operand")]
27542                     UNSPECV_LWPVAL_INTRINSIC)]
27543   "TARGET_LWP"
27544   "lwpval\t{%2, %1, %0|%0, %1, %2}"
27545   [(set_attr "type" "lwp")
27546    (set_attr "mode" "<MODE>")
27547    (set (attr "length")
27548         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
27550 (define_insn "@lwp_lwpins<mode>"
27551   [(set (reg:CCC FLAGS_REG)
27552         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
27553                               (match_operand:SI 1 "nonimmediate_operand" "rm")
27554                               (match_operand:SI 2 "const_int_operand")]
27555                              UNSPECV_LWPINS_INTRINSIC))]
27556   "TARGET_LWP"
27557   "lwpins\t{%2, %1, %0|%0, %1, %2}"
27558   [(set_attr "type" "lwp")
27559    (set_attr "mode" "<MODE>")
27560    (set (attr "length")
27561         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
27563 (define_int_iterator RDFSGSBASE
27564         [UNSPECV_RDFSBASE
27565          UNSPECV_RDGSBASE])
27567 (define_int_iterator WRFSGSBASE
27568         [UNSPECV_WRFSBASE
27569          UNSPECV_WRGSBASE])
27571 (define_int_attr fsgs
27572         [(UNSPECV_RDFSBASE "fs")
27573          (UNSPECV_RDGSBASE "gs")
27574          (UNSPECV_WRFSBASE "fs")
27575          (UNSPECV_WRGSBASE "gs")])
27577 (define_insn "rd<fsgs>base<mode>"
27578   [(set (match_operand:SWI48 0 "register_operand" "=r")
27579         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
27580   "TARGET_64BIT && TARGET_FSGSBASE"
27581   "rd<fsgs>base\t%0"
27582   [(set_attr "type" "other")
27583    (set_attr "prefix_0f" "1")
27584    (set_attr "prefix_rep" "1")])
27586 (define_insn "wr<fsgs>base<mode>"
27587   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
27588                     WRFSGSBASE)]
27589   "TARGET_64BIT && TARGET_FSGSBASE"
27590   "wr<fsgs>base\t%0"
27591   [(set_attr "type" "other")
27592    (set_attr "prefix_0f" "1")
27593    (set_attr "prefix_rep" "1")])
27595 (define_insn "ptwrite<mode>"
27596   [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
27597                     UNSPECV_PTWRITE)]
27598   "TARGET_PTWRITE"
27599   "ptwrite\t%0"
27600   [(set_attr "type" "other")
27601    (set_attr "prefix_0f" "1")
27602    (set_attr "prefix_rep" "1")])
27604 (define_insn "@rdrand<mode>"
27605   [(set (match_operand:SWI248 0 "register_operand" "=r")
27606         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
27607    (set (reg:CCC FLAGS_REG)
27608         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
27609   "TARGET_RDRND"
27610   "rdrand\t%0"
27611   [(set_attr "type" "other")
27612    (set_attr "prefix_0f" "1")])
27614 (define_insn "@rdseed<mode>"
27615   [(set (match_operand:SWI248 0 "register_operand" "=r")
27616         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
27617    (set (reg:CCC FLAGS_REG)
27618         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
27619   "TARGET_RDSEED"
27620   "rdseed\t%0"
27621   [(set_attr "type" "other")
27622    (set_attr "prefix_0f" "1")])
27624 (define_expand "pause"
27625   [(set (match_dup 0)
27626         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
27627   ""
27629   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
27630   MEM_VOLATILE_P (operands[0]) = 1;
27633 ;; Use "rep; nop", instead of "pause", to support older assemblers.
27634 ;; They have the same encoding.
27635 (define_insn "*pause"
27636   [(set (match_operand:BLK 0)
27637         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
27638   ""
27639   "rep%; nop"
27640   [(set_attr "length" "2")
27641    (set_attr "memory" "unknown")])
27643 ;; CET instructions
27644 (define_insn "@rdssp<mode>"
27645   [(set (match_operand:SWI48 0 "register_operand" "=r")
27646         (unspec_volatile:SWI48 [(match_operand:SWI48 1 "register_operand" "0")]
27647                                UNSPECV_NOP_RDSSP))]
27648   "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
27649   "rdssp<mskmodesuffix>\t%0"
27650   [(set_attr "length" "6")
27651    (set_attr "type" "other")])
27653 (define_insn "@incssp<mode>"
27654   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
27655                     UNSPECV_INCSSP)]
27656   "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
27657   "incssp<mskmodesuffix>\t%0"
27658   [(set_attr "length" "4")
27659    (set_attr "type" "other")])
27661 (define_insn "saveprevssp"
27662   [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
27663   "TARGET_SHSTK"
27664   "saveprevssp"
27665   [(set_attr "length" "5")
27666    (set_attr "type" "other")])
27668 (define_insn "rstorssp"
27669   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
27670                     UNSPECV_RSTORSSP)]
27671   "TARGET_SHSTK"
27672   "rstorssp\t%0"
27673   [(set_attr "length" "5")
27674    (set_attr "type" "other")])
27676 (define_insn "@wrss<mode>"
27677   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
27678                      (match_operand:SWI48 1 "memory_operand" "m")]
27679                     UNSPECV_WRSS)]
27680   "TARGET_SHSTK"
27681   "wrss<mskmodesuffix>\t%0, %1"
27682   [(set_attr "length" "3")
27683    (set_attr "type" "other")])
27685 (define_insn "@wruss<mode>"
27686   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
27687                      (match_operand:SWI48 1 "memory_operand" "m")]
27688                     UNSPECV_WRUSS)]
27689   "TARGET_SHSTK"
27690   "wruss<mskmodesuffix>\t%0, %1"
27691   [(set_attr "length" "4")
27692    (set_attr "type" "other")])
27694 (define_insn "setssbsy"
27695   [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
27696   "TARGET_SHSTK"
27697   "setssbsy"
27698   [(set_attr "length" "4")
27699    (set_attr "type" "other")])
27701 (define_insn "clrssbsy"
27702   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
27703                     UNSPECV_CLRSSBSY)]
27704   "TARGET_SHSTK"
27705   "clrssbsy\t%0"
27706   [(set_attr "length" "4")
27707    (set_attr "type" "other")])
27709 (define_insn "nop_endbr"
27710   [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
27711   "(flag_cf_protection & CF_BRANCH)"
27713   return TARGET_64BIT ? "endbr64" : "endbr32";
27715   [(set_attr "length" "4")
27716    (set_attr "length_immediate" "0")
27717    (set_attr "modrm" "0")])
27719 ;; For RTM support
27720 (define_expand "xbegin"
27721   [(set (match_operand:SI 0 "register_operand")
27722         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
27723   "TARGET_RTM"
27725   rtx_code_label *label = gen_label_rtx ();
27727   /* xbegin is emitted as jump_insn, so reload won't be able
27728      to reload its operand.  Force the value into AX hard register.  */
27729   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
27730   emit_move_insn (ax_reg, constm1_rtx);
27732   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
27734   emit_label (label);
27735   LABEL_NUSES (label) = 1;
27737   emit_move_insn (operands[0], ax_reg);
27739   DONE;
27742 (define_insn "xbegin_1"
27743   [(set (pc)
27744         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
27745                           (const_int 0))
27746                       (label_ref (match_operand 1))
27747                       (pc)))
27748    (set (match_operand:SI 0 "register_operand" "+a")
27749         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
27750   "TARGET_RTM"
27751   "xbegin\t%l1"
27752   [(set_attr "type" "other")
27753    (set_attr "length" "6")])
27755 (define_insn "xend"
27756   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
27757   "TARGET_RTM"
27758   "xend"
27759   [(set_attr "type" "other")
27760    (set_attr "length" "3")])
27762 (define_insn "xabort"
27763   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand")]
27764                     UNSPECV_XABORT)]
27765   "TARGET_RTM"
27766   "xabort\t%0"
27767   [(set_attr "type" "other")
27768    (set_attr "length" "3")])
27770 (define_expand "xtest"
27771   [(set (match_operand:QI 0 "register_operand")
27772         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
27773   "TARGET_RTM"
27775   emit_insn (gen_xtest_1 ());
27777   ix86_expand_setcc (operands[0], NE,
27778                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
27779   DONE;
27782 (define_insn "xtest_1"
27783   [(set (reg:CCZ FLAGS_REG)
27784         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
27785   "TARGET_RTM"
27786   "xtest"
27787   [(set_attr "type" "other")
27788    (set_attr "length" "3")])
27790 (define_insn "clwb"
27791   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
27792                    UNSPECV_CLWB)]
27793   "TARGET_CLWB"
27794   "clwb\t%a0"
27795   [(set_attr "type" "sse")
27796    (set_attr "atom_sse_attr" "fence")
27797    (set_attr "memory" "unknown")])
27799 (define_insn "clflushopt"
27800   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
27801                    UNSPECV_CLFLUSHOPT)]
27802   "TARGET_CLFLUSHOPT"
27803   "clflushopt\t%a0"
27804   [(set_attr "type" "sse")
27805    (set_attr "atom_sse_attr" "fence")
27806    (set_attr "memory" "unknown")])
27808 ;; MONITORX and MWAITX
27809 (define_insn "mwaitx"
27810   [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
27811                      (match_operand:SI 1 "register_operand" "a")
27812                      (match_operand:SI 2 "register_operand" "b")]
27813                    UNSPECV_MWAITX)]
27814   "TARGET_MWAITX"
27815 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
27816 ;; Since 32bit register operands are implicitly zero extended to 64bit,
27817 ;; we only need to set up 32bit registers.
27818   "mwaitx"
27819   [(set_attr "length" "3")])
27821 (define_insn "@monitorx_<mode>"
27822   [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
27823                      (match_operand:SI 1 "register_operand" "c")
27824                      (match_operand:SI 2 "register_operand" "d")]
27825                    UNSPECV_MONITORX)]
27826   "TARGET_MWAITX"
27827 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
27828 ;; RCX and RDX are used.  Since 32bit register operands are implicitly
27829 ;; zero extended to 64bit, we only need to set up 32bit registers.
27830   "%^monitorx"
27831   [(set (attr "length")
27832      (symbol_ref ("(Pmode != word_mode) + 3")))])
27834 ;; CLZERO
27835 (define_insn "@clzero_<mode>"
27836   [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
27837                    UNSPECV_CLZERO)]
27838   "TARGET_CLZERO"
27839   "clzero"
27840   [(set_attr "length" "3")
27841   (set_attr "memory" "unknown")])
27843 ;; RDPKRU and WRPKRU
27845 (define_expand "rdpkru"
27846   [(parallel
27847      [(set (match_operand:SI 0 "register_operand")
27848            (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
27849       (set (match_dup 2) (const_int 0))])]
27850   "TARGET_PKU"
27852   operands[1] = force_reg (SImode, const0_rtx);
27853   operands[2] = gen_reg_rtx (SImode);
27856 (define_insn "*rdpkru"
27857   [(set (match_operand:SI 0 "register_operand" "=a")
27858         (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
27859                             UNSPECV_PKU))
27860    (set (match_operand:SI 1 "register_operand" "=d")
27861         (const_int 0))]
27862   "TARGET_PKU"
27863   "rdpkru"
27864   [(set_attr "type" "other")])
27866 (define_expand "wrpkru"
27867   [(unspec_volatile:SI
27868      [(match_operand:SI 0 "register_operand")
27869       (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
27870   "TARGET_PKU"
27872   operands[1] = force_reg (SImode, const0_rtx);
27873   operands[2] = force_reg (SImode, const0_rtx);
27876 (define_insn "*wrpkru"
27877   [(unspec_volatile:SI
27878      [(match_operand:SI 0 "register_operand" "a")
27879       (match_operand:SI 1 "register_operand" "d")
27880       (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
27881   "TARGET_PKU"
27882   "wrpkru"
27883   [(set_attr "type" "other")])
27885 (define_insn "rdpid"
27886   [(set (match_operand:SI 0 "register_operand" "=r")
27887         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
27888   "!TARGET_64BIT && TARGET_RDPID"
27889   "rdpid\t%0"
27890   [(set_attr "type" "other")])
27892 (define_insn "rdpid_rex64"
27893   [(set (match_operand:DI 0 "register_operand" "=r")
27894         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
27895   "TARGET_64BIT && TARGET_RDPID"
27896   "rdpid\t%0"
27897   [(set_attr "type" "other")])
27899 ;; Intirinsics for > i486
27901 (define_insn "wbinvd"
27902   [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
27903   ""
27904   "wbinvd"
27905   [(set_attr "type" "other")])
27907 (define_insn "wbnoinvd"
27908   [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
27909   "TARGET_WBNOINVD"
27910   "wbnoinvd"
27911   [(set_attr "type" "other")])
27913 ;; MOVDIRI and MOVDIR64B
27915 (define_insn "movdiri<mode>"
27916   [(set (match_operand:SWI48 0 "memory_operand" "=m")
27917         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
27918                       UNSPEC_MOVDIRI))]
27919   "TARGET_MOVDIRI"
27920   "movdiri\t{%1, %0|%0, %1}"
27921   [(set_attr "type" "other")])
27923 (define_insn "@movdir64b_<mode>"
27924   [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
27925         (unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
27926                    UNSPEC_MOVDIR64B))]
27927   "TARGET_MOVDIR64B"
27928   "movdir64b\t{%1, %0|%0, %1}"
27929   [(set_attr "type" "other")])
27931 ;; TSXLDTRK
27932 (define_int_iterator TSXLDTRK [UNSPECV_XSUSLDTRK UNSPECV_XRESLDTRK])
27933 (define_int_attr tsxldtrk [(UNSPECV_XSUSLDTRK "xsusldtrk")
27934                  (UNSPECV_XRESLDTRK "xresldtrk")])
27935 (define_insn "<tsxldtrk>"
27936   [(unspec_volatile [(const_int 0)] TSXLDTRK)]
27937   "TARGET_TSXLDTRK"
27938   "<tsxldtrk>"
27939   [(set_attr "type" "other")
27940    (set_attr "length" "4")])
27942 ;; ENQCMD and ENQCMDS
27944 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
27945 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
27947 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
27948   [(set (reg:CCZ FLAGS_REG)
27949         (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
27950                               (match_operand:XI 1 "memory_operand" "m")]
27951                              ENQCMD))]
27952   "TARGET_ENQCMD"
27953   "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
27954   [(set_attr "type" "other")])
27956 ;; UINTR
27957 (define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI])
27958 (define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")])
27960 (define_insn "<uintr>"
27961   [(unspec_volatile [(const_int 0)] UINTR)]
27962   "TARGET_UINTR && TARGET_64BIT"
27963   "<uintr>"
27964   [(set_attr "type" "other")
27965    (set_attr "length" "4")])
27967 (define_insn "testui"
27968   [(set (reg:CCC FLAGS_REG)
27969         (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))]
27970   "TARGET_UINTR && TARGET_64BIT"
27971   "testui"
27972   [(set_attr "type" "other")
27973    (set_attr "length" "4")])
27975 (define_insn "senduipi"
27976   [(unspec_volatile
27977     [(match_operand:DI 0 "register_operand" "r")]
27978     UNSPECV_SENDUIPI)]
27979   "TARGET_UINTR && TARGET_64BIT"
27980   "senduipi\t%0"
27981   [(set_attr "type" "other")
27982    (set_attr "length" "4")])
27984 ;; WAITPKG
27986 (define_insn "umwait"
27987   [(set (reg:CCC FLAGS_REG)
27988         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
27989                               (match_operand:DI 1 "register_operand" "A")]
27990                              UNSPECV_UMWAIT))]
27991   "!TARGET_64BIT && TARGET_WAITPKG"
27992   "umwait\t%0"
27993   [(set_attr "length" "3")])
27995 (define_insn "umwait_rex64"
27996   [(set (reg:CCC FLAGS_REG)
27997         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
27998                               (match_operand:SI 1 "register_operand" "a")
27999                               (match_operand:SI 2 "register_operand" "d")]
28000                              UNSPECV_UMWAIT))]
28001   "TARGET_64BIT && TARGET_WAITPKG"
28002   "umwait\t%0"
28003   [(set_attr "length" "3")])
28005 (define_insn "@umonitor_<mode>"
28006   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
28007                     UNSPECV_UMONITOR)]
28008   "TARGET_WAITPKG"
28009   "umonitor\t%0"
28010   [(set (attr "length")
28011      (symbol_ref ("(Pmode != word_mode) + 3")))])
28013 (define_insn "tpause"
28014   [(set (reg:CCC FLAGS_REG)
28015         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
28016                               (match_operand:DI 1 "register_operand" "A")]
28017                              UNSPECV_TPAUSE))]
28018   "!TARGET_64BIT && TARGET_WAITPKG"
28019   "tpause\t%0"
28020   [(set_attr "length" "3")])
28022 (define_insn "tpause_rex64"
28023   [(set (reg:CCC FLAGS_REG)
28024         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
28025                               (match_operand:SI 1 "register_operand" "a")
28026                               (match_operand:SI 2 "register_operand" "d")]
28027                              UNSPECV_TPAUSE))]
28028   "TARGET_64BIT && TARGET_WAITPKG"
28029   "tpause\t%0"
28030   [(set_attr "length" "3")])
28032 (define_insn "cldemote"
28033   [(unspec_volatile[(match_operand 0 "address_operand" "p")]
28034                  UNSPECV_CLDEMOTE)]
28035   "TARGET_CLDEMOTE"
28036   "cldemote\t%a0"
28037   [(set_attr "type" "other")
28038    (set_attr "memory" "unknown")])
28040 (define_insn "speculation_barrier"
28041   [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
28042   ""
28043   "lfence"
28044   [(set_attr "type" "other")
28045    (set_attr "length" "3")])
28047 (define_insn "serialize"
28048   [(unspec_volatile [(const_int 0)] UNSPECV_SERIALIZE)]
28049   "TARGET_SERIALIZE"
28050   "serialize"
28051   [(set_attr "type" "other")
28052    (set_attr "length" "3")])
28054 (define_insn "patchable_area"
28055   [(unspec_volatile [(match_operand 0 "const_int_operand")
28056                      (match_operand 1 "const_int_operand")]
28057                     UNSPECV_PATCHABLE_AREA)]
28058   ""
28060   ix86_output_patchable_area (INTVAL (operands[0]),
28061                               INTVAL (operands[1]) != 0);
28062   return "";
28064   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
28065    (set_attr "length_immediate" "0")
28066    (set_attr "modrm" "0")])
28068 (define_insn "hreset"
28069   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")]
28070                      UNSPECV_HRESET)]
28071   "TARGET_HRESET"
28072   "hreset\t{$0|0}"
28073   [(set_attr "type" "other")
28074    (set_attr "length" "4")])
28076 ;; Spaceship optimization
28077 (define_expand "spaceship<mode>3"
28078   [(match_operand:SI 0 "register_operand")
28079    (match_operand:MODEF 1 "cmp_fp_expander_operand")
28080    (match_operand:MODEF 2 "cmp_fp_expander_operand")]
28081   "(TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
28082    && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
28084   ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
28085   DONE;
28088 (define_expand "spaceshipxf3"
28089   [(match_operand:SI 0 "register_operand")
28090    (match_operand:XF 1 "nonmemory_operand")
28091    (match_operand:XF 2 "nonmemory_operand")]
28092   "TARGET_80387 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
28094   ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
28095   DONE;
28098 ;; Defined because the generic expand_builtin_issignaling for XFmode
28099 ;; only tests for sNaNs, but i387 treats also pseudo numbers as always
28100 ;; signaling.
28101 (define_expand "issignalingxf2"
28102   [(match_operand:SI 0 "register_operand")
28103    (match_operand:XF 1 "general_operand")]
28104   ""
28106   rtx temp = operands[1];
28107   if (!MEM_P (temp))
28108     {
28109       rtx mem = assign_stack_temp (XFmode, GET_MODE_SIZE (XFmode));
28110       emit_move_insn (mem, temp);
28111       temp = mem;
28112     }
28113   rtx ex = adjust_address (temp, HImode, 8);
28114   rtx hi = adjust_address (temp, SImode, 4);
28115   rtx lo = adjust_address (temp, SImode, 0);
28116   rtx val = GEN_INT (HOST_WIDE_INT_M1U << 30);
28117   rtx mask = GEN_INT (0x7fff);
28118   rtx bit = GEN_INT (HOST_WIDE_INT_1U << 30);
28119   /* Expand to:
28120      ((ex & mask) && (int) hi >= 0)
28121      || ((ex & mask) == mask && ((hi ^ bit) | ((lo | -lo) >> 31)) > val).  */
28122   rtx nlo = expand_unop (SImode, neg_optab, lo, NULL_RTX, 0);
28123   lo = expand_binop (SImode, ior_optab, lo, nlo,
28124                      NULL_RTX, 1, OPTAB_LIB_WIDEN);
28125   lo = expand_shift (RSHIFT_EXPR, SImode, lo, 31, NULL_RTX, 1);
28126   temp = expand_binop (SImode, xor_optab, hi, bit,
28127                        NULL_RTX, 1, OPTAB_LIB_WIDEN);
28128   temp = expand_binop (SImode, ior_optab, temp, lo,
28129                        NULL_RTX, 1, OPTAB_LIB_WIDEN);
28130   temp = emit_store_flag_force (gen_reg_rtx (SImode), GTU, temp, val,
28131                                 SImode, 1, 1);
28132   ex = expand_binop (HImode, and_optab, ex, mask,
28133                      NULL_RTX, 1, OPTAB_LIB_WIDEN);
28134   rtx temp2 = emit_store_flag_force (gen_reg_rtx (SImode), NE,
28135                                      ex, const0_rtx, SImode, 1, 1);
28136   ex = emit_store_flag_force (gen_reg_rtx (SImode), EQ,
28137                               ex, mask, HImode, 1, 1);
28138   temp = expand_binop (SImode, and_optab, temp, ex,
28139                        NULL_RTX, 1, OPTAB_LIB_WIDEN);
28140   rtx temp3 = emit_store_flag_force (gen_reg_rtx (SImode), GE,
28141                                      hi, const0_rtx, SImode, 0, 1);
28142   temp2 = expand_binop (SImode, and_optab, temp2, temp3,
28143                         NULL_RTX, 1, OPTAB_LIB_WIDEN);
28144   temp = expand_binop (SImode, ior_optab, temp, temp2,
28145                        NULL_RTX, 1, OPTAB_LIB_WIDEN);
28146   emit_move_insn (operands[0], temp);
28147   DONE;
28150 (define_insn "urdmsr"
28151   [(set (match_operand:DI 0 "register_operand" "=r")
28152     (unspec_volatile:DI
28153       [(match_operand:DI 1 "x86_64_szext_nonmemory_operand" "reZ")]
28154       UNSPECV_URDMSR))]
28155   "TARGET_USER_MSR && TARGET_64BIT"
28156   "urdmsr\t{%1, %0|%0, %1}"
28157   [(set_attr "prefix" "vex")
28158    (set_attr "type" "other")])
28160 (define_insn "uwrmsr"
28161   [(unspec_volatile
28162     [(match_operand:DI 0 "x86_64_szext_nonmemory_operand" "reZ")
28163       (match_operand:DI 1 "register_operand" "r")]
28164       UNSPECV_UWRMSR)]
28165   "TARGET_USER_MSR && TARGET_64BIT"
28166   "uwrmsr\t{%1, %0|%0, %1}"
28167   [(set_attr "prefix" "vex")
28168    (set_attr "type" "other")])
28170 (define_insn "ldtilecfg"
28171   [(unspec_volatile [(match_operand:XI 0 "memory_operand" "m")]
28172             UNSPECV_LDTILECFG)]
28173   "TARGET_AMX_TILE"
28174   "ldtilecfg\t%0"
28175   [(set_attr "type" "other")
28176    (set_attr "prefix" "maybe_evex")
28177    (set_attr "memory" "load")
28178    (set_attr "mode" "XI")])
28180 (define_insn "sttilecfg"
28181   [(set (match_operand:XI 0 "memory_operand" "=m")
28182         (unspec_volatile:XI [(const_int 0)] UNSPECV_STTILECFG))]
28183   "TARGET_AMX_TILE"
28184   "sttilecfg\t%0"
28185   [(set_attr "type" "other")
28186    (set_attr "prefix" "maybe_evex")
28187    (set_attr "memory" "store")
28188    (set_attr "mode" "XI")])
28190 (include "mmx.md")
28191 (include "sse.md")
28192 (include "sync.md")