libcpp, c, middle-end: Optimize initializers using #embed in C
[official-gcc.git] / gcc / config / i386 / i386.md
blobe4d1c56ea542320297ba1c6c91e79d327a8c54a9
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
120   UNSPEC_OPTCOMX
121   UNSPEC_SETCC_SI_SLP
123   ;; For SSE/MMX support:
124   UNSPEC_FIX_NOTRUNC
125   UNSPEC_MASKMOV
126   UNSPEC_MOVCC_MASK
127   UNSPEC_MOVMSK
128   UNSPEC_INSERTPS
129   UNSPEC_BLENDV
130   UNSPEC_PSHUFB
131   UNSPEC_XOP_PERMUTE
132   UNSPEC_RCP
133   UNSPEC_RSQRT
134   UNSPEC_PSADBW
136   ;; Different from generic us_truncate RTX
137   ;; as it does unsigned saturation of signed source.
138   UNSPEC_US_TRUNCATE
140   ;; For AVX/AVX512F support
141   UNSPEC_SCALEF
142   UNSPEC_PCMP
143   UNSPEC_CVTBFSF
144   UNSPEC_COMX
146   ;; Generic math support
147   UNSPEC_IEEE_MIN       ; not commutative
148   UNSPEC_IEEE_MAX       ; not commutative
150   ;; x87 Floating point
151   UNSPEC_SIN
152   UNSPEC_COS
153   UNSPEC_FPATAN
154   UNSPEC_FYL2X
155   UNSPEC_FYL2XP1
156   UNSPEC_FRNDINT
157   UNSPEC_FIST
158   UNSPEC_F2XM1
159   UNSPEC_TAN
160   UNSPEC_FXAM
162   ;; x87 Rounding
163   UNSPEC_FRNDINT_ROUNDEVEN
164   UNSPEC_FRNDINT_FLOOR
165   UNSPEC_FRNDINT_CEIL
166   UNSPEC_FRNDINT_TRUNC
167   UNSPEC_FIST_FLOOR
168   UNSPEC_FIST_CEIL
170   ;; x87 Double output FP
171   UNSPEC_SINCOS_COS
172   UNSPEC_SINCOS_SIN
173   UNSPEC_XTRACT_FRACT
174   UNSPEC_XTRACT_EXP
175   UNSPEC_FSCALE_FRACT
176   UNSPEC_FSCALE_EXP
177   UNSPEC_FPREM_F
178   UNSPEC_FPREM_U
179   UNSPEC_FPREM1_F
180   UNSPEC_FPREM1_U
182   UNSPEC_C2_FLAG
183   UNSPEC_FXAM_MEM
185   ;; SSP patterns
186   UNSPEC_SP_SET
187   UNSPEC_SP_TEST
189   ;; For ROUND support
190   UNSPEC_ROUND
192   ;; For CRC32 support
193   UNSPEC_CRC32
195   ;; For LZCNT suppoprt
196   UNSPEC_LZCNT
198   ;; For BMI support
199   UNSPEC_TZCNT
200   UNSPEC_BEXTR
202   ;; For BMI2 support
203   UNSPEC_PDEP
204   UNSPEC_PEXT
206   ;; IRET support
207   UNSPEC_INTERRUPT_RETURN
209   ;; For MOVDIRI and MOVDIR64B support
210   UNSPEC_MOVDIRI
211   UNSPEC_MOVDIR64B
213   ;; For insn_callee_abi:
214   UNSPEC_CALLEE_ABI
216   ;; For APX PUSH2/POP2 support
217   UNSPEC_APXPUSH2
218   UNSPEC_APXPOP2_LOW
219   UNSPEC_APXPOP2_HIGH
221   ;; For APX PPX support
222   UNSPEC_APX_PPX
224   ;; For APX CCMP support
225   ;; DFV = default flag value
226   UNSPEC_APX_DFV
229 (define_c_enum "unspecv" [
230   UNSPECV_UD2
231   UNSPECV_BLOCKAGE
232   UNSPECV_STACK_PROBE
233   UNSPECV_PROBE_STACK_RANGE
234   UNSPECV_ALIGN
235   UNSPECV_PROLOGUE_USE
236   UNSPECV_SPLIT_STACK_RETURN
237   UNSPECV_CLD
238   UNSPECV_NOPS
239   UNSPECV_RDTSC
240   UNSPECV_RDTSCP
241   UNSPECV_RDPMC
242   UNSPECV_LLWP_INTRINSIC
243   UNSPECV_SLWP_INTRINSIC
244   UNSPECV_LWPVAL_INTRINSIC
245   UNSPECV_LWPINS_INTRINSIC
246   UNSPECV_RDFSBASE
247   UNSPECV_RDGSBASE
248   UNSPECV_WRFSBASE
249   UNSPECV_WRGSBASE
250   UNSPECV_FXSAVE
251   UNSPECV_FXRSTOR
252   UNSPECV_FXSAVE64
253   UNSPECV_FXRSTOR64
254   UNSPECV_XSAVE
255   UNSPECV_XRSTOR
256   UNSPECV_XSAVE64
257   UNSPECV_XRSTOR64
258   UNSPECV_XSAVEOPT
259   UNSPECV_XSAVEOPT64
260   UNSPECV_XSAVES
261   UNSPECV_XRSTORS
262   UNSPECV_XSAVES64
263   UNSPECV_XRSTORS64
264   UNSPECV_XSAVEC
265   UNSPECV_XSAVEC64
266   UNSPECV_XGETBV
267   UNSPECV_XSETBV
268   UNSPECV_WBINVD
269   UNSPECV_WBNOINVD
271   ;; For atomic compound assignments.
272   UNSPECV_FNSTENV
273   UNSPECV_FLDENV
274   UNSPECV_FNSTSW
275   UNSPECV_FNCLEX
277   ;; For RDRAND support
278   UNSPECV_RDRAND
280   ;; For RDSEED support
281   UNSPECV_RDSEED
283   ;; For RTM support
284   UNSPECV_XBEGIN
285   UNSPECV_XEND
286   UNSPECV_XABORT
287   UNSPECV_XTEST
289   UNSPECV_NLGR
291   ;; For CLWB support
292   UNSPECV_CLWB
294   ;; For CLFLUSHOPT support
295   UNSPECV_CLFLUSHOPT
297   ;; For MONITORX and MWAITX support 
298   UNSPECV_MONITORX
299   UNSPECV_MWAITX
301   ;; For CLZERO support
302   UNSPECV_CLZERO
304   ;; For RDPKRU and WRPKRU support
305   UNSPECV_PKU
307   ;; For RDPID support
308   UNSPECV_RDPID
310   ;; For CET support
311   UNSPECV_NOP_ENDBR
312   UNSPECV_NOP_RDSSP
313   UNSPECV_INCSSP
314   UNSPECV_SAVEPREVSSP
315   UNSPECV_RSTORSSP
316   UNSPECV_WRSS
317   UNSPECV_WRUSS
318   UNSPECV_SETSSBSY
319   UNSPECV_CLRSSBSY
321   ;; For TSXLDTRK support
322   UNSPECV_XSUSLDTRK
323   UNSPECV_XRESLDTRK
325   ;; For WAITPKG support
326   UNSPECV_UMWAIT
327   UNSPECV_UMONITOR
328   UNSPECV_TPAUSE
330   ;; For UINTR support
331   UNSPECV_CLUI
332   UNSPECV_STUI
333   UNSPECV_TESTUI
334   UNSPECV_SENDUIPI
336   ;; For CLDEMOTE support
337   UNSPECV_CLDEMOTE
339   ;; For Speculation Barrier support
340   UNSPECV_SPECULATION_BARRIER
342   UNSPECV_PTWRITE
344   ;; For ENQCMD and ENQCMDS support
345   UNSPECV_ENQCMD
346   UNSPECV_ENQCMDS
348   ;; For SERIALIZE support
349   UNSPECV_SERIALIZE
351   ;; For patchable area support
352   UNSPECV_PATCHABLE_AREA
354   ;; For HRESET support
355   UNSPECV_HRESET
357   ;; For PREFETCHI support
358   UNSPECV_PREFETCHI
360   ;; For USER_MSR support
361   UNSPECV_URDMSR
362   UNSPECV_UWRMSR
364   ;; For AMX-TILE
365   UNSPECV_LDTILECFG
366   UNSPECV_STTILECFG
369 ;; Constants to represent rounding modes in the ROUND instruction
370 (define_constants
371   [(ROUND_ROUNDEVEN             0x0)
372    (ROUND_FLOOR                 0x1)
373    (ROUND_CEIL                  0x2)
374    (ROUND_TRUNC                 0x3)
375    (ROUND_MXCSR                 0x4)
376    (ROUND_NO_EXC                0x8)
377   ])
379 ;; Constants to represent AVX512F embeded rounding
380 (define_constants
381   [(ROUND_NEAREST_INT                   0)
382    (ROUND_NEG_INF                       1)
383    (ROUND_POS_INF                       2)
384    (ROUND_ZERO                          3)
385    (NO_ROUND                            4)
386    (ROUND_SAE                           8)
387   ])
389 ;; Constants to represent pcomtrue/pcomfalse variants
390 (define_constants
391   [(PCOM_FALSE                  0)
392    (PCOM_TRUE                   1)
393    (COM_FALSE_S                 2)
394    (COM_FALSE_P                 3)
395    (COM_TRUE_S                  4)
396    (COM_TRUE_P                  5)
397   ])
399 ;; Constants used in the XOP pperm instruction
400 (define_constants
401   [(PPERM_SRC                   0x00)   /* copy source */
402    (PPERM_INVERT                0x20)   /* invert source */
403    (PPERM_REVERSE               0x40)   /* bit reverse source */
404    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
405    (PPERM_ZERO                  0x80)   /* all 0's */
406    (PPERM_ONES                  0xa0)   /* all 1's */
407    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
408    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
409    (PPERM_SRC1                  0x00)   /* use first source byte */
410    (PPERM_SRC2                  0x10)   /* use second source byte */
411    ])
413 ;; Registers by name.
414 (define_constants
415   [(AX_REG                       0)
416    (DX_REG                       1)
417    (CX_REG                       2)
418    (BX_REG                       3)
419    (SI_REG                       4)
420    (DI_REG                       5)
421    (BP_REG                       6)
422    (SP_REG                       7)
423    (ST0_REG                      8)
424    (ST1_REG                      9)
425    (ST2_REG                     10)
426    (ST3_REG                     11)
427    (ST4_REG                     12)
428    (ST5_REG                     13)
429    (ST6_REG                     14)
430    (ST7_REG                     15)
431    (ARGP_REG                    16)
432    (FLAGS_REG                   17)
433    (FPSR_REG                    18)
434    (FRAME_REG                   19)
435    (XMM0_REG                    20)
436    (XMM1_REG                    21)
437    (XMM2_REG                    22)
438    (XMM3_REG                    23)
439    (XMM4_REG                    24)
440    (XMM5_REG                    25)
441    (XMM6_REG                    26)
442    (XMM7_REG                    27)
443    (MM0_REG                     28)
444    (MM1_REG                     29)
445    (MM2_REG                     30)
446    (MM3_REG                     31)
447    (MM4_REG                     32)
448    (MM5_REG                     33)
449    (MM6_REG                     34)
450    (MM7_REG                     35)
451    (R8_REG                      36)
452    (R9_REG                      37)
453    (R10_REG                     38)
454    (R11_REG                     39)
455    (R12_REG                     40)
456    (R13_REG                     41)
457    (R14_REG                     42)
458    (R15_REG                     43)
459    (XMM8_REG                    44)
460    (XMM9_REG                    45)
461    (XMM10_REG                   46)
462    (XMM11_REG                   47)
463    (XMM12_REG                   48)
464    (XMM13_REG                   49)
465    (XMM14_REG                   50)
466    (XMM15_REG                   51)
467    (XMM16_REG                   52)
468    (XMM17_REG                   53)
469    (XMM18_REG                   54)
470    (XMM19_REG                   55)
471    (XMM20_REG                   56)
472    (XMM21_REG                   57)
473    (XMM22_REG                   58)
474    (XMM23_REG                   59)
475    (XMM24_REG                   60)
476    (XMM25_REG                   61)
477    (XMM26_REG                   62)
478    (XMM27_REG                   63)
479    (XMM28_REG                   64)
480    (XMM29_REG                   65)
481    (XMM30_REG                   66)
482    (XMM31_REG                   67)
483    (MASK0_REG                   68)
484    (MASK1_REG                   69)
485    (MASK2_REG                   70)
486    (MASK3_REG                   71)
487    (MASK4_REG                   72)
488    (MASK5_REG                   73)
489    (MASK6_REG                   74)
490    (MASK7_REG                   75)
491    (R16_REG                     76)
492    (R17_REG                     77)
493    (R18_REG                     78)
494    (R19_REG                     79)
495    (R20_REG                     80)
496    (R21_REG                     81)
497    (R22_REG                     82)
498    (R23_REG                     83)
499    (R24_REG                     84)
500    (R25_REG                     85)
501    (R26_REG                     86)
502    (R27_REG                     87)
503    (R28_REG                     88)
504    (R29_REG                     89)
505    (R30_REG                     90)
506    (R31_REG                     91)
507    (FIRST_PSEUDO_REG            92)
508   ])
510 ;; Insn callee abi index.
511 (define_constants
512   [(ABI_DEFAULT         0)
513    (ABI_VZEROUPPER      1)
514    (ABI_UNKNOWN         2)])
516 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
517 ;; from i386.cc.
519 ;; In C guard expressions, put expressions which may be compile-time
520 ;; constants first.  This allows for better optimization.  For
521 ;; example, write "TARGET_64BIT && reload_completed", not
522 ;; "reload_completed && TARGET_64BIT".
525 ;; Processor type.
526 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
527                     atom,slm,glm,haswell,generic,lujiazui,yongfeng,amdfam10,bdver1,
528                     bdver2,bdver3,bdver4,btver2,znver1,znver2,znver3,znver4,
529                     znver5"
530   (const (symbol_ref "ix86_schedule")))
532 ;; A basic instruction type.  Refinements due to arguments to be
533 ;; provided in other attributes.
534 (define_attr "type"
535   "other,multi,
536    alu,alu1,negnot,imov,imovx,lea,
537    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
538    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
539    push,pop,call,callv,leave,
540    str,bitmanip,
541    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
542    fxch,fistp,fisttp,frndint,
543    sse,ssemov,ssemov2,sseadd,sseadd1,sseiadd,sseiadd1,
544    ssemul,sseimul,ssediv,sselog,sselog1,
545    sseishft,sseishft1,ssecmp,ssecomi,
546    ssecvt,ssecvt1,sseicvt,sseicvt2,sseins,
547    sseshuf,sseshuf1,ssemuladd,sse4arg,
548    lwp,mskmov,msklog,
549    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
550   (const_string "other"))
552 ;; Main data type used by the insn
553 (define_attr "mode"
554   "unknown,none,QI,HI,SI,DI,TI,OI,XI,HF,BF,SF,DF,XF,TF,
555    V32HF,V16HF,V8HF,V4HF,V2HF,V32BF,V16BF,V8BF,V4BF,V2BF,
556    V16SF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,V8DF"
557   (const_string "unknown"))
559 ;; The CPU unit operations uses.
560 (define_attr "unit" "integer,i387,sse,mmx,unknown"
561   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
562                           fxch,fistp,fisttp,frndint")
563            (const_string "i387")
564          (eq_attr "type" "sse,ssemov,ssemov2,sseadd,sseadd1,sseiadd,sseiadd1,
565                           ssemul,sseimul,ssediv,sselog,sselog1,
566                           sseishft,sseishft1,ssecmp,ssecomi,
567                           ssecvt,ssecvt1,sseicvt,sseicvt2,sseins,
568                           sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
569            (const_string "sse")
570          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
571            (const_string "mmx")
572          (eq_attr "type" "other")
573            (const_string "unknown")]
574          (const_string "integer")))
576 ;; Used to control the "enabled" attribute on a per-instruction basis.
577 (define_attr "isa" "base,x64,nox64,x64_sse2,x64_sse4,x64_sse4_noavx,
578                     x64_avx,x64_avx512bw,x64_avx512dq,apx_ndd,apx_ndd_64,
579                     sse_noavx,sse2,sse2_noavx,sse3,sse3_noavx,sse4,sse4_noavx,
580                     avx,noavx,avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,avx512f_512,
581                     noavx512f,avx512bw,avx512bw_512,noavx512bw,avx512dq,
582                     noavx512dq,fma_or_avx512vl,avx512vl,noavx512vl,avxvnni,
583                     avx512vnnivl,avx512fp16,avxifma,avx512ifmavl,avxneconvert,
584                     avx512bf16vl,vpclmulqdqvl,avx_noavx512f,avx_noavx512vl,
585                     vaes_avx512vl,noapx_nf,avx10_2"
586   (const_string "base"))
588 ;; The (bounding maximum) length of an instruction immediate.
589 (define_attr "length_immediate" ""
590   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
591                           bitmanip,imulx,msklog,mskmov")
592            (const_int 0)
593          (ior (eq_attr "type" "sse4arg")
594               (eq_attr "isa" "fma4"))
595            (const_int 1)
596          (eq_attr "unit" "i387,sse,mmx")
597            (const_int 0)
598          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
599                           rotate,rotatex,rotate1,imul,icmp,push,pop")
600            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
601          (eq_attr "type" "imov,test")
602            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
603          (eq_attr "type" "call")
604            (if_then_else (match_operand 0 "constant_call_address_operand")
605              (const_int 4)
606              (const_int 0))
607          (eq_attr "type" "callv")
608            (if_then_else (match_operand 1 "constant_call_address_operand")
609              (const_int 4)
610              (const_int 0))
611          ;; We don't know the size before shorten_branches.  Expect
612          ;; the instruction to fit for better scheduling.
613          (eq_attr "type" "ibr")
614            (const_int 1)
615          ]
616          (symbol_ref "/* Update immediate_length and other attributes! */
617                       gcc_unreachable (),1")))
619 ;; The (bounding maximum) length of an instruction address.
620 (define_attr "length_address" ""
621   (cond [(eq_attr "type" "str,other,multi,fxch")
622            (const_int 0)
623          (and (eq_attr "type" "call")
624               (match_operand 0 "constant_call_address_operand"))
625              (const_int 0)
626          (and (eq_attr "type" "callv")
627               (match_operand 1 "constant_call_address_operand"))
628              (const_int 0)
629          ]
630          (symbol_ref "ix86_attr_length_address_default (insn)")))
632 ;; Set when length prefix is used.
633 (define_attr "prefix_data16" ""
634   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
635            (const_int 0)
636          (eq_attr "mode" "HI")
637            (const_int 1)
638          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
639            (const_int 1)
640         ]
641         (const_int 0)))
643 ;; Set when string REP prefix is used.
644 (define_attr "prefix_rep" ""
645   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
646            (const_int 0)
647          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
648            (const_int 1)
649         ]
650         (const_int 0)))
652 ;; Set when 0f opcode prefix is used.
653 (define_attr "prefix_0f" ""
654   (if_then_else
655     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
656          (eq_attr "unit" "sse,mmx"))
657     (const_int 1)
658     (const_int 0)))
660 ;; Set when REX opcode prefix is used.
661 (define_attr "prefix_rex" ""
662   (cond [(not (match_test "TARGET_64BIT"))
663            (const_int 0)
664          (and (eq_attr "mode" "DI")
665               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
666                    (eq_attr "unit" "!mmx")))
667            (const_int 1)
668          (and (eq_attr "mode" "QI")
669               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
670            (const_int 1)
671          (match_test "x86_extended_reg_mentioned_p (insn)")
672            (const_int 1)
673          (and (eq_attr "type" "imovx")
674               (match_operand:QI 1 "ext_QIreg_operand"))
675            (const_int 1)
676         ]
677         (const_int 0)))
679 ;; There are also additional prefixes in 3DNOW, SSSE3.
680 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
681 ;; While generally inapplicable to VEX/XOP/EVEX encodings, "length_vex" uses
682 ;; the attribute evaluating to zero to know that VEX2 encoding may be usable.
683 (define_attr "prefix_extra" ""
684   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
685            (const_int 1)
686         ]
687         (const_int 0)))
689 ;; Prefix used: original, VEX or maybe VEX.
690 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
691   (cond [(eq_attr "mode" "OI,V8SF,V4DF")
692            (const_string "vex")
693          (eq_attr "mode" "XI,V16SF,V8DF")
694            (const_string "evex")
695          (eq_attr "type" "ssemuladd")
696            (if_then_else (eq_attr "isa" "fma4")
697              (const_string "vex")
698              (const_string "maybe_evex"))
699          (eq_attr "type" "sse4arg")
700            (const_string "vex")
701         ]
702         (const_string "orig")))
704 ;; VEX W bit is used.
705 (define_attr "prefix_vex_w" "" (const_int 0))
707 ;; The length of VEX prefix
708 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
709 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
710 ;; still prefix_0f 1, with prefix_extra 1.
711 (define_attr "length_vex" ""
712   (if_then_else (and (eq_attr "prefix_0f" "1")
713                      (eq_attr "prefix_extra" "0"))
714     (if_then_else (eq_attr "prefix_vex_w" "1")
715       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
716       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
717     (if_then_else (eq_attr "prefix_vex_w" "1")
718       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
719       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
721 ;; 4-bytes evex prefix and 1 byte opcode.
722 (define_attr "length_evex" "" (const_int 5))
724 ;; Set when modrm byte is used.
725 (define_attr "modrm" ""
726   (cond [(eq_attr "type" "str,leave")
727            (const_int 0)
728          (eq_attr "unit" "i387")
729            (const_int 0)
730          (and (eq_attr "type" "incdec")
731               (and (not (match_test "TARGET_64BIT"))
732                    (ior (match_operand:SI 1 "register_operand")
733                         (match_operand:HI 1 "register_operand"))))
734            (const_int 0)
735          (and (eq_attr "type" "push")
736               (not (match_operand 1 "memory_operand")))
737            (const_int 0)
738          (and (eq_attr "type" "pop")
739               (not (match_operand 0 "memory_operand")))
740            (const_int 0)
741          (and (eq_attr "type" "imov")
742               (and (not (eq_attr "mode" "DI"))
743                    (ior (and (match_operand 0 "register_operand")
744                              (match_operand 1 "immediate_operand"))
745                         (ior (and (match_operand 0 "ax_reg_operand")
746                                   (match_operand 1 "memory_displacement_only_operand"))
747                              (and (match_operand 0 "memory_displacement_only_operand")
748                                   (match_operand 1 "ax_reg_operand"))))))
749            (const_int 0)
750          (and (eq_attr "type" "call")
751               (match_operand 0 "constant_call_address_operand"))
752              (const_int 0)
753          (and (eq_attr "type" "callv")
754               (match_operand 1 "constant_call_address_operand"))
755              (const_int 0)
756          (and (eq_attr "type" "alu,alu1,icmp,test")
757               (match_operand 0 "ax_reg_operand"))
758              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
759          ]
760          (const_int 1)))
762 ;; The (bounding maximum) length of an instruction in bytes.
763 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
764 ;; Later we may want to split them and compute proper length as for
765 ;; other insns.
766 (define_attr "length" ""
767   (cond [(eq_attr "type" "other,multi,fistp,frndint")
768            (const_int 16)
769          (eq_attr "type" "fcmp")
770            (const_int 4)
771          (eq_attr "unit" "i387")
772            (plus (const_int 2)
773                  (plus (attr "prefix_data16")
774                        (attr "length_address")))
775          (ior (eq_attr "prefix" "evex")
776               (and (ior (eq_attr "prefix" "maybe_evex")
777                         (eq_attr "prefix" "maybe_vex"))
778                    (match_test "TARGET_AVX512F")))
779            (plus (attr "length_evex")
780                  (plus (attr "length_immediate")
781                        (plus (attr "modrm")
782                              (attr "length_address"))))
783          (ior (eq_attr "prefix" "vex")
784               (and (ior (eq_attr "prefix" "maybe_vex")
785                         (eq_attr "prefix" "maybe_evex"))
786                    (match_test "TARGET_AVX")))
787            (plus (attr "length_vex")
788                  (plus (attr "length_immediate")
789                        (plus (attr "modrm")
790                              (attr "length_address"))))]
791          (plus (plus (attr "modrm")
792                      (plus (attr "prefix_0f")
793                            (plus (attr "prefix_rex")
794                                  (plus (attr "prefix_extra")
795                                        (const_int 1)))))
796                (plus (attr "prefix_rep")
797                      (plus (attr "prefix_data16")
798                            (plus (attr "length_immediate")
799                                  (attr "length_address")))))))
801 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
802 ;; `store' if there is a simple memory reference therein, or `unknown'
803 ;; if the instruction is complex.
805 (define_attr "memory" "none,load,store,both,unknown"
806   (cond [(eq_attr "type" "other,multi,str,lwp")
807            (const_string "unknown")
808          (eq_attr "type" "lea,fcmov,fpspc")
809            (const_string "none")
810          (eq_attr "type" "fistp,leave")
811            (const_string "both")
812          (eq_attr "type" "frndint")
813            (const_string "load")
814          (eq_attr "type" "push")
815            (if_then_else (match_operand 1 "memory_operand")
816              (const_string "both")
817              (const_string "store"))
818          (eq_attr "type" "pop")
819            (if_then_else (match_operand 0 "memory_operand")
820              (const_string "both")
821              (const_string "load"))
822          (eq_attr "type" "setcc")
823            (if_then_else (match_operand 0 "memory_operand")
824              (const_string "store")
825              (const_string "none"))
826          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
827            (if_then_else (ior (match_operand 0 "memory_operand")
828                               (match_operand 1 "memory_operand"))
829              (const_string "load")
830              (const_string "none"))
831          (eq_attr "type" "ibr")
832            (if_then_else (match_operand 0 "memory_operand")
833              (const_string "load")
834              (const_string "none"))
835          (eq_attr "type" "call")
836            (if_then_else (match_operand 0 "constant_call_address_operand")
837              (const_string "none")
838              (const_string "load"))
839          (eq_attr "type" "callv")
840            (if_then_else (match_operand 1 "constant_call_address_operand")
841              (const_string "none")
842              (const_string "load"))
843          (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
844               (match_operand 1 "memory_operand"))
845            (const_string "both")
846          (and (match_operand 0 "memory_operand")
847               (match_operand 1 "memory_operand"))
848            (const_string "both")
849          (match_operand 0 "memory_operand")
850            (const_string "store")
851          (match_operand 1 "memory_operand")
852            (const_string "load")
853          (and (eq_attr "type"
854                  "!alu1,negnot,ishift1,rotate1,
855                    imov,imovx,icmp,test,bitmanip,
856                    fmov,fcmp,fsgn,
857                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
858                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
859                    mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
860               (match_operand 2 "memory_operand"))
861            (const_string "load")
862          (and (eq_attr "type" "ssemov2,sseicvt2")
863               (match_operand 2 "memory_operand"))
864            (const_string "load")
865          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
866               (match_operand 3 "memory_operand"))
867            (const_string "load")
868         ]
869         (const_string "none")))
871 ;; Indicates if an instruction has both an immediate and a displacement.
873 (define_attr "imm_disp" "false,true,unknown"
874   (cond [(eq_attr "type" "other,multi")
875            (const_string "unknown")
876          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
877               (and (match_operand 0 "memory_displacement_operand")
878                    (match_operand 1 "immediate_operand")))
879            (const_string "true")
880          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
881               (and (match_operand 0 "memory_displacement_operand")
882                    (match_operand 2 "immediate_operand")))
883            (const_string "true")
884         ]
885         (const_string "false")))
887 ;; Indicates if an FP operation has an integer source.
889 (define_attr "fp_int_src" "false,true"
890   (const_string "false"))
892 ;; Defines rounding mode of an FP operation.
894 (define_attr "i387_cw" "roundeven,floor,ceil,trunc,uninitialized,any"
895   (const_string "any"))
897 ;; Define attribute to indicate AVX insns with partial XMM register update.
898 (define_attr "avx_partial_xmm_update" "false,true"
899   (const_string "false"))
901 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
902 (define_attr "use_carry" "0,1" (const_string "0"))
904 ;; Define attribute to indicate unaligned ssemov insns
905 (define_attr "movu" "0,1" (const_string "0"))
907 ;; Define attribute to limit memory address register set.
908 (define_attr "addr" "gpr8,gpr16,gpr32" (const_string "gpr32"))
910 ;; Define instruction set of MMX instructions
911 (define_attr "mmx_isa" "base,native,sse,sse_noavx,avx"
912   (const_string "base"))
914 (define_attr "enabled" ""
915   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
916          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
917          (eq_attr "isa" "x64_sse2")
918            (symbol_ref "TARGET_64BIT && TARGET_SSE2")
919          (eq_attr "isa" "x64_sse4")
920            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
921          (eq_attr "isa" "x64_sse4_noavx")
922            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
923          (eq_attr "isa" "x64_avx")
924            (symbol_ref "TARGET_64BIT && TARGET_AVX")
925          (eq_attr "isa" "x64_avx512bw")
926            (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
927          (eq_attr "isa" "x64_avx512dq")
928            (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
929          (eq_attr "isa" "sse_noavx")
930            (symbol_ref "TARGET_SSE && !TARGET_AVX")
931          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
932          (eq_attr "isa" "sse2_noavx")
933            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
934          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
935          (eq_attr "isa" "sse3_noavx")
936            (symbol_ref "TARGET_SSE3 && !TARGET_AVX")
937          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
938          (eq_attr "isa" "sse4_noavx")
939            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
940          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
941          (eq_attr "isa" "avx_noavx512f")
942            (symbol_ref "TARGET_AVX && !TARGET_AVX512F")
943          (eq_attr "isa" "avx_noavx512vl")
944            (symbol_ref "TARGET_AVX && !TARGET_AVX512VL")
945          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
946          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
947          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
948          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
949          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
950          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
951          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
952          (eq_attr "isa" "fma_or_avx512vl")
953            (symbol_ref "TARGET_FMA || TARGET_AVX512VL")
954          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
955          (eq_attr "isa" "avx512f_512")
956            (symbol_ref "TARGET_AVX512F && TARGET_EVEX512")
957          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
958          (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
959          (eq_attr "isa" "avx512bw_512")
960            (symbol_ref "TARGET_AVX512BW && TARGET_EVEX512")
961          (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
962          (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
963          (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
964          (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
965          (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
966          (eq_attr "isa" "avxvnni") (symbol_ref "TARGET_AVXVNNI")
967          (eq_attr "isa" "avx512vnnivl")
968            (symbol_ref "TARGET_AVX512VNNI && TARGET_AVX512VL")
969          (eq_attr "isa" "avx512fp16")
970            (symbol_ref "TARGET_AVX512FP16")
971          (eq_attr "isa" "avxifma") (symbol_ref "TARGET_AVXIFMA")
972          (eq_attr "isa" "avx512ifmavl")
973            (symbol_ref "TARGET_AVX512IFMA && TARGET_AVX512VL")
974          (eq_attr "isa" "avxneconvert") (symbol_ref "TARGET_AVXNECONVERT")
975          (eq_attr "isa" "avx512bf16vl")
976            (symbol_ref "TARGET_AVX512BF16 && TARGET_AVX512VL")
977          (eq_attr "isa" "vpclmulqdqvl")
978            (symbol_ref "TARGET_VPCLMULQDQ && TARGET_AVX512VL")
979          (eq_attr "isa" "apx_ndd")
980            (symbol_ref "TARGET_APX_NDD")
981          (eq_attr "isa" "apx_ndd_64")
982            (symbol_ref "TARGET_APX_NDD && Pmode == DImode")
983          (eq_attr "isa" "vaes_avx512vl")
984            (symbol_ref "TARGET_VAES && TARGET_AVX512VL")
985          (eq_attr "isa" "avx10_2") (symbol_ref "TARGET_AVX10_2_256")
987          (eq_attr "mmx_isa" "native")
988            (symbol_ref "!TARGET_MMX_WITH_SSE")
989          (eq_attr "mmx_isa" "sse")
990            (symbol_ref "TARGET_MMX_WITH_SSE")
991          (eq_attr "mmx_isa" "sse_noavx")
992            (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
993          (eq_attr "mmx_isa" "avx")
994            (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
995          (eq_attr "isa" "noapx_nf") (symbol_ref "!TARGET_APX_NF")
996         ]
997         (const_int 1)))
999 (define_attr "preferred_for_size" "" (const_int 1))
1000 (define_attr "preferred_for_speed" "" (const_int 1))
1002 ;; Define attribute to mark the insn has nf variant.
1003 (define_attr "has_nf" "0,1" (const_string "0"))
1005 ;; Describe a user's asm statement.
1006 (define_asm_attributes
1007   [(set_attr "length" "128")
1008    (set_attr "type" "multi")])
1010 (define_code_iterator plusminus [plus minus])
1011 (define_code_iterator plusminusmult [plus minus mult])
1012 (define_code_iterator plusminusmultdiv [plus minus mult div])
1014 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
1016 ;; Base name for insn mnemonic.
1017 (define_code_attr plusminus_mnemonic
1018   [(plus "add") (ss_plus "adds") (us_plus "addus")
1019    (minus "sub") (ss_minus "subs") (us_minus "subus")])
1021 (define_code_iterator multdiv [mult div])
1023 (define_code_attr multdiv_mnemonic
1024   [(mult "mul") (div "div")])
1026 ;; Mark commutative operators as such in constraints.
1027 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
1028                         (minus "") (ss_minus "") (us_minus "")
1029                         (mult "%") (div "")])
1031 ;; Mapping of max and min
1032 (define_code_iterator maxmin [smax smin umax umin])
1034 ;; Mapping of signed max and min
1035 (define_code_iterator smaxmin [smax smin])
1037 ;; Mapping of unsigned max and min
1038 (define_code_iterator umaxmin [umax umin])
1040 ;; Base name for integer and FP insn mnemonic
1041 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
1042                               (umax "maxu") (umin "minu")])
1043 (define_code_attr maxmin_float [(smax "max") (smin "min")])
1045 (define_int_iterator IEEE_MAXMIN
1046         [UNSPEC_IEEE_MAX
1047          UNSPEC_IEEE_MIN])
1049 (define_int_attr ieee_maxmin
1050         [(UNSPEC_IEEE_MAX "max")
1051          (UNSPEC_IEEE_MIN "min")])
1053 ;; Mapping of logic operators
1054 (define_code_iterator any_logic [and ior xor])
1055 (define_code_iterator any_or [ior xor])
1056 (define_code_iterator fpint_logic [and xor])
1058 ;; Base name for insn mnemonic.
1059 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
1061 ;; Mapping of logic-shift operators
1062 (define_code_iterator any_lshift [ashift lshiftrt])
1064 ;; Mapping of shift-right operators
1065 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
1067 ;; Mapping of all shift operators
1068 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
1070 ;; Base name for insn mnemonic.
1071 (define_code_attr shift [(ashift "sal") (lshiftrt "shr") (ashiftrt "sar")])
1072 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
1074 ;; Mapping of rotate operators
1075 (define_code_iterator any_rotate [rotate rotatert])
1077 ;; Base name for insn mnemonic.
1078 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
1080 ;; Mapping of abs neg operators
1081 (define_code_iterator absneg [abs neg])
1083 ;; Mapping of abs neg operators to logic operation
1084 (define_code_attr absneg_op [(abs "and") (neg "xor")])
1086 ;; Base name for x87 insn mnemonic.
1087 (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
1089 ;; Mapping of extend operators
1090 (define_code_iterator any_extend [sign_extend zero_extend])
1092 ;; Mapping of highpart multiply operators
1093 (define_code_iterator any_mul_highpart [smul_highpart umul_highpart])
1095 ;; Prefix for insn menmonic.
1096 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
1097                              (smul_highpart "i") (umul_highpart "")
1098                              (div "i") (udiv "")])
1099 ;; Prefix for define_insn
1100 (define_code_attr s [(sign_extend "s") (zero_extend "u")
1101                      (smul_highpart "s") (umul_highpart "u")])
1102 (define_code_attr u [(sign_extend "") (zero_extend "u")
1103                      (div "") (udiv "u")])
1104 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")
1105                           (div "false") (udiv "true")])
1107 ;; Used in signed and unsigned truncations.
1108 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
1109 ;; Instruction suffix for truncations.
1110 (define_code_attr trunsuffix
1111   [(ss_truncate "s") (truncate "") (us_truncate "us")])
1113 ;; Instruction suffix for SSE sign and zero extensions.
1114 (define_code_attr extsuffix [(sign_extend "sx") (zero_extend "zx")])
1116 ;; Used in signed and unsigned fix.
1117 (define_code_iterator any_fix [fix unsigned_fix])
1118 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
1119 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
1120 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
1122 ;; Used in signed and unsigned float.
1123 (define_code_iterator any_float [float unsigned_float])
1124 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
1125 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
1126 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
1128 ;; Base name for expression
1129 (define_code_attr insn
1130   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
1131    (minus "sub") (ss_minus "sssub") (us_minus "ussub")
1132    (sign_extend "extend") (zero_extend "zero_extend")
1133    (ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")
1134    (rotate "rotl") (rotatert "rotr")
1135    (mult "mul") (div "div")])
1137 ;; All integer modes.
1138 (define_mode_iterator SWI1248x [QI HI SI DI])
1140 ;; All integer modes without QImode.
1141 (define_mode_iterator SWI248x [HI SI DI])
1143 ;; All integer modes without QImode and HImode.
1144 (define_mode_iterator SWI48x [SI DI])
1146 ;; All integer modes without SImode and DImode.
1147 (define_mode_iterator SWI12 [QI HI])
1149 ;; All integer modes without DImode.
1150 (define_mode_iterator SWI124 [QI HI SI])
1152 ;; All integer modes without QImode and DImode.
1153 (define_mode_iterator SWI24 [HI SI])
1155 ;; Single word integer modes.
1156 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1158 ;; Single word integer modes without QImode.
1159 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1161 ;; Single word integer modes without QImode and HImode.
1162 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1164 ;; All math-dependant single and double word integer modes.
1165 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1166                              (HI "TARGET_HIMODE_MATH")
1167                              SI DI (TI "TARGET_64BIT")])
1169 ;; Math-dependant single word integer modes.
1170 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1171                             (HI "TARGET_HIMODE_MATH")
1172                             SI (DI "TARGET_64BIT")])
1174 ;; Math-dependant integer modes without DImode.
1175 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1176                                (HI "TARGET_HIMODE_MATH")
1177                                SI])
1179 ;; Math-dependant integer modes with DImode.
1180 (define_mode_iterator SWIM1248x
1181         [(QI "TARGET_QIMODE_MATH")
1182          (HI "TARGET_HIMODE_MATH")
1183          SI DI])
1185 ;; Math-dependant single word integer modes without QImode.
1186 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1187                                SI (DI "TARGET_64BIT")])
1189 ;; Double word integer modes.
1190 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1191                            (TI "TARGET_64BIT")])
1193 ;; SWI and DWI together.
1194 (define_mode_iterator SWIDWI [QI HI SI DI (TI "TARGET_64BIT")])
1196 ;; SWI48 and DWI together.
1197 (define_mode_iterator SWI48DWI [SI DI (TI "TARGET_64BIT")])
1199 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
1200 ;; compile time constant, it is faster to use <MODE_SIZE> than
1201 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
1202 ;; command line options just use GET_MODE_SIZE macro.
1203 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8")
1204                              (TI "16") (HF "2") (BF "2") (SF "4") (DF "8")
1205                              (XF "GET_MODE_SIZE (XFmode)")
1206                              (V16QI "16") (V32QI "32") (V64QI "64")
1207                              (V8HI "16") (V16HI "32") (V32HI "64")
1208                              (V4SI "16") (V8SI "32") (V16SI "64")
1209                              (V2DI "16") (V4DI "32") (V8DI "64")
1210                              (V1TI "16") (V2TI "32") (V4TI "64")
1211                              (V2DF "16") (V4DF "32") (V8DF "64")
1212                              (V4SF "16") (V8SF "32") (V16SF "64")
1213                              (V8HF "16") (V16HF "32") (V32HF "64")
1214                              (V4HF "8") (V2HF "4")
1215                              (V8BF "16") (V16BF "32") (V32BF "64")
1216                              (V4BF "8") (V2BF "4")])
1218 ;; Double word integer modes as mode attribute.
1219 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "OI")])
1220 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti") (TI "oi")])
1222 ;; Half sized integer modes.
1223 (define_mode_attr HALF [(TI "DI") (DI "SI")])
1224 (define_mode_attr half [(TI "di") (DI "si")])
1226 ;; LEA mode corresponding to an integer mode
1227 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1229 ;; Half mode for double word integer modes.
1230 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1231                             (DI "TARGET_64BIT")])
1233 ;; Instruction suffix for integer modes.
1234 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1236 ;; Instruction suffix for masks.
1237 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1239 ;; Pointer size prefix for integer modes (Intel asm dialect)
1240 (define_mode_attr iptrsize [(QI "BYTE")
1241                             (HI "WORD")
1242                             (SI "DWORD")
1243                             (DI "QWORD")])
1245 ;; Register class for integer modes.
1246 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1248 ;; Immediate operand constraint for integer modes.
1249 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1251 ;; General operand constraint for word modes.
1252 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1254 ;; Memory operand constraint for word modes.
1255 (define_mode_attr m [(QI "m") (HI "m") (SI "BM") (DI "BM")])
1257 ;; Immediate operand constraint for double integer modes.
1258 (define_mode_attr di [(SI "nF") (DI "Wd")])
1260 ;; Immediate operand constraint for shifts.
1261 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1262 (define_mode_attr KS [(QI "Wb") (HI "Ww") (SI "I") (DI "J")])
1264 ;; Print register name in the specified mode.
1265 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1267 ;; General operand predicate for integer modes.
1268 (define_mode_attr general_operand
1269         [(QI "general_operand")
1270          (HI "general_operand")
1271          (SI "x86_64_general_operand")
1272          (DI "x86_64_general_operand")
1273          (TI "x86_64_general_operand")])
1275 ;; General operand predicate for integer modes, where for TImode
1276 ;; we need both words of the operand to be general operands.
1277 (define_mode_attr general_hilo_operand
1278         [(QI "general_operand")
1279          (HI "general_operand")
1280          (SI "x86_64_general_operand")
1281          (DI "x86_64_general_operand")
1282          (TI "x86_64_hilo_general_operand")])
1284 ;; General sign extend operand predicate for integer modes,
1285 ;; which disallows VOIDmode operands and thus it is suitable
1286 ;; for use inside sign_extend.
1287 (define_mode_attr general_sext_operand
1288         [(QI "sext_operand")
1289          (HI "sext_operand")
1290          (SI "x86_64_sext_operand")
1291          (DI "x86_64_sext_operand")])
1293 ;; General sign/zero extend operand predicate for integer modes.
1294 (define_mode_attr general_szext_operand
1295         [(QI "general_operand")
1296          (HI "general_operand")
1297          (SI "x86_64_szext_general_operand")
1298          (DI "x86_64_szext_general_operand")
1299          (TI "x86_64_hilo_general_operand")])
1301 (define_mode_attr nonmemory_szext_operand
1302         [(QI "nonmemory_operand")
1303          (HI "nonmemory_operand")
1304          (SI "x86_64_szext_nonmemory_operand")
1305          (DI "x86_64_szext_nonmemory_operand")])
1307 ;; Immediate operand predicate for integer modes.
1308 (define_mode_attr immediate_operand
1309         [(QI "immediate_operand")
1310          (HI "immediate_operand")
1311          (SI "x86_64_immediate_operand")
1312          (DI "x86_64_immediate_operand")])
1314 ;; Nonmemory operand predicate for integer modes.
1315 (define_mode_attr nonmemory_operand
1316         [(QI "nonmemory_operand")
1317          (HI "nonmemory_operand")
1318          (SI "x86_64_nonmemory_operand")
1319          (DI "x86_64_nonmemory_operand")])
1321 ;; Operand predicate for shifts.
1322 (define_mode_attr shift_operand
1323         [(QI "nonimmediate_operand")
1324          (HI "nonimmediate_operand")
1325          (SI "nonimmediate_operand")
1326          (DI "shiftdi_operand")
1327          (TI "register_operand")])
1329 ;; Operand predicate for shift argument.
1330 (define_mode_attr shift_immediate_operand
1331         [(QI "const_1_to_31_operand")
1332          (HI "const_1_to_31_operand")
1333          (SI "const_1_to_31_operand")
1334          (DI "const_1_to_63_operand")])
1336 ;; Input operand predicate for arithmetic left shifts.
1337 (define_mode_attr ashl_input_operand
1338         [(QI "nonimmediate_operand")
1339          (HI "nonimmediate_operand")
1340          (SI "nonimmediate_operand")
1341          (DI "ashldi_input_operand")
1342          (TI "reg_or_pm1_operand")])
1344 ;; SSE and x87 SFmode and DFmode floating point modes
1345 (define_mode_iterator MODEF [SF DF])
1347 (define_mode_iterator MODEF248 [BF HF SF (DF "TARGET_SSE2")])
1349 ;; SSE floating point modes
1350 (define_mode_iterator MODEFH [(HF "TARGET_AVX512FP16") SF DF])
1352 ;; All x87 floating point modes
1353 (define_mode_iterator X87MODEF [SF DF XF])
1355 ;; All x87 floating point modes plus HFmode
1356 (define_mode_iterator X87MODEFH [HF SF DF XF BF])
1358 ;; All SSE floating point modes
1359 (define_mode_iterator SSEMODEF [HF SF DF TF])
1360 (define_mode_attr ssevecmodef [(HF "V8HF") (SF "V4SF") (DF "V2DF") (TF "TF")])
1362 ;; SSE instruction suffix for various modes
1363 (define_mode_attr ssemodesuffix
1364   [(HF "sh") (SF "ss") (DF "sd")
1365    (V32HF "ph") (V16SF "ps") (V8DF "pd")
1366    (V16HF "ph") (V16BF "bf") (V8SF "ps") (V4DF "pd")
1367    (V8HF "ph")  (V8BF "bf") (V4SF "ps") (V2DF "pd")
1368    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1369    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1370    (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1372 ;; SSE vector suffix for floating point modes
1373 ;; BF HF use same suffix as SF for logic operations.
1374 (define_mode_attr ssevecmodesuffix [(BF "ps") (HF "ps") (SF "ps") (DF "pd")])
1376 ;; SSE vector mode corresponding to a scalar mode
1377 (define_mode_attr ssevecmode
1378   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (HF "V8HF") (BF "V8BF") (SF "V4SF") (DF "V2DF")])
1379 (define_mode_attr ssevecmodelower
1380   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1382 ;; AVX512F vector mode corresponding to a scalar mode
1383 (define_mode_attr avx512fvecmode
1384   [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI")
1385    (HF "V32HF") (BF "V32BF") (SF "V16SF") (DF "V8DF")])
1387 ;; Instruction suffix for REX 64bit operators.
1388 (define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")])
1389 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1391 ;; This mode iterator allows :P to be used for patterns that operate on
1392 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1393 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1395 ;; This mode iterator allows :W to be used for patterns that operate on
1396 ;; word_mode sized quantities.
1397 (define_mode_iterator W
1398   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1400 ;; This mode iterator allows :PTR to be used for patterns that operate on
1401 ;; ptr_mode sized quantities.
1402 (define_mode_iterator PTR
1403   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1405 ;; Scheduling descriptions
1407 (include "pentium.md")
1408 (include "ppro.md")
1409 (include "k6.md")
1410 (include "athlon.md")
1411 (include "bdver1.md")
1412 (include "bdver3.md")
1413 (include "btver2.md")
1414 (include "znver.md")
1415 (include "zn4zn5.md")
1416 (include "geode.md")
1417 (include "atom.md")
1418 (include "slm.md")
1419 (include "glm.md")
1420 (include "core2.md")
1421 (include "haswell.md")
1422 (include "lujiazui.md")
1423 (include "yongfeng.md")
1426 ;; Operand and operator predicates and constraints
1428 (include "predicates.md")
1429 (include "constraints.md")
1432 ;; Compare and branch/compare and store instructions.
1434 (define_expand "cbranch<mode>4"
1435   [(set (reg:CC FLAGS_REG)
1436         (compare:CC (match_operand:SWIM1248x 1 "nonimmediate_operand")
1437                     (match_operand:SWIM1248x 2 "<general_operand>")))
1438    (set (pc) (if_then_else
1439                (match_operator 0 "ordered_comparison_operator"
1440                 [(reg:CC FLAGS_REG) (const_int 0)])
1441                (label_ref (match_operand 3))
1442                (pc)))]
1443   ""
1445   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1446     operands[1] = force_reg (<MODE>mode, operands[1]);
1447   ix86_expand_branch (GET_CODE (operands[0]),
1448                       operands[1], operands[2], operands[3]);
1449   DONE;
1452 (define_expand "cbranchti4"
1453   [(set (reg:CC FLAGS_REG)
1454         (compare:CC (match_operand:TI 1 "nonimmediate_operand")
1455                     (match_operand:TI 2 "ix86_timode_comparison_operand")))
1456    (set (pc) (if_then_else
1457                (match_operator 0 "ix86_timode_comparison_operator"
1458                 [(reg:CC FLAGS_REG) (const_int 0)])
1459                (label_ref (match_operand 3))
1460                (pc)))]
1461   "TARGET_64BIT || TARGET_SSE4_1"
1463   ix86_expand_branch (GET_CODE (operands[0]),
1464                       operands[1], operands[2], operands[3]);
1465   DONE;
1468 (define_expand "cbranchoi4"
1469   [(set (reg:CC FLAGS_REG)
1470         (compare:CC (match_operand:OI 1 "nonimmediate_operand")
1471                     (match_operand:OI 2 "nonimmediate_operand")))
1472    (set (pc) (if_then_else
1473                (match_operator 0 "bt_comparison_operator"
1474                 [(reg:CC FLAGS_REG) (const_int 0)])
1475                (label_ref (match_operand 3))
1476                (pc)))]
1477   "TARGET_AVX"
1479   ix86_expand_branch (GET_CODE (operands[0]),
1480                       operands[1], operands[2], operands[3]);
1481   DONE;
1484 (define_expand "cbranchxi4"
1485   [(set (reg:CC FLAGS_REG)
1486         (compare:CC (match_operand:XI 1 "nonimmediate_operand")
1487                     (match_operand:XI 2 "nonimmediate_operand")))
1488    (set (pc) (if_then_else
1489                (match_operator 0 "bt_comparison_operator"
1490                 [(reg:CC FLAGS_REG) (const_int 0)])
1491                (label_ref (match_operand 3))
1492                (pc)))]
1493   "TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256"
1495   ix86_expand_branch (GET_CODE (operands[0]),
1496                       operands[1], operands[2], operands[3]);
1497   DONE;
1500 (define_expand "cstore<mode>4"
1501   [(set (reg:CC FLAGS_REG)
1502         (compare:CC (match_operand:SDWIM 2 "nonimmediate_operand")
1503                     (match_operand:SDWIM 3 "<general_operand>")))
1504    (set (match_operand:QI 0 "register_operand")
1505         (match_operator 1 "ordered_comparison_operator"
1506           [(reg:CC FLAGS_REG) (const_int 0)]))]
1507   ""
1509   if (<MODE>mode == (TARGET_64BIT ? TImode : DImode))
1510     {
1511       if (GET_CODE (operands[1]) != EQ
1512           && GET_CODE (operands[1]) != NE)
1513         FAIL;
1514     }
1515   else if (MEM_P (operands[2]) && MEM_P (operands[3]))
1516     operands[2] = force_reg (<MODE>mode, operands[2]);
1517   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1518                      operands[2], operands[3]);
1519   DONE;
1522 (define_insn "@ccmp<mode>"
1523  [(set (match_operand:CC 0 "flags_reg_operand")
1524        (if_then_else:CC
1525          (match_operator 1 "comparison_operator"
1526           [(reg:CC FLAGS_REG) (const_int 0)])
1527         (compare:CC
1528           (minus:SWI (match_operand:SWI 2 "nonimmediate_operand" "<r>,<r>m,<r>")
1529                      (match_operand:SWI 3 "<general_operand>" "C,<r><i>,<m>"))
1530           (const_int 0))
1531         (unspec:CC
1532           [(match_operand:SI 4 "const_0_to_15_operand")]
1533           UNSPEC_APX_DFV)))]
1534  "TARGET_APX_CCMP"
1535  "@
1536   ctest%C1{<imodesuffix>}\t%G4 %2, %2
1537   ccmp%C1{<imodesuffix>}\t%G4 {%3, %2|%2, %3}
1538   ccmp%C1{<imodesuffix>}\t%G4 {%3, %2|%2, %3}"
1539  [(set_attr "type" "icmp")
1540   (set_attr "mode" "<MODE>")
1541   (set_attr "length_immediate" "1")
1542   (set_attr "prefix" "evex")])
1544 (define_expand "@cmp<mode>_1"
1545   [(set (reg:CC FLAGS_REG)
1546         (compare:CC (match_operand:SWI 0 "nonimmediate_operand")
1547                     (match_operand:SWI 1 "<general_operand>")))])
1549 (define_mode_iterator SWI1248_AVX512BWDQ_64
1550   [(QI "TARGET_AVX512DQ") HI
1551    (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1553 (define_insn "*cmp<mode>_ccz_1"
1554   [(set (reg FLAGS_REG)
1555         (compare (match_operand:SWI1248_AVX512BWDQ_64 0
1556                         "nonimmediate_operand" "<r>,?m<r>,$k")
1557                  (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))]
1558   "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
1559   "@
1560    test{<imodesuffix>}\t%0, %0
1561    cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1562    kortest<mskmodesuffix>\t%0, %0"
1563   [(set_attr "type" "test,icmp,msklog")
1564    (set_attr "length_immediate" "0,1,*")
1565    (set_attr "prefix" "*,*,vex")
1566    (set_attr "mode" "<MODE>")])
1568 (define_insn "*cmp<mode>_ccno_1"
1569   [(set (reg FLAGS_REG)
1570         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1571                  (match_operand:SWI 1 "const0_operand")))]
1572   "ix86_match_ccmode (insn, CCNOmode)"
1573   "@
1574    test{<imodesuffix>}\t%0, %0
1575    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1576   [(set_attr "type" "test,icmp")
1577    (set_attr "length_immediate" "0,1")
1578    (set_attr "mode" "<MODE>")])
1580 (define_insn "*cmp<mode>_1"
1581   [(set (reg FLAGS_REG)
1582         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1583                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>")))]
1584   "ix86_match_ccmode (insn, CCmode)"
1585   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1586   [(set_attr "type" "icmp")
1587    (set_attr "mode" "<MODE>")])
1589 (define_insn "*cmp<mode>_minus_1"
1590   [(set (reg FLAGS_REG)
1591         (compare
1592           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1593                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>"))
1594           (const_int 0)))]
1595   "ix86_match_ccmode (insn, CCGOCmode)"
1596   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1597   [(set_attr "type" "icmp")
1598    (set_attr "mode" "<MODE>")])
1600 (define_insn "*cmpqi_ext<mode>_1"
1601   [(set (reg FLAGS_REG)
1602         (compare
1603           (match_operand:QI 0 "nonimmediate_operand" "QBn")
1604           (subreg:QI
1605             (match_operator:SWI248 2 "extract_operator"
1606               [(match_operand 1 "int248_register_operand" "Q")
1607                (const_int 8)
1608                (const_int 8)]) 0)))]
1609   "ix86_match_ccmode (insn, CCmode)"
1610   "cmp{b}\t{%h1, %0|%0, %h1}"
1611   [(set_attr "addr" "gpr8")
1612    (set_attr "type" "icmp")
1613    (set_attr "mode" "QI")])
1615 (define_insn "*cmpqi_ext<mode>_2"
1616   [(set (reg FLAGS_REG)
1617         (compare
1618           (subreg:QI
1619             (match_operator:SWI248 2 "extract_operator"
1620               [(match_operand 0 "int248_register_operand" "Q")
1621                (const_int 8)
1622                (const_int 8)]) 0)
1623           (match_operand:QI 1 "const0_operand")))]
1624   "ix86_match_ccmode (insn, CCNOmode)"
1625   "test{b}\t%h0, %h0"
1626   [(set_attr "type" "test")
1627    (set_attr "length_immediate" "0")
1628    (set_attr "mode" "QI")])
1630 (define_expand "cmpqi_ext_3"
1631   [(set (reg:CC FLAGS_REG)
1632         (compare:CC
1633           (subreg:QI
1634             (zero_extract:HI
1635               (match_operand:HI 0 "register_operand")
1636               (const_int 8)
1637               (const_int 8)) 0)
1638           (match_operand:QI 1 "const_int_operand")))])
1640 (define_insn "*cmpqi_ext<mode>_3"
1641   [(set (reg FLAGS_REG)
1642         (compare
1643           (subreg:QI
1644             (match_operator:SWI248 2 "extract_operator"
1645               [(match_operand 0 "int248_register_operand" "Q")
1646                (const_int 8)
1647                (const_int 8)]) 0)
1648           (match_operand:QI 1 "general_operand" "QnBn")))]
1649   "ix86_match_ccmode (insn, CCmode)"
1650   "cmp{b}\t{%1, %h0|%h0, %1}"
1651   [(set_attr "addr" "gpr8")
1652    (set_attr "type" "icmp")
1653    (set_attr "mode" "QI")])
1655 (define_insn "*cmpqi_ext<mode>_4"
1656   [(set (reg FLAGS_REG)
1657         (compare
1658           (subreg:QI
1659             (match_operator:SWI248 2 "extract_operator"
1660               [(match_operand 0 "int248_register_operand" "Q")
1661                (const_int 8)
1662                (const_int 8)]) 0)
1663           (subreg:QI
1664             (match_operator:SWI248 3 "extract_operator"
1665               [(match_operand 1 "int248_register_operand" "Q")
1666                (const_int 8)
1667                (const_int 8)]) 0)))]
1668   "ix86_match_ccmode (insn, CCmode)"
1669   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1670   [(set_attr "type" "icmp")
1671    (set_attr "mode" "QI")])
1673 (define_insn_and_split "*cmp<dwi>_doubleword"
1674   [(set (reg:CCZ FLAGS_REG)
1675         (compare:CCZ (match_operand:<DWI> 0 "nonimmediate_operand")
1676                      (match_operand:<DWI> 1 "general_operand")))]
1677   "ix86_pre_reload_split ()"
1678   "#"
1679   "&& 1"
1680   [(parallel [(set (reg:CCZ FLAGS_REG)
1681                    (compare:CCZ (ior:DWIH (match_dup 4) (match_dup 5))
1682                                 (const_int 0)))
1683               (set (match_dup 4) (ior:DWIH (match_dup 4) (match_dup 5)))])]
1685   split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);
1687   operands[4] = gen_reg_rtx (<MODE>mode);
1689   /* Special case comparisons against -1.  */
1690   if (operands[1] == constm1_rtx && operands[3] == constm1_rtx)
1691     {
1692       emit_insn (gen_and<mode>3 (operands[4], operands[0], operands[2]));
1693       emit_insn (gen_cmp_1 (<MODE>mode, operands[4], constm1_rtx));
1694       DONE;
1695     }
1697   if (operands[1] == const0_rtx)
1698     emit_move_insn (operands[4], operands[0]);
1699   else if (operands[0] == const0_rtx)
1700     emit_move_insn (operands[4], operands[1]);
1701   else if (operands[1] == constm1_rtx)
1702     emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[0]));
1703   else if (operands[0] == constm1_rtx)
1704     emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[1]));
1705   else
1706     {
1707       if (CONST_SCALAR_INT_P (operands[1])
1708           && !x86_64_immediate_operand (operands[1], <MODE>mode))
1709         operands[1] = force_reg (<MODE>mode, operands[1]);
1710       emit_insn (gen_xor<mode>3 (operands[4], operands[0], operands[1]));
1711     }
1713   if (operands[3] == const0_rtx)
1714     operands[5] = operands[2];
1715   else if (operands[2] == const0_rtx)
1716     operands[5] = operands[3];
1717   else
1718     {
1719       operands[5] = gen_reg_rtx (<MODE>mode);
1720       if (operands[3] == constm1_rtx)
1721         emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[2]));
1722       else if (operands[2] == constm1_rtx)
1723         emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[3]));
1724       else
1725         {
1726           if (CONST_SCALAR_INT_P (operands[3])
1727               && !x86_64_immediate_operand (operands[3], <MODE>mode))
1728             operands[3] = force_reg (<MODE>mode, operands[3]);
1729           emit_insn (gen_xor<mode>3 (operands[5], operands[2], operands[3]));
1730         }
1731     }
1734 ;; These implement float point compares.
1735 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1736 ;; which would allow mix and match FP modes on the compares.  Which is what
1737 ;; the old patterns did, but with many more of them.
1739 (define_expand "cbranchxf4"
1740   [(set (reg:CC FLAGS_REG)
1741         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1742                     (match_operand:XF 2 "nonmemory_operand")))
1743    (set (pc) (if_then_else
1744               (match_operator 0 "ix86_fp_comparison_operator_xf"
1745                [(reg:CC FLAGS_REG)
1746                 (const_int 0)])
1747               (label_ref (match_operand 3))
1748               (pc)))]
1749   "TARGET_80387"
1751   ix86_expand_branch (GET_CODE (operands[0]),
1752                       operands[1], operands[2], operands[3]);
1753   DONE;
1756 (define_expand "cstorexf4"
1757   [(set (reg:CC FLAGS_REG)
1758         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1759                     (match_operand:XF 3 "nonmemory_operand")))
1760    (set (match_operand:QI 0 "register_operand")
1761               (match_operator 1 "ix86_fp_comparison_operator_xf"
1762                [(reg:CC FLAGS_REG)
1763                 (const_int 0)]))]
1764   "TARGET_80387"
1766   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1767                      operands[2], operands[3]);
1768   DONE;
1771 (define_expand "cbranchhf4"
1772   [(set (reg:CC FLAGS_REG)
1773         (compare:CC (match_operand:HF 1 "cmp_fp_expander_operand")
1774                     (match_operand:HF 2 "cmp_fp_expander_operand")))
1775    (set (pc) (if_then_else
1776               (match_operator 0 "ix86_fp_comparison_operator"
1777                [(reg:CC FLAGS_REG)
1778                 (const_int 0)])
1779               (label_ref (match_operand 3))
1780               (pc)))]
1781   "TARGET_AVX512FP16"
1783   ix86_expand_branch (GET_CODE (operands[0]),
1784                       operands[1], operands[2], operands[3]);
1785   DONE;
1788 (define_expand "cbranch<mode>4"
1789   [(set (reg:CC FLAGS_REG)
1790         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1791                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1792    (set (pc) (if_then_else
1793               (match_operator 0 "ix86_fp_comparison_operator"
1794                [(reg:CC FLAGS_REG)
1795                 (const_int 0)])
1796               (label_ref (match_operand 3))
1797               (pc)))]
1798   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1800   ix86_expand_branch (GET_CODE (operands[0]),
1801                       operands[1], operands[2], operands[3]);
1802   DONE;
1805 (define_expand "cbranchbf4"
1806   [(set (reg:CC FLAGS_REG)
1807         (compare:CC (match_operand:BF 1 "cmp_fp_expander_operand")
1808                     (match_operand:BF 2 "cmp_fp_expander_operand")))
1809    (set (pc) (if_then_else
1810               (match_operator 0 "comparison_operator"
1811                [(reg:CC FLAGS_REG)
1812                 (const_int 0)])
1813               (label_ref (match_operand 3))
1814               (pc)))]
1815   "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1817   rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[1]);
1818   rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1819   do_compare_rtx_and_jump (op1, op2, GET_CODE (operands[0]), 0,
1820                            SFmode, NULL_RTX, NULL,
1821                            as_a <rtx_code_label *> (operands[3]),
1822                            /* Unfortunately this isn't propagated.  */
1823                            profile_probability::even ());
1824   DONE;
1827 (define_expand "cstorehf4"
1828   [(set (reg:CC FLAGS_REG)
1829         (compare:CC (match_operand:HF 2 "cmp_fp_expander_operand")
1830                     (match_operand:HF 3 "cmp_fp_expander_operand")))
1831    (set (match_operand:QI 0 "register_operand")
1832         (match_operator 1 "ix86_fp_comparison_operator"
1833           [(reg:CC FLAGS_REG)
1834            (const_int 0)]))]
1835   "TARGET_AVX512FP16"
1837   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1838                      operands[2], operands[3]);
1839   DONE;
1842 (define_expand "cstorebf4"
1843   [(set (reg:CC FLAGS_REG)
1844         (compare:CC (match_operand:BF 2 "cmp_fp_expander_operand")
1845                     (match_operand:BF 3 "cmp_fp_expander_operand")))
1846    (set (match_operand:QI 0 "register_operand")
1847         (match_operator 1 "comparison_operator"
1848           [(reg:CC FLAGS_REG)
1849            (const_int 0)]))]
1850   "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1852   rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1853   rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[3]);
1854   rtx res = emit_store_flag_force (operands[0], GET_CODE (operands[1]),
1855                                    op1, op2, SFmode, 0, 1);
1856   if (!rtx_equal_p (res, operands[0]))
1857     emit_move_insn (operands[0], res);
1858   DONE;
1861 (define_expand "cstore<mode>4"
1862   [(set (reg:CC FLAGS_REG)
1863         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1864                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1865    (set (match_operand:QI 0 "register_operand")
1866               (match_operator 1 "ix86_fp_comparison_operator"
1867                [(reg:CC FLAGS_REG)
1868                 (const_int 0)]))]
1869   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1871   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1872                      operands[2], operands[3]);
1873   DONE;
1876 (define_expand "cbranchcc4"
1877   [(set (pc) (if_then_else
1878               (match_operator 0 "comparison_operator"
1879                [(match_operand 1 "flags_reg_operand")
1880                 (match_operand 2 "const0_operand")])
1881               (label_ref (match_operand 3))
1882               (pc)))]
1883   ""
1885   ix86_expand_branch (GET_CODE (operands[0]),
1886                       operands[1], operands[2], operands[3]);
1887   DONE;
1890 ;; For conditonal compare, the middle-end hook will convert
1891 ;; CCmode to sub-CCmode using SELECT_CC_MODE macro and try
1892 ;; to find cstore<submodes> in optab. Add ALL_CC to support
1893 ;; the cstore after ccmp sequence.
1895 (define_mode_iterator ALL_CC
1896  [CCGC CCGOC CCNO CCGZ CCA CCC CCO CCP CCS CCZ CC])
1898 (define_expand "cstore<mode>4"
1899   [(set (match_operand:QI 0 "register_operand")
1900               (match_operator 1 "comparison_operator"
1901                [(match_operand:ALL_CC 2 "flags_reg_operand")
1902                 (match_operand 3 "const0_operand")]))]
1903   ""
1905   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1906                      operands[2], operands[3]);
1907   DONE;
1910 ;; FP compares, step 1:
1911 ;; Set the FP condition codes and move fpsr to ax.
1913 ;; We may not use "#" to split and emit these
1914 ;; due to reg-stack pops killing fpsr.
1916 (define_insn "*cmpxf_i387"
1917   [(set (match_operand:HI 0 "register_operand" "=a")
1918         (unspec:HI
1919           [(compare:CCFP
1920              (match_operand:XF 1 "register_operand" "f")
1921              (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1922           UNSPEC_FNSTSW))]
1923   "TARGET_80387"
1924   "* return output_fp_compare (insn, operands, false, false);"
1925   [(set_attr "type" "multi")
1926    (set_attr "unit" "i387")
1927    (set_attr "mode" "XF")])
1929 (define_insn "*cmp<mode>_i387"
1930   [(set (match_operand:HI 0 "register_operand" "=a")
1931         (unspec:HI
1932           [(compare:CCFP
1933              (match_operand:MODEF 1 "register_operand" "f")
1934              (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1935           UNSPEC_FNSTSW))]
1936   "TARGET_80387"
1937   "* return output_fp_compare (insn, operands, false, false);"
1938   [(set_attr "type" "multi")
1939    (set_attr "unit" "i387")
1940    (set_attr "mode" "<MODE>")])
1942 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1943   [(set (match_operand:HI 0 "register_operand" "=a")
1944         (unspec:HI
1945           [(compare:CCFP
1946              (match_operand:X87MODEF 1 "register_operand" "f")
1947              (float:X87MODEF
1948                (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1949           UNSPEC_FNSTSW))]
1950   "TARGET_80387
1951    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1952        || optimize_function_for_size_p (cfun))"
1953   "* return output_fp_compare (insn, operands, false, false);"
1954   [(set_attr "type" "multi")
1955    (set_attr "unit" "i387")
1956    (set_attr "fp_int_src" "true")
1957    (set_attr "mode" "<SWI24:MODE>")])
1959 (define_insn "*cmpu<mode>_i387"
1960   [(set (match_operand:HI 0 "register_operand" "=a")
1961         (unspec:HI
1962           [(unspec:CCFP
1963              [(compare:CCFP
1964                 (match_operand:X87MODEF 1 "register_operand" "f")
1965                 (match_operand:X87MODEF 2 "register_operand" "f"))]
1966              UNSPEC_NOTRAP)]
1967           UNSPEC_FNSTSW))]
1968   "TARGET_80387"
1969   "* return output_fp_compare (insn, operands, false, true);"
1970   [(set_attr "type" "multi")
1971    (set_attr "unit" "i387")
1972    (set_attr "mode" "<MODE>")])
1974 ;; FP compares, step 2:
1975 ;; Get ax into flags, general case.
1977 (define_insn "x86_sahf_1"
1978   [(set (reg:CC FLAGS_REG)
1979         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1980                    UNSPEC_SAHF))]
1981   "TARGET_SAHF"
1983 #ifndef HAVE_AS_IX86_SAHF
1984   if (TARGET_64BIT)
1985     return ASM_BYTE "0x9e";
1986   else
1987 #endif
1988   return "sahf";
1990   [(set_attr "length" "1")
1991    (set_attr "athlon_decode" "vector")
1992    (set_attr "amdfam10_decode" "direct")
1993    (set_attr "bdver1_decode" "direct")
1994    (set_attr "mode" "SI")])
1996 ;; Pentium Pro can do both steps in one go.
1997 ;; (these instructions set flags directly)
1999 (define_subst_attr "unord" "unord_subst" "" "u")
2000 (define_subst_attr "unordered" "unord_subst" "false" "true")
2002 (define_subst "unord_subst"
2003   [(set (match_operand:CCFP 0)
2004         (match_operand:CCFP 1))]
2005   ""
2006   [(set (match_dup 0)
2007         (unspec:CCFP
2008           [(match_dup 1)]
2009           UNSPEC_NOTRAP))])
2011 (define_insn "*cmpi<unord>xf_i387"
2012   [(set (reg:CCFP FLAGS_REG)
2013         (compare:CCFP
2014           (match_operand:XF 0 "register_operand" "f")
2015           (match_operand:XF 1 "register_operand" "f")))]
2016   "TARGET_80387 && TARGET_CMOVE"
2017   "* return output_fp_compare (insn, operands, true, <unordered>);"
2018   [(set_attr "type" "fcmp")
2019    (set_attr "mode" "XF")
2020    (set_attr "athlon_decode" "vector")
2021    (set_attr "amdfam10_decode" "direct")
2022    (set_attr "bdver1_decode" "double")
2023    (set_attr "znver1_decode" "double")])
2025 (define_insn "*cmpx<unord><MODEF:mode>"
2026   [(set (reg:CCFP FLAGS_REG)
2027         (unspec:CCFP [
2028           (compare:CCFP
2029             (match_operand:MODEF 0 "register_operand" "v")
2030             (match_operand:MODEF 1 "nonimmediate_operand" "vm"))]
2031           UNSPEC_OPTCOMX))]
2032   "TARGET_AVX10_2_256"
2033   "%v<unord>comx<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
2034   [(set_attr "type" "ssecomi")
2035    (set_attr "prefix" "evex")
2036    (set_attr "mode" "<MODEF:MODE>")])
2038 (define_insn "*cmpx<unord>hf"
2039   [(set (reg:CCFP FLAGS_REG)
2040         (unspec:CCFP [
2041           (compare:CCFP
2042             (match_operand:HF 0 "register_operand" "v")
2043             (match_operand:HF 1 "nonimmediate_operand" "vm"))]
2044           UNSPEC_OPTCOMX))]
2045   "TARGET_AVX10_2_256"
2046   "v<unord>comxsh\t{%1, %0|%0, %1}"
2047   [(set_attr "type" "ssecomi")
2048    (set_attr "prefix" "evex")
2049    (set_attr "mode" "HF")])
2051 (define_insn "*cmpi<unord><MODEF:mode>"
2052   [(set (reg:CCFP FLAGS_REG)
2053         (compare:CCFP
2054           (match_operand:MODEF 0 "register_operand" "f,v")
2055           (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
2056   "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
2057    || (TARGET_80387 && TARGET_CMOVE)"
2058   "@
2059    * return output_fp_compare (insn, operands, true, <unordered>);
2060    %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
2061   [(set_attr "type" "fcmp,ssecomi")
2062    (set_attr "prefix" "orig,maybe_vex")
2063    (set_attr "mode" "<MODEF:MODE>")
2064    (set_attr "prefix_rep" "*,0")
2065    (set (attr "prefix_data16")
2066         (cond [(eq_attr "alternative" "0")
2067                  (const_string "*")
2068                (eq_attr "mode" "DF")
2069                  (const_string "1")
2070               ]
2071               (const_string "0")))
2072    (set_attr "athlon_decode" "vector")
2073    (set_attr "amdfam10_decode" "direct")
2074    (set_attr "bdver1_decode" "double")
2075    (set_attr "znver1_decode" "double")
2076    (set (attr "enabled")
2077      (if_then_else
2078        (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
2079        (if_then_else
2080          (eq_attr "alternative" "0")
2081          (symbol_ref "TARGET_MIX_SSE_I387")
2082          (symbol_ref "true"))
2083        (if_then_else
2084          (eq_attr "alternative" "0")
2085          (symbol_ref "true")
2086          (symbol_ref "false"))))])
2088 (define_insn "*cmpi<unord>hf"
2089   [(set (reg:CCFP FLAGS_REG)
2090         (compare:CCFP
2091           (match_operand:HF 0 "register_operand" "v")
2092           (match_operand:HF 1 "nonimmediate_operand" "vm")))]
2093   "TARGET_AVX512FP16"
2094   "v<unord>comish\t{%1, %0|%0, %1}"
2095   [(set_attr "type" "ssecomi")
2096    (set_attr "prefix" "evex")
2097    (set_attr "mode" "HF")])
2099 ;; Set carry flag.
2100 (define_insn "x86_stc"
2101   [(set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2102   ""
2103   "stc"
2104   [(set_attr "length" "1")
2105    (set_attr "length_immediate" "0")
2106    (set_attr "modrm" "0")])
2108 ;; On Pentium 4, set the carry flag using mov $1,%al;addb $-1,%al.
2109 (define_peephole2
2110   [(match_scratch:QI 0 "r")
2111    (set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2112   "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2113   [(set (match_dup 0) (const_int 1))
2114    (parallel
2115      [(set (reg:CCC FLAGS_REG)
2116            (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2117                         (match_dup 0)))
2118       (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2120 ;; Complement carry flag.
2121 (define_insn "*x86_cmc"
2122   [(set (reg:CCC FLAGS_REG)
2123         (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2124                      (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2125   ""
2126   "cmc"
2127   [(set_attr "length" "1")
2128    (set_attr "length_immediate" "0")
2129    (set_attr "use_carry" "1")
2130    (set_attr "modrm" "0")])
2132 ;; On Pentium 4, cmc is replaced with setnc %al;addb $-1,%al.
2133 (define_peephole2
2134   [(match_scratch:QI 0 "r")
2135    (set (reg:CCC FLAGS_REG)
2136         (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2137                      (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2138   "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2139   [(set (match_dup 0) (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
2140    (parallel
2141      [(set (reg:CCC FLAGS_REG)
2142            (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2143                         (match_dup 0)))
2144       (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2146 ;; Push/pop instructions.
2148 (define_insn_and_split "*pushv1ti2"
2149   [(set (match_operand:V1TI 0 "push_operand" "=<")
2150         (match_operand:V1TI 1 "register_operand" "v"))]
2151   "TARGET_64BIT && TARGET_STV"
2152   "#"
2153   "&& reload_completed"
2154   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2155    (set (match_dup 0) (match_dup 1))]
2157   operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (V1TImode)));
2158   /* Preserve memory attributes. */
2159   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2161   [(set_attr "type" "multi")
2162    (set_attr "mode" "TI")])
2164 (define_insn "*push<mode>2"
2165   [(set (match_operand:DWI 0 "push_operand" "=<,<")
2166         (match_operand:DWI 1 "general_no_elim_operand" "riF*o,*v"))]
2167   ""
2168   "#"
2169   [(set_attr "type" "multi")
2170    (set_attr "mode" "<MODE>")])
2172 (define_split
2173   [(set (match_operand:DWI 0 "push_operand")
2174         (match_operand:DWI 1 "general_gr_operand"))]
2175   "reload_completed"
2176   [(const_int 0)]
2177   "ix86_split_long_move (operands); DONE;")
2179 (define_insn "*pushdi2_rex64"
2180   [(set (match_operand:DI 0 "push_operand" "=<,<,!<")
2181         (match_operand:DI 1 "general_no_elim_operand" "re*m,*v,n"))]
2182   "TARGET_64BIT"
2183   "@
2184    push{q}\t%1
2185    #
2186    #"
2187   [(set_attr "type" "push,multi,multi")
2188    (set_attr "mode" "DI")])
2190 ;; Convert impossible pushes of immediate to existing instructions.
2191 ;; First try to get scratch register and go through it.  In case this
2192 ;; fails, push sign extended lower part first and then overwrite
2193 ;; upper part by 32bit move.
2195 (define_peephole2
2196   [(match_scratch:DI 2 "r")
2197    (set (match_operand:DI 0 "push_operand")
2198         (match_operand:DI 1 "immediate_operand"))]
2199   "TARGET_64BIT
2200    && !symbolic_operand (operands[1], DImode)
2201    && !x86_64_immediate_operand (operands[1], DImode)"
2202   [(set (match_dup 2) (match_dup 1))
2203    (set (match_dup 0) (match_dup 2))])
2205 (define_split
2206   [(set (match_operand:DI 0 "push_operand")
2207         (match_operand:DI 1 "immediate_operand"))]
2208   "TARGET_64BIT && epilogue_completed
2209    && !symbolic_operand (operands[1], DImode)
2210    && !x86_64_immediate_operand (operands[1], DImode)"
2211   [(set (match_dup 0) (match_dup 1))
2212    (set (match_dup 2) (match_dup 3))]
2214   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
2216   operands[1] = gen_lowpart (DImode, operands[2]);
2217   operands[2] = gen_rtx_MEM (SImode,
2218                              plus_constant (Pmode, stack_pointer_rtx, 4));
2221 ;; For TARGET_64BIT we always round up to 8 bytes.
2222 (define_insn "*pushsi2_rex64"
2223   [(set (match_operand:SI 0 "push_operand" "=X,X")
2224         (match_operand:SI 1 "nonmemory_no_elim_operand" "re,*v"))]
2225   "TARGET_64BIT"
2226   "@
2227    push{q}\t%q1
2228    #"
2229   [(set_attr "type" "push,multi")
2230    (set_attr "mode" "DI")])
2232 (define_insn "*pushsi2"
2233   [(set (match_operand:SI 0 "push_operand" "=<,<")
2234         (match_operand:SI 1 "general_no_elim_operand" "ri*m,*v"))]
2235   "!TARGET_64BIT"
2236   "@
2237    push{l}\t%1
2238    #"
2239   [(set_attr "type" "push,multi")
2240    (set_attr "mode" "SI")])
2242 (define_split
2243   [(set (match_operand:SWI48DWI 0 "push_operand")
2244         (match_operand:SWI48DWI 1 "sse_reg_operand"))]
2245   "TARGET_SSE && reload_completed"
2246   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2247     (set (match_dup 0) (match_dup 1))]
2249   operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (<SWI48DWI:MODE>mode)));
2250   /* Preserve memory attributes. */
2251   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2254 ;; emit_push_insn when it calls move_by_pieces requires an insn to
2255 ;; "push a byte/word".  But actually we use push{l,q}, which has
2256 ;; the effect of rounding the amount pushed up to a word.
2258 (define_insn "*push<mode>2"
2259   [(set (match_operand:SWI12 0 "push_operand" "=X")
2260         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
2261   ""
2262   "* return TARGET_64BIT ? \"push{q}\t%q1\" : \"push{l}\t%k1\";"
2263   [(set_attr "type" "push")
2264    (set (attr "mode")
2265         (if_then_else (match_test "TARGET_64BIT")
2266           (const_string "DI")
2267           (const_string "SI")))])
2269 (define_insn "*push<mode>2_prologue"
2270   [(set (match_operand:W 0 "push_operand" "=<")
2271         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
2272    (clobber (mem:BLK (scratch)))]
2273   ""
2274   "push{<imodesuffix>}\t%1"
2275   [(set_attr "type" "push")
2276    (set_attr "mode" "<MODE>")])
2278 (define_insn "*pop<mode>1"
2279   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2280         (match_operand:W 1 "pop_operand" ">"))]
2281   ""
2282   "pop{<imodesuffix>}\t%0"
2283   [(set_attr "type" "pop")
2284    (set_attr "mode" "<MODE>")])
2286 (define_insn "*pop<mode>1_epilogue"
2287   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2288         (match_operand:W 1 "pop_operand" ">"))
2289    (clobber (mem:BLK (scratch)))]
2290   ""
2291   "pop{<imodesuffix>}\t%0"
2292   [(set_attr "type" "pop")
2293    (set_attr "mode" "<MODE>")])
2295 (define_insn "@pushfl<mode>2"
2296   [(set (match_operand:W 0 "push_operand" "=<")
2297         (unspec:W [(match_operand 1 "flags_reg_operand")]
2298                   UNSPEC_PUSHFL))]
2299   "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_CC"
2300   "pushf{<imodesuffix>}"
2301   [(set_attr "type" "push")
2302    (set_attr "mode" "<MODE>")])
2304 (define_insn "@popfl<mode>1"
2305   [(set (match_operand:CC 0 "flags_reg_operand")
2306         (unspec:CC [(match_operand:W 1 "pop_operand" ">")]
2307                    UNSPEC_POPFL))]
2308   ""
2309   "popf{<imodesuffix>}"
2310   [(set_attr "type" "pop")
2311    (set_attr "mode" "<MODE>")])
2314 ;; Reload patterns to support multi-word load/store
2315 ;; with non-offsetable address.
2316 (define_expand "reload_noff_store"
2317   [(parallel [(match_operand 0 "memory_operand" "=m")
2318               (match_operand 1 "register_operand" "r")
2319               (match_operand:DI 2 "register_operand" "=&r")])]
2320   "TARGET_64BIT"
2322   rtx mem = operands[0];
2323   rtx addr = XEXP (mem, 0);
2325   emit_move_insn (operands[2], addr);
2326   mem = replace_equiv_address_nv (mem, operands[2]);
2328   emit_insn (gen_rtx_SET (mem, operands[1]));
2329   DONE;
2332 (define_expand "reload_noff_load"
2333   [(parallel [(match_operand 0 "register_operand" "=r")
2334               (match_operand 1 "memory_operand" "m")
2335               (match_operand:DI 2 "register_operand" "=r")])]
2336   "TARGET_64BIT"
2338   rtx mem = operands[1];
2339   rtx addr = XEXP (mem, 0);
2341   emit_move_insn (operands[2], addr);
2342   mem = replace_equiv_address_nv (mem, operands[2]);
2344   emit_insn (gen_rtx_SET (operands[0], mem));
2345   DONE;
2348 ;; Move instructions.
2350 (define_expand "movxi"
2351   [(set (match_operand:XI 0 "nonimmediate_operand")
2352         (match_operand:XI 1 "general_operand"))]
2353   "TARGET_AVX512F && TARGET_EVEX512"
2354   "ix86_expand_vector_move (XImode, operands); DONE;")
2356 (define_expand "movoi"
2357   [(set (match_operand:OI 0 "nonimmediate_operand")
2358         (match_operand:OI 1 "general_operand"))]
2359   "TARGET_AVX"
2360   "ix86_expand_vector_move (OImode, operands); DONE;")
2362 (define_expand "movti"
2363   [(set (match_operand:TI 0 "nonimmediate_operand")
2364         (match_operand:TI 1 "general_operand"))]
2365   "TARGET_64BIT || TARGET_SSE"
2367   if (TARGET_64BIT)
2368     ix86_expand_move (TImode, operands);
2369   else
2370     ix86_expand_vector_move (TImode, operands);
2371   DONE;
2374 ;; This expands to what emit_move_complex would generate if we didn't
2375 ;; have a movti pattern.  Having this avoids problems with reload on
2376 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2377 ;; to have around all the time.
2378 (define_expand "movcdi"
2379   [(set (match_operand:CDI 0 "nonimmediate_operand")
2380         (match_operand:CDI 1 "general_operand"))]
2381   ""
2383   if (push_operand (operands[0], CDImode))
2384     emit_move_complex_push (CDImode, operands[0], operands[1]);
2385   else
2386     emit_move_complex_parts (operands[0], operands[1]);
2387   DONE;
2390 (define_expand "mov<mode>"
2391   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2392         (match_operand:SWI1248x 1 "general_operand"))]
2393   ""
2394   "ix86_expand_move (<MODE>mode, operands); DONE;")
2396 (define_insn "*mov<mode>_xor"
2397   [(set (match_operand:SWI48 0 "register_operand" "=r")
2398         (match_operand:SWI48 1 "const0_operand"))
2399    (clobber (reg:CC FLAGS_REG))]
2400   "reload_completed"
2401   "xor{l}\t%k0, %k0"
2402   [(set_attr "type" "alu1")
2403    (set_attr "mode" "SI")
2404    (set_attr "length_immediate" "0")])
2406 (define_insn "*mov<mode>_and"
2407   [(set (match_operand:SWI248 0 "memory_operand" "=m")
2408         (match_operand:SWI248 1 "const0_operand"))
2409    (clobber (reg:CC FLAGS_REG))]
2410   "reload_completed"
2411   "and{<imodesuffix>}\t{%1, %0|%0, %1}"
2412   [(set_attr "type" "alu1")
2413    (set_attr "mode" "<MODE>")
2414    (set_attr "length_immediate" "1")])
2416 (define_insn "*mov<mode>_or"
2417   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
2418         (match_operand:SWI248 1 "constm1_operand"))
2419    (clobber (reg:CC FLAGS_REG))]
2420   "reload_completed"
2421   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2422   [(set_attr "type" "alu1")
2423    (set_attr "mode" "<MODE>")
2424    (set_attr "length_immediate" "1")])
2426 (define_insn "*movxi_internal_avx512f"
2427   [(set (match_operand:XI 0 "nonimmediate_operand"              "=v,v ,v ,m")
2428         (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2429   "TARGET_AVX512F && TARGET_EVEX512
2430    && (register_operand (operands[0], XImode)
2431        || register_operand (operands[1], XImode))"
2433   switch (get_attr_type (insn))
2434     {
2435     case TYPE_SSELOG1:
2436       return standard_sse_constant_opcode (insn, operands);
2438     case TYPE_SSEMOV:
2439       return ix86_output_ssemov (insn, operands);
2441     default:
2442       gcc_unreachable ();
2443     }
2445   [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2446    (set_attr "prefix" "evex")
2447    (set_attr "mode" "XI")])
2449 (define_insn "*movoi_internal_avx"
2450   [(set (match_operand:OI 0 "nonimmediate_operand"              "=v,v ,v ,m")
2451         (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2452   "TARGET_AVX
2453    && (register_operand (operands[0], OImode)
2454        || register_operand (operands[1], OImode))"
2456   switch (get_attr_type (insn))
2457     {
2458     case TYPE_SSELOG1:
2459       return standard_sse_constant_opcode (insn, operands);
2461     case TYPE_SSEMOV:
2462       return ix86_output_ssemov (insn, operands);
2464     default:
2465       gcc_unreachable ();
2466     }
2468   [(set_attr "isa" "*,avx2,*,*")
2469    (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2470    (set_attr "prefix" "vex")
2471    (set_attr "mode" "OI")])
2473 (define_insn "*movti_internal"
2474   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?jc,?Yd")
2475         (match_operand:TI 1 "general_operand"      "riFo,re,C,BC,vm,v,Yd,jc"))]
2476   "(TARGET_64BIT
2477     && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2478    || (TARGET_SSE
2479        && nonimmediate_or_sse_const_operand (operands[1], TImode)
2480        && (register_operand (operands[0], TImode)
2481            || register_operand (operands[1], TImode)))"
2483   switch (get_attr_type (insn))
2484     {
2485     case TYPE_MULTI:
2486       return "#";
2488     case TYPE_SSELOG1:
2489       return standard_sse_constant_opcode (insn, operands);
2491     case TYPE_SSEMOV:
2492       return ix86_output_ssemov (insn, operands);
2494     default:
2495       gcc_unreachable ();
2496     }
2498   [(set (attr "isa")
2499      (cond [(eq_attr "alternative" "0,1,6,7")
2500               (const_string "x64")
2501             (eq_attr "alternative" "3")
2502               (const_string "sse2")
2503            ]
2504            (const_string "*")))
2505    (set (attr "type")
2506      (cond [(eq_attr "alternative" "0,1,6,7")
2507               (const_string "multi")
2508             (eq_attr "alternative" "2,3")
2509               (const_string "sselog1")
2510            ]
2511            (const_string "ssemov")))
2512    (set (attr "prefix")
2513      (if_then_else (eq_attr "type" "sselog1,ssemov")
2514        (const_string "maybe_vex")
2515        (const_string "orig")))
2516    (set (attr "mode")
2517         (cond [(eq_attr "alternative" "0,1")
2518                  (const_string "DI")
2519                (match_test "TARGET_AVX")
2520                  (const_string "TI")
2521                (ior (not (match_test "TARGET_SSE2"))
2522                     (match_test "optimize_function_for_size_p (cfun)"))
2523                  (const_string "V4SF")
2524                (and (eq_attr "alternative" "5")
2525                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2526                  (const_string "V4SF")
2527                ]
2528                (const_string "TI")))
2529    (set (attr "preferred_for_speed")
2530      (cond [(eq_attr "alternative" "6")
2531               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2532             (eq_attr "alternative" "7")
2533               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2534            ]
2535            (symbol_ref "true")))])
2537 (define_split
2538   [(set (match_operand:TI 0 "sse_reg_operand")
2539         (match_operand:TI 1 "general_reg_operand"))]
2540   "TARGET_64BIT && TARGET_SSE4_1
2541    && reload_completed"
2542   [(set (match_dup 2)
2543         (vec_merge:V2DI
2544           (vec_duplicate:V2DI (match_dup 3))
2545           (match_dup 2)
2546           (const_int 2)))]
2548   operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2549   operands[3] = gen_highpart (DImode, operands[1]);
2551   emit_move_insn (gen_lowpart (DImode, operands[0]),
2552                   gen_lowpart (DImode, operands[1]));
2555 (define_insn "*movdi_internal"
2556   [(set (match_operand:DI 0 "nonimmediate_operand"
2557     "=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")
2558         (match_operand:DI 1 "general_operand"
2559     "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"))]
2560   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2561    && ix86_hardreg_mov_ok (operands[0], operands[1])"
2563   switch (get_attr_type (insn))
2564     {
2565     case TYPE_MSKMOV:
2566       return "kmovq\t{%1, %0|%0, %1}";
2568     case TYPE_MSKLOG:
2569       if (operands[1] == const0_rtx)
2570         return "kxorq\t%0, %0, %0";
2571       else if (operands[1] == constm1_rtx)
2572         return "kxnorq\t%0, %0, %0";
2573       gcc_unreachable ();
2575     case TYPE_MULTI:
2576       return "#";
2578     case TYPE_MMX:
2579       return "pxor\t%0, %0";
2581     case TYPE_MMXMOV:
2582       /* Handle broken assemblers that require movd instead of movq.  */
2583       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2584           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2585         return "movd\t{%1, %0|%0, %1}";
2586       return "movq\t{%1, %0|%0, %1}";
2588     case TYPE_SSELOG1:
2589       return standard_sse_constant_opcode (insn, operands);
2591     case TYPE_SSEMOV:
2592       return ix86_output_ssemov (insn, operands);
2594     case TYPE_SSECVT:
2595       if (SSE_REG_P (operands[0]))
2596         return "movq2dq\t{%1, %0|%0, %1}";
2597       else
2598         return "movdq2q\t{%1, %0|%0, %1}";
2600     case TYPE_LEA:
2601       return "lea{q}\t{%E1, %0|%0, %E1}";
2603     case TYPE_IMOV:
2604       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2605       if (get_attr_mode (insn) == MODE_SI)
2606         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2607       else if (which_alternative == 4)
2608         return "movabs{q}\t{%1, %0|%0, %1}";
2609       else if (ix86_use_lea_for_mov (insn, operands))
2610         return "lea{q}\t{%E1, %0|%0, %E1}";
2611       else
2612         return "mov{q}\t{%1, %0|%0, %1}";
2614     default:
2615       gcc_unreachable ();
2616     }
2618   [(set (attr "isa")
2619      (cond [(eq_attr "alternative" "0,1,17,18")
2620               (const_string "nox64")
2621             (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2622               (const_string "x64")
2623             (eq_attr "alternative" "19,20")
2624               (const_string "x64_sse2")
2625             (eq_attr "alternative" "21,22")
2626               (const_string "sse2")
2627            ]
2628            (const_string "*")))
2629    (set (attr "type")
2630      (cond [(eq_attr "alternative" "0,1,17,18")
2631               (const_string "multi")
2632             (eq_attr "alternative" "6")
2633               (const_string "mmx")
2634             (eq_attr "alternative" "7,8,9,10,11")
2635               (const_string "mmxmov")
2636             (eq_attr "alternative" "12")
2637               (const_string "sselog1")
2638             (eq_attr "alternative" "13,14,15,16,19,20")
2639               (const_string "ssemov")
2640             (eq_attr "alternative" "21,22")
2641               (const_string "ssecvt")
2642             (eq_attr "alternative" "23,24,25,26")
2643               (const_string "mskmov")
2644             (eq_attr "alternative" "27")
2645               (const_string "msklog")
2646             (and (match_operand 0 "register_operand")
2647                  (match_operand 1 "pic_32bit_operand"))
2648               (const_string "lea")
2649            ]
2650            (const_string "imov")))
2651    (set (attr "modrm")
2652      (if_then_else
2653        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2654        (const_string "0")
2655        (const_string "*")))
2656    (set (attr "length_immediate")
2657      (if_then_else
2658        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2659        (const_string "8")
2660        (const_string "*")))
2661    (set (attr "prefix_rex")
2662      (if_then_else
2663        (eq_attr "alternative" "10,11,19,20")
2664        (const_string "1")
2665        (const_string "*")))
2666    (set (attr "prefix")
2667      (if_then_else (eq_attr "type" "sselog1,ssemov")
2668        (const_string "maybe_vex")
2669        (const_string "orig")))
2670    (set (attr "prefix_data16")
2671      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2672        (const_string "1")
2673        (const_string "*")))
2674    (set (attr "mode")
2675      (cond [(eq_attr "alternative" "2")
2676               (const_string "SI")
2677             (eq_attr "alternative" "12")
2678               (cond [(match_test "TARGET_AVX")
2679                        (const_string "TI")
2680                      (ior (not (match_test "TARGET_SSE2"))
2681                           (match_test "optimize_function_for_size_p (cfun)"))
2682                        (const_string "V4SF")
2683                     ]
2684                     (const_string "TI"))
2685             (eq_attr "alternative" "13")
2686               (cond [(match_test "TARGET_AVX512VL")
2687                        (const_string "TI")
2688                      (match_test "TARGET_AVX512F")
2689                        (const_string "DF")
2690                      (match_test "TARGET_AVX")
2691                        (const_string "TI")
2692                      (ior (not (match_test "TARGET_SSE2"))
2693                           (match_test "optimize_function_for_size_p (cfun)"))
2694                        (const_string "V4SF")
2695                     ]
2696                     (const_string "TI"))
2698             (and (eq_attr "alternative" "14,15,16")
2699                  (not (match_test "TARGET_SSE2")))
2700               (const_string "V2SF")
2701            ]
2702            (const_string "DI")))
2703    (set (attr "preferred_for_speed")
2704      (cond [(eq_attr "alternative" "10,17,19")
2705               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2706             (eq_attr "alternative" "11,18,20")
2707               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2708            ]
2709            (symbol_ref "true")))
2710    (set (attr "enabled")
2711      (cond [(eq_attr "alternative" "15")
2712               (if_then_else
2713                 (match_test "TARGET_STV && TARGET_SSE2")
2714                 (symbol_ref "false")
2715                 (const_string "*"))
2716             (eq_attr "alternative" "16")
2717               (if_then_else
2718                 (match_test "TARGET_STV && TARGET_SSE2")
2719                 (symbol_ref "true")
2720                 (symbol_ref "false"))
2721            ]
2722            (const_string "*")))])
2724 (define_split
2725   [(set (match_operand:<DWI> 0 "general_reg_operand")
2726         (match_operand:<DWI> 1 "sse_reg_operand"))]
2727   "TARGET_SSE4_1
2728    && reload_completed"
2729   [(set (match_dup 2)
2730         (vec_select:DWIH
2731           (match_dup 3)
2732           (parallel [(const_int 1)])))]
2734   operands[2] = gen_highpart (<MODE>mode, operands[0]);
2735   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2737   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2738                   gen_lowpart (<MODE>mode, operands[1]));
2741 (define_split
2742   [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2743         (match_operand:DWI 1 "general_gr_operand"))]
2744   "reload_completed"
2745   [(const_int 0)]
2746   "ix86_split_long_move (operands); DONE;")
2748 (define_split
2749   [(set (match_operand:DI 0 "sse_reg_operand")
2750         (match_operand:DI 1 "general_reg_operand"))]
2751   "!TARGET_64BIT && TARGET_SSE4_1
2752    && reload_completed"
2753   [(set (match_dup 2)
2754         (vec_merge:V4SI
2755           (vec_duplicate:V4SI (match_dup 3))
2756           (match_dup 2)
2757           (const_int 2)))]
2759   operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2760   operands[3] = gen_highpart (SImode, operands[1]);
2762   emit_move_insn (gen_lowpart (SImode, operands[0]),
2763                   gen_lowpart (SImode, operands[1]));
2766 ;; movabsq $0x0012345678000000, %rax is longer
2767 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2768 (define_peephole2
2769   [(set (match_operand:DI 0 "register_operand")
2770         (match_operand:DI 1 "const_int_operand"))]
2771   "TARGET_64BIT
2772    && optimize_insn_for_size_p ()
2773    && LEGACY_INT_REG_P (operands[0])
2774    && !x86_64_immediate_operand (operands[1], DImode)
2775    && !x86_64_zext_immediate_operand (operands[1], DImode)
2776    && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2777         & ~HOST_WIDE_INT_C (0xffffffff))
2778    && peep2_regno_dead_p (0, FLAGS_REG)"
2779   [(set (match_dup 0) (match_dup 1))
2780    (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2781               (clobber (reg:CC FLAGS_REG))])]
2783   int shift = ctz_hwi (UINTVAL (operands[1]));
2784   rtx op1 = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2785   if (ix86_endbr_immediate_operand (op1, VOIDmode))
2786     FAIL;
2787   operands[1] = op1;
2788   operands[2] = gen_int_mode (shift, QImode);
2791 (define_insn "*movsi_internal"
2792   [(set (match_operand:SI 0 "nonimmediate_operand"
2793     "=r,m ,*y,*y,?*y,?m,?r,?*y,?Yv,?v,?v,m ,?r,?v,*k,*k  ,*rm,*k")
2794         (match_operand:SI 1 "general_operand"
2795     "g ,re,C ,*y,Bk ,*y,*y,r  ,C  ,?v,Bk,?v,?v,r  ,*r,*kBk,*k ,CBC"))]
2796   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2797    && ix86_hardreg_mov_ok (operands[0], operands[1])"
2799   switch (get_attr_type (insn))
2800     {
2801     case TYPE_SSELOG1:
2802       return standard_sse_constant_opcode (insn, operands);
2804     case TYPE_MSKMOV:
2805       return "kmovd\t{%1, %0|%0, %1}";
2807     case TYPE_MSKLOG:
2808       if (operands[1] == const0_rtx)
2809         return "kxord\t%0, %0, %0";
2810       else if (operands[1] == constm1_rtx)
2811         return "kxnord\t%0, %0, %0";
2812       gcc_unreachable ();
2814     case TYPE_SSEMOV:
2815       return ix86_output_ssemov (insn, operands);
2817     case TYPE_MMX:
2818       return "pxor\t%0, %0";
2820     case TYPE_MMXMOV:
2821       switch (get_attr_mode (insn))
2822         {
2823         case MODE_DI:
2824           return "movq\t{%1, %0|%0, %1}";
2825         case MODE_SI:
2826           return "movd\t{%1, %0|%0, %1}";
2828         default:
2829           gcc_unreachable ();
2830         }
2832     case TYPE_LEA:
2833       return "lea{l}\t{%E1, %0|%0, %E1}";
2835     case TYPE_IMOV:
2836       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2837       if (ix86_use_lea_for_mov (insn, operands))
2838         return "lea{l}\t{%E1, %0|%0, %E1}";
2839       else
2840         return "mov{l}\t{%1, %0|%0, %1}";
2842     default:
2843       gcc_unreachable ();
2844     }
2846   [(set (attr "isa")
2847      (cond [(eq_attr "alternative" "12,13")
2848               (const_string "sse2")
2849            ]
2850            (const_string "*")))
2851    (set (attr "type")
2852      (cond [(eq_attr "alternative" "2")
2853               (const_string "mmx")
2854             (eq_attr "alternative" "3,4,5,6,7")
2855               (const_string "mmxmov")
2856             (eq_attr "alternative" "8")
2857               (const_string "sselog1")
2858             (eq_attr "alternative" "9,10,11,12,13")
2859               (const_string "ssemov")
2860             (eq_attr "alternative" "14,15,16")
2861               (const_string "mskmov")
2862             (eq_attr "alternative" "17")
2863               (const_string "msklog")
2864             (and (match_operand 0 "register_operand")
2865                  (match_operand 1 "pic_32bit_operand"))
2866               (const_string "lea")
2867            ]
2868            (const_string "imov")))
2869    (set (attr "prefix")
2870      (if_then_else (eq_attr "type" "sselog1,ssemov")
2871        (const_string "maybe_vex")
2872        (const_string "orig")))
2873    (set (attr "prefix_data16")
2874      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2875        (const_string "1")
2876        (const_string "*")))
2877    (set (attr "mode")
2878      (cond [(eq_attr "alternative" "2,3")
2879               (const_string "DI")
2880             (eq_attr "alternative" "8")
2881               (cond [(match_test "TARGET_AVX")
2882                        (const_string "TI")
2883                      (ior (not (match_test "TARGET_SSE2"))
2884                           (match_test "optimize_function_for_size_p (cfun)"))
2885                        (const_string "V4SF")
2886                     ]
2887                     (const_string "TI"))
2888             (eq_attr "alternative" "9")
2889               (cond [(match_test "TARGET_AVX512VL")
2890                        (const_string "TI")
2891                      (match_test "TARGET_AVX512F")
2892                        (const_string "SF")
2893                      (match_test "TARGET_AVX")
2894                        (const_string "TI")
2895                      (ior (not (match_test "TARGET_SSE2"))
2896                           (match_test "optimize_function_for_size_p (cfun)"))
2897                        (const_string "V4SF")
2898                     ]
2899                     (const_string "TI"))
2901             (and (eq_attr "alternative" "10,11")
2902                  (not (match_test "TARGET_SSE2")))
2903               (const_string "SF")
2904            ]
2905            (const_string "SI")))
2906    (set (attr "preferred_for_speed")
2907      (cond [(eq_attr "alternative" "6,12")
2908               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2909             (eq_attr "alternative" "7,13")
2910               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2911            ]
2912            (symbol_ref "true")))])
2914 ;; With -Oz, transform mov $imm,reg to the shorter push $imm; pop reg.
2915 (define_peephole2
2916   [(set (match_operand:SWI248 0 "general_reg_operand")
2917         (match_operand:SWI248 1 "const_int_operand"))]
2918   "optimize_insn_for_size_p () && optimize_size > 1
2919    && operands[1] != const0_rtx
2920    && IN_RANGE (INTVAL (operands[1]), -128, 127)
2921    && !ix86_red_zone_used
2922    && REGNO (operands[0]) != SP_REG"
2923   [(set (match_dup 2) (match_dup 1))
2924    (set (match_dup 0) (match_dup 3))]
2926   if (GET_MODE (operands[0]) != word_mode)
2927     operands[0] = gen_rtx_REG (word_mode, REGNO (operands[0]));
2929   operands[2] = gen_rtx_MEM (word_mode,
2930                              gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
2931   operands[3] = gen_rtx_MEM (word_mode,
2932                              gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2935 ;; With -Oz, transform mov $0,mem to the shorter and $0,mem.
2936 ;; Likewise, transform mov $-1,mem to the shorter or $-1,mem.
2937 (define_peephole2
2938   [(set (match_operand:SWI248 0 "memory_operand")
2939         (match_operand:SWI248 1 "const_int_operand"))]
2940   "(operands[1] == const0_rtx || operands[1] == constm1_rtx)
2941    && optimize_insn_for_size_p () && optimize_size > 1
2942    && peep2_regno_dead_p (0, FLAGS_REG)"
2943   [(parallel [(set (match_dup 0) (match_dup 1))
2944               (clobber (reg:CC FLAGS_REG))])])
2946 (define_insn "*movhi_internal"
2947   [(set (match_operand:HI 0 "nonimmediate_operand"
2948     "=r,r,r,m ,*k,*k ,r ,m ,*k ,?r,?*v,*Yv,*v,*v,jm,m")
2949         (match_operand:HI 1 "general_operand"
2950     "r ,n,m,rn,r ,*km,*k,*k,CBC,*v,r  ,C  ,*v,m ,*x,*v"))]
2951   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2952    && ix86_hardreg_mov_ok (operands[0], operands[1])"
2954   switch (get_attr_type (insn))
2955     {
2956     case TYPE_IMOVX:
2957       /* movzwl is faster than movw on p2 due to partial word stalls,
2958          though not as fast as an aligned movl.  */
2959       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2961     case TYPE_MSKMOV:
2962       switch (which_alternative)
2963         {
2964         case 4:
2965           return "kmovw\t{%k1, %0|%0, %k1}";
2966         case 6:
2967           return "kmovw\t{%1, %k0|%k0, %1}";
2968         case 5:
2969         case 7:
2970           return "kmovw\t{%1, %0|%0, %1}";
2971         default:
2972           gcc_unreachable ();
2973         }
2975     case TYPE_SSEMOV:
2976       return ix86_output_ssemov (insn, operands);
2978     case TYPE_SSELOG1:
2979       if (satisfies_constraint_C (operands[1]))
2980         return standard_sse_constant_opcode (insn, operands);
2982       if (SSE_REG_P (operands[0]))
2983         return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
2984       else
2985         return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
2987     case TYPE_MSKLOG:
2988       if (operands[1] == const0_rtx)
2989         return "kxorw\t%0, %0, %0";
2990       else if (operands[1] == constm1_rtx)
2991         return "kxnorw\t%0, %0, %0";
2992       gcc_unreachable ();
2994     default:
2995       if (get_attr_mode (insn) == MODE_SI)
2996         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2997       else
2998         return "mov{w}\t{%1, %0|%0, %1}";
2999     }
3001   [(set (attr "isa")
3002         (cond [(eq_attr "alternative" "9,10,11,12,13")
3003                   (const_string "sse2")
3004                (eq_attr "alternative" "14")
3005                   (const_string "sse4_noavx")
3006                (eq_attr "alternative" "15")
3007                   (const_string "avx")
3008                ]
3009                (const_string "*")))
3010    (set (attr "addr")
3011         (if_then_else (eq_attr "alternative" "14")
3012                       (const_string "gpr16")
3013                       (const_string "*")))
3014    (set (attr "type")
3015      (cond [(eq_attr "alternative" "4,5,6,7")
3016               (const_string "mskmov")
3017             (eq_attr "alternative" "8")
3018               (const_string "msklog")
3019             (eq_attr "alternative" "13,14,15")
3020               (if_then_else (match_test "TARGET_AVX512FP16")
3021                 (const_string "ssemov")
3022                 (const_string "sselog1"))
3023             (eq_attr "alternative" "11")
3024               (const_string "sselog1")
3025             (eq_attr "alternative" "9,10,12")
3026               (const_string "ssemov")
3027             (match_test "optimize_function_for_size_p (cfun)")
3028               (const_string "imov")
3029             (and (eq_attr "alternative" "0")
3030                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
3031                       (not (match_test "TARGET_HIMODE_MATH"))))
3032               (const_string "imov")
3033             (and (eq_attr "alternative" "1,2")
3034                  (match_operand:HI 1 "aligned_operand"))
3035               (const_string "imov")
3036             (and (match_test "TARGET_MOVX")
3037                  (eq_attr "alternative" "0,2"))
3038               (const_string "imovx")
3039            ]
3040            (const_string "imov")))
3041    (set (attr "prefix")
3042         (cond [(eq_attr "alternative" "4,5,6,7,8")
3043                  (const_string "vex")
3044                (eq_attr "alternative" "9,10,11,12,13,14,15")
3045                  (const_string "maybe_evex")
3046               ]
3047               (const_string "orig")))
3048    (set (attr "mode")
3049      (cond [(eq_attr "alternative" "9,10")
3050               (if_then_else (match_test "TARGET_AVX512FP16")
3051                 (const_string "HI")
3052                 (const_string "SI"))
3053             (eq_attr "alternative" "13,14,15")
3054               (if_then_else (match_test "TARGET_AVX512FP16")
3055                 (const_string "HI")
3056                 (const_string "TI"))
3057             (eq_attr "alternative" "11")
3058               (cond [(match_test "TARGET_AVX")
3059                        (const_string "TI")
3060                      (ior (not (match_test "TARGET_SSE2"))
3061                           (match_test "optimize_function_for_size_p (cfun)"))
3062                        (const_string "V4SF")
3063                     ]
3064                     (const_string "TI"))
3065             (eq_attr "alternative" "12")
3066               (cond [(match_test "TARGET_AVX512VL")
3067                        (const_string "TI")
3068                      (match_test "TARGET_AVX512FP16")
3069                        (const_string "HF")
3070                      (match_test "TARGET_AVX512F")
3071                        (const_string "SF")
3072                      (match_test "TARGET_AVX")
3073                        (const_string "TI")
3074                      (ior (not (match_test "TARGET_SSE2"))
3075                           (match_test "optimize_function_for_size_p (cfun)"))
3076                        (const_string "V4SF")
3077                     ]
3078                     (const_string "TI"))
3079             (eq_attr "type" "imovx")
3080               (const_string "SI")
3081             (and (eq_attr "alternative" "1,2")
3082                  (match_operand:HI 1 "aligned_operand"))
3083               (const_string "SI")
3084             (and (eq_attr "alternative" "0")
3085                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
3086                       (not (match_test "TARGET_HIMODE_MATH"))))
3087               (const_string "SI")
3088             ]
3089             (const_string "HI")))
3090    (set (attr "preferred_for_speed")
3091      (cond [(eq_attr "alternative" "9")
3092               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3093             (eq_attr "alternative" "10")
3094               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3095            ]
3096            (symbol_ref "true")))])
3098 ;; Situation is quite tricky about when to choose full sized (SImode) move
3099 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
3100 ;; partial register dependency machines (such as AMD Athlon), where QImode
3101 ;; moves issue extra dependency and for partial register stalls machines
3102 ;; that don't use QImode patterns (and QImode move cause stall on the next
3103 ;; instruction).
3105 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
3106 ;; register stall machines with, where we use QImode instructions, since
3107 ;; partial register stall can be caused there.  Then we use movzx.
3109 (define_insn "*movqi_internal"
3110   [(set (match_operand:QI 0 "nonimmediate_operand"
3111                         "=Q,R,r,q,q,r,r ,?r,m ,*k,*k,*r,*m,*k,*k,*k")
3112         (match_operand:QI 1 "general_operand"
3113                         "Q ,R,r,n,m,q,rn, m,qn,*r,*k,*k,*k,*m,C,BC"))]
3114   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3115    && ix86_hardreg_mov_ok (operands[0], operands[1])"
3118   char buf[128];
3119   const char *ops;
3120   const char *suffix;
3122   switch (get_attr_type (insn))
3123     {
3124     case TYPE_IMOVX:
3125       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
3126       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
3128     case TYPE_MSKMOV:
3129       switch (which_alternative)
3130         {
3131         case 9:
3132           ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
3133           break;
3134         case 11:
3135           ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
3136           break;
3137         case 12:
3138         case 13:
3139           gcc_assert (TARGET_AVX512DQ);
3140           /* FALLTHRU */
3141         case 10:
3142           ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
3143           break;
3144         default:
3145           gcc_unreachable ();
3146         }
3148       suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
3150       snprintf (buf, sizeof (buf), ops, suffix);
3151       output_asm_insn (buf, operands);
3152       return "";
3154     case TYPE_MSKLOG:
3155       if (operands[1] == const0_rtx)
3156         {
3157           if (get_attr_mode (insn) == MODE_HI)
3158             return "kxorw\t%0, %0, %0";
3159           else
3160             return "kxorb\t%0, %0, %0";
3161         }
3162       else if (operands[1] == constm1_rtx)
3163         {
3164           gcc_assert (TARGET_AVX512DQ);
3165           return "kxnorb\t%0, %0, %0";
3166         }
3167       gcc_unreachable ();
3169     default:
3170       if (get_attr_mode (insn) == MODE_SI)
3171         return "mov{l}\t{%k1, %k0|%k0, %k1}";
3172       else
3173         return "mov{b}\t{%1, %0|%0, %1}";
3174     }
3176   [(set (attr "isa")
3177      (cond [(eq_attr "alternative" "1,2")
3178               (const_string "x64")
3179             (eq_attr "alternative" "12,13,15")
3180               (const_string "avx512dq")
3181            ]
3182            (const_string "*")))
3183    (set (attr "type")
3184      (cond [(eq_attr "alternative" "9,10,11,12,13")
3185               (const_string "mskmov")
3186             (eq_attr "alternative" "14,15")
3187               (const_string "msklog")
3188             (and (eq_attr "alternative" "7")
3189                  (not (match_operand:QI 1 "aligned_operand")))
3190               (const_string "imovx")
3191             (match_test "optimize_function_for_size_p (cfun)")
3192               (const_string "imov")
3193             (and (eq_attr "alternative" "5")
3194                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
3195                       (not (match_test "TARGET_QIMODE_MATH"))))
3196               (const_string "imov")
3197             (eq_attr "alternative" "5,7")
3198               (const_string "imovx")
3199             (and (match_test "TARGET_MOVX")
3200                  (eq_attr "alternative" "4"))
3201               (const_string "imovx")
3202            ]
3203            (const_string "imov")))
3204    (set (attr "prefix")
3205      (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15")
3206        (const_string "vex")
3207        (const_string "orig")))
3208    (set (attr "mode")
3209       (cond [(eq_attr "alternative" "5,6,7")
3210                (const_string "SI")
3211              (eq_attr "alternative" "8")
3212                (const_string "QI")
3213              (and (eq_attr "alternative" "9,10,11,14")
3214                   (not (match_test "TARGET_AVX512DQ")))
3215                (const_string "HI")
3216              (eq_attr "type" "imovx")
3217                (const_string "SI")
3218              ;; For -Os, 8-bit immediates are always shorter than 32-bit
3219              ;; ones.
3220              (and (eq_attr "type" "imov")
3221                   (and (eq_attr "alternative" "3")
3222                        (match_test "optimize_function_for_size_p (cfun)")))
3223                (const_string "QI")
3224              ;; For -Os, movl where one or both operands are NON_Q_REGS
3225              ;; and both are LEGACY_REGS is shorter than movb.
3226              ;; Otherwise movb and movl sizes are the same, so decide purely
3227              ;; based on speed factors.
3228              (and (eq_attr "type" "imov")
3229                   (and (eq_attr "alternative" "1")
3230                        (match_test "optimize_function_for_size_p (cfun)")))
3231                (const_string "SI")
3232              (and (eq_attr "type" "imov")
3233                   (and (eq_attr "alternative" "0,1,2,3")
3234                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
3235                             (not (match_test "TARGET_PARTIAL_REG_STALL")))))
3236                (const_string "SI")
3237              ;; Avoid partial register stalls when not using QImode arithmetic
3238              (and (eq_attr "type" "imov")
3239                   (and (eq_attr "alternative" "0,1,2,3")
3240                        (and (match_test "TARGET_PARTIAL_REG_STALL")
3241                             (not (match_test "TARGET_QIMODE_MATH")))))
3242                (const_string "SI")
3243            ]
3244            (const_string "QI")))])
3246 /* Reload dislikes loading 0/-1 directly into mask registers.
3247    Try to tidy things up here.  */
3248 (define_peephole2
3249   [(set (match_operand:SWI 0 "general_reg_operand")
3250         (match_operand:SWI 1 "immediate_operand"))
3251    (set (match_operand:SWI 2 "mask_reg_operand")
3252         (match_dup 0))]
3253   "peep2_reg_dead_p (2, operands[0])
3254    && (const0_operand (operands[1], <MODE>mode)
3255        || (constm1_operand (operands[1], <MODE>mode)
3256            && (<MODE_SIZE> > 1 || TARGET_AVX512DQ)))"
3257   [(set (match_dup 2) (match_dup 1))])
3259 ;; Stores and loads of ax to arbitrary constant address.
3260 ;; We fake an second form of instruction to force reload to load address
3261 ;; into register when rax is not available
3262 (define_insn "*movabs<mode>_1"
3263   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
3264         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
3265   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
3267   /* Recover the full memory rtx.  */
3268   operands[0] = SET_DEST (PATTERN (insn));
3269   switch (which_alternative)
3270     {
3271     case 0:
3272       return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
3273     case 1:
3274       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3275     default:
3276       gcc_unreachable ();
3277     }
3279   [(set_attr "type" "imov")
3280    (set_attr "modrm" "0,*")
3281    (set_attr "length_address" "8,0")
3282    (set_attr "length_immediate" "0,*")
3283    (set_attr "memory" "store")
3284    (set_attr "mode" "<MODE>")])
3286 (define_insn "*movabs<mode>_2"
3287   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
3288         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
3289   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
3291   /* Recover the full memory rtx.  */
3292   operands[1] = SET_SRC (PATTERN (insn));
3293   switch (which_alternative)
3294     {
3295     case 0:
3296       return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
3297     case 1:
3298       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3299     default:
3300       gcc_unreachable ();
3301     }
3303   [(set_attr "type" "imov")
3304    (set_attr "modrm" "0,*")
3305    (set_attr "length_address" "8,0")
3306    (set_attr "length_immediate" "0")
3307    (set_attr "memory" "load")
3308    (set_attr "mode" "<MODE>")])
3310 (define_insn "swap<mode>"
3311   [(set (match_operand:SWI48 0 "register_operand" "+r")
3312         (match_operand:SWI48 1 "register_operand" "+r"))
3313    (set (match_dup 1)
3314         (match_dup 0))]
3315   ""
3316   "xchg{<imodesuffix>}\t%1, %0"
3317   [(set_attr "type" "imov")
3318    (set_attr "mode" "<MODE>")
3319    (set_attr "pent_pair" "np")
3320    (set_attr "athlon_decode" "vector")
3321    (set_attr "amdfam10_decode" "double")
3322    (set_attr "bdver1_decode" "double")])
3324 (define_insn "*swap<mode>"
3325   [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
3326         (match_operand:SWI12 1 "register_operand" "+<r>,r"))
3327    (set (match_dup 1)
3328         (match_dup 0))]
3329   ""
3330   "@
3331    xchg{<imodesuffix>}\t%1, %0
3332    xchg{l}\t%k1, %k0"
3333   [(set_attr "type" "imov")
3334    (set_attr "mode" "<MODE>,SI")
3335    (set (attr "preferred_for_size")
3336      (cond [(eq_attr "alternative" "0")
3337               (symbol_ref "false")]
3338            (symbol_ref "true")))
3339    ;; Potential partial reg stall on alternative 1.
3340    (set (attr "preferred_for_speed")
3341      (cond [(eq_attr "alternative" "1")
3342               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
3343            (symbol_ref "true")))
3344    (set_attr "pent_pair" "np")
3345    (set_attr "athlon_decode" "vector")
3346    (set_attr "amdfam10_decode" "double")
3347    (set_attr "bdver1_decode" "double")])
3349 (define_peephole2
3350   [(set (match_operand:SWI 0 "general_reg_operand")
3351         (match_operand:SWI 1 "general_reg_operand"))
3352    (set (match_dup 1)
3353         (match_operand:SWI 2 "general_reg_operand"))
3354    (set (match_dup 2) (match_dup 0))]
3355   "peep2_reg_dead_p (3, operands[0])
3356    && optimize_insn_for_size_p ()"
3357   [(parallel [(set (match_dup 1) (match_dup 2))
3358               (set (match_dup 2) (match_dup 1))])])
3360 ;; Convert xchg with a REG_UNUSED note to a mov (variant #1).
3361 (define_peephole2
3362   [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3363                    (match_operand:SWI 1 "general_reg_operand"))
3364               (set (match_dup 1) (match_dup 0))])]
3365   "((REGNO (operands[0]) != AX_REG
3366      && REGNO (operands[1]) != AX_REG)
3367     || optimize_size < 2
3368     || !optimize_insn_for_size_p ())
3369    && peep2_reg_dead_p (1, operands[0])"
3370   [(set (match_dup 1) (match_dup 0))])
3372 ;; Convert xchg with a REG_UNUSED note to a mov (variant #2).
3373 (define_peephole2
3374   [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3375                    (match_operand:SWI 1 "general_reg_operand"))
3376               (set (match_dup 1) (match_dup 0))])]
3377   "((REGNO (operands[0]) != AX_REG
3378      && REGNO (operands[1]) != AX_REG)
3379     || optimize_size < 2
3380     || !optimize_insn_for_size_p ())
3381    && peep2_reg_dead_p (1, operands[1])"
3382   [(set (match_dup 0) (match_dup 1))])
3384 ;; Convert moves to/from AX_REG into xchg with -Oz.
3385 (define_peephole2
3386   [(set (match_operand:SWI48 0 "general_reg_operand")
3387         (match_operand:SWI48 1 "general_reg_operand"))]
3388  "optimize_size > 1
3389   && ((REGNO (operands[0]) == AX_REG)
3390       != (REGNO (operands[1]) == AX_REG))
3391   && optimize_insn_for_size_p ()
3392   && peep2_reg_dead_p (1, operands[1])"
3393   [(parallel [(set (match_dup 0) (match_dup 1))
3394               (set (match_dup 1) (match_dup 0))])])
3396 (define_expand "movstrict<mode>"
3397   [(set (strict_low_part (match_operand:SWI12 0 "register_operand"))
3398         (match_operand:SWI12 1 "general_operand"))]
3399   ""
3401   gcc_assert (SUBREG_P (operands[0]));
3402   if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
3403       || !VALID_INT_MODE_P (GET_MODE (SUBREG_REG (operands[0]))))
3404     FAIL;
3407 (define_insn "*movstrict<mode>_1"
3408   [(set (strict_low_part
3409           (match_operand:SWI12 0 "register_operand" "+<r>"))
3410         (match_operand:SWI12 1 "general_operand" "<r>mn"))]
3411   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
3412   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
3413   [(set_attr "type" "imov")
3414    (set_attr "mode" "<MODE>")])
3416 (define_insn "*movstrict<mode>_xor"
3417   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
3418         (match_operand:SWI12 1 "const0_operand"))
3419    (clobber (reg:CC FLAGS_REG))]
3420   "reload_completed"
3421   "xor{<imodesuffix>}\t%0, %0"
3422   [(set_attr "type" "alu1")
3423    (set_attr "mode" "<MODE>")
3424    (set_attr "length_immediate" "0")])
3426 (define_insn "*movstrictqi_ext<mode>_1"
3427   [(set (strict_low_part
3428           (match_operand:QI 0 "register_operand" "+Q"))
3429           (subreg:QI
3430             (match_operator:SWI248 2 "extract_operator"
3431               [(match_operand 1 "int248_register_operand" "Q")
3432                (const_int 8)
3433                (const_int 8)]) 0))]
3434   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
3435   "mov{b}\t{%h1, %0|%0, %h1}"
3436   [(set_attr "type" "imov")
3437    (set_attr "mode" "QI")])
3439 (define_expand "extv<mode>"
3440   [(set (match_operand:SWI24 0 "register_operand")
3441         (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
3442                             (match_operand:QI 2 "const_int_operand")
3443                             (match_operand:QI 3 "const_int_operand")))]
3444   ""
3446   /* Handle extractions from %ah et al.  */
3447   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3448     FAIL;
3450   unsigned int regno = reg_or_subregno (operands[1]);
3452   /* Be careful to expand only with registers having upper parts.  */
3453   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3454     operands[1] = copy_to_reg (operands[1]);
3457 (define_insn "*extv<mode>"
3458   [(set (match_operand:SWI24 0 "register_operand" "=R")
3459         (sign_extract:SWI24 (match_operand 1 "int248_register_operand" "Q")
3460                             (const_int 8)
3461                             (const_int 8)))]
3462   ""
3463   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
3464   [(set_attr "type" "imovx")
3465    (set_attr "mode" "SI")])
3467 ;; Split sign-extension of single least significant bit as and x,$1;neg x
3468 (define_insn_and_split "*extv<mode>_1_0"
3469   [(set (match_operand:SWI48 0 "register_operand" "=r")
3470         (sign_extract:SWI48 (match_operand:SWI48 1 "register_operand" "0")
3471                             (const_int 1)
3472                             (const_int 0)))
3473    (clobber (reg:CC FLAGS_REG))]
3474   ""
3475   "#"
3476   ""
3477   [(parallel [(set (match_dup 0) (and:SWI48 (match_dup 1) (const_int 1)))
3478               (clobber (reg:CC FLAGS_REG))])
3479    (parallel [(set (match_dup 0) (neg:SWI48 (match_dup 0)))
3480               (clobber (reg:CC FLAGS_REG))])])
3482 (define_expand "extzv<mode>"
3483   [(set (match_operand:SWI248 0 "register_operand")
3484         (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
3485                              (match_operand:QI 2 "const_int_operand")
3486                              (match_operand:QI 3 "const_int_operand")))]
3487   ""
3489   if (ix86_expand_pextr (operands))
3490     DONE;
3492   /* Handle extractions from %ah et al.  */
3493   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3494     FAIL;
3496   unsigned int regno = reg_or_subregno (operands[1]);
3498   /* Be careful to expand only with registers having upper parts.  */
3499   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3500     operands[1] = copy_to_reg (operands[1]);
3503 (define_insn "*extzv<mode>"
3504   [(set (match_operand:SWI248 0 "register_operand" "=R")
3505         (zero_extract:SWI248 (match_operand 1 "int248_register_operand" "Q")
3506                              (const_int 8)
3507                              (const_int 8)))]
3508   ""
3509   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
3510   [(set_attr "type" "imovx")
3511    (set_attr "mode" "SI")])
3513 (define_insn "*extzvqi"
3514   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn,?R")
3515         (subreg:QI
3516           (match_operator:SWI248 2 "extract_operator"
3517             [(match_operand 1 "int248_register_operand" "Q,Q")
3518              (const_int 8)
3519              (const_int 8)]) 0))]
3520   ""
3522   switch (get_attr_type (insn))
3523     {
3524     case TYPE_IMOVX:
3525       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
3526     default:
3527       return "mov{b}\t{%h1, %0|%0, %h1}";
3528     }
3530   [(set_attr "addr" "gpr8,*")
3531    (set (attr "type")
3532      (if_then_else (and (match_operand:QI 0 "register_operand")
3533                         (ior (not (match_operand:QI 0 "QIreg_operand"))
3534                              (match_test "TARGET_MOVX")))
3535         (const_string "imovx")
3536         (const_string "imov")))
3537    (set (attr "mode")
3538      (if_then_else (eq_attr "type" "imovx")
3539         (const_string "SI")
3540         (const_string "QI")))])
3542 (define_expand "insv<mode>"
3543   [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3544                              (match_operand:QI 1 "const_int_operand")
3545                              (match_operand:QI 2 "const_int_operand"))
3546         (match_operand:SWI248 3 "register_operand"))]
3547   ""
3549   rtx dst;
3551   if (ix86_expand_pinsr (operands))
3552     DONE;
3554   /* Handle insertions to %ah et al.  */
3555   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3556     FAIL;
3558   unsigned int regno = reg_or_subregno (operands[0]);
3560   /* Be careful to expand only with registers having upper parts.  */
3561   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3562     dst = copy_to_reg (operands[0]);
3563   else
3564     dst = operands[0];
3566   emit_insn (gen_insv_1 (<MODE>mode, dst, operands[3]));
3568   /* Fix up the destination if needed.  */
3569   if (dst != operands[0])
3570     emit_move_insn (operands[0], dst);
3572   DONE;
3575 (define_insn "@insv<mode>_1"
3576   [(set (zero_extract:SWI248
3577           (match_operand 0 "int248_register_operand" "+Q")
3578           (const_int 8)
3579           (const_int 8))
3580         (match_operand:SWI248 1 "general_operand" "QnBn"))]
3581   ""
3583   if (CONST_INT_P (operands[1]))
3584     operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3585   return "mov{b}\t{%b1, %h0|%h0, %b1}";
3587   [(set_attr "addr" "gpr8")
3588    (set_attr "type" "imov")
3589    (set_attr "mode" "QI")])
3591 (define_insn "*insvqi_1"
3592   [(set (zero_extract:SWI248
3593           (match_operand 0 "int248_register_operand" "+Q")
3594           (const_int 8)
3595           (const_int 8))
3596         (subreg:SWI248
3597           (match_operand:QI 1 "general_operand" "QnBn") 0))]
3598   ""
3599   "mov{b}\t{%1, %h0|%h0, %1}"
3600   [(set_attr "addr" "gpr8")
3601    (set_attr "type" "imov")
3602    (set_attr "mode" "QI")])
3604 ;; Eliminate redundant insv, e.g. xorl %eax,%eax; movb $0, %ah
3605 (define_peephole2
3606   [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3607                    (const_int 0))
3608               (clobber (reg:CC FLAGS_REG))])
3609    (set (zero_extract:SWI248 (match_operand 1 "int248_register_operand")
3610                              (const_int 8)
3611                              (const_int 8))
3612         (const_int 0))]
3613   "REGNO (operands[0]) == REGNO (operands[1])"
3614   [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3615                    (const_int 0))
3616               (clobber (reg:CC FLAGS_REG))])])
3618 ;; Combine movl followed by movb.
3619 (define_peephole2
3620   [(set (match_operand:SWI48 0 "general_reg_operand")
3621         (match_operand:SWI48 1 "const_int_operand"))
3622    (set (zero_extract:SWI248 (match_operand 2 "int248_register_operand")
3623                              (const_int 8)
3624                              (const_int 8))
3625         (match_operand:SWI248 3 "const_int_operand"))]
3626   "REGNO (operands[0]) == REGNO (operands[2])"
3627   [(set (match_operand:SWI48 0 "general_reg_operand")
3628         (match_dup 4))]
3630   HOST_WIDE_INT tmp = INTVAL (operands[1]) & ~HOST_WIDE_INT_C (0xff00);
3631   tmp |= (INTVAL (operands[3]) & 0xff) << 8;
3632   operands[4] = gen_int_mode (tmp, <SWI48:MODE>mode);
3635 (define_insn "*insvqi_2"
3636   [(set (zero_extract:SWI248
3637           (match_operand 0 "int248_register_operand" "+Q")
3638           (const_int 8)
3639           (const_int 8))
3640         (match_operator:SWI248 2 "extract_operator"
3641           [(match_operand 1 "int248_register_operand" "Q")
3642            (const_int 8)
3643            (const_int 8)]))]
3644   ""
3645   "mov{b}\t{%h1, %h0|%h0, %h1}"
3646   [(set_attr "type" "imov")
3647    (set_attr "mode" "QI")])
3649 (define_insn "*insvqi_3"
3650   [(set (zero_extract:SWI248
3651           (match_operand 0 "int248_register_operand" "+Q")
3652           (const_int 8)
3653           (const_int 8))
3654         (any_shiftrt:SWI248
3655           (match_operand:SWI248 1 "register_operand" "Q")
3656           (const_int 8)))]
3657   ""
3658   "mov{b}\t{%h1, %h0|%h0, %h1}"
3659   [(set_attr "type" "imov")
3660    (set_attr "mode" "QI")])
3662 (define_code_iterator any_or_plus [plus ior xor])
3664 (define_insn_and_split "*insvti_highpart_1"
3665   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3666         (any_or_plus:TI
3667           (and:TI
3668             (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3669             (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3670           (ashift:TI
3671             (zero_extend:TI
3672               (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))
3673             (const_int 64))))]
3674   "TARGET_64BIT
3675    && CONST_WIDE_INT_P (operands[3])
3676    && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3677    && CONST_WIDE_INT_ELT (operands[3], 0) == -1
3678    && CONST_WIDE_INT_ELT (operands[3], 1) == 0"
3679   "#"
3680   "&& reload_completed"
3681   [(const_int 0)]
3683   operands[4] = gen_lowpart (DImode, operands[1]);
3684   split_double_concat (TImode, operands[0], operands[4], operands[2]);
3685   DONE;
3688 (define_insn_and_split "*insvti_lowpart_1"
3689   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3690         (any_or_plus:TI
3691           (and:TI
3692             (match_operand:TI 1 "nonimmediate_operand" "r,o,r,o")
3693             (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3694           (zero_extend:TI
3695             (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))))]
3696   "TARGET_64BIT
3697    && CONST_WIDE_INT_P (operands[3])
3698    && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3699    && CONST_WIDE_INT_ELT (operands[3], 0) == 0
3700    && CONST_WIDE_INT_ELT (operands[3], 1) == -1"
3701   "#"
3702   "&& reload_completed"
3703   [(const_int 0)]
3705   operands[4] = gen_highpart (DImode, operands[1]);
3706   split_double_concat (TImode, operands[0], operands[2], operands[4]);
3707   DONE;
3710 (define_insn_and_split "*insvdi_lowpart_1"
3711   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,r,r,&r")
3712         (any_or_plus:DI
3713           (and:DI
3714             (match_operand:DI 1 "nonimmediate_operand" "r,o,r,o")
3715             (match_operand:DI 3 "const_int_operand" "n,n,n,n"))
3716           (zero_extend:DI
3717             (match_operand:SI 2 "nonimmediate_operand" "r,r,m,m"))))]
3718   "!TARGET_64BIT
3719    && CONST_INT_P (operands[3])
3720    && UINTVAL (operands[3]) == 0xffffffff00000000ll"
3721   "#"
3722   "&& reload_completed"
3723   [(const_int 0)]
3725   operands[4] = gen_highpart (SImode, operands[1]);
3726   split_double_concat (DImode, operands[0], operands[2], operands[4]);
3727   DONE;
3730 ;; Floating point push instructions.
3732 (define_insn "*pushtf"
3733   [(set (match_operand:TF 0 "push_operand" "=<,<")
3734         (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3735   "TARGET_64BIT || TARGET_SSE"
3737   /* This insn should be already split before reg-stack.  */
3738   return "#";
3740   [(set_attr "isa" "*,x64")
3741    (set_attr "type" "multi")
3742    (set_attr "unit" "sse,*")
3743    (set_attr "mode" "TF,DI")])
3745 ;; %%% Kill this when call knows how to work this out.
3746 (define_split
3747   [(set (match_operand:TF 0 "push_operand")
3748         (match_operand:TF 1 "sse_reg_operand"))]
3749   "TARGET_SSE && reload_completed"
3750   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3751    (set (match_dup 0) (match_dup 1))]
3753   /* Preserve memory attributes. */
3754   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3757 (define_insn "*pushxf"
3758   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3759         (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3760   ""
3762   /* This insn should be already split before reg-stack.  */
3763   return "#";
3765   [(set_attr "isa" "*,*,*,nox64,x64")
3766    (set_attr "type" "multi")
3767    (set_attr "unit" "i387,*,*,*,*")
3768    (set (attr "mode")
3769         (cond [(eq_attr "alternative" "1,2,3,4")
3770                  (if_then_else (match_test "TARGET_64BIT")
3771                    (const_string "DI")
3772                    (const_string "SI"))
3773               ]
3774               (const_string "XF")))
3775    (set (attr "preferred_for_size")
3776      (cond [(eq_attr "alternative" "1")
3777               (symbol_ref "false")]
3778            (symbol_ref "true")))])
3780 ;; %%% Kill this when call knows how to work this out.
3781 (define_split
3782   [(set (match_operand:XF 0 "push_operand")
3783         (match_operand:XF 1 "fp_register_operand"))]
3784   "reload_completed"
3785   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3786    (set (match_dup 0) (match_dup 1))]
3788   operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3789   /* Preserve memory attributes. */
3790   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3793 (define_insn "*pushdf"
3794   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3795         (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,v"))]
3796   ""
3798   /* This insn should be already split before reg-stack.  */
3799   return "#";
3801   [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3802    (set_attr "type" "multi")
3803    (set_attr "unit" "i387,*,*,*,*,sse")
3804    (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3805    (set (attr "preferred_for_size")
3806      (cond [(eq_attr "alternative" "1")
3807               (symbol_ref "false")]
3808            (symbol_ref "true")))
3809    (set (attr "preferred_for_speed")
3810      (cond [(eq_attr "alternative" "1")
3811               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3812            (symbol_ref "true")))])
3813    
3814 ;; %%% Kill this when call knows how to work this out.
3815 (define_split
3816   [(set (match_operand:DF 0 "push_operand")
3817         (match_operand:DF 1 "any_fp_register_operand"))]
3818   "reload_completed"
3819   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3820    (set (match_dup 0) (match_dup 1))]
3822   /* Preserve memory attributes. */
3823   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3826 (define_mode_iterator HFBF [HF BF])
3828 (define_insn "*push<mode>_rex64"
3829   [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3830         (match_operand:HFBF 1 "nonmemory_no_elim_operand" "r,x"))]
3831   "TARGET_64BIT"
3833   /* Anything else should be already split before reg-stack.  */
3834   gcc_assert (which_alternative == 0);
3835   return "push{q}\t%q1";
3837   [(set_attr "isa"  "*,sse4")
3838    (set_attr "type" "push,multi")
3839    (set_attr "mode" "DI,TI")])
3841 (define_insn "*push<mode>"
3842   [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3843         (match_operand:HFBF 1 "general_no_elim_operand" "rmF,x"))]
3844   "!TARGET_64BIT"
3846   /* Anything else should be already split before reg-stack.  */
3847   gcc_assert (which_alternative == 0);
3848   return "push{l}\t%k1";
3850   [(set_attr "isa"  "*,sse4")
3851    (set_attr "type" "push,multi")
3852    (set_attr "mode" "SI,TI")])
3854 (define_insn "push2_di"
3855   [(set (match_operand:TI 0 "push_operand" "=<")
3856         (unspec:TI [(match_operand:DI 1 "register_operand" "r")
3857                     (match_operand:DI 2 "register_operand" "r")]
3858                     UNSPEC_APXPUSH2))]
3859   "TARGET_APX_PUSH2POP2"
3860   "push2\t{%2, %1|%1, %2}"
3861   [(set_attr "mode" "TI")
3862    (set_attr "type" "multi")
3863    (set_attr "prefix" "evex")])
3865 (define_insn "pop2_di"
3866   [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3867                    (unspec:DI [(match_operand:TI 1 "pop_operand" ">")]
3868                               UNSPEC_APXPOP2_LOW))
3869               (set (match_operand:DI 2 "register_operand" "=r")
3870                    (unspec:DI [(const_int 0)] UNSPEC_APXPOP2_HIGH))])]
3871   "TARGET_APX_PUSH2POP2"
3872   "pop2\t{%2, %0|%0, %2}"
3873   [(set_attr "mode" "TI")
3874    (set_attr "prefix" "evex")])
3876 (define_insn "pushp_di"
3877   [(set (match_operand:DI 0 "push_operand" "=<")
3878         (match_operand:DI 1 "register_operand" "r"))
3879    (unspec:DI [(const_int 0)] UNSPEC_APX_PPX)]
3880   "TARGET_64BIT"
3881   "pushp\t%1"
3882   [(set_attr "mode" "DI")])
3884 (define_insn "popp_di"
3885   [(set (match_operand:DI 0 "register_operand" "=r")
3886         (match_operand:DI 1 "pop_operand" ">"))
3887    (unspec:DI [(const_int 0)] UNSPEC_APX_PPX)]
3888   "TARGET_APX_PPX"
3889   "popp\t%0"
3890   [(set_attr "mode" "DI")])
3892 (define_insn "push2p_di"
3893   [(set (match_operand:TI 0 "push_operand" "=<")
3894         (unspec:TI [(match_operand:DI 1 "register_operand" "r")
3895                     (match_operand:DI 2 "register_operand" "r")]
3896                     UNSPEC_APXPUSH2))
3897    (unspec:DI [(const_int 0)] UNSPEC_APX_PPX)]
3898   "TARGET_APX_PUSH2POP2 && TARGET_APX_PPX"
3899   "push2p\t{%2, %1|%1, %2}"
3900   [(set_attr "mode" "TI")
3901    (set_attr "type" "multi")
3902    (set_attr "prefix" "evex")])
3904 (define_insn "pop2p_di"
3905   [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3906                    (unspec:DI [(match_operand:TI 1 "pop_operand" ">")]
3907                               UNSPEC_APXPOP2_LOW))
3908               (set (match_operand:DI 2 "register_operand" "=r")
3909                    (unspec:DI [(const_int 0)] UNSPEC_APXPOP2_HIGH))
3910               (unspec:DI [(const_int 0)] UNSPEC_APX_PPX)])]
3911   "TARGET_APX_PUSH2POP2 && TARGET_APX_PPX"
3912   "pop2p\t{%2, %0|%0, %2}"
3913   [(set_attr "mode" "TI")
3914    (set_attr "prefix" "evex")])
3916 (define_insn "*pushsf_rex64"
3917   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3918         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,v"))]
3919   "TARGET_64BIT"
3921   /* Anything else should be already split before reg-stack.  */
3922   if (which_alternative != 1)
3923     return "#";
3924   return "push{q}\t%q1";
3926   [(set_attr "type" "multi,push,multi")
3927    (set_attr "unit" "i387,*,*")
3928    (set_attr "mode" "SF,DI,SF")])
3930 (define_insn "*pushsf"
3931   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3932         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,v"))]
3933   "!TARGET_64BIT"
3935   /* Anything else should be already split before reg-stack.  */
3936   if (which_alternative != 1)
3937     return "#";
3938   return "push{l}\t%1";
3940   [(set_attr "type" "multi,push,multi")
3941    (set_attr "unit" "i387,*,*")
3942    (set_attr "mode" "SF,SI,SF")])
3944 (define_mode_iterator MODESH [SF HF BF])
3945 ;; %%% Kill this when call knows how to work this out.
3946 (define_split
3947   [(set (match_operand:MODESH 0 "push_operand")
3948         (match_operand:MODESH 1 "any_fp_register_operand"))]
3949   "reload_completed"
3950   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3951    (set (match_dup 0) (match_dup 1))]
3953   rtx op = XEXP (operands[0], 0);
3954   if (GET_CODE (op) == PRE_DEC)
3955     {
3956       gcc_assert (!TARGET_64BIT);
3957       op = GEN_INT (-4);
3958     }
3959   else
3960     {
3961       op = XEXP (XEXP (op, 1), 1);
3962       gcc_assert (CONST_INT_P (op));
3963     }
3964   operands[2] = op;
3965   /* Preserve memory attributes. */
3966   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3969 (define_split
3970   [(set (match_operand:SF 0 "push_operand")
3971         (match_operand:SF 1 "memory_operand"))]
3972   "reload_completed
3973    && find_constant_src (insn)"
3974   [(set (match_dup 0) (match_dup 2))]
3975   "operands[2] = find_constant_src (curr_insn);")
3977 (define_split
3978   [(set (match_operand 0 "push_operand")
3979         (match_operand 1 "general_gr_operand"))]
3980   "reload_completed
3981    && (GET_MODE (operands[0]) == TFmode
3982        || GET_MODE (operands[0]) == XFmode
3983        || GET_MODE (operands[0]) == DFmode)"
3984   [(const_int 0)]
3985   "ix86_split_long_move (operands); DONE;")
3987 ;; Floating point move instructions.
3989 (define_expand "movtf"
3990   [(set (match_operand:TF 0 "nonimmediate_operand")
3991         (match_operand:TF 1 "nonimmediate_operand"))]
3992   "TARGET_64BIT || TARGET_SSE"
3993   "ix86_expand_move (TFmode, operands); DONE;")
3995 (define_expand "mov<mode>"
3996   [(set (match_operand:X87MODEFH 0 "nonimmediate_operand")
3997         (match_operand:X87MODEFH 1 "general_operand"))]
3998   ""
3999   "ix86_expand_move (<MODE>mode, operands); DONE;")
4001 (define_insn "*movtf_internal"
4002   [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
4003         (match_operand:TF 1 "general_operand"      "C ,vm,v,*roF,*rC"))]
4004   "(TARGET_64BIT || TARGET_SSE)
4005    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
4006    && (lra_in_progress || reload_completed
4007        || !CONST_DOUBLE_P (operands[1])
4008        || (standard_sse_constant_p (operands[1], TFmode) == 1
4009            && !memory_operand (operands[0], TFmode))
4010        || (!TARGET_MEMORY_MISMATCH_STALL
4011            && memory_operand (operands[0], TFmode)))"
4013   switch (get_attr_type (insn))
4014     {
4015     case TYPE_SSELOG1:
4016       return standard_sse_constant_opcode (insn, operands);
4018     case TYPE_SSEMOV:
4019       return ix86_output_ssemov (insn, operands);
4021     case TYPE_MULTI:
4022         return "#";
4024     default:
4025       gcc_unreachable ();
4026     }
4028   [(set_attr "isa" "*,*,*,x64,x64")
4029    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
4030    (set (attr "prefix")
4031      (if_then_else (eq_attr "type" "sselog1,ssemov")
4032        (const_string "maybe_vex")
4033        (const_string "orig")))
4034    (set (attr "mode")
4035         (cond [(eq_attr "alternative" "3,4")
4036                  (const_string "DI")
4037                (match_test "TARGET_AVX")
4038                  (const_string "TI")
4039                (ior (not (match_test "TARGET_SSE2"))
4040                     (match_test "optimize_function_for_size_p (cfun)"))
4041                  (const_string "V4SF")
4042                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
4043                  (const_string "V4SF")
4044                (and (eq_attr "alternative" "2")
4045                     (match_test "TARGET_SSE_TYPELESS_STORES"))
4046                  (const_string "V4SF")
4047                ]
4048                (const_string "TI")))])
4050 (define_split
4051   [(set (match_operand:TF 0 "nonimmediate_gr_operand")
4052         (match_operand:TF 1 "general_gr_operand"))]
4053   "reload_completed"
4054   [(const_int 0)]
4055   "ix86_split_long_move (operands); DONE;")
4057 ;; Possible store forwarding (partial memory) stall
4058 ;; in alternatives 4, 6, 7 and 8.
4059 (define_insn "*movxf_internal"
4060   [(set (match_operand:XF 0 "nonimmediate_operand"
4061          "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r  ,o ,o")
4062         (match_operand:XF 1 "general_operand"
4063          "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
4064   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4065    && (lra_in_progress || reload_completed
4066        || !CONST_DOUBLE_P (operands[1])
4067        || ((optimize_function_for_size_p (cfun)
4068             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4069            && standard_80387_constant_p (operands[1]) > 0
4070            && !memory_operand (operands[0], XFmode))
4071        || (!TARGET_MEMORY_MISMATCH_STALL
4072            && memory_operand (operands[0], XFmode))
4073        || !TARGET_HARD_XF_REGS)"
4075   switch (get_attr_type (insn))
4076     {
4077     case TYPE_FMOV:
4078       if (which_alternative == 2)
4079         return standard_80387_constant_opcode (operands[1]);
4080       return output_387_reg_move (insn, operands);
4082     case TYPE_MULTI:
4083       return "#";
4085     default:
4086       gcc_unreachable ();
4087     }
4089   [(set (attr "isa")
4090         (cond [(eq_attr "alternative" "7,10")
4091                  (const_string "nox64")
4092                (eq_attr "alternative" "8,11")
4093                  (const_string "x64")
4094               ]
4095               (const_string "*")))
4096    (set (attr "type")
4097         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
4098                  (const_string "multi")
4099               ]
4100               (const_string "fmov")))
4101    (set (attr "mode")
4102         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
4103                  (if_then_else (match_test "TARGET_64BIT")
4104                    (const_string "DI")
4105                    (const_string "SI"))
4106               ]
4107               (const_string "XF")))
4108    (set (attr "preferred_for_size")
4109      (cond [(eq_attr "alternative" "3,4")
4110               (symbol_ref "false")]
4111            (symbol_ref "true")))
4112    (set (attr "enabled")
4113      (cond [(eq_attr "alternative" "9,10,11")
4114               (if_then_else
4115                 (match_test "TARGET_HARD_XF_REGS")
4116                 (symbol_ref "false")
4117                 (const_string "*"))
4118             (not (match_test "TARGET_HARD_XF_REGS"))
4119               (symbol_ref "false")
4120            ]
4121            (const_string "*")))])
4122    
4123 (define_split
4124   [(set (match_operand:XF 0 "nonimmediate_gr_operand")
4125         (match_operand:XF 1 "general_gr_operand"))]
4126   "reload_completed"
4127   [(const_int 0)]
4128   "ix86_split_long_move (operands); DONE;")
4130 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
4131 (define_insn "*movdf_internal"
4132   [(set (match_operand:DF 0 "nonimmediate_operand"
4133     "=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")
4134         (match_operand:DF 1 "general_operand"
4135     "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"))]
4136   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4137    && (lra_in_progress || reload_completed
4138        || !CONST_DOUBLE_P (operands[1])
4139        || ((optimize_function_for_size_p (cfun)
4140             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4141            && IS_STACK_MODE (DFmode)
4142            && standard_80387_constant_p (operands[1]) > 0
4143            && !memory_operand (operands[0], DFmode))
4144        || (TARGET_SSE2 && TARGET_SSE_MATH
4145            && standard_sse_constant_p (operands[1], DFmode) == 1
4146            && !memory_operand (operands[0], DFmode))
4147        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
4148            && memory_operand (operands[0], DFmode))
4149        || !TARGET_HARD_DF_REGS)"
4151   switch (get_attr_type (insn))
4152     {
4153     case TYPE_FMOV:
4154       if (which_alternative == 2)
4155         return standard_80387_constant_opcode (operands[1]);
4156       return output_387_reg_move (insn, operands);
4158     case TYPE_MULTI:
4159       return "#";
4161     case TYPE_IMOV:
4162       if (get_attr_mode (insn) == MODE_SI)
4163         return "mov{l}\t{%1, %k0|%k0, %1}";
4164       else if (which_alternative == 11)
4165         return "movabs{q}\t{%1, %0|%0, %1}";
4166       else
4167         return "mov{q}\t{%1, %0|%0, %1}";
4169     case TYPE_SSELOG1:
4170       return standard_sse_constant_opcode (insn, operands);
4172     case TYPE_SSEMOV:
4173       return ix86_output_ssemov (insn, operands);
4175     default:
4176       gcc_unreachable ();
4177     }
4179   [(set (attr "isa")
4180         (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
4181                  (const_string "nox64")
4182                (eq_attr "alternative" "8,9,10,11,24,25")
4183                  (const_string "x64")
4184                (eq_attr "alternative" "12,13,14,15")
4185                  (const_string "sse2")
4186                (eq_attr "alternative" "20,21")
4187                  (const_string "x64_sse2")
4188               ]
4189               (const_string "*")))
4190    (set (attr "type")
4191         (cond [(eq_attr "alternative" "0,1,2")
4192                  (const_string "fmov")
4193                (eq_attr "alternative" "3,4,5,6,7,22,23")
4194                  (const_string "multi")
4195                (eq_attr "alternative" "8,9,10,11,24,25")
4196                  (const_string "imov")
4197                (eq_attr "alternative" "12,16")
4198                  (const_string "sselog1")
4199               ]
4200               (const_string "ssemov")))
4201    (set (attr "modrm")
4202      (if_then_else (eq_attr "alternative" "11")
4203        (const_string "0")
4204        (const_string "*")))
4205    (set (attr "length_immediate")
4206      (if_then_else (eq_attr "alternative" "11")
4207        (const_string "8")
4208        (const_string "*")))
4209    (set (attr "prefix")
4210      (if_then_else (eq_attr "type" "sselog1,ssemov")
4211        (const_string "maybe_vex")
4212        (const_string "orig")))
4213    (set (attr "prefix_data16")
4214      (if_then_else
4215        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
4216             (eq_attr "mode" "V1DF"))
4217        (const_string "1")
4218        (const_string "*")))
4219    (set (attr "mode")
4220         (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
4221                  (const_string "SI")
4222                (eq_attr "alternative" "8,9,11,20,21,24,25")
4223                  (const_string "DI")
4225                /* xorps is one byte shorter for non-AVX targets.  */
4226                (eq_attr "alternative" "12,16")
4227                  (cond [(match_test "TARGET_AVX")
4228                           (const_string "V2DF")
4229                         (ior (not (match_test "TARGET_SSE2"))
4230                              (match_test "optimize_function_for_size_p (cfun)"))
4231                           (const_string "V4SF")
4232                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4233                           (const_string "TI")
4234                        ]
4235                        (const_string "V2DF"))
4237                /* For architectures resolving dependencies on
4238                   whole SSE registers use movapd to break dependency
4239                   chains, otherwise use short move to avoid extra work.  */
4241                /* movaps is one byte shorter for non-AVX targets.  */
4242                (eq_attr "alternative" "13,17")
4243                  (cond [(match_test "TARGET_AVX512VL")
4244                           (const_string "V2DF")
4245                         (match_test "TARGET_AVX512F")
4246                           (const_string "DF")
4247                         (match_test "TARGET_AVX")
4248                           (const_string "V2DF")
4249                         (ior (not (match_test "TARGET_SSE2"))
4250                              (match_test "optimize_function_for_size_p (cfun)"))
4251                           (const_string "V4SF")
4252                         (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
4253                           (const_string "V4SF")
4254                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4255                           (const_string "V2DF")
4256                        ]
4257                        (const_string "DF"))
4259                /* For architectures resolving dependencies on register
4260                   parts we may avoid extra work to zero out upper part
4261                   of register.  */
4262                (eq_attr "alternative" "14,18")
4263                  (cond [(not (match_test "TARGET_SSE2"))
4264                           (const_string "V2SF")
4265                         (match_test "TARGET_AVX")
4266                           (const_string "DF")
4267                         (match_test "TARGET_SSE_SPLIT_REGS")
4268                           (const_string "V1DF")
4269                        ]
4270                        (const_string "DF"))
4272                (and (eq_attr "alternative" "15,19")
4273                     (not (match_test "TARGET_SSE2")))
4274                  (const_string "V2SF")
4275               ]
4276               (const_string "DF")))
4277    (set (attr "preferred_for_size")
4278      (cond [(eq_attr "alternative" "3,4")
4279               (symbol_ref "false")]
4280            (symbol_ref "true")))
4281    (set (attr "preferred_for_speed")
4282      (cond [(eq_attr "alternative" "3,4")
4283               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
4284             (eq_attr "alternative" "20")
4285               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4286             (eq_attr "alternative" "21")
4287               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4288            ]
4289            (symbol_ref "true")))
4290    (set (attr "enabled")
4291      (cond [(eq_attr "alternative" "22,23,24,25")
4292               (if_then_else
4293                 (match_test "TARGET_HARD_DF_REGS")
4294                 (symbol_ref "false")
4295                 (const_string "*"))
4296             (not (match_test "TARGET_HARD_DF_REGS"))
4297               (symbol_ref "false")
4298            ]
4299            (const_string "*")))])
4301 (define_split
4302   [(set (match_operand:DF 0 "nonimmediate_gr_operand")
4303         (match_operand:DF 1 "general_gr_operand"))]
4304   "!TARGET_64BIT && reload_completed"
4305   [(const_int 0)]
4306   "ix86_split_long_move (operands); DONE;")
4308 (define_insn "*movsf_internal"
4309   [(set (match_operand:SF 0 "nonimmediate_operand"
4310           "=Yf*f,m   ,Yf*f,?r ,?m,Yv,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r  ,m")
4311         (match_operand:SF 1 "general_operand"
4312           "Yf*fm,Yf*f,G   ,rmF,rF,C ,v,m,v,v ,r ,*y ,m  ,*y,*y,r  ,rmF,rF"))]
4313   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4314    && (lra_in_progress || reload_completed
4315        || !CONST_DOUBLE_P (operands[1])
4316        || ((optimize_function_for_size_p (cfun)
4317             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4318            && IS_STACK_MODE (SFmode)
4319            && standard_80387_constant_p (operands[1]) > 0)
4320        || (TARGET_SSE && TARGET_SSE_MATH
4321            && standard_sse_constant_p (operands[1], SFmode) == 1)
4322        || memory_operand (operands[0], SFmode)
4323        || !TARGET_HARD_SF_REGS)"
4325   switch (get_attr_type (insn))
4326     {
4327     case TYPE_FMOV:
4328       if (which_alternative == 2)
4329         return standard_80387_constant_opcode (operands[1]);
4330       return output_387_reg_move (insn, operands);
4332     case TYPE_IMOV:
4333       return "mov{l}\t{%1, %0|%0, %1}";
4335     case TYPE_SSELOG1:
4336       return standard_sse_constant_opcode (insn, operands);
4338     case TYPE_SSEMOV:
4339       return ix86_output_ssemov (insn, operands);
4341     case TYPE_MMXMOV:
4342       switch (get_attr_mode (insn))
4343         {
4344         case MODE_DI:
4345           return "movq\t{%1, %0|%0, %1}";
4346         case MODE_SI:
4347           return "movd\t{%1, %0|%0, %1}";
4349         default:
4350           gcc_unreachable ();
4351         }
4353     default:
4354       gcc_unreachable ();
4355     }
4357   [(set (attr "isa")
4358      (cond [(eq_attr "alternative" "9,10")
4359               (const_string "sse2")
4360            ]
4361            (const_string "*")))
4362    (set (attr "type")
4363         (cond [(eq_attr "alternative" "0,1,2")
4364                  (const_string "fmov")
4365                (eq_attr "alternative" "3,4,16,17")
4366                  (const_string "imov")
4367                (eq_attr "alternative" "5")
4368                  (const_string "sselog1")
4369                (eq_attr "alternative" "11,12,13,14,15")
4370                  (const_string "mmxmov")
4371               ]
4372               (const_string "ssemov")))
4373    (set (attr "prefix")
4374      (if_then_else (eq_attr "type" "sselog1,ssemov")
4375        (const_string "maybe_vex")
4376        (const_string "orig")))
4377    (set (attr "prefix_data16")
4378      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
4379        (const_string "1")
4380        (const_string "*")))
4381    (set (attr "mode")
4382         (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
4383                  (const_string "SI")
4384                (eq_attr "alternative" "11")
4385                  (const_string "DI")
4386                (eq_attr "alternative" "5")
4387                  (cond [(and (match_test "TARGET_AVX512F && TARGET_EVEX512")
4388                              (not (match_test "TARGET_PREFER_AVX256")))
4389                           (const_string "V16SF")
4390                         (match_test "TARGET_AVX")
4391                           (const_string "V4SF")
4392                         (ior (not (match_test "TARGET_SSE2"))
4393                              (match_test "optimize_function_for_size_p (cfun)"))
4394                           (const_string "V4SF")
4395                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4396                           (const_string "TI")
4397                        ]
4398                        (const_string "V4SF"))
4400                /* For architectures resolving dependencies on
4401                   whole SSE registers use APS move to break dependency
4402                   chains, otherwise use short move to avoid extra work.
4404                   Do the same for architectures resolving dependencies on
4405                   the parts.  While in DF mode it is better to always handle
4406                   just register parts, the SF mode is different due to lack
4407                   of instructions to load just part of the register.  It is
4408                   better to maintain the whole registers in single format
4409                   to avoid problems on using packed logical operations.  */
4410                (eq_attr "alternative" "6")
4411                  (cond [(match_test "TARGET_AVX512VL")
4412                           (const_string "V4SF")
4413                         (match_test "TARGET_AVX512F")
4414                           (const_string "SF")
4415                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4416                              (match_test "TARGET_SSE_SPLIT_REGS"))
4417                           (const_string "V4SF")
4418                        ]
4419                        (const_string "SF"))
4420               ]
4421               (const_string "SF")))
4422    (set (attr "preferred_for_speed")
4423      (cond [(eq_attr "alternative" "9,14")
4424               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4425             (eq_attr "alternative" "10,15")
4426               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4427            ]
4428            (symbol_ref "true")))
4429    (set (attr "enabled")
4430      (cond [(eq_attr "alternative" "16,17")
4431               (if_then_else
4432                 (match_test "TARGET_HARD_SF_REGS")
4433                 (symbol_ref "false")
4434                 (const_string "*"))
4435             (not (match_test "TARGET_HARD_SF_REGS"))
4436               (symbol_ref "false")
4437            ]
4438            (const_string "*")))])
4440 (define_mode_attr hfbfconstf
4441  [(HF "F") (BF "")])
4443 (define_insn "*mov<mode>_internal"
4444  [(set (match_operand:HFBF 0 "nonimmediate_operand"
4445          "=?r,?r,?r,?m           ,Yv,v,?r,jm,m,?v,v")
4446        (match_operand:HFBF 1 "general_operand"
4447          "r  ,F ,m ,r<hfbfconstf>,C ,v, v,v ,v,r ,m"))]
4448  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4449   && (lra_in_progress
4450       || reload_completed
4451       || !CONST_DOUBLE_P (operands[1])
4452       || (TARGET_SSE2
4453           && standard_sse_constant_p (operands[1], <MODE>mode) == 1)
4454       || memory_operand (operands[0], <MODE>mode))"
4456   switch (get_attr_type (insn))
4457     {
4458     case TYPE_IMOVX:
4459       /* movzwl is faster than movw on p2 due to partial word stalls,
4460          though not as fast as an aligned movl.  */
4461       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
4463     case TYPE_SSEMOV:
4464       return ix86_output_ssemov (insn, operands);
4466     case TYPE_SSELOG1:
4467       if (satisfies_constraint_C (operands[1]))
4468         return standard_sse_constant_opcode (insn, operands);
4470       if (SSE_REG_P (operands[0]))
4471         return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
4472       else
4473         return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
4475     default:
4476       if (get_attr_mode (insn) == MODE_SI)
4477         return "mov{l}\t{%k1, %k0|%k0, %k1}";
4478       else
4479         return "mov{w}\t{%1, %0|%0, %1}";
4480     }
4482   [(set (attr "isa")
4483         (cond [(eq_attr "alternative" "4,5,6,9,10")
4484                  (const_string "sse2")
4485                (eq_attr "alternative" "7")
4486                  (const_string "sse4_noavx")
4487                (eq_attr "alternative" "8")
4488                  (const_string "avx")
4489               ]
4490               (const_string "*")))
4491    (set (attr "addr")
4492         (if_then_else (eq_attr "alternative" "7")
4493                       (const_string "gpr16")
4494                       (const_string "*")))
4495    (set (attr "type")
4496         (cond [(eq_attr "alternative" "4")
4497                  (const_string "sselog1")
4498                (eq_attr "alternative" "5,6,9")
4499                  (const_string "ssemov")
4500                (eq_attr "alternative" "7,8,10")
4501                  (if_then_else
4502                    (match_test ("TARGET_AVX512FP16"))
4503                    (const_string "ssemov")
4504                    (const_string "sselog1"))
4505                (match_test "optimize_function_for_size_p (cfun)")
4506                  (const_string "imov")
4507                (and (eq_attr "alternative" "0")
4508                     (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4509                          (not (match_test "TARGET_HIMODE_MATH"))))
4510                  (const_string "imov")
4511                (and (eq_attr "alternative" "1,2")
4512                     (match_operand:HI 1 "aligned_operand"))
4513                  (const_string "imov")
4514                (and (match_test "TARGET_MOVX")
4515                     (eq_attr "alternative" "0,2"))
4516                  (const_string "imovx")
4517                  ]
4518               (const_string "imov")))
4519    (set (attr "prefix")
4520         (cond [(eq_attr "alternative" "4,5,6,7,8,9,10")
4521                  (const_string "maybe_vex")
4522               ]
4523               (const_string "orig")))
4524    (set (attr "mode")
4525         (cond [(eq_attr "alternative" "4")
4526                  (const_string "V4SF")
4527                (eq_attr "alternative" "6,9")
4528                  (if_then_else
4529                    (match_test "TARGET_AVX512FP16")
4530                    (const_string "HI")
4531                    (const_string "SI"))
4532                (eq_attr "alternative" "7,8,10")
4533                  (if_then_else
4534                    (match_test "TARGET_AVX512FP16")
4535                    (const_string "HI")
4536                    (const_string "TI"))
4537                (eq_attr "alternative" "5")
4538                  (cond [(match_test "TARGET_AVX512VL")
4539                         (const_string "V4SF")
4540                         (match_test "TARGET_AVX512FP16")
4541                           (const_string "HF")
4542                         (match_test "TARGET_AVX512F")
4543                           (const_string "SF")
4544                         (match_test "TARGET_AVX")
4545                           (const_string "V4SF")
4546                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4547                              (match_test "TARGET_SSE_SPLIT_REGS"))
4548                           (const_string "V4SF")
4549                        ]
4550                        (const_string "SF"))
4551                (eq_attr "type" "imovx")
4552                  (const_string "SI")
4553                (and (eq_attr "alternative" "1,2")
4554                     (match_operand:HI 1 "aligned_operand"))
4555                  (const_string "SI")
4556                (and (eq_attr "alternative" "0")
4557                     (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4558                          (not (match_test "TARGET_HIMODE_MATH"))))
4559                  (const_string "SI")
4560               ]
4561               (const_string "HI")))
4562    (set (attr "enabled")
4563         (cond [(and (match_test "<MODE>mode == BFmode")
4564                     (eq_attr "alternative" "1"))
4565                 (symbol_ref "false")
4566               ]
4567               (const_string "*")))])
4569 (define_split
4570   [(set (match_operand 0 "any_fp_register_operand")
4571         (match_operand 1 "memory_operand"))]
4572   "reload_completed
4573    && (GET_MODE (operands[0]) == TFmode
4574        || GET_MODE (operands[0]) == XFmode
4575        || GET_MODE (operands[0]) == DFmode
4576        || GET_MODE (operands[0]) == SFmode)
4577    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4578   [(set (match_dup 0) (match_dup 2))]
4579   "operands[2] = find_constant_src (curr_insn);")
4581 (define_split
4582   [(set (match_operand 0 "any_fp_register_operand")
4583         (float_extend (match_operand 1 "memory_operand")))]
4584   "reload_completed
4585    && (GET_MODE (operands[0]) == TFmode
4586        || GET_MODE (operands[0]) == XFmode
4587        || GET_MODE (operands[0]) == DFmode)
4588    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4589   [(set (match_dup 0) (match_dup 2))]
4590   "operands[2] = find_constant_src (curr_insn);")
4592 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
4593 (define_split
4594   [(set (match_operand:X87MODEF 0 "fp_register_operand")
4595         (match_operand:X87MODEF 1 "immediate_operand"))]
4596   "reload_completed
4597    && (standard_80387_constant_p (operands[1]) == 8
4598        || standard_80387_constant_p (operands[1]) == 9)"
4599   [(set (match_dup 0)(match_dup 1))
4600    (set (match_dup 0)
4601         (neg:X87MODEF (match_dup 0)))]
4603   if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
4604     operands[1] = CONST0_RTX (<MODE>mode);
4605   else
4606     operands[1] = CONST1_RTX (<MODE>mode);
4609 (define_insn "*swapxf"
4610   [(set (match_operand:XF 0 "register_operand" "+f")
4611         (match_operand:XF 1 "register_operand" "+f"))
4612    (set (match_dup 1)
4613         (match_dup 0))]
4614   "TARGET_80387"
4616   if (STACK_TOP_P (operands[0]))
4617     return "fxch\t%1";
4618   else
4619     return "fxch\t%0";
4621   [(set_attr "type" "fxch")
4622    (set_attr "mode" "XF")])
4625 ;; Zero extension instructions
4627 (define_insn_and_split "zero_extendditi2"
4628   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4629         (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "rm,r")))]
4630   "TARGET_64BIT"
4631   "#"
4632   "&& reload_completed"
4633   [(set (match_dup 3) (match_dup 1))
4634    (set (match_dup 4) (const_int 0))]
4635   "split_double_mode (TImode, &operands[0], 1, &operands[3], &operands[4]);")
4637 (define_expand "zero_extendsidi2"
4638   [(set (match_operand:DI 0 "nonimmediate_operand")
4639         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
4641 (define_insn "*zero_extendsidi2"
4642   [(set (match_operand:DI 0 "nonimmediate_operand"
4643                 "=r,?r,?o,r   ,o,?*y,?!*y,$r,$v,$x,*x,*v,?r,?k")
4644         (zero_extend:DI
4645          (match_operand:SI 1 "x86_64_zext_operand"
4646                 "0 ,rm,r ,rmWz,0,r  ,m   ,v ,r ,m ,*x,*v,?k,?km")))]
4647   ""
4649   switch (get_attr_type (insn))
4650     {
4651     case TYPE_IMOVX:
4652       if (ix86_use_lea_for_mov (insn, operands))
4653         return "lea{l}\t{%E1, %k0|%k0, %E1}";
4654       else
4655         return "mov{l}\t{%1, %k0|%k0, %1}";
4657     case TYPE_MULTI:
4658       return "#";
4660     case TYPE_MMXMOV:
4661       return "movd\t{%1, %0|%0, %1}";
4663     case TYPE_SSEMOV:
4664       if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
4665         {
4666           if (EXT_REX_SSE_REG_P (operands[0])
4667               || EXT_REX_SSE_REG_P (operands[1]))
4668             return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
4669           else
4670             return "%vpmovzxdq\t{%1, %0|%0, %1}";
4671         }
4673       if (GENERAL_REG_P (operands[0]))
4674         return "%vmovd\t{%1, %k0|%k0, %1}";
4676       return "%vmovd\t{%1, %0|%0, %1}";
4678     case TYPE_MSKMOV:
4679       return "kmovd\t{%1, %k0|%k0, %1}";
4681     default:
4682       gcc_unreachable ();
4683     }
4685   [(set (attr "isa")
4686      (cond [(eq_attr "alternative" "0,1,2")
4687               (const_string "nox64")
4688             (eq_attr "alternative" "3")
4689               (const_string "x64")
4690             (eq_attr "alternative" "7,8,9")
4691               (const_string "sse2")
4692             (eq_attr "alternative" "10")
4693               (const_string "sse4")
4694             (eq_attr "alternative" "11")
4695               (const_string "avx512f")
4696             (eq_attr "alternative" "12")
4697               (const_string "x64_avx512bw")
4698             (eq_attr "alternative" "13")
4699               (const_string "avx512bw")
4700            ]
4701            (const_string "*")))
4702    (set (attr "mmx_isa")
4703      (if_then_else (eq_attr "alternative" "5,6")
4704                    (const_string "native")
4705                    (const_string "*")))
4706    (set (attr "type")
4707      (cond [(eq_attr "alternative" "0,1,2,4")
4708               (const_string "multi")
4709             (eq_attr "alternative" "5,6")
4710               (const_string "mmxmov")
4711             (eq_attr "alternative" "7")
4712               (if_then_else (match_test "TARGET_64BIT")
4713                 (const_string "ssemov")
4714                 (const_string "multi"))
4715             (eq_attr "alternative" "8,9,10,11")
4716               (const_string "ssemov")
4717             (eq_attr "alternative" "12,13")
4718               (const_string "mskmov")
4719            ]
4720            (const_string "imovx")))
4721    (set (attr "prefix_extra")
4722      (if_then_else (eq_attr "alternative" "10,11")
4723        (const_string "1")
4724        (const_string "*")))
4725    (set (attr "prefix")
4726      (if_then_else (eq_attr "type" "ssemov")
4727        (const_string "maybe_vex")
4728        (const_string "orig")))
4729    (set (attr "prefix_0f")
4730      (if_then_else (eq_attr "type" "imovx")
4731        (const_string "0")
4732        (const_string "*")))
4733    (set (attr "mode")
4734      (cond [(eq_attr "alternative" "5,6")
4735               (const_string "DI")
4736             (and (eq_attr "alternative" "7")
4737                  (match_test "TARGET_64BIT"))
4738               (const_string "TI")
4739             (eq_attr "alternative" "8,10,11")
4740               (const_string "TI")
4741            ]
4742            (const_string "SI")))
4743    (set (attr "preferred_for_speed")
4744      (cond [(eq_attr "alternative" "7")
4745               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4746             (eq_attr "alternative" "5,8")
4747               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4748            ]
4749            (symbol_ref "true")))])
4751 (define_split
4752   [(set (match_operand:DI 0 "memory_operand")
4753         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
4754   "reload_completed"
4755   [(set (match_dup 4) (const_int 0))]
4756   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4758 (define_split
4759   [(set (match_operand:DI 0 "general_reg_operand")
4760         (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
4761   "!TARGET_64BIT && reload_completed
4762    && REGNO (operands[0]) == REGNO (operands[1])"
4763   [(set (match_dup 4) (const_int 0))]
4764   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4766 (define_split
4767   [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4768         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4769   "!TARGET_64BIT && reload_completed
4770    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4771   [(set (match_dup 3) (match_dup 1))
4772    (set (match_dup 4) (const_int 0))]
4773   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4775 (define_mode_attr kmov_isa
4776   [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
4778 (define_insn "zero_extend<mode>di2"
4779   [(set (match_operand:DI 0 "register_operand" "=r,?r,?k")
4780         (zero_extend:DI
4781          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,?k,?km")))]
4782   "TARGET_64BIT"
4783   "@
4784    movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4785    kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
4786    kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4787   [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4788    (set_attr "type" "imovx,mskmov,mskmov")
4789    (set_attr "mode" "SI,<MODE>,<MODE>")])
4791 (define_expand "zero_extend<mode>si2"
4792   [(set (match_operand:SI 0 "register_operand")
4793         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4794   ""
4796   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4797     {
4798       operands[1] = force_reg (<MODE>mode, operands[1]);
4799       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4800       DONE;
4801     }
4804 (define_insn_and_split "zero_extend<mode>si2_and"
4805   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4806         (zero_extend:SI
4807           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4808    (clobber (reg:CC FLAGS_REG))]
4809   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4810   "#"
4811   "&& reload_completed"
4812   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4813               (clobber (reg:CC FLAGS_REG))])]
4815   if (!REG_P (operands[1])
4816       || REGNO (operands[0]) != REGNO (operands[1]))
4817     {
4818       ix86_expand_clear (operands[0]);
4820       gcc_assert (!TARGET_PARTIAL_REG_STALL);
4821       emit_insn (gen_rtx_SET
4822                  (gen_rtx_STRICT_LOW_PART
4823                   (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
4824                   operands[1]));
4825       DONE;
4826     }
4828   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4830   [(set_attr "type" "alu1")
4831    (set_attr "mode" "SI")])
4833 (define_insn "*zero_extend<mode>si2"
4834   [(set (match_operand:SI 0 "register_operand" "=r,?r,?k")
4835         (zero_extend:SI
4836           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,?k,?km")))]
4837   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4838   "@
4839    movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4840    kmov<mskmodesuffix>\t{%1, %0|%0, %1}
4841    kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4842   [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4843    (set_attr "type" "imovx,mskmov,mskmov")
4844    (set_attr "mode" "SI,<MODE>,<MODE>")])
4846 (define_expand "zero_extendqihi2"
4847   [(set (match_operand:HI 0 "register_operand")
4848         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4849   ""
4851   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4852     {
4853       operands[1] = force_reg (QImode, operands[1]);
4854       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4855       DONE;
4856     }
4859 (define_insn_and_split "zero_extendqihi2_and"
4860   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4861         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4862    (clobber (reg:CC FLAGS_REG))]
4863   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4864   "#"
4865   "&& reload_completed"
4866   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4867               (clobber (reg:CC FLAGS_REG))])]
4869   if (!REG_P (operands[1])
4870       || REGNO (operands[0]) != REGNO (operands[1]))
4871     {
4872       ix86_expand_clear (operands[0]);
4874       gcc_assert (!TARGET_PARTIAL_REG_STALL);
4875       emit_insn (gen_rtx_SET
4876                  (gen_rtx_STRICT_LOW_PART
4877                   (VOIDmode, gen_lowpart (QImode, operands[0])),
4878                   operands[1]));
4879       DONE;
4880     }
4882   operands[0] = gen_lowpart (SImode, operands[0]);
4884   [(set_attr "type" "alu1")
4885    (set_attr "mode" "SI")])
4887 ; zero extend to SImode to avoid partial register stalls
4888 (define_insn "*zero_extendqihi2"
4889   [(set (match_operand:HI 0 "register_operand" "=r,?r,?k")
4890         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,?k,?km")))]
4891   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4892   "@
4893    movz{bl|x}\t{%1, %k0|%k0, %1}
4894    kmovb\t{%1, %k0|%k0, %1}
4895    kmovb\t{%1, %0|%0, %1}"
4896   [(set_attr "isa" "*,avx512dq,avx512dq")
4897    (set_attr "type" "imovx,mskmov,mskmov")
4898    (set_attr "mode" "SI,QI,QI")])
4900 ;; Transform xorl; mov[bw] (set strict_low_part) into movz[bw]l.
4901 (define_peephole2
4902   [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
4903                    (const_int 0))
4904               (clobber (reg:CC FLAGS_REG))])
4905    (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4906         (match_operand:SWI12 2 "nonimmediate_operand"))]
4907   "REGNO (operands[0]) == REGNO (operands[1])
4908    && (<SWI48:MODE>mode != SImode
4909        || !TARGET_ZERO_EXTEND_WITH_AND
4910        || !optimize_function_for_speed_p (cfun))"
4911   [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4913 ;; Likewise, but preserving FLAGS_REG.
4914 (define_peephole2
4915   [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
4916    (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4917         (match_operand:SWI12 2 "nonimmediate_operand"))]
4918   "REGNO (operands[0]) == REGNO (operands[1])
4919    && (<SWI48:MODE>mode != SImode
4920        || !TARGET_ZERO_EXTEND_WITH_AND
4921        || !optimize_function_for_speed_p (cfun))"
4922   [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4924 ;; Sign extension instructions
4926 (define_expand "extendsidi2"
4927   [(set (match_operand:DI 0 "register_operand")
4928         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4929   ""
4931   if (!TARGET_64BIT)
4932     {
4933       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4934       DONE;
4935     }
4938 (define_insn "*extendsidi2_rex64"
4939   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4940         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4941   "TARGET_64BIT"
4942   "@
4943    {cltq|cdqe}
4944    movs{lq|x}\t{%1, %0|%0, %1}"
4945   [(set_attr "type" "imovx")
4946    (set_attr "mode" "DI")
4947    (set_attr "prefix_0f" "0")
4948    (set_attr "modrm" "0,1")])
4950 (define_insn "extendsidi2_1"
4951   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4952         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4953    (clobber (reg:CC FLAGS_REG))
4954    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4955   "!TARGET_64BIT"
4956   "#")
4958 (define_insn "extendditi2"
4959   [(set (match_operand:TI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4960         (sign_extend:TI (match_operand:DI 1 "register_operand" "0,0,r,r")))
4961    (clobber (reg:CC FLAGS_REG))
4962    (clobber (match_scratch:DI 2 "=X,X,X,&r"))]
4963   "TARGET_64BIT"
4964   "#")
4966 ;; Split the memory case.  If the source register doesn't die, it will stay
4967 ;; this way, if it does die, following peephole2s take care of it.
4968 (define_split
4969   [(set (match_operand:<DWI> 0 "memory_operand")
4970         (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4971    (clobber (reg:CC FLAGS_REG))
4972    (clobber (match_operand:DWIH 2 "register_operand"))]
4973   "reload_completed"
4974   [(const_int 0)]
4976   rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4978   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4980   emit_move_insn (operands[3], operands[1]);
4982   /* Generate a cltd if possible and doing so it profitable.  */
4983   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4984       && REGNO (operands[1]) == AX_REG
4985       && REGNO (operands[2]) == DX_REG)
4986     {
4987       emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[1], bits));
4988     }
4989   else
4990     {
4991       emit_move_insn (operands[2], operands[1]);
4992       emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[2], bits));
4993     }
4994   emit_move_insn (operands[4], operands[2]);
4995   DONE;
4998 ;; Peepholes for the case where the source register does die, after
4999 ;; being split with the above splitter.
5000 (define_peephole2
5001   [(set (match_operand:DWIH 0 "memory_operand")
5002         (match_operand:DWIH 1 "general_reg_operand"))
5003    (set (match_operand:DWIH 2 "general_reg_operand") (match_dup 1))
5004    (parallel [(set (match_dup 2)
5005                    (ashiftrt:DWIH (match_dup 2)
5006                                   (match_operand 4 "const_int_operand")))
5007                (clobber (reg:CC FLAGS_REG))])
5008    (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
5009   "REGNO (operands[1]) != REGNO (operands[2])
5010    && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
5011    && peep2_reg_dead_p (2, operands[1])
5012    && peep2_reg_dead_p (4, operands[2])
5013    && !reg_mentioned_p (operands[2], operands[3])"
5014   [(set (match_dup 0) (match_dup 1))
5015    (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
5016               (clobber (reg:CC FLAGS_REG))])
5017    (set (match_dup 3) (match_dup 1))])
5019 (define_peephole2
5020   [(set (match_operand:DWIH 0 "memory_operand")
5021         (match_operand:DWIH 1 "general_reg_operand"))
5022    (parallel [(set (match_operand:DWIH 2 "general_reg_operand")
5023                    (ashiftrt:DWIH (match_dup 1)
5024                                   (match_operand 4 "const_int_operand")))
5025                (clobber (reg:CC FLAGS_REG))])
5026    (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
5027   "/* cltd is shorter than sarl $31, %eax */
5028    !optimize_function_for_size_p (cfun)
5029    && REGNO (operands[1]) == AX_REG
5030    && REGNO (operands[2]) == DX_REG
5031    && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
5032    && peep2_reg_dead_p (2, operands[1])
5033    && peep2_reg_dead_p (3, operands[2])
5034    && !reg_mentioned_p (operands[2], operands[3])"
5035   [(set (match_dup 0) (match_dup 1))
5036    (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
5037               (clobber (reg:CC FLAGS_REG))])
5038    (set (match_dup 3) (match_dup 1))])
5040 ;; Extend to register case.  Optimize case where source and destination
5041 ;; registers match and cases where we can use cltd.
5042 (define_split
5043   [(set (match_operand:<DWI> 0 "register_operand")
5044         (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
5045    (clobber (reg:CC FLAGS_REG))
5046    (clobber (match_scratch:DWIH 2))]
5047   "reload_completed"
5048   [(const_int 0)]
5050   rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
5052   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
5054   if (REGNO (operands[3]) != REGNO (operands[1]))
5055     emit_move_insn (operands[3], operands[1]);
5057   rtx src = operands[1];
5058   if (REGNO (operands[3]) == AX_REG)
5059     src = operands[3];
5061   /* Generate a cltd if possible and doing so it profitable.  */
5062   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
5063       && REGNO (src) == AX_REG
5064       && REGNO (operands[4]) == DX_REG)
5065     {
5066       emit_insn (gen_ashr<mode>3_cvt (operands[4], src, bits));
5067       DONE;
5068     }
5070   if (REGNO (operands[4]) != REGNO (operands[1]))
5071     emit_move_insn (operands[4], operands[1]);
5073   emit_insn (gen_ashr<mode>3_cvt (operands[4], operands[4], bits));
5074   DONE;
5077 (define_peephole2
5078   [(set (match_operand:DI 0 "general_reg_operand")
5079         (match_operand:DI 1 "general_reg_operand"))
5080    (parallel [(set (match_dup 0)
5081                    (ashiftrt:DI (match_dup 0)
5082                                 (const_int 63)))
5083                (clobber (reg:CC FLAGS_REG))])
5084    (set (match_operand:DI 2 "general_reg_operand") (match_dup 1))
5085    (set (match_operand:DI 3 "general_reg_operand") (match_dup 0))]
5086   "(optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
5087    && REGNO (operands[2]) == AX_REG
5088    && REGNO (operands[3]) == DX_REG
5089    && peep2_reg_dead_p (4, operands[0])
5090    && !reg_mentioned_p (operands[0], operands[1])
5091    && !reg_mentioned_p (operands[2], operands[0])"
5092   [(set (match_dup 2) (match_dup 1))
5093    (parallel [(set (match_dup 3) (ashiftrt:DI (match_dup 2) (const_int 63)))
5094               (clobber (reg:CC FLAGS_REG))])])
5096 (define_insn "extend<mode>di2"
5097   [(set (match_operand:DI 0 "register_operand" "=r")
5098         (sign_extend:DI
5099          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
5100   "TARGET_64BIT"
5101   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
5102   [(set_attr "type" "imovx")
5103    (set_attr "mode" "DI")])
5105 (define_insn "extendhisi2"
5106   [(set (match_operand:SI 0 "register_operand" "=*a,r")
5107         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
5108   ""
5110   switch (get_attr_prefix_0f (insn))
5111     {
5112     case 0:
5113       return "{cwtl|cwde}";
5114     default:
5115       return "movs{wl|x}\t{%1, %0|%0, %1}";
5116     }
5118   [(set_attr "type" "imovx")
5119    (set_attr "mode" "SI")
5120    (set (attr "prefix_0f")
5121      ;; movsx is short decodable while cwtl is vector decoded.
5122      (if_then_else (and (eq_attr "cpu" "!k6")
5123                         (eq_attr "alternative" "0"))
5124         (const_string "0")
5125         (const_string "1")))
5126    (set (attr "znver1_decode")
5127      (if_then_else (eq_attr "prefix_0f" "0")
5128         (const_string "double")
5129         (const_string "direct")))
5130    (set (attr "modrm")
5131      (if_then_else (eq_attr "prefix_0f" "0")
5132         (const_string "0")
5133         (const_string "1")))])
5135 (define_insn "*extendhisi2_zext"
5136   [(set (match_operand:DI 0 "register_operand" "=*a,r")
5137         (zero_extend:DI
5138          (sign_extend:SI
5139           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
5140   "TARGET_64BIT"
5142   switch (get_attr_prefix_0f (insn))
5143     {
5144     case 0:
5145       return "{cwtl|cwde}";
5146     default:
5147       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
5148     }
5150   [(set_attr "type" "imovx")
5151    (set_attr "mode" "SI")
5152    (set (attr "prefix_0f")
5153      ;; movsx is short decodable while cwtl is vector decoded.
5154      (if_then_else (and (eq_attr "cpu" "!k6")
5155                         (eq_attr "alternative" "0"))
5156         (const_string "0")
5157         (const_string "1")))
5158    (set (attr "modrm")
5159      (if_then_else (eq_attr "prefix_0f" "0")
5160         (const_string "0")
5161         (const_string "1")))])
5163 (define_insn "extendqisi2"
5164   [(set (match_operand:SI 0 "register_operand" "=r")
5165         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
5166   ""
5167   "movs{bl|x}\t{%1, %0|%0, %1}"
5168    [(set_attr "type" "imovx")
5169     (set_attr "mode" "SI")])
5171 (define_insn "*extendqisi2_zext"
5172   [(set (match_operand:DI 0 "register_operand" "=r")
5173         (zero_extend:DI
5174           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
5175   "TARGET_64BIT"
5176   "movs{bl|x}\t{%1, %k0|%k0, %1}"
5177    [(set_attr "type" "imovx")
5178     (set_attr "mode" "SI")])
5180 (define_insn "extendqihi2"
5181   [(set (match_operand:HI 0 "register_operand" "=*a,r")
5182         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
5183   ""
5185   switch (get_attr_prefix_0f (insn))
5186     {
5187     case 0:
5188       return "{cbtw|cbw}";
5189     default:
5190       return "movs{bw|x}\t{%1, %0|%0, %1}";
5191     }
5193   [(set_attr "type" "imovx")
5194    (set_attr "mode" "HI")
5195    (set (attr "prefix_0f")
5196      ;; movsx is short decodable while cwtl is vector decoded.
5197      (if_then_else (and (eq_attr "cpu" "!k6")
5198                         (eq_attr "alternative" "0"))
5199         (const_string "0")
5200         (const_string "1")))
5201    (set (attr "modrm")
5202      (if_then_else (eq_attr "prefix_0f" "0")
5203         (const_string "0")
5204         (const_string "1")))])
5206 (define_insn "*extendqi<SWI24:mode>_ext_1"
5207   [(set (match_operand:SWI24 0 "register_operand" "=R")
5208         (sign_extend:SWI24
5209           (subreg:QI
5210             (match_operator:SWI248 2 "extract_operator"
5211               [(match_operand 1 "int248_register_operand" "Q")
5212                (const_int 8)
5213                (const_int 8)]) 0)))]
5214   ""
5215   "movs{b<SWI24:imodesuffix>|x}\t{%h1, %0|%0, %h1}"
5216    [(set_attr "type" "imovx")
5217     (set_attr "mode" "<SWI24:MODE>")])
5219 ;; Conversions between float and double.
5221 ;; These are all no-ops in the model used for the 80387.
5222 ;; So just emit moves.
5224 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
5225 (define_split
5226   [(set (match_operand:DF 0 "push_operand")
5227         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
5228   "reload_completed"
5229   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
5230    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
5232 (define_split
5233   [(set (match_operand:XF 0 "push_operand")
5234         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
5235   "reload_completed"
5236   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
5237    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
5238   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
5240 (define_expand "extendsfdf2"
5241   [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
5242         (float_extend:DF (match_operand:SF 1 "general_operand")))]
5243   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5245   /* ??? Needed for compress_float_constant since all fp constants
5246      are TARGET_LEGITIMATE_CONSTANT_P.  */
5247   if (CONST_DOUBLE_P (operands[1]))
5248     {
5249       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
5250           && standard_80387_constant_p (operands[1]) > 0)
5251         {
5252           operands[1] = simplify_const_unary_operation
5253             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
5254           emit_move_insn_1 (operands[0], operands[1]);
5255           DONE;
5256         }
5257       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
5258     }
5261 (define_insn "*extendsfdf2"
5262   [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
5263         (float_extend:DF
5264           (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
5265   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5267   switch (which_alternative)
5268     {
5269     case 0:
5270     case 1:
5271       return output_387_reg_move (insn, operands);
5273     case 2:
5274       return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
5275     case 3:
5276       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
5278     default:
5279       gcc_unreachable ();
5280     }
5282   [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5283    (set_attr "avx_partial_xmm_update" "false,false,false,true")
5284    (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
5285    (set_attr "mode" "SF,XF,DF,DF")
5286    (set (attr "enabled")
5287      (if_then_else
5288        (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5289        (if_then_else
5290          (eq_attr "alternative" "0,1")
5291          (symbol_ref "TARGET_MIX_SSE_I387")
5292          (symbol_ref "true"))
5293        (if_then_else
5294          (eq_attr "alternative" "0,1")
5295          (symbol_ref "true")
5296          (symbol_ref "false"))))])
5298 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
5299    cvtss2sd:
5300       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
5301       cvtps2pd xmm2,xmm1
5302    We do the conversion post reload to avoid producing of 128bit spills
5303    that might lead to ICE on 32bit target.  The sequence unlikely combine
5304    anyway.  */
5305 (define_split
5306   [(set (match_operand:DF 0 "sse_reg_operand")
5307         (float_extend:DF
5308           (match_operand:SF 1 "nonimmediate_operand")))]
5309   "TARGET_USE_VECTOR_FP_CONVERTS
5310    && optimize_insn_for_speed_p ()
5311    && reload_completed
5312    && (!EXT_REX_SSE_REG_P (operands[0])
5313        || TARGET_AVX512VL)"
5314    [(set (match_dup 2)
5315          (float_extend:V2DF
5316            (vec_select:V2SF
5317              (match_dup 3)
5318              (parallel [(const_int 0) (const_int 1)]))))]
5320   operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5321   operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
5322   /* Use movss for loading from memory, unpcklps reg, reg for registers.
5323      Try to avoid move when unpacking can be done in source.  */
5324   if (REG_P (operands[1]))
5325     {
5326       /* If it is unsafe to overwrite upper half of source, we need
5327          to move to destination and unpack there.  */
5328       if (REGNO (operands[0]) != REGNO (operands[1])
5329           || (EXT_REX_SSE_REG_P (operands[1]) && !TARGET_AVX512VL))
5330         {
5331           rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
5332           emit_move_insn (tmp, operands[1]);
5333         }
5334       else
5335         operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
5336       /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
5337          =v, v, then vbroadcastss will be only needed for AVX512F without
5338          AVX512VL.  */
5339       if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
5340         emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
5341                                                operands[3]));
5342       else
5343         {
5344           rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
5345           emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
5346         }
5347     }
5348   else
5349     emit_insn (gen_vec_setv4sf_0 (operands[3],
5350                                   CONST0_RTX (V4SFmode), operands[1]));
5353 ;; It's more profitable to split and then extend in the same register.
5354 (define_peephole2
5355   [(set (match_operand:DF 0 "sse_reg_operand")
5356         (float_extend:DF
5357           (match_operand:SF 1 "memory_operand")))]
5358   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5359    && optimize_insn_for_speed_p ()"
5360   [(set (match_dup 2) (match_dup 1))
5361    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
5362   "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
5364 ;; Break partial SSE register dependency stall.  This splitter should split
5365 ;; late in the pass sequence (after register rename pass), so allocated
5366 ;; registers won't change anymore
5368 (define_split
5369   [(set (match_operand:DF 0 "sse_reg_operand")
5370         (float_extend:DF
5371           (match_operand:SF 1 "nonimmediate_operand")))]
5372   "!TARGET_AVX
5373    && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5374    && epilogue_completed
5375    && optimize_function_for_speed_p (cfun)
5376    && (!REG_P (operands[1])
5377        || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5378    && (!EXT_REX_SSE_REG_P (operands[0])
5379        || TARGET_AVX512VL)"
5380   [(set (match_dup 0)
5381         (vec_merge:V2DF
5382           (vec_duplicate:V2DF
5383             (float_extend:DF
5384               (match_dup 1)))
5385           (match_dup 0)
5386           (const_int 1)))]
5388   operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5389   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5392 (define_expand "extendhfsf2"
5393   [(set (match_operand:SF 0 "register_operand")
5394         (float_extend:SF
5395           (match_operand:HF 1 "nonimmediate_operand")))]
5396   "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5398   if (!TARGET_AVX512FP16)
5399     {
5400       rtx res = gen_reg_rtx (V4SFmode);
5401       rtx tmp = gen_reg_rtx (V8HFmode);
5402       rtx zero = force_reg (V8HFmode, CONST0_RTX (V8HFmode));
5404       emit_insn (gen_vec_setv8hf_0 (tmp, zero, operands[1]));
5405       emit_insn (gen_vcvtph2ps (res, gen_lowpart (V8HImode, tmp)));
5406       emit_move_insn (operands[0], gen_lowpart (SFmode, res));
5407       DONE;
5408     }
5411 (define_expand "extendhfdf2"
5412   [(set (match_operand:DF 0 "register_operand")
5413         (float_extend:DF
5414           (match_operand:HF 1 "nonimmediate_operand")))]
5415   "TARGET_AVX512FP16")
5417 (define_insn "*extendhf<mode>2"
5418   [(set (match_operand:MODEF 0 "register_operand" "=v")
5419         (float_extend:MODEF
5420           (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5421   "TARGET_AVX512FP16"
5422   "vcvtsh2<ssemodesuffix>\t{%1, %0, %0|%0, %0, %1}"
5423   [(set_attr "type" "ssecvt")
5424    (set_attr "prefix" "evex")
5425    (set_attr "mode" "<MODE>")])
5427 (define_expand "extendbfsf2"
5428   [(set (match_operand:SF 0 "register_operand")
5429         (unspec:SF
5430           [(match_operand:BF 1 "register_operand")]
5431          UNSPEC_CVTBFSF))]
5432  "TARGET_SSE2 && !HONOR_NANS (BFmode)")
5434 ;; Don't use float_extend since psrlld doesn't raise
5435 ;; exceptions and turn a sNaN into a qNaN.
5436 (define_insn "extendbfsf2_1"
5437   [(set (match_operand:SF 0 "register_operand"   "=x,Yv,v")
5438         (unspec:SF
5439           [(match_operand:BF 1 "register_operand" " 0,Yv,v")]
5440           UNSPEC_CVTBFSF))]
5441  "TARGET_SSE2"
5442  "@
5443   pslld\t{$16, %0|%0, 16}
5444   vpslld\t{$16, %1, %0|%0, %1, 16}
5445   vpslld\t{$16, %g1, %g0|%g0, %g1, 16}"
5446   [(set_attr "isa" "noavx,avx,*")
5447    (set_attr "type" "sseishft1")
5448    (set_attr "length_immediate" "1")
5449    (set_attr "prefix_data16" "1,*,*")
5450    (set_attr "prefix" "orig,maybe_evex,evex")
5451    (set_attr "mode" "TI,TI,XI")
5452    (set_attr "memory" "none")
5453    (set (attr "enabled")
5454      (if_then_else (eq_attr "alternative" "2")
5455        (symbol_ref "TARGET_AVX512F && TARGET_EVEX512
5456                     && !TARGET_AVX512VL && !TARGET_PREFER_AVX256")
5457        (const_string "*")))])
5459 (define_expand "extend<mode>xf2"
5460   [(set (match_operand:XF 0 "nonimmediate_operand")
5461         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
5462   "TARGET_80387"
5464   /* ??? Needed for compress_float_constant since all fp constants
5465      are TARGET_LEGITIMATE_CONSTANT_P.  */
5466   if (CONST_DOUBLE_P (operands[1]))
5467     {
5468       if (standard_80387_constant_p (operands[1]) > 0)
5469         {
5470           operands[1] = simplify_const_unary_operation
5471             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
5472           emit_move_insn_1 (operands[0], operands[1]);
5473           DONE;
5474         }
5475       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
5476     }
5479 (define_insn "*extend<mode>xf2_i387"
5480   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
5481         (float_extend:XF
5482           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
5483   "TARGET_80387"
5484   "* return output_387_reg_move (insn, operands);"
5485   [(set_attr "type" "fmov")
5486    (set_attr "mode" "<MODE>,XF")])
5488 ;; %%% This seems like bad news.
5489 ;; This cannot output into an f-reg because there is no way to be sure
5490 ;; of truncating in that case.  Otherwise this is just like a simple move
5491 ;; insn.  So we pretend we can output to a reg in order to get better
5492 ;; register preferencing, but we really use a stack slot.
5494 ;; Conversion from DFmode to SFmode.
5496 (define_insn "truncdfsf2"
5497   [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
5498         (float_truncate:SF
5499           (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
5500   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5502   switch (which_alternative)
5503     {
5504     case 0:
5505     case 1:
5506       return output_387_reg_move (insn, operands);
5508     case 2:
5509       return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
5510     case 3:
5511       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
5513     default:
5514       gcc_unreachable ();
5515     }
5517   [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5518    (set_attr "avx_partial_xmm_update" "false,false,false,true")
5519    (set_attr "mode" "SF")
5520    (set (attr "enabled")
5521      (if_then_else
5522        (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5523        (cond [(eq_attr "alternative" "0")
5524                 (symbol_ref "TARGET_MIX_SSE_I387")
5525               (eq_attr "alternative" "1")
5526                 (symbol_ref "TARGET_MIX_SSE_I387
5527                              && flag_unsafe_math_optimizations")
5528            ]
5529            (symbol_ref "true"))
5530        (cond [(eq_attr "alternative" "0")
5531                 (symbol_ref "true")
5532               (eq_attr "alternative" "1")
5533                 (symbol_ref "flag_unsafe_math_optimizations")
5534            ]
5535            (symbol_ref "false"))))])
5537 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
5538    cvtsd2ss:
5539       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
5540       cvtpd2ps xmm2,xmm1
5541    We do the conversion post reload to avoid producing of 128bit spills
5542    that might lead to ICE on 32bit target.  The sequence unlikely combine
5543    anyway.  */
5544 (define_split
5545   [(set (match_operand:SF 0 "sse_reg_operand")
5546         (float_truncate:SF
5547           (match_operand:DF 1 "nonimmediate_operand")))]
5548   "TARGET_USE_VECTOR_FP_CONVERTS
5549    && optimize_insn_for_speed_p ()
5550    && reload_completed
5551    && (!EXT_REX_SSE_REG_P (operands[0])
5552        || TARGET_AVX512VL)"
5553    [(set (match_dup 2)
5554          (vec_concat:V4SF
5555            (float_truncate:V2SF
5556              (match_dup 4))
5557            (match_dup 3)))]
5559   operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5560   operands[3] = CONST0_RTX (V2SFmode);
5561   operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
5562   /* Use movsd for loading from memory, unpcklpd for registers.
5563      Try to avoid move when unpacking can be done in source, or SSE3
5564      movddup is available.  */
5565   if (REG_P (operands[1]))
5566     {
5567       if ((!TARGET_SSE3 && REGNO (operands[0]) != REGNO (operands[1]))
5568           || (EXT_REX_SSE_REG_P (operands[1]) && !TARGET_AVX512VL))
5569         {
5570           rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
5571           emit_move_insn (tmp, operands[1]);
5572           operands[1] = tmp;
5573         }
5574       else if (!TARGET_SSE3)
5575         operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
5576       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
5577     }
5578   else
5579     emit_insn (gen_vec_concatv2df (operands[4], operands[1],
5580                                    CONST0_RTX (DFmode)));
5583 ;; It's more profitable to split and then truncate in the same register.
5584 (define_peephole2
5585   [(set (match_operand:SF 0 "sse_reg_operand")
5586         (float_truncate:SF
5587           (match_operand:DF 1 "memory_operand")))]
5588   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5589    && optimize_insn_for_speed_p ()"
5590   [(set (match_dup 2) (match_dup 1))
5591    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
5592   "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
5594 ;; Break partial SSE register dependency stall.  This splitter should split
5595 ;; late in the pass sequence (after register rename pass), so allocated
5596 ;; registers won't change anymore
5598 (define_split
5599   [(set (match_operand:SF 0 "sse_reg_operand")
5600         (float_truncate:SF
5601           (match_operand:DF 1 "nonimmediate_operand")))]
5602   "!TARGET_AVX
5603    && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5604    && epilogue_completed
5605    && optimize_function_for_speed_p (cfun)
5606    && (!REG_P (operands[1])
5607        || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5608    && (!EXT_REX_SSE_REG_P (operands[0])
5609        || TARGET_AVX512VL)"
5610   [(set (match_dup 0)
5611         (vec_merge:V4SF
5612           (vec_duplicate:V4SF
5613             (float_truncate:SF
5614               (match_dup 1)))
5615           (match_dup 0)
5616           (const_int 1)))]
5618   operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5619   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5622 ;; Conversion from XFmode to {SF,DF}mode
5624 (define_insn "truncxf<mode>2"
5625   [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
5626         (float_truncate:MODEF
5627           (match_operand:XF 1 "register_operand" "f,f")))]
5628   "TARGET_80387"
5629   "* return output_387_reg_move (insn, operands);"
5630   [(set_attr "type" "fmov")
5631    (set_attr "mode" "<MODE>")
5632    (set (attr "enabled")
5633      (cond [(eq_attr "alternative" "1")
5634               (symbol_ref "flag_unsafe_math_optimizations")
5635            ]
5636            (symbol_ref "true")))])
5638 ;; Conversion from {SF,DF}mode to HFmode.
5640 (define_expand "truncsfhf2"
5641   [(set (match_operand:HF 0 "register_operand")
5642         (float_truncate:HF
5643           (match_operand:SF 1 "nonimmediate_operand")))]
5644   "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5645   {
5646     if (!TARGET_AVX512FP16)
5647     {
5648       rtx res = gen_reg_rtx (V8HFmode);
5649       rtx tmp = gen_reg_rtx (V4SFmode);
5650       rtx zero = force_reg (V4SFmode, CONST0_RTX (V4SFmode));
5652       emit_insn (gen_vec_setv4sf_0 (tmp, zero, operands[1]));
5653       emit_insn (gen_vcvtps2ph (gen_lowpart (V8HImode, res), tmp, GEN_INT (4)));
5654       emit_move_insn (operands[0], gen_lowpart (HFmode, res));
5655       DONE;
5656     }
5657   })
5659 (define_expand "truncdfhf2"
5660   [(set (match_operand:HF 0 "register_operand")
5661         (float_truncate:HF
5662           (match_operand:DF 1 "nonimmediate_operand")))]
5663   "TARGET_AVX512FP16")
5665 (define_insn "*trunc<mode>hf2"
5666   [(set (match_operand:HF 0 "register_operand" "=v")
5667        (float_truncate:HF
5668          (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5669   "TARGET_AVX512FP16"
5670   "vcvt<ssemodesuffix>2sh\t{%1, %d0|%d0, %1}"
5671   [(set_attr "type" "ssecvt")
5672    (set_attr "prefix" "evex")
5673    (set_attr "mode" "HF")])
5675 (define_insn "truncsfbf2"
5676   [(set (match_operand:BF 0 "register_operand" "=x,x,v,Yv")
5677         (float_truncate:BF
5678           (match_operand:SF 1 "register_operand" "0,x,v,Yv")))]
5679   "TARGET_SSE2 && flag_unsafe_math_optimizations && !HONOR_NANS (BFmode)"
5680   "@
5681   psrld\t{$16, %0|%0, 16}
5682   %{vex%} vcvtneps2bf16\t{%1, %0|%0, %1}
5683   vcvtneps2bf16\t{%1, %0|%0, %1}
5684   vpsrld\t{$16, %1, %0|%0, %1, 16}"
5685   [(set_attr "isa" "noavx,avxneconvert,avx512bf16vl,avx")
5686    (set_attr "prefix" "orig,vex,evex,vex")
5687    (set_attr "type" "sseishft1,ssecvt,ssecvt,sseishft1")])
5689 ;; Signed conversion to DImode.
5691 (define_expand "fix_truncxfdi2"
5692   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5693                    (fix:DI (match_operand:XF 1 "register_operand")))
5694               (clobber (reg:CC FLAGS_REG))])]
5695   "TARGET_80387"
5697   if (TARGET_FISTTP)
5698    {
5699      emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5700      DONE;
5701    }
5704 (define_expand "fix_trunc<mode>di2"
5705   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5706                    (fix:DI (match_operand:MODEF 1 "register_operand")))
5707               (clobber (reg:CC FLAGS_REG))])]
5708   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
5710   if (TARGET_FISTTP
5711       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5712    {
5713      emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5714      DONE;
5715    }
5716   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
5717    {
5718      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
5719      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
5720      if (out != operands[0])
5721         emit_move_insn (operands[0], out);
5722      DONE;
5723    }
5726 (define_insn "fix<fixunssuffix>_trunchf<mode>2"
5727   [(set (match_operand:SWI48 0 "register_operand" "=r")
5728         (any_fix:SWI48
5729           (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5730   "TARGET_AVX512FP16"
5731   "vcvttsh2<fixsuffix>si\t{%1, %0|%0, %1}"
5732   [(set_attr "type" "sseicvt")
5733    (set_attr "prefix" "evex")
5734    (set_attr "mode" "<MODE>")])
5736 ;; Signed conversion to SImode.
5738 (define_expand "fix_truncxfsi2"
5739   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5740                    (fix:SI (match_operand:XF 1 "register_operand")))
5741               (clobber (reg:CC FLAGS_REG))])]
5742   "TARGET_80387"
5744   if (TARGET_FISTTP)
5745    {
5746      emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5747      DONE;
5748    }
5751 (define_expand "fix_trunc<mode>si2"
5752   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5753                    (fix:SI (match_operand:MODEF 1 "register_operand")))
5754               (clobber (reg:CC FLAGS_REG))])]
5755   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
5757   if (TARGET_FISTTP
5758       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5759    {
5760      emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5761      DONE;
5762    }
5763   if (SSE_FLOAT_MODE_P (<MODE>mode))
5764    {
5765      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
5766      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
5767      if (out != operands[0])
5768         emit_move_insn (operands[0], out);
5769      DONE;
5770    }
5773 ;; Signed conversion to HImode.
5775 (define_expand "fix_trunc<mode>hi2"
5776   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
5777                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
5778               (clobber (reg:CC FLAGS_REG))])]
5779   "TARGET_80387
5780    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5782   if (TARGET_FISTTP)
5783    {
5784      emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
5785      DONE;
5786    }
5789 ;; Unsigned conversion to DImode
5791 (define_insn "fixuns_trunc<mode>di2"
5792   [(set (match_operand:DI 0 "register_operand" "=r")
5793         (unsigned_fix:DI
5794           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5795   "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5796   "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5797   [(set_attr "type" "sseicvt")
5798    (set_attr "prefix" "evex")
5799    (set_attr "mode" "DI")])
5801 ;; Unsigned conversion to SImode.
5803 (define_expand "fixuns_trunc<mode>si2"
5804   [(parallel
5805     [(set (match_operand:SI 0 "register_operand")
5806           (unsigned_fix:SI
5807             (match_operand:MODEF 1 "nonimmediate_operand")))
5808      (use (match_dup 2))
5809      (clobber (scratch:<ssevecmode>))
5810      (clobber (scratch:<ssevecmode>))])]
5811   "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
5813   machine_mode mode = <MODE>mode;
5814   machine_mode vecmode = <ssevecmode>mode;
5815   REAL_VALUE_TYPE TWO31r;
5816   rtx two31;
5818   if (TARGET_AVX512F)
5819     {
5820       emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
5821       DONE;
5822     }
5824   if (optimize_insn_for_size_p ())
5825     FAIL;
5827   real_ldexp (&TWO31r, &dconst1, 31);
5828   two31 = const_double_from_real_value (TWO31r, mode);
5829   two31 = ix86_build_const_vector (vecmode, true, two31);
5830   operands[2] = force_reg (vecmode, two31);
5833 (define_insn "fixuns_trunc<mode>si2_avx512f"
5834   [(set (match_operand:SI 0 "register_operand" "=r")
5835         (unsigned_fix:SI
5836           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5837   "TARGET_AVX512F && TARGET_SSE_MATH"
5838   "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5839   [(set_attr "type" "sseicvt")
5840    (set_attr "prefix" "evex")
5841    (set_attr "mode" "SI")])
5843 (define_insn "*fixuns_trunchfsi2zext"
5844   [(set (match_operand:DI 0 "register_operand" "=r")
5845         (zero_extend:DI
5846           (unsigned_fix:SI
5847             (match_operand:HF 1 "nonimmediate_operand" "vm"))))]
5848   "TARGET_64BIT && TARGET_AVX512FP16"
5849   "vcvttsh2usi\t{%1, %k0|%k0, %1}"
5850   [(set_attr "type" "sseicvt")
5851    (set_attr "prefix" "evex")
5852    (set_attr "mode" "SI")])
5854 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
5855   [(set (match_operand:DI 0 "register_operand" "=r")
5856         (zero_extend:DI
5857           (unsigned_fix:SI
5858             (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
5859   "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5860   "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
5861   [(set_attr "type" "sseicvt")
5862    (set_attr "prefix" "evex")
5863    (set_attr "mode" "SI")])
5865 (define_insn_and_split "*fixuns_trunc<mode>_1"
5866   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5867         (unsigned_fix:SI
5868           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5869    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
5870    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5871    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5872   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5873    && optimize_function_for_speed_p (cfun)"
5874   "#"
5875   "&& reload_completed"
5876   [(const_int 0)]
5878   ix86_split_convert_uns_si_sse (operands);
5879   DONE;
5882 ;; Unsigned conversion to HImode.
5883 ;; Without these patterns, we'll try the unsigned SI conversion which
5884 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5886 (define_expand "fixuns_trunchfhi2"
5887   [(set (match_dup 2)
5888         (fix:SI (match_operand:HF 1 "nonimmediate_operand")))
5889    (set (match_operand:HI 0 "nonimmediate_operand")
5890         (subreg:HI (match_dup 2) 0))]
5891   "TARGET_AVX512FP16"
5892   "operands[2] = gen_reg_rtx (SImode);")
5894 (define_expand "fixuns_trunc<mode>hi2"
5895   [(set (match_dup 2)
5896         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5897    (set (match_operand:HI 0 "nonimmediate_operand")
5898         (subreg:HI (match_dup 2) 0))]
5899   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5900   "operands[2] = gen_reg_rtx (SImode);")
5902 ;; When SSE is available, it is always faster to use it!
5903 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5904   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5905         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5906   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5907    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5908   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5909   [(set_attr "type" "sseicvt")
5910    (set_attr "prefix" "maybe_vex")
5911    (set (attr "prefix_rex")
5912         (if_then_else
5913           (match_test "<SWI48:MODE>mode == DImode")
5914           (const_string "1")
5915           (const_string "*")))
5916    (set_attr "mode" "<MODEF:MODE>")
5917    (set_attr "athlon_decode" "double,vector")
5918    (set_attr "amdfam10_decode" "double,double")
5919    (set_attr "bdver1_decode" "double,double")])
5921 ;; Avoid vector decoded forms of the instruction.
5922 (define_peephole2
5923   [(match_scratch:MODEF 2 "x")
5924    (set (match_operand:SWI48 0 "register_operand")
5925         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5926   "TARGET_AVOID_VECTOR_DECODE
5927    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5928    && optimize_insn_for_speed_p ()"
5929   [(set (match_dup 2) (match_dup 1))
5930    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5932 (define_insn "fix_trunc<mode>_i387_fisttp"
5933   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
5934         (fix:SWI248x (match_operand 1 "register_operand" "f")))
5935    (clobber (match_scratch:XF 2 "=&f"))]
5936   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5937    && TARGET_FISTTP
5938    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5939          && (TARGET_64BIT || <MODE>mode != DImode))
5940         && TARGET_SSE_MATH)"
5941   "* return output_fix_trunc (insn, operands, true);"
5942   [(set_attr "type" "fisttp")
5943    (set_attr "mode" "<MODE>")])
5945 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5946 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5947 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5948 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5949 ;; function in i386.cc.
5950 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5951   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5952         (fix:SWI248x (match_operand 1 "register_operand")))
5953    (clobber (reg:CC FLAGS_REG))]
5954   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5955    && !TARGET_FISTTP
5956    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5957          && (TARGET_64BIT || <MODE>mode != DImode))
5958    && ix86_pre_reload_split ()"
5959   "#"
5960   "&& 1"
5961   [(const_int 0)]
5963   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5965   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5966   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5968   emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5969                                        operands[2], operands[3]));
5970   DONE;
5972   [(set_attr "type" "fistp")
5973    (set_attr "i387_cw" "trunc")
5974    (set_attr "mode" "<MODE>")])
5976 (define_insn "fix_truncdi_i387"
5977   [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
5978         (fix:DI (match_operand 1 "register_operand" "f")))
5979    (use (match_operand:HI 2 "memory_operand" "m"))
5980    (use (match_operand:HI 3 "memory_operand" "m"))
5981    (clobber (match_scratch:XF 4 "=&f"))]
5982   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5983    && !TARGET_FISTTP
5984    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5985   "* return output_fix_trunc (insn, operands, false);"
5986   [(set_attr "type" "fistp")
5987    (set_attr "i387_cw" "trunc")
5988    (set_attr "mode" "DI")])
5990 (define_insn "fix_trunc<mode>_i387"
5991   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
5992         (fix:SWI24 (match_operand 1 "register_operand" "f")))
5993    (use (match_operand:HI 2 "memory_operand" "m"))
5994    (use (match_operand:HI 3 "memory_operand" "m"))]
5995   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5996    && !TARGET_FISTTP
5997    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5998   "* return output_fix_trunc (insn, operands, false);"
5999   [(set_attr "type" "fistp")
6000    (set_attr "i387_cw" "trunc")
6001    (set_attr "mode" "<MODE>")])
6003 (define_insn "x86_fnstcw_1"
6004   [(set (match_operand:HI 0 "memory_operand" "=m")
6005         (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
6006   "TARGET_80387"
6007   "fnstcw\t%0"
6008   [(set (attr "length")
6009         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
6010    (set_attr "mode" "HI")
6011    (set_attr "unit" "i387")
6012    (set_attr "bdver1_decode" "vector")])
6014 ;; Conversion between fixed point and floating point.
6016 ;; Even though we only accept memory inputs, the backend _really_
6017 ;; wants to be able to do this between registers.  Thankfully, LRA
6018 ;; will fix this up for us during register allocation.
6020 (define_insn "floathi<mode>2"
6021   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
6022         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
6023   "TARGET_80387
6024    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
6025        || TARGET_MIX_SSE_I387)"
6026   "fild%Z1\t%1"
6027   [(set_attr "type" "fmov")
6028    (set_attr "mode" "<MODE>")
6029    (set_attr "znver1_decode" "double")
6030    (set_attr "fp_int_src" "true")])
6032 (define_insn "float<SWI48x:mode>xf2"
6033   [(set (match_operand:XF 0 "register_operand" "=f")
6034         (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
6035   "TARGET_80387"
6036   "fild%Z1\t%1"
6037   [(set_attr "type" "fmov")
6038    (set_attr "mode" "XF")
6039    (set_attr "znver1_decode" "double")
6040    (set_attr "fp_int_src" "true")])
6042 (define_expand "float<SWI48x:mode><MODEF:mode>2"
6043   [(set (match_operand:MODEF 0 "register_operand")
6044         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
6045   "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
6046    || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
6047        && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
6049 (define_insn "*float<SWI48:mode><MODEF:mode>2"
6050   [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
6051         (float:MODEF
6052           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
6053   "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
6054    || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
6055   "@
6056    fild%Z1\t%1
6057    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
6058    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
6059   [(set_attr "type" "fmov,sseicvt,sseicvt")
6060    (set_attr "avx_partial_xmm_update" "false,true,true")
6061    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
6062    (set_attr "mode" "<MODEF:MODE>")
6063    (set (attr "prefix_rex")
6064      (if_then_else
6065        (and (eq_attr "prefix" "maybe_vex")
6066             (match_test "<SWI48:MODE>mode == DImode"))
6067        (const_string "1")
6068        (const_string "*")))
6069    (set_attr "unit" "i387,*,*")
6070    (set_attr "athlon_decode" "*,double,direct")
6071    (set_attr "amdfam10_decode" "*,vector,double")
6072    (set_attr "bdver1_decode" "*,double,direct")
6073    (set_attr "znver1_decode" "double,*,*")
6074    (set_attr "fp_int_src" "true")
6075    (set (attr "enabled")
6076      (if_then_else
6077        (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
6078        (if_then_else
6079          (eq_attr "alternative" "0")
6080          (symbol_ref "TARGET_MIX_SSE_I387
6081                       && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
6082                                            <SWI48:MODE>mode)")
6083          (symbol_ref "true"))
6084        (if_then_else
6085          (eq_attr "alternative" "0")
6086          (symbol_ref "true")
6087          (symbol_ref "false"))))
6088    (set (attr "preferred_for_speed")
6089      (cond [(eq_attr "alternative" "1")
6090               (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
6091            (symbol_ref "true")))])
6093 (define_insn "float<floatunssuffix><mode>hf2"
6094   [(set (match_operand:HF 0 "register_operand" "=v")
6095         (any_float:HF
6096           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
6097   "TARGET_AVX512FP16"
6098   "vcvt<floatsuffix>si2sh<rex64suffix>\t{%1, %d0|%d0, %1}"
6099   [(set_attr "type" "sseicvt")
6100    (set_attr "prefix" "evex")
6101    (set_attr "mode" "HF")])
6103 (define_insn "*floatdi<MODEF:mode>2_i387"
6104   [(set (match_operand:MODEF 0 "register_operand" "=f")
6105         (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
6106   "!TARGET_64BIT
6107    && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
6108   "fild%Z1\t%1"
6109   [(set_attr "type" "fmov")
6110    (set_attr "mode" "<MODEF:MODE>")
6111    (set_attr "znver1_decode" "double")
6112    (set_attr "fp_int_src" "true")])
6114 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
6115 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
6116 ;; alternative in sse2_loadld.
6117 (define_split
6118   [(set (match_operand:MODEF 0 "sse_reg_operand")
6119         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
6120   "TARGET_SSE2
6121    && TARGET_USE_VECTOR_CONVERTS
6122    && optimize_function_for_speed_p (cfun)
6123    && reload_completed
6124    && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
6125    && (!EXT_REX_SSE_REG_P (operands[0])
6126        || TARGET_AVX512VL)"
6127   [(const_int 0)]
6129   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
6130   operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
6132   emit_insn (gen_sse2_loadld (operands[4],
6133                               CONST0_RTX (V4SImode), operands[1]));
6135   if (<ssevecmode>mode == V4SFmode)
6136     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
6137   else
6138     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
6139   DONE;
6142 ;; Avoid store forwarding (partial memory) stall penalty
6143 ;; by passing DImode value through XMM registers.  */
6145 (define_split
6146   [(set (match_operand:X87MODEF 0 "register_operand")
6147         (float:X87MODEF
6148           (match_operand:DI 1 "register_operand")))]
6149   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
6150    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6151    && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
6152    && can_create_pseudo_p ()"
6153   [(const_int 0)]
6155   rtx s = assign_386_stack_local (DImode, SLOT_FLOATxFDI_387);
6156   emit_insn (gen_floatdi<mode>2_i387_with_xmm (operands[0], operands[1], s));
6157   DONE;
6160 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
6161   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
6162         (float:X87MODEF
6163           (match_operand:DI 1 "register_operand" "r,r")))
6164    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
6165    (clobber (match_scratch:V4SI 3 "=x,x"))
6166    (clobber (match_scratch:V4SI 4 "=X,x"))]
6167   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
6168    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6169    && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
6170   "#"
6171   "&& reload_completed"
6172   [(set (match_dup 2) (match_dup 3))
6173    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
6175   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
6176      Assemble the 64-bit DImode value in an xmm register.  */
6177   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
6178                               gen_lowpart (SImode, operands[1])));
6179   if (TARGET_SSE4_1)
6180     emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
6181                                   gen_highpart (SImode, operands[1]),
6182                                   GEN_INT (2)));
6183   else
6184     {
6185       emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
6186                                   gen_highpart (SImode, operands[1])));
6187       emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
6188                                              operands[4]));
6189     }
6190   operands[3] = gen_lowpart (DImode, operands[3]);
6192   [(set_attr "isa" "sse4,*")
6193    (set_attr "type" "multi")
6194    (set_attr "mode" "<X87MODEF:MODE>")
6195    (set_attr "unit" "i387")
6196    (set_attr "fp_int_src" "true")])
6198 ;; Break partial SSE register dependency stall.  This splitter should split
6199 ;; late in the pass sequence (after register rename pass), so allocated
6200 ;; registers won't change anymore
6202 (define_split
6203   [(set (match_operand:MODEF 0 "sse_reg_operand")
6204         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
6205   "!TARGET_AVX
6206    && TARGET_SSE_PARTIAL_REG_CONVERTS_DEPENDENCY
6207    && epilogue_completed
6208    && optimize_function_for_speed_p (cfun)
6209    && (!EXT_REX_SSE_REG_P (operands[0])
6210        || TARGET_AVX512VL)"
6211   [(set (match_dup 0)
6212         (vec_merge:<MODEF:ssevecmode>
6213           (vec_duplicate:<MODEF:ssevecmode>
6214             (float:MODEF
6215               (match_dup 1)))
6216           (match_dup 0)
6217           (const_int 1)))]
6219   const machine_mode vmode = <MODEF:ssevecmode>mode;
6221   operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
6222   emit_move_insn (operands[0], CONST0_RTX (vmode));
6225 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
6226   [(set (match_operand:MODEF 0 "register_operand")
6227         (unsigned_float:MODEF
6228           (match_operand:SWI12 1 "nonimmediate_operand")))]
6229   "!TARGET_64BIT
6230    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
6232   operands[1] = convert_to_mode (SImode, operands[1], 1);
6233   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
6234   DONE;
6237 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
6238   [(set (match_operand:MODEF 0 "register_operand" "=v")
6239         (unsigned_float:MODEF
6240           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
6241   "TARGET_AVX512F && TARGET_SSE_MATH"
6242   "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
6243   [(set_attr "type" "sseicvt")
6244    (set_attr "avx_partial_xmm_update" "true")
6245    (set_attr "prefix" "evex")
6246    (set_attr "mode" "<MODEF:MODE>")])
6248 ;; Avoid store forwarding (partial memory) stall penalty by extending
6249 ;; SImode value to DImode through XMM register instead of pushing two
6250 ;; SImode values to stack. Also note that fild loads from memory only.
6252 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
6253   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
6254         (unsigned_float:X87MODEF
6255           (match_operand:SI 1 "nonimmediate_operand" "rm")))
6256    (clobber (match_operand:DI 2 "memory_operand" "=m"))
6257    (clobber (match_scratch:DI 3 "=x"))]
6258   "!TARGET_64BIT
6259    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6260    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
6261   "#"
6262   "&& reload_completed"
6263   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
6264    (set (match_dup 2) (match_dup 3))
6265    (set (match_dup 0)
6266         (float:X87MODEF (match_dup 2)))]
6267   ""
6268   [(set_attr "type" "multi")
6269    (set_attr "mode" "<MODE>")])
6271 (define_expand "floatunssi<mode>2"
6272   [(set (match_operand:X87MODEF 0 "register_operand")
6273         (unsigned_float:X87MODEF
6274           (match_operand:SI 1 "nonimmediate_operand")))]
6275   "(!TARGET_64BIT
6276     && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6277     && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
6278    || ((!TARGET_64BIT || TARGET_AVX512F)
6279        && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6281   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
6282     {
6283       emit_insn (gen_floatunssi<mode>2_i387_with_xmm
6284                   (operands[0], operands[1],
6285                    assign_386_stack_local (DImode, SLOT_TEMP)));
6286       DONE;
6287     }
6288   if (!TARGET_AVX512F)
6289     {
6290       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6291       DONE;
6292     }
6295 (define_expand "floatunsdisf2"
6296   [(set (match_operand:SF 0 "register_operand")
6297         (unsigned_float:SF
6298           (match_operand:DI 1 "nonimmediate_operand")))]
6299   "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
6301   if (!TARGET_AVX512F)
6302     {
6303       x86_emit_floatuns (operands);
6304       DONE;
6305     }
6308 (define_expand "floatunsdidf2"
6309   [(set (match_operand:DF 0 "register_operand")
6310         (unsigned_float:DF
6311           (match_operand:DI 1 "nonimmediate_operand")))]
6312   "((TARGET_64BIT && TARGET_AVX512F)
6313     || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6314    && TARGET_SSE2 && TARGET_SSE_MATH"
6316   if (!TARGET_64BIT)
6317     {
6318       ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6319       DONE;
6320     }
6321   if (!TARGET_AVX512F)
6322     {
6323       x86_emit_floatuns (operands);
6324       DONE;
6325     }
6328 ;; Load effective address instructions
6330 (define_insn "*lea<mode>"
6331   [(set (match_operand:SWI48 0 "register_operand" "=r")
6332         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
6333   "ix86_hardreg_mov_ok (operands[0], operands[1])"
6335   if (SImode_address_operand (operands[1], VOIDmode))
6336     {
6337       gcc_assert (TARGET_64BIT);
6338       return "lea{l}\t{%E1, %k0|%k0, %E1}";
6339     }
6340   else
6341     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
6343   [(set_attr "type" "lea")
6344    (set (attr "mode")
6345      (if_then_else
6346        (match_operand 1 "SImode_address_operand")
6347        (const_string "SI")
6348        (const_string "<MODE>")))])
6350 (define_peephole2
6351   [(set (match_operand:SWI48 0 "register_operand")
6352         (match_operand:SWI48 1 "address_no_seg_operand"))]
6353   "ix86_hardreg_mov_ok (operands[0], operands[1])
6354    && peep2_regno_dead_p (0, FLAGS_REG)
6355    && ix86_avoid_lea_for_addr (peep2_next_insn (0), operands)"
6356   [(const_int 0)]
6358   machine_mode mode = <MODE>mode;
6360   /* Emit all operations in SImode for zero-extended addresses.  */
6361   if (SImode_address_operand (operands[1], VOIDmode))
6362     mode = SImode;
6364   ix86_split_lea_for_addr (peep2_next_insn (0), operands, mode);
6366   /* Zero-extend return register to DImode for zero-extended addresses.  */
6367   if (mode != <MODE>mode)
6368     emit_insn (gen_zero_extendsidi2 (operands[0],
6369                                      gen_lowpart (mode, operands[0])));
6371   DONE;
6374 ;; ix86_split_lea_for_addr emits the shifts as MULT to avoid it from being
6375 ;; peephole2 optimized back into a lea.  Split that into the shift during
6376 ;; the following split pass.
6377 (define_split
6378   [(set (match_operand:SWI48 0 "general_reg_operand")
6379         (mult:SWI48 (match_dup 0) (match_operand:SWI48 1 "const1248_operand")))
6380    (clobber (reg:CC FLAGS_REG))]
6381   "reload_completed"
6382   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
6383               (clobber (reg:CC FLAGS_REG))])]
6384   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
6386 (define_split
6387   [(set (match_operand:SWI48 0 "general_reg_operand")
6388         (mult:SWI48 (match_dup 0) (match_operand:SWI48 1 "const1248_operand")))]
6389   "TARGET_APX_NF && reload_completed"
6390   [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))]
6391   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
6393 ;; The peephole2 pass may expose consecutive additions suitable for lea.
6394 (define_peephole2
6395   [(parallel [(set (match_operand:SWI48 0 "register_operand")
6396                    (plus:SWI48 (match_dup 0)
6397                                (match_operand 1 "register_operand")))
6398               (clobber (reg:CC FLAGS_REG))])
6399    (parallel [(set (match_dup 0)
6400                    (plus:SWI48 (match_dup 0)
6401                                (match_operand 2 "x86_64_immediate_operand")))
6402               (clobber (reg:CC FLAGS_REG))])]
6403   "!TARGET_AVOID_LEA_FOR_ADDR || optimize_function_for_size_p (cfun)"
6404   [(set (match_dup 0) (plus:SWI48 (plus:SWI48 (match_dup 0)
6405                                               (match_dup 1))
6406                                   (match_dup 2)))])
6408 ;; Add instructions
6410 (define_expand "add<mode>3"
6411   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6412         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6413                     (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6414   ""
6416   ix86_expand_binary_operator (PLUS, <MODE>mode, operands, TARGET_APX_NDD);
6417   DONE;
6420 (define_insn_and_split "*add<dwi>3_doubleword"
6421   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r,&r,&r,&r")
6422         (plus:<DWI>
6423           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r,ro,jO,r")
6424           (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r,<di>,K,<di>,r")))
6425    (clobber (reg:CC FLAGS_REG))]
6426   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands, TARGET_APX_NDD)"
6427   "#"
6428   "&& reload_completed"
6429   [(parallel [(set (reg:CCC FLAGS_REG)
6430                    (compare:CCC
6431                      (plus:DWIH (match_dup 1) (match_dup 2))
6432                      (match_dup 1)))
6433               (set (match_dup 0)
6434                    (plus:DWIH (match_dup 1) (match_dup 2)))])
6435    (parallel [(set (match_dup 3)
6436                    (plus:DWIH
6437                      (plus:DWIH
6438                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6439                        (match_dup 4))
6440                      (match_dup 5)))
6441               (clobber (reg:CC FLAGS_REG))])]
6443   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6444   if (operands[2] == const0_rtx)
6445     {
6446       /* Under NDD op0 and op1 may not equal, do not delete insn then.  */
6447       bool emit_insn_deleted_note_p = true;
6448       if (!rtx_equal_p (operands[0], operands[1]))
6449         {
6450           emit_move_insn (operands[0], operands[1]);
6451           emit_insn_deleted_note_p = false;
6452         }
6453       if (operands[5] != const0_rtx)
6454         ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3],
6455                                      TARGET_APX_NDD);
6456       else if (!rtx_equal_p (operands[3], operands[4]))
6457         emit_move_insn (operands[3], operands[4]);
6458       else if (emit_insn_deleted_note_p)
6459         emit_note (NOTE_INSN_DELETED);
6460       DONE;
6461     }
6463 [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd_64,apx_ndd")])
6465 (define_insn_and_split "*add<dwi>3_doubleword_zext"
6466   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,&r,&r")
6467         (plus:<DWI>
6468           (zero_extend:<DWI>
6469             (match_operand:DWIH 2 "nonimmediate_operand" "rm,r,rm,r"))
6470           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0,r,o")))
6471    (clobber (reg:CC FLAGS_REG))]
6472   "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands, TARGET_APX_NDD)"
6473   "#"
6474   "&& reload_completed"
6475   [(parallel [(set (reg:CCC FLAGS_REG)
6476                    (compare:CCC
6477                      (plus:DWIH (match_dup 1) (match_dup 2))
6478                      (match_dup 1)))
6479               (set (match_dup 0)
6480                    (plus:DWIH (match_dup 1) (match_dup 2)))])
6481    (parallel [(set (match_dup 3)
6482                    (plus:DWIH
6483                      (plus:DWIH
6484                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6485                        (match_dup 4))
6486                      (const_int 0)))
6487               (clobber (reg:CC FLAGS_REG))])]
6488  "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);"
6489  [(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
6491 (define_insn_and_split "*add<dwi>3_doubleword_concat"
6492   [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6493         (plus:<DWI>
6494           (any_or_plus:<DWI>
6495             (ashift:<DWI>
6496               (zero_extend:<DWI>
6497                 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6498               (match_operand:QI 3 "const_int_operand"))
6499             (zero_extend:<DWI>
6500               (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6501           (match_operand:<DWI> 1 "register_operand" "0")))
6502    (clobber (reg:CC FLAGS_REG))]
6503   "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6504   "#"
6505   "&& reload_completed"
6506   [(parallel [(set (reg:CCC FLAGS_REG)
6507                    (compare:CCC
6508                      (plus:DWIH (match_dup 1) (match_dup 4))
6509                      (match_dup 1)))
6510               (set (match_dup 0)
6511                    (plus:DWIH (match_dup 1) (match_dup 4)))])
6512    (parallel [(set (match_dup 5)
6513                    (plus:DWIH
6514                      (plus:DWIH
6515                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6516                        (match_dup 6))
6517                      (match_dup 2)))
6518               (clobber (reg:CC FLAGS_REG))])]
6519  "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[5]);")
6521 (define_insn_and_split "*add<dwi>3_doubleword_concat_zext"
6522   [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6523         (plus:<DWI>
6524           (any_or_plus:<DWI>
6525             (ashift:<DWI>
6526               (zero_extend:<DWI>
6527                 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6528               (match_operand:QI 3 "const_int_operand"))
6529             (zero_extend:<DWI>
6530               (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6531           (zero_extend:<DWI>
6532             (match_operand:DWIH 1 "nonimmediate_operand" "rm"))))
6533    (clobber (reg:CC FLAGS_REG))]
6534   "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6535   "#"
6536   "&& reload_completed"
6537   [(set (match_dup 0) (match_dup 4))
6538    (parallel [(set (reg:CCC FLAGS_REG)
6539                    (compare:CCC
6540                      (plus:DWIH (match_dup 0) (match_dup 1))
6541                      (match_dup 0)))
6542               (set (match_dup 0)
6543                    (plus:DWIH (match_dup 0) (match_dup 1)))])
6544    (set (match_dup 5) (match_dup 2))
6545    (parallel [(set (match_dup 5)
6546                    (plus:DWIH
6547                      (plus:DWIH
6548                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6549                        (match_dup 5))
6550                      (const_int 0)))
6551               (clobber (reg:CC FLAGS_REG))])]
6552  "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[5]);")
6554 (define_subst_attr "nf_name" "nf_subst" "_nf" "")
6555 (define_subst_attr "nf_prefix" "nf_subst" "%{nf%} " "")
6556 (define_subst_attr "nf_condition" "nf_subst" "TARGET_APX_NF" "true")
6557 (define_subst_attr "nf_add_mem_constraint" "nf_subst" "je" "m")
6558 (define_subst_attr "nf_mem_constraint" "nf_subst" "jM" "m")
6559 (define_subst_attr "nf_applied" "nf_subst" "true" "false")
6560 (define_subst_attr "nf_nonf_attr" "nf_subst"  "noapx_nf" "*")
6561 (define_subst_attr "nf_nonf_x64_attr" "nf_subst" "noapx_nf" "x64")
6563 (define_subst "nf_subst"
6564   [(set (match_operand:SWIDWI 0)
6565         (match_operand:SWIDWI 1))]
6566   ""
6567   [(set (match_dup 0)
6568         (match_dup 1))
6569         (clobber (reg:CC FLAGS_REG))])
6571 (define_insn "*add<mode>_1<nf_name>"
6572   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r<nf_add_mem_constraint>,r<nf_mem_constraint>,r,r,r,r,r,r")
6573         (plus:SWI48
6574           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,0,r,r,rje,jM,r")
6575           (match_operand:SWI48 2 "x86_64_general_operand" "r,e,BM,0,le,r,e,BM")))]
6576   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
6577   && <nf_condition>"
6579   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
6580   switch (get_attr_type (insn))
6581     {
6582     case TYPE_LEA:
6583       if (TARGET_APX_NDD && <nf_applied>)
6584         return "%{nf%} add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}";
6585       else
6586         return "#";
6588     case TYPE_INCDEC:
6589       if (operands[2] == const1_rtx)
6590         return use_ndd ? "<nf_prefix>inc{<imodesuffix>}\t{%1, %0|%0, %1}"
6591                        : "<nf_prefix>inc{<imodesuffix>}\t%0";
6592       else
6593         {
6594           gcc_assert (operands[2] == constm1_rtx);
6595           return use_ndd ? "<nf_prefix>dec{<imodesuffix>}\t{%1, %0|%0, %1}"
6596                          : "<nf_prefix>dec{<imodesuffix>}\t%0";
6597         }
6599     default:
6600       /* For most processors, ADD is faster than LEA.  This alternative
6601          was added to use ADD as much as possible.  */
6602       if (which_alternative == 3)
6603         std::swap (operands[1], operands[2]);
6604         
6605       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6606         return use_ndd ? "<nf_prefix>sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6607                        : "<nf_prefix>sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6609       return use_ndd ? "<nf_prefix>add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6610                      : "<nf_prefix>add{<imodesuffix>}\t{%2, %0|%0, %2}";
6611     }
6613   [(set_attr "isa" "*,*,*,*,*,apx_ndd,apx_ndd,apx_ndd")
6614    (set (attr "type")
6615      (cond [(eq_attr "alternative" "4")
6616               (const_string "lea")
6617             (match_operand:SWI48 2 "incdec_operand")
6618               (const_string "incdec")
6619            ]
6620            (const_string "alu")))
6621    (set (attr "length_immediate")
6622       (if_then_else
6623         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6624         (const_string "1")
6625         (const_string "*")))
6626    (set_attr "has_nf" "1")
6627    (set_attr "mode" "<MODE>")])
6629 ;; For APX instruction with an NDD, the destination GPR  will get the
6630 ;; instruction’s result in bits [OSIZE-1:0] and, if OSIZE < 64b, have
6631 ;; its upper bits [63:OSIZE] zeroed.
6633 (define_insn "*addqi_1_zext<mode><nf_name>"
6634   [(set (match_operand:SWI248x 0 "register_operand" "=r,r")
6635         (zero_extend:SWI248x
6636           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%rm,r")
6637                    (match_operand:QI 2 "general_operand" "rn,m"))))]
6638   "TARGET_APX_NDD && <nf_condition>
6639    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6641   switch (get_attr_type (insn))
6642     {
6643     case TYPE_INCDEC:
6644       if (operands[2] == const1_rtx)
6645         return "<nf_prefix>inc{b}\t{%1, %b0|%b0, %1}";
6646       else
6647         {
6648           gcc_assert (operands[2] == constm1_rtx);
6649           return "<nf_prefix>dec{b}\t{%1, %b0|%b0, %1}";
6650         }
6652     default:
6653       if (x86_maybe_negate_const_int (&operands[2], QImode))
6654         return "<nf_prefix>sub{b}\t{%2, %1, %b0|%b0, %1, %2}";
6655       return "<nf_prefix>add{b}\t{%2, %1, %b0|%b0, %1, %2}";
6656     }
6658   [(set (attr "type")
6659      (cond [(match_operand:QI 2 "incdec_operand")
6660               (const_string "incdec")
6661            ]
6662            (const_string "alu")))
6663    (set (attr "length_immediate")
6664       (if_then_else
6665         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6666         (const_string "1")
6667         (const_string "*")))
6668    (set_attr "has_nf" "1")
6669    (set_attr "mode" "QI")])
6671 (define_insn "*addhi_1_zext<mode><nf_name>"
6672   [(set (match_operand:SWI48x 0 "register_operand" "=r,r")
6673         (zero_extend:SWI48x
6674           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,r")
6675                    (match_operand:HI 2 "general_operand" "rn,m"))))]
6676   "TARGET_APX_NDD && <nf_condition>
6677    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6679   switch (get_attr_type (insn))
6680     {
6681     case TYPE_INCDEC:
6682       if (operands[2] == const1_rtx)
6683         return "<nf_prefix>inc{w}\t{%1, %w0|%w0, %1}";
6684       else
6685         {
6686           gcc_assert (operands[2] == constm1_rtx);
6687           return "<nf_prefix>dec{w}\t{%1, %w0|%w0, %1}";
6688         }
6690     default:
6691       if (x86_maybe_negate_const_int (&operands[2], HImode))
6692         return "<nf_prefix>sub{w}\t{%2, %1, %w0|%w0, %1, %2}";
6693       return "<nf_prefix>add{w}\t{%2, %1, %w0|%w0, %1, %2}";
6694     }
6696   [(set (attr "type")
6697      (cond [(match_operand:QI 2 "incdec_operand")
6698               (const_string "incdec")
6699            ]
6700            (const_string "alu")))
6701    (set (attr "length_immediate")
6702       (if_then_else
6703         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6704         (const_string "1")
6705         (const_string "*")))
6706    (set_attr "has_nf" "1")
6707    (set_attr "mode" "HI")])
6709 ;; It may seem that nonimmediate operand is proper one for operand 1.
6710 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6711 ;; we take care in ix86_binary_operator_ok to not allow two memory
6712 ;; operands so proper swapping will be done in reload.  This allow
6713 ;; patterns constructed from addsi_1 to match.
6715 (define_insn "addsi_1_zext"
6716   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r")
6717         (zero_extend:DI
6718           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r,r,rm,rjM")
6719                    (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le,rBMe,r,e"))))
6720    (clobber (reg:CC FLAGS_REG))]
6721   "TARGET_64BIT
6722    && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
6724   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
6725   switch (get_attr_type (insn))
6726     {
6727     case TYPE_LEA:
6728       return "#";
6730     case TYPE_INCDEC:
6731       if (operands[2] == const1_rtx)
6732         return use_ndd ? "inc{l}\t{%1, %k0|%k0, %1}"
6733                        : "inc{l}\t%k0";
6734       else
6735         {
6736           gcc_assert (operands[2] == constm1_rtx);
6737           return use_ndd ? "dec{l}\t{%1, %k0|%k0, %1}"
6738                          : "dec{l}\t%k0";
6739         }
6741     default:
6742       /* For most processors, ADD is faster than LEA.  This alternative
6743          was added to use ADD as much as possible.  */
6744       if (which_alternative == 1)
6745         std::swap (operands[1], operands[2]);
6747       if (x86_maybe_negate_const_int (&operands[2], SImode))
6748         return use_ndd ? "sub{l}\t{%2 ,%1, %k0|%k0, %1, %2}"
6749                        : "sub{l}\t{%2, %k0|%k0, %2}";
6751       return use_ndd ? "add{l}\t{%2 ,%1, %k0|%k0, %1, %2}"
6752                      : "add{l}\t{%2, %k0|%k0, %2}";
6753     }
6755   [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd")
6756    (set (attr "type")
6757      (cond [(eq_attr "alternative" "2")
6758               (const_string "lea")
6759             (match_operand:SI 2 "incdec_operand")
6760               (const_string "incdec")
6761            ]
6762            (const_string "alu")))
6763    (set (attr "length_immediate")
6764       (if_then_else
6765         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6766         (const_string "1")
6767         (const_string "*")))
6768    (set_attr "mode" "SI")])
6770 (define_insn "*addhi_1<nf_name>"
6771   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp,r,r")
6772         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp,rm,r")
6773                  (match_operand:HI 2 "general_operand" "rn,m,0,ln,rn,m")))]
6774   "ix86_binary_operator_ok (PLUS, HImode, operands, TARGET_APX_NDD)
6775   && <nf_condition>"
6777   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
6778   switch (get_attr_type (insn))
6779     {
6780     case TYPE_LEA:
6781       if (TARGET_APX_NDD && <nf_applied>)
6782         return "%{nf%} add{w}\t{%2, %1, %0|%0, %1, %2}";
6783       else
6784         return "#";
6786     case TYPE_INCDEC:
6787       if (operands[2] == const1_rtx)
6788         return use_ndd ? "<nf_prefix>inc{w}\t{%1, %0|%0, %1}"
6789                        : "<nf_prefix>inc{w}\t%0";
6790       else
6791         {
6792           gcc_assert (operands[2] == constm1_rtx);
6793           return use_ndd ? "<nf_prefix>dec{w}\t{%1, %0|%0, %1}"
6794                          : "<nf_prefix>dec{w}\t%0";
6795         }
6797     default:
6798       /* For most processors, ADD is faster than LEA.  This alternative
6799          was added to use ADD as much as possible.  */
6800       if (which_alternative == 2)
6801         std::swap (operands[1], operands[2]);
6803       if (x86_maybe_negate_const_int (&operands[2], HImode))
6804         return use_ndd ? "<nf_prefix>sub{w}\t{%2, %1, %0|%0, %1, %2}"
6805                        : "<nf_prefix>sub{w}\t{%2, %0|%0, %2}";
6807       return use_ndd ? "<nf_prefix>add{w}\t{%2, %1, %0|%0, %1, %2}"
6808                      : "<nf_prefix>add{w}\t{%2, %0|%0, %2}";
6809     }
6811   [(set_attr "isa" "*,*,*,*,apx_ndd,apx_ndd")
6812    (set (attr "type")
6813      (cond [(eq_attr "alternative" "3")
6814               (const_string "lea")
6815             (match_operand:HI 2 "incdec_operand")
6816               (const_string "incdec")
6817            ]
6818            (const_string "alu")))
6819    (set (attr "length_immediate")
6820       (if_then_else
6821         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6822         (const_string "1")
6823         (const_string "*")))
6824    (set_attr "has_nf" "1")
6825    (set_attr "mode" "HI,HI,HI,SI,HI,HI")])
6827 (define_insn "*addqi_1<nf_name>"
6828   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp,r,r")
6829         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp,rm,r")
6830                  (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln,rn,m")))]
6831   "ix86_binary_operator_ok (PLUS, QImode, operands, TARGET_APX_NDD)
6832   && <nf_condition>"
6834   bool widen = (get_attr_mode (insn) != MODE_QI);
6835   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
6836   switch (get_attr_type (insn))
6837     {
6838     case TYPE_LEA:
6839       if (TARGET_APX_NDD && <nf_applied>)
6840         return "%{nf%} add{b}\t{%2, %1, %0|%0, %1, %2}";
6841       else
6842         return "#";
6844     case TYPE_INCDEC:
6845       if (operands[2] == const1_rtx)
6846         if (use_ndd)
6847           return "<nf_prefix>inc{b}\t{%1, %0|%0, %1}";
6848         else
6849           return widen ? "<nf_prefix>inc{l}\t%k0" : "<nf_prefix>inc{b}\t%0";
6850       else
6851         {
6852           gcc_assert (operands[2] == constm1_rtx);
6853           if (use_ndd)
6854             return "<nf_prefix>dec{b}\t{%1, %0|%0, %1}";
6855           else
6856             return widen ? "<nf_prefix>dec{l}\t%k0" : "<nf_prefix>dec{b}\t%0";
6857         }
6859     default:
6860       /* For most processors, ADD is faster than LEA.  These alternatives
6861          were added to use ADD as much as possible.  */
6862       if (which_alternative == 2 || which_alternative == 4)
6863         std::swap (operands[1], operands[2]);
6865       if (x86_maybe_negate_const_int (&operands[2], QImode))
6866         {
6867           if (use_ndd)
6868             return "<nf_prefix>sub{b}\t{%2, %1, %0|%0, %1, %2}";
6869           else
6870             return widen ? "<nf_prefix>sub{l}\t{%2, %k0|%k0, %2}"
6871                          : "<nf_prefix>sub{b}\t{%2, %0|%0, %2}";
6872         }
6873       if (use_ndd)
6874         return "<nf_prefix>add{b}\t{%2, %1, %0|%0, %1, %2}";
6875       else
6876         return widen ? "<nf_prefix>add{l}\t{%k2, %k0|%k0, %k2}"
6877                      : "<nf_prefix>add{b}\t{%2, %0|%0, %2}";
6878     }
6880   [(set_attr "isa" "*,*,*,*,*,*,apx_ndd,apx_ndd")
6881    (set (attr "type")
6882      (cond [(eq_attr "alternative" "5")
6883               (const_string "lea")
6884             (match_operand:QI 2 "incdec_operand")
6885               (const_string "incdec")
6886            ]
6887            (const_string "alu")))
6888    (set (attr "length_immediate")
6889       (if_then_else
6890         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6891         (const_string "1")
6892         (const_string "*")))
6893    (set_attr "has_nf" "1")
6894    (set_attr "mode" "QI,QI,QI,SI,SI,SI,QI,QI")
6895    ;; Potential partial reg stall on alternatives 3 and 4.
6896    (set (attr "preferred_for_speed")
6897      (cond [(eq_attr "alternative" "3,4")
6898               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
6899            (symbol_ref "true")))])
6901 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6902 (define_insn_and_split "*add<mode>_1_slp"
6903   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
6904         (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
6905                     (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
6906    (clobber (reg:CC FLAGS_REG))]
6907   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6909   if (which_alternative)
6910     return "#";
6912   switch (get_attr_type (insn))
6913     {
6914     case TYPE_INCDEC:
6915       if (operands[2] == const1_rtx)
6916         return "inc{<imodesuffix>}\t%0";
6917       else
6918         {
6919           gcc_assert (operands[2] == constm1_rtx);
6920           return "dec{<imodesuffix>}\t%0";
6921         }
6923     default:
6924       if (x86_maybe_negate_const_int (&operands[2], QImode))
6925         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6927       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6928     }
6930   "&& reload_completed
6931    && !(rtx_equal_p (operands[0], operands[1])
6932         || rtx_equal_p (operands[0], operands[2]))"
6933   [(set (strict_low_part (match_dup 0)) (match_dup 1))
6934    (parallel
6935      [(set (strict_low_part (match_dup 0))
6936            (plus:SWI12 (match_dup 0) (match_dup 2)))
6937       (clobber (reg:CC FLAGS_REG))])]
6938   ""
6939   [(set (attr "type")
6940      (if_then_else (match_operand:QI 2 "incdec_operand")
6941         (const_string "incdec")
6942         (const_string "alu")))
6943    (set_attr "mode" "<MODE>")])
6945 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6946 (define_insn_and_split "*addqi_ext<mode>_1_slp"
6947   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
6948         (plus:QI
6949           (subreg:QI
6950             (match_operator:SWI248 3 "extract_operator"
6951               [(match_operand 2 "int248_register_operand" "Q,Q")
6952                (const_int 8)
6953                (const_int 8)]) 0)
6954           (match_operand:QI 1 "nonimmediate_operand" "0,!qm")))
6955    (clobber (reg:CC FLAGS_REG))]
6956   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6957   "@
6958    add{b}\t{%h2, %0|%0, %h2}
6959    #"
6960   "&& reload_completed
6961    && !rtx_equal_p (operands[0], operands[1])"
6962   [(set (strict_low_part (match_dup 0)) (match_dup 1))
6963    (parallel
6964      [(set (strict_low_part (match_dup 0))
6965            (plus:QI
6966              (subreg:QI
6967                (match_op_dup 3
6968                  [(match_dup 2) (const_int 8) (const_int 8)]) 0)
6969              (match_dup 0)))
6970       (clobber (reg:CC FLAGS_REG))])]
6971   ""
6972   [(set_attr "type" "alu")
6973    (set_attr "mode" "QI")])
6975 (define_insn_and_split "*addqi_ext<mode>_2_slp"
6976   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
6977         (plus:QI
6978           (subreg:QI
6979             (match_operator:SWI248 3 "extract_operator"
6980               [(match_operand 1 "int248_register_operand" "Q")
6981                (const_int 8)
6982                (const_int 8)]) 0)
6983           (subreg:QI
6984             (match_operator:SWI248 4 "extract_operator"
6985               [(match_operand 2 "int248_register_operand" "Q")
6986                (const_int 8)
6987                (const_int 8)]) 0)))
6988    (clobber (reg:CC FLAGS_REG))]
6989   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6990   "#"
6991   "&& reload_completed"
6992   [(set (strict_low_part (match_dup 0))
6993         (subreg:QI
6994           (match_op_dup 4
6995             [(match_dup 2) (const_int 8) (const_int 8)]) 0))
6996    (parallel
6997      [(set (strict_low_part (match_dup 0))
6998            (plus:QI
6999              (subreg:QI
7000                (match_op_dup 3
7001                  [(match_dup 1) (const_int 8) (const_int 8)]) 0)
7002              (match_dup 0)))
7003       (clobber (reg:CC FLAGS_REG))])]
7004   ""
7005   [(set_attr "type" "alu")
7006    (set_attr "mode" "QI")])
7008 ;; Split non destructive adds if we cannot use lea.
7009 (define_split
7010   [(set (match_operand:SWI48 0 "register_operand")
7011         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
7012                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
7013    (clobber (reg:CC FLAGS_REG))]
7014   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
7015   [(set (match_dup 0) (match_dup 1))
7016    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
7017               (clobber (reg:CC FLAGS_REG))])])
7019 ;; Split non destructive adds if we cannot use lea.
7020 (define_split
7021   [(set (match_operand:DI 0 "register_operand")
7022         (zero_extend:DI
7023           (plus:SI (match_operand:SI 1 "register_operand")
7024                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
7025    (clobber (reg:CC FLAGS_REG))]
7026   "TARGET_64BIT
7027    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
7028   [(set (match_dup 3) (match_dup 1))
7029    (parallel [(set (match_dup 0)
7030                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
7031               (clobber (reg:CC FLAGS_REG))])]
7032   "operands[3] = gen_lowpart (SImode, operands[0]);")
7034 ;; Convert add to the lea pattern to avoid flags dependency.
7035 (define_split
7036   [(set (match_operand:SWI 0 "register_operand")
7037         (plus:SWI (match_operand:SWI 1 "register_operand")
7038                   (match_operand:SWI 2 "<nonmemory_operand>")))
7039    (clobber (reg:CC FLAGS_REG))]
7040   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
7041   [(set (match_dup 0)
7042         (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
7044   if (<MODE>mode != <LEAMODE>mode)
7045     {
7046       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
7047       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
7048       operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
7049     }
7052 (define_split
7053   [(set (match_operand:SWI 0 "register_operand")
7054         (plus:SWI (match_operand:SWI 1 "register_operand")
7055                   (match_operand:SWI 2 "<nonmemory_operand>")))]
7056   "TARGET_APX_NF && reload_completed
7057    && ix86_lea_for_add_ok (insn, operands)"
7058   [(set (match_dup 0)
7059         (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
7061   if (<MODE>mode != <LEAMODE>mode)
7062     {
7063       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
7064       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
7065       operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
7066     }
7069 ;; Convert add to the lea pattern to avoid flags dependency.
7070 (define_split
7071   [(set (match_operand:DI 0 "register_operand")
7072         (zero_extend:DI
7073           (plus:SI (match_operand:SI 1 "register_operand")
7074                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
7075    (clobber (reg:CC FLAGS_REG))]
7076   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
7077   [(set (match_dup 0)
7078         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
7080 (define_insn "*add<mode>_2"
7081   [(set (reg FLAGS_REG)
7082         (compare
7083           (plus:SWI
7084             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>,rm,r")
7085             (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,0,r<i>,<m>"))
7086           (const_int 0)))
7087    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>,r,r")
7088         (plus:SWI (match_dup 1) (match_dup 2)))]
7089   "ix86_match_ccmode (insn, CCGOCmode)
7090    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
7092   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
7093   switch (get_attr_type (insn))
7094     {
7095     case TYPE_INCDEC:
7096       if (operands[2] == const1_rtx)
7097         return use_ndd ? "inc{<imodesuffix>}\t{%1, %0|%0, %1}"
7098                        : "inc{<imodesuffix>}\t%0";
7099       else
7100         {
7101           gcc_assert (operands[2] == constm1_rtx);
7102           return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}"
7103                          : "dec{<imodesuffix>}\t%0";
7104         }
7106     default:
7107       if (which_alternative == 2)
7108         std::swap (operands[1], operands[2]);
7109         
7110       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
7111         return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7112                        : "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
7114       return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7115                      : "add{<imodesuffix>}\t{%2, %0|%0, %2}";
7116     }
7118   [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd")
7119    (set (attr "type")
7120      (if_then_else (match_operand:SWI 2 "incdec_operand")
7121         (const_string "incdec")
7122         (const_string "alu")))
7123    (set (attr "length_immediate")
7124       (if_then_else
7125         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7126         (const_string "1")
7127         (const_string "*")))
7128    (set_attr "mode" "<MODE>")])
7130 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7131 (define_insn "*addsi_2_zext"
7132   [(set (reg FLAGS_REG)
7133         (compare
7134           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r,rm")
7135                    (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,rBMe,re"))
7136           (const_int 0)))
7137    (set (match_operand:DI 0 "register_operand" "=r,r,r,r")
7138         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7139   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7140    && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
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{l}\t{%1, %k0|%k0, %1}"
7148                        : "inc{l}\t%k0";
7149       else
7150         {
7151           gcc_assert (operands[2] == constm1_rtx);
7152           return use_ndd ? "dec{l}\t{%1, %k0|%k0, %1}"
7153                          : "dec{l}\t%k0";
7154         }
7156     default:
7157       if (which_alternative == 1)
7158         std::swap (operands[1], operands[2]);
7160       if (x86_maybe_negate_const_int (&operands[2], SImode))
7161         return use_ndd ? "sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
7162                        : "sub{l}\t{%2, %k0|%k0, %2}";
7164       return use_ndd ? "add{l}\t{%2, %1, %k0|%k0, %1, %2}"
7165                      : "add{l}\t{%2, %k0|%k0, %2}";
7166     }
7168   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
7169    (set (attr "type")
7170      (if_then_else (match_operand:SI 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" "SI")])
7180 (define_insn "*add<mode>_3"
7181   [(set (reg FLAGS_REG)
7182         (compare
7183           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0,<g>,re"))
7184           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>,r,rm")))
7185    (clobber (match_scratch:SWI 0 "=<r>,<r>,r,r"))]
7186   "ix86_match_ccmode (insn, CCZmode)
7187    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7189   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
7190   switch (get_attr_type (insn))
7191     {
7192     case TYPE_INCDEC:
7193       if (operands[2] == const1_rtx)
7194         return use_ndd ? "inc{<imodesuffix>}\t{%1, %0|%0, %1}"
7195                        : "inc{<imodesuffix>}\t%0";
7196       else
7197         {
7198           gcc_assert (operands[2] == constm1_rtx);
7199           return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}"
7200                          : "dec{<imodesuffix>}\t%0";
7201         }
7203     default:
7204       if (which_alternative == 1)
7205         std::swap (operands[1], operands[2]);
7207       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
7208         return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7209                        : "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
7211       return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7212                      : "add{<imodesuffix>}\t{%2, %0|%0, %2}";
7213     }
7215   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
7216    (set (attr "type")
7217      (if_then_else (match_operand:SWI 2 "incdec_operand")
7218         (const_string "incdec")
7219         (const_string "alu")))
7220    (set (attr "length_immediate")
7221       (if_then_else
7222         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7223         (const_string "1")
7224         (const_string "*")))
7225    (set_attr "mode" "<MODE>")])
7227 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7228 (define_insn "*addsi_3_zext"
7229   [(set (reg FLAGS_REG)
7230         (compare
7231           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,rBMe,re"))
7232           (match_operand:SI 1 "nonimmediate_operand" "%0,r,r,rm")))
7233    (set (match_operand:DI 0 "register_operand" "=r,r,r,r")
7234         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7235   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
7236    && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
7238   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
7239   switch (get_attr_type (insn))
7240     {
7241     case TYPE_INCDEC:
7242       if (operands[2] == const1_rtx)
7243         return use_ndd ? "inc{l}\t{%1, %k0|%k0, %1}" : "inc{l}\t%k0";
7244       else
7245         {
7246           gcc_assert (operands[2] == constm1_rtx);
7247           return use_ndd ? "dec{l}\t{%1, %k0|%k0, %1}" : "dec{l}\t%k0";
7248         }
7250     default:
7251       if (which_alternative == 1)
7252         std::swap (operands[1], operands[2]);
7254       if (x86_maybe_negate_const_int (&operands[2], SImode))
7255         return use_ndd ? "sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
7256                        : "sub{l}\t{%2, %k0|%k0, %2}";
7258       return use_ndd ? "add{l}\t{%2, %1, %k0|%k0, %1, %2}"
7259                      : "add{l}\t{%2, %k0|%k0, %2}";
7260     }
7262   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
7263    (set (attr "type")
7264      (if_then_else (match_operand:SI 2 "incdec_operand")
7265         (const_string "incdec")
7266         (const_string "alu")))
7267    (set (attr "length_immediate")
7268       (if_then_else
7269         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7270         (const_string "1")
7271         (const_string "*")))
7272    (set_attr "mode" "SI")])
7274 ; For comparisons against 1, -1 and 128, we may generate better code
7275 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
7276 ; is matched then.  We can't accept general immediate, because for
7277 ; case of overflows,  the result is messed up.
7278 ; Also carry flag is reversed compared to cmp, so this conversion is valid
7279 ; only for comparisons not depending on it.
7281 (define_insn "*adddi_4"
7282   [(set (reg FLAGS_REG)
7283         (compare
7284           (match_operand:DI 1 "nonimmediate_operand" "0")
7285           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
7286    (clobber (match_scratch:DI 0 "=r"))]
7287   "TARGET_64BIT
7288    && ix86_match_ccmode (insn, CCGCmode)"
7290   switch (get_attr_type (insn))
7291     {
7292     case TYPE_INCDEC:
7293       if (operands[2] == constm1_rtx)
7294         return "inc{q}\t%0";
7295       else
7296         {
7297           gcc_assert (operands[2] == const1_rtx);
7298           return "dec{q}\t%0";
7299         }
7301     default:
7302       if (x86_maybe_negate_const_int (&operands[2], DImode))
7303         return "add{q}\t{%2, %0|%0, %2}";
7305       return "sub{q}\t{%2, %0|%0, %2}";
7306     }
7308   [(set (attr "type")
7309      (if_then_else (match_operand:DI 2 "incdec_operand")
7310         (const_string "incdec")
7311         (const_string "alu")))
7312    (set (attr "length_immediate")
7313       (if_then_else
7314         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7315         (const_string "1")
7316         (const_string "*")))
7317    (set_attr "mode" "DI")])
7319 ; For comparisons against 1, -1 and 128, we may generate better code
7320 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
7321 ; is matched then.  We can't accept general immediate, because for
7322 ; case of overflows,  the result is messed up.
7323 ; Also carry flag is reversed compared to cmp, so this conversion is valid
7324 ; only for comparisons not depending on it.
7326 (define_insn "*add<mode>_4"
7327   [(set (reg FLAGS_REG)
7328         (compare
7329           (match_operand:SWI124 1 "nonimmediate_operand" "0")
7330           (match_operand:SWI124 2 "const_int_operand")))
7331    (clobber (match_scratch:SWI124 0 "=<r>"))]
7332   "ix86_match_ccmode (insn, CCGCmode)"
7334   switch (get_attr_type (insn))
7335     {
7336     case TYPE_INCDEC:
7337       if (operands[2] == constm1_rtx)
7338         return "inc{<imodesuffix>}\t%0";
7339       else
7340         {
7341           gcc_assert (operands[2] == const1_rtx);
7342           return "dec{<imodesuffix>}\t%0";
7343         }
7345     default:
7346       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
7347         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
7349       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
7350     }
7352   [(set (attr "type")
7353      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
7354         (const_string "incdec")
7355         (const_string "alu")))
7356    (set (attr "length_immediate")
7357       (if_then_else
7358         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7359         (const_string "1")
7360         (const_string "*")))
7361    (set_attr "mode" "<MODE>")])
7363 (define_insn "*add<mode>_5"
7364   [(set (reg FLAGS_REG)
7365         (compare
7366           (plus:SWI
7367             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>,r,rm")
7368             (match_operand:SWI 2 "<general_operand>" "<g>,0,<g>,re"))
7369           (const_int 0)))
7370    (clobber (match_scratch:SWI 0 "=<r>,<r>,r,r"))]
7371   "ix86_match_ccmode (insn, CCGOCmode)
7372    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7374   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
7375   switch (get_attr_type (insn))
7376     {
7377     case TYPE_INCDEC:
7378       if (operands[2] == const1_rtx)
7379         return use_ndd ? "inc{<imodesuffix>}\t{%1, %0|%0, %1}"
7380                        : "inc{<imodesuffix>}\t%0";
7381       else
7382         {
7383           gcc_assert (operands[2] == constm1_rtx);
7384           return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}"
7385                          : "dec{<imodesuffix>}\t%0";
7386         }
7388     default:
7389       if (which_alternative == 1)
7390         std::swap (operands[1], operands[2]);
7392       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
7393         return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7394                        : "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
7396       return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7397                      : "add{<imodesuffix>}\t{%2, %0|%0, %2}";
7398     }
7400   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
7401    (set (attr "type")
7402      (if_then_else (match_operand:SWI 2 "incdec_operand")
7403         (const_string "incdec")
7404         (const_string "alu")))
7405    (set (attr "length_immediate")
7406       (if_then_else
7407         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7408         (const_string "1")
7409         (const_string "*")))
7410    (set_attr "mode" "<MODE>")])
7412 (define_insn "*addqi_ext<mode>_0"
7413   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
7414         (plus:QI
7415           (subreg:QI
7416             (match_operator:SWI248 3 "extract_operator"
7417               [(match_operand 2 "int248_register_operand" "Q")
7418                (const_int 8)
7419                (const_int 8)]) 0)
7420           (match_operand:QI 1 "nonimmediate_operand" "0")))
7421    (clobber (reg:CC FLAGS_REG))]
7422   ""
7423   "add{b}\t{%h2, %0|%0, %h2}"
7424   [(set_attr "addr" "gpr8")
7425    (set_attr "type" "alu")
7426    (set_attr "mode" "QI")])
7428 (define_insn_and_split "*addqi_ext2<mode>_0"
7429   [(set (match_operand:QI 0 "register_operand" "=&Q")
7430         (plus:QI
7431           (subreg:QI
7432             (match_operator:SWI248 3 "extract_operator"
7433               [(match_operand 1 "int248_register_operand" "Q")
7434                (const_int 8)
7435                (const_int 8)]) 0)
7436           (subreg:QI
7437             (match_operator:SWI248 4 "extract_operator"
7438               [(match_operand 2 "int248_register_operand" "Q")
7439                (const_int 8)
7440                (const_int 8)]) 0)))
7441    (clobber (reg:CC FLAGS_REG))]
7442   ""
7443   "#"
7444   "&& reload_completed"
7445   [(set (match_dup 0)
7446         (subreg:QI
7447           (match_op_dup 4
7448             [(match_dup 2) (const_int 8) (const_int 8)]) 0))
7449    (parallel
7450      [(set (match_dup 0)
7451            (plus:QI
7452              (subreg:QI
7453                (match_op_dup 3
7454                  [(match_dup 1) (const_int 8) (const_int 8)]) 0)
7455            (match_dup 0)))
7456       (clobber (reg:CC FLAGS_REG))])]
7457   ""
7458   [(set_attr "type" "alu")
7459    (set_attr "mode" "QI")])
7461 (define_expand "addqi_ext_1"
7462   [(parallel
7463      [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
7464                             (const_int 8)
7465                             (const_int 8))
7466            (subreg:HI
7467              (plus:QI
7468                (subreg:QI
7469                  (zero_extract:HI (match_operand:HI 1 "register_operand")
7470                                   (const_int 8)
7471                                   (const_int 8)) 0)
7472                (match_operand:QI 2 "const_int_operand")) 0))
7473       (clobber (reg:CC FLAGS_REG))])])
7475 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7476 (define_insn_and_split "*addqi_ext<mode>_1"
7477   [(set (zero_extract:SWI248
7478           (match_operand 0 "int248_register_operand" "+Q,&Q")
7479           (const_int 8)
7480           (const_int 8))
7481         (subreg:SWI248
7482           (plus:QI
7483             (subreg:QI
7484               (match_operator:SWI248 3 "extract_operator"
7485                 [(match_operand 1 "int248_register_operand" "0,!Q")
7486                  (const_int 8)
7487                  (const_int 8)]) 0)
7488             (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
7489    (clobber (reg:CC FLAGS_REG))]
7490   ""
7492   if (which_alternative)
7493     return "#";
7495   switch (get_attr_type (insn))
7496     {
7497     case TYPE_INCDEC:
7498       if (operands[2] == const1_rtx)
7499         return "inc{b}\t%h0";
7500       else
7501         {
7502           gcc_assert (operands[2] == constm1_rtx);
7503           return "dec{b}\t%h0";
7504         }
7506     default:
7507       return "add{b}\t{%2, %h0|%h0, %2}";
7508     }
7510   "reload_completed
7511    && !rtx_equal_p (operands[0], operands[1])"
7512   [(set (zero_extract:SWI248
7513           (match_dup 0) (const_int 8) (const_int 8))
7514         (zero_extract:SWI248
7515           (match_dup 1) (const_int 8) (const_int 8)))
7516    (parallel
7517      [(set (zero_extract:SWI248
7518              (match_dup 0) (const_int 8) (const_int 8))
7519            (subreg:SWI248
7520              (plus:QI
7521                (subreg:QI
7522                  (match_op_dup 3
7523                    [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7524                (match_dup 2)) 0))
7525       (clobber (reg:CC FLAGS_REG))])]
7526   ""
7527   [(set_attr "addr" "gpr8")
7528    (set (attr "type")
7529      (if_then_else (match_operand:QI 2 "incdec_operand")
7530         (const_string "incdec")
7531         (const_string "alu")))
7532    (set_attr "mode" "QI")])
7534 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7535 (define_insn_and_split "*<insn>qi_ext<mode>_2"
7536   [(set (zero_extract:SWI248
7537           (match_operand 0 "int248_register_operand" "+Q,&Q")
7538           (const_int 8)
7539           (const_int 8))
7540         (subreg:SWI248
7541           (plusminus:QI
7542             (subreg:QI
7543               (match_operator:SWI248 3 "extract_operator"
7544                 [(match_operand 1 "int248_register_operand" "<comm>0,!Q")
7545                  (const_int 8)
7546                  (const_int 8)]) 0)
7547             (subreg:QI
7548               (match_operator:SWI248 4 "extract_operator"
7549                 [(match_operand 2 "int248_register_operand" "Q,Q")
7550                  (const_int 8)
7551                  (const_int 8)]) 0)) 0))
7552    (clobber (reg:CC FLAGS_REG))]
7553   ""
7554   "@
7555    <insn>{b}\t{%h2, %h0|%h0, %h2}
7556    #"
7557   "reload_completed
7558    && !(rtx_equal_p (operands[0], operands[1])
7559         || (<CODE> == PLUS && rtx_equal_p (operands[0], operands[2])))"
7560   [(set (zero_extract:SWI248
7561           (match_dup 0) (const_int 8) (const_int 8))
7562         (zero_extract:SWI248
7563           (match_dup 1) (const_int 8) (const_int 8)))
7564    (parallel
7565      [(set (zero_extract:SWI248
7566              (match_dup 0) (const_int 8) (const_int 8))
7567            (subreg:SWI248
7568              (plusminus:QI
7569                (subreg:QI
7570                  (match_op_dup 3
7571                    [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7572                (subreg:QI
7573                  (match_op_dup 4
7574                    [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
7575       (clobber (reg:CC FLAGS_REG))])]
7576   ""
7577   [(set_attr "type" "alu")
7578    (set_attr "mode" "QI")])
7580 ;; Like DWI, but use POImode instead of OImode.
7581 (define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
7583 ;; Add with jump on overflow.
7584 (define_expand "addv<mode>4"
7585   [(parallel [(set (reg:CCO FLAGS_REG)
7586                    (eq:CCO
7587                      (plus:<DPWI>
7588                        (sign_extend:<DPWI>
7589                          (match_operand:SWIDWI 1 "nonimmediate_operand"))
7590                        (match_dup 4))
7591                          (sign_extend:<DPWI>
7592                            (plus:SWIDWI (match_dup 1)
7593                              (match_operand:SWIDWI 2
7594                                "<general_hilo_operand>")))))
7595               (set (match_operand:SWIDWI 0 "register_operand")
7596                    (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7597    (set (pc) (if_then_else
7598                (eq (reg:CCO FLAGS_REG) (const_int 0))
7599                (label_ref (match_operand 3))
7600                (pc)))]
7601   ""
7603   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
7604   if (CONST_SCALAR_INT_P (operands[2]))
7605     operands[4] = operands[2];
7606   else
7607     operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7610 (define_insn "*addv<mode>4"
7611   [(set (reg:CCO FLAGS_REG)
7612         (eq:CCO (plus:<DWI>
7613                    (sign_extend:<DWI>
7614                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r"))
7615                    (sign_extend:<DWI>
7616                       (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m,rWe,m")))
7617                 (sign_extend:<DWI>
7618                    (plus:SWI (match_dup 1) (match_dup 2)))))
7619    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
7620         (plus:SWI (match_dup 1) (match_dup 2)))]
7621   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
7622   "@
7623    add{<imodesuffix>}\t{%2, %0|%0, %2}
7624    add{<imodesuffix>}\t{%2, %0|%0, %2}
7625    add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7626    add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7627   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
7628    (set_attr "type" "alu")
7629    (set_attr "mode" "<MODE>")])
7631 (define_insn "addv<mode>4_1"
7632   [(set (reg:CCO FLAGS_REG)
7633         (eq:CCO (plus:<DWI>
7634                    (sign_extend:<DWI>
7635                       (match_operand:SWI 1 "nonimmediate_operand" "0,rm"))
7636                    (match_operand:<DWI> 3 "const_int_operand"))
7637                 (sign_extend:<DWI>
7638                    (plus:SWI
7639                      (match_dup 1)
7640                      (match_operand:SWI 2 "x86_64_immediate_operand" "<i>,<i>")))))
7641    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
7642         (plus:SWI (match_dup 1) (match_dup 2)))]
7643   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
7644    && CONST_INT_P (operands[2])
7645    && INTVAL (operands[2]) == INTVAL (operands[3])"
7646   "@
7647   add{<imodesuffix>}\t{%2, %0|%0, %2}
7648   add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7649   [(set_attr "isa" "*,apx_ndd")
7650    (set_attr "type" "alu")
7651    (set_attr "mode" "<MODE>")
7652    (set (attr "length_immediate")
7653         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7654                   (const_string "1")
7655                (match_test "<MODE_SIZE> == 8")
7656                   (const_string "4")]
7657               (const_string "<MODE_SIZE>")))])
7659 ;; Quad word integer modes as mode attribute.
7660 (define_mode_attr QPWI [(SI "TI") (DI "POI")])
7662 (define_insn_and_split "*addv<dwi>4_doubleword"
7663   [(set (reg:CCO FLAGS_REG)
7664         (eq:CCO
7665           (plus:<QPWI>
7666             (sign_extend:<QPWI>
7667               (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r"))
7668             (sign_extend:<QPWI>
7669               (match_operand:<DWI> 2 "nonimmediate_operand" "r,o,r,o")))
7670           (sign_extend:<QPWI>
7671             (plus:<DWI> (match_dup 1) (match_dup 2)))))
7672    (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r")
7673         (plus:<DWI> (match_dup 1) (match_dup 2)))]
7674   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands, TARGET_APX_NDD)"
7675   "#"
7676   "&& reload_completed"
7677   [(parallel [(set (reg:CCC FLAGS_REG)
7678                    (compare:CCC
7679                      (plus:DWIH (match_dup 1) (match_dup 2))
7680                      (match_dup 1)))
7681               (set (match_dup 0)
7682                    (plus:DWIH (match_dup 1) (match_dup 2)))])
7683    (parallel [(set (reg:CCO FLAGS_REG)
7684                    (eq:CCO
7685                      (plus:<DWI>
7686                        (plus:<DWI>
7687                          (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7688                          (sign_extend:<DWI> (match_dup 4)))
7689                        (sign_extend:<DWI> (match_dup 5)))
7690                      (sign_extend:<DWI>
7691                        (plus:DWIH
7692                          (plus:DWIH
7693                            (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7694                            (match_dup 4))
7695                          (match_dup 5)))))
7696               (set (match_dup 3)
7697                    (plus:DWIH
7698                      (plus:DWIH
7699                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7700                        (match_dup 4))
7701                      (match_dup 5)))])]
7703   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7705 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
7707 (define_insn_and_split "*addv<dwi>4_doubleword_1"
7708   [(set (reg:CCO FLAGS_REG)
7709         (eq:CCO
7710           (plus:<QPWI>
7711             (sign_extend:<QPWI>
7712               (match_operand:<DWI> 1 "nonimmediate_operand" "%0,rjO"))
7713             (match_operand:<QPWI> 3 "const_scalar_int_operand" "n,n"))
7714           (sign_extend:<QPWI>
7715             (plus:<DWI>
7716               (match_dup 1)
7717               (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>,<di>")))))
7718    (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,&r")
7719         (plus:<DWI> (match_dup 1) (match_dup 2)))]
7720   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands, TARGET_APX_NDD)
7721    && CONST_SCALAR_INT_P (operands[2])
7722    && rtx_equal_p (operands[2], operands[3])"
7723   "#"
7724   "&& reload_completed"
7725   [(parallel [(set (reg:CCC FLAGS_REG)
7726                    (compare:CCC
7727                      (plus:DWIH (match_dup 1) (match_dup 2))
7728                      (match_dup 1)))
7729               (set (match_dup 0)
7730                    (plus:DWIH (match_dup 1) (match_dup 2)))])
7731    (parallel [(set (reg:CCO FLAGS_REG)
7732                    (eq:CCO
7733                      (plus:<DWI>
7734                        (plus:<DWI>
7735                          (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7736                          (sign_extend:<DWI> (match_dup 4)))
7737                        (match_dup 5))
7738                      (sign_extend:<DWI>
7739                        (plus:DWIH
7740                          (plus:DWIH
7741                            (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7742                            (match_dup 4))
7743                          (match_dup 5)))))
7744               (set (match_dup 3)
7745                    (plus:DWIH
7746                      (plus:DWIH
7747                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7748                        (match_dup 4))
7749                      (match_dup 5)))])]
7751   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7752   if (operands[2] == const0_rtx)
7753     {
7754       if (!rtx_equal_p (operands[0], operands[1]))
7755         emit_move_insn (operands[0], operands[1]);
7756       emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
7757                                     operands[5]));
7758       DONE;
7759     }
7761 [(set_attr "isa" "*,apx_ndd")])
7763 (define_insn "*addv<mode>4_overflow_1"
7764   [(set (reg:CCO FLAGS_REG)
7765         (eq:CCO
7766           (plus:<DWI>
7767             (plus:<DWI>
7768               (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7769                 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7770               (sign_extend:<DWI>
7771                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r")))
7772             (sign_extend:<DWI>
7773               (match_operand:SWI 2 "<general_sext_operand>" "rWe,m,rWe,m")))
7774           (sign_extend:<DWI>
7775             (plus:SWI
7776               (plus:SWI
7777                 (match_operator:SWI 5 "ix86_carry_flag_operator"
7778                   [(match_dup 3) (const_int 0)])
7779                 (match_dup 1))
7780               (match_dup 2)))))
7781    (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r,r,r")
7782         (plus:SWI
7783           (plus:SWI
7784             (match_op_dup 5 [(match_dup 3) (const_int 0)])
7785             (match_dup 1))
7786           (match_dup 2)))]
7787   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
7788   "@
7789    adc{<imodesuffix>}\t{%2, %0|%0, %2}
7790    adc{<imodesuffix>}\t{%2, %0|%0, %2}
7791    adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7792    adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7793   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
7794    (set_attr "type" "alu")
7795    (set_attr "mode" "<MODE>")])
7797 (define_insn "*addv<mode>4_overflow_2"
7798   [(set (reg:CCO FLAGS_REG)
7799         (eq:CCO
7800           (plus:<DWI>
7801             (plus:<DWI>
7802               (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7803                 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7804               (sign_extend:<DWI>
7805                 (match_operand:SWI 1 "nonimmediate_operand" "%0,rm")))
7806             (match_operand:<DWI> 6 "const_int_operand" "n,n"))
7807           (sign_extend:<DWI>
7808             (plus:SWI
7809               (plus:SWI
7810                 (match_operator:SWI 5 "ix86_carry_flag_operator"
7811                   [(match_dup 3) (const_int 0)])
7812                 (match_dup 1))
7813               (match_operand:SWI 2 "x86_64_immediate_operand" "e,e")))))
7814    (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7815         (plus:SWI
7816           (plus:SWI
7817             (match_op_dup 5 [(match_dup 3) (const_int 0)])
7818             (match_dup 1))
7819           (match_dup 2)))]
7820   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
7821    && CONST_INT_P (operands[2])
7822    && INTVAL (operands[2]) == INTVAL (operands[6])"
7823   "@
7824   adc{<imodesuffix>}\t{%2, %0|%0, %2}
7825   adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7826   [(set_attr "isa" "*,apx_ndd")
7827    (set_attr "type" "alu")
7828    (set_attr "mode" "<MODE>")
7829    (set (attr "length_immediate")
7830      (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7831        (const_string "1")
7832        (const_string "4")))])
7834 (define_expand "uaddv<mode>4"
7835   [(parallel [(set (reg:CCC FLAGS_REG)
7836                    (compare:CCC
7837                      (plus:SWIDWI
7838                        (match_operand:SWIDWI 1 "nonimmediate_operand")
7839                        (match_operand:SWIDWI 2 "<general_hilo_operand>"))
7840                      (match_dup 1)))
7841               (set (match_operand:SWIDWI 0 "register_operand")
7842                    (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7843    (set (pc) (if_then_else
7844                (ltu (reg:CCC FLAGS_REG) (const_int 0))
7845                (label_ref (match_operand 3))
7846                (pc)))]
7847   ""
7848   "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
7850 ;; The lea patterns for modes less than 32 bits need to be matched by
7851 ;; several insns converted to real lea by splitters.
7853 (define_insn_and_split "*lea<mode>_general_1"
7854   [(set (match_operand:SWI12 0 "register_operand" "=r")
7855         (plus:SWI12
7856           (plus:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7857                       (match_operand:SWI12 2 "register_operand" "r"))
7858           (match_operand:SWI12 3 "immediate_operand" "i")))]
7859   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7860   "#"
7861   "&& reload_completed"
7862   [(set (match_dup 0)
7863         (plus:SI
7864           (plus:SI (match_dup 1) (match_dup 2))
7865           (match_dup 3)))]
7867   operands[0] = gen_lowpart (SImode, operands[0]);
7868   operands[1] = gen_lowpart (SImode, operands[1]);
7869   operands[2] = gen_lowpart (SImode, operands[2]);
7870   operands[3] = gen_lowpart (SImode, operands[3]);
7872   [(set_attr "type" "lea")
7873    (set_attr "mode" "SI")])
7875 (define_insn_and_split "*lea<mode>_general_2"
7876   [(set (match_operand:SWI12 0 "register_operand" "=r")
7877         (plus:SWI12
7878           (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7879                       (match_operand 2 "const248_operand" "n"))
7880           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7881   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7882   "#"
7883   "&& reload_completed"
7884   [(set (match_dup 0)
7885         (plus:SI
7886           (mult:SI (match_dup 1) (match_dup 2))
7887           (match_dup 3)))]
7889   operands[0] = gen_lowpart (SImode, operands[0]);
7890   operands[1] = gen_lowpart (SImode, operands[1]);
7891   operands[3] = gen_lowpart (SImode, operands[3]);
7893   [(set_attr "type" "lea")
7894    (set_attr "mode" "SI")])
7896 (define_insn_and_split "*lea<mode>_general_2b"
7897   [(set (match_operand:SWI12 0 "register_operand" "=r")
7898         (plus:SWI12
7899           (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7900                         (match_operand 2 "const123_operand" "n"))
7901           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7902   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7903   "#"
7904   "&& reload_completed"
7905   [(set (match_dup 0)
7906         (plus:SI
7907           (ashift:SI (match_dup 1) (match_dup 2))
7908           (match_dup 3)))]
7910   operands[0] = gen_lowpart (SImode, operands[0]);
7911   operands[1] = gen_lowpart (SImode, operands[1]);
7912   operands[3] = gen_lowpart (SImode, operands[3]);
7914   [(set_attr "type" "lea")
7915    (set_attr "mode" "SI")])
7917 (define_insn_and_split "*lea<mode>_general_3"
7918   [(set (match_operand:SWI12 0 "register_operand" "=r")
7919         (plus:SWI12
7920           (plus:SWI12
7921             (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7922                         (match_operand 2 "const248_operand" "n"))
7923             (match_operand:SWI12 3 "register_operand" "r"))
7924           (match_operand:SWI12 4 "immediate_operand" "i")))]
7925   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7926   "#"
7927   "&& reload_completed"
7928   [(set (match_dup 0)
7929         (plus:SI
7930           (plus:SI
7931             (mult:SI (match_dup 1) (match_dup 2))
7932             (match_dup 3))
7933           (match_dup 4)))]
7935   operands[0] = gen_lowpart (SImode, operands[0]);
7936   operands[1] = gen_lowpart (SImode, operands[1]);
7937   operands[3] = gen_lowpart (SImode, operands[3]);
7938   operands[4] = gen_lowpart (SImode, operands[4]);
7940   [(set_attr "type" "lea")
7941    (set_attr "mode" "SI")])
7943 (define_insn_and_split "*lea<mode>_general_3b"
7944   [(set (match_operand:SWI12 0 "register_operand" "=r")
7945         (plus:SWI12
7946           (plus:SWI12
7947             (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7948                           (match_operand 2 "const123_operand" "n"))
7949             (match_operand:SWI12 3 "register_operand" "r"))
7950           (match_operand:SWI12 4 "immediate_operand" "i")))]
7951   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7952   "#"
7953   "&& reload_completed"
7954   [(set (match_dup 0)
7955         (plus:SI
7956           (plus:SI
7957             (ashift:SI (match_dup 1) (match_dup 2))
7958             (match_dup 3))
7959           (match_dup 4)))]
7961   operands[0] = gen_lowpart (SImode, operands[0]);
7962   operands[1] = gen_lowpart (SImode, operands[1]);
7963   operands[3] = gen_lowpart (SImode, operands[3]);
7964   operands[4] = gen_lowpart (SImode, operands[4]);
7966   [(set_attr "type" "lea")
7967    (set_attr "mode" "SI")])
7969 (define_insn_and_split "*lea<mode>_general_4"
7970   [(set (match_operand:SWI12 0 "register_operand" "=r")
7971         (any_or:SWI12
7972           (ashift:SWI12
7973             (match_operand:SWI12 1 "register_no_SP_operand" "l")
7974             (match_operand 2 "const_0_to_3_operand"))
7975           (match_operand 3 "const_int_operand")))]
7976   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7977    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
7978        < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
7979   "#"
7980   "&& reload_completed"
7981   [(set (match_dup 0)
7982         (plus:SI
7983           (mult:SI (match_dup 1) (match_dup 2))
7984           (match_dup 3)))]
7986   operands[0] = gen_lowpart (SImode, operands[0]);
7987   operands[1] = gen_lowpart (SImode, operands[1]);
7988   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
7990   [(set_attr "type" "lea")
7991    (set_attr "mode" "SI")])
7993 (define_insn_and_split "*lea<mode>_general_4"
7994   [(set (match_operand:SWI48 0 "register_operand" "=r")
7995         (any_or:SWI48
7996           (ashift:SWI48
7997             (match_operand:SWI48 1 "register_no_SP_operand" "l")
7998             (match_operand 2 "const_0_to_3_operand"))
7999           (match_operand 3 "const_int_operand")))]
8000   "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
8001    < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
8002   "#"
8003   "&& reload_completed"
8004   [(set (match_dup 0)
8005         (plus:SWI48
8006           (mult:SWI48 (match_dup 1) (match_dup 2))
8007           (match_dup 3)))]
8008   "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
8009   [(set_attr "type" "lea")
8010    (set_attr "mode" "<MODE>")])
8012 ;; Subtract instructions
8014 (define_expand "sub<mode>3"
8015   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8016         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
8017                      (match_operand:SDWIM 2 "<general_hilo_operand>")))]
8018   ""
8020   ix86_expand_binary_operator (MINUS, <MODE>mode, operands, TARGET_APX_NDD);
8021   DONE;
8024 (define_insn_and_split "*sub<dwi>3_doubleword"
8025   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r")
8026         (minus:<DWI>
8027           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0,ro,r")
8028           (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r<di>,o")))
8029    (clobber (reg:CC FLAGS_REG))]
8030   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
8031   "#"
8032   "&& reload_completed"
8033   [(parallel [(set (reg:CC FLAGS_REG)
8034                    (compare:CC (match_dup 1) (match_dup 2)))
8035               (set (match_dup 0)
8036                    (minus:DWIH (match_dup 1) (match_dup 2)))])
8037    (parallel [(set (match_dup 3)
8038                    (minus:DWIH
8039                      (minus:DWIH
8040                        (match_dup 4)
8041                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
8042                      (match_dup 5)))
8043               (clobber (reg:CC FLAGS_REG))])]
8045   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
8046   if (operands[2] == const0_rtx)
8047     {
8048       if (!rtx_equal_p (operands[0], operands[1]))
8049         emit_move_insn (operands[0], operands[1]);
8050       ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3],
8051                                    TARGET_APX_NDD);
8052       DONE;
8053     }
8055 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
8057 (define_insn_and_split "*sub<dwi>3_doubleword_zext"
8058   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,&r,&r")
8059         (minus:<DWI>
8060           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0,r,o")
8061           (zero_extend:<DWI>
8062             (match_operand:DWIH 2 "nonimmediate_operand" "rm,r,rm,r"))))
8063    (clobber (reg:CC FLAGS_REG))]
8064   "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands, TARGET_APX_NDD)"
8065   "#"
8066   "&& reload_completed"
8067   [(parallel [(set (reg:CC FLAGS_REG)
8068                    (compare:CC (match_dup 1) (match_dup 2)))
8069               (set (match_dup 0)
8070                    (minus:DWIH (match_dup 1) (match_dup 2)))])
8071    (parallel [(set (match_dup 3)
8072                    (minus:DWIH
8073                      (minus:DWIH
8074                        (match_dup 4)
8075                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
8076                      (const_int 0)))
8077               (clobber (reg:CC FLAGS_REG))])]
8078   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);"
8079 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
8081 (define_insn "*sub<mode>_1<nf_name>"
8082   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r<nf_mem_constraint>,<r>,r,r,r")
8083         (minus:SWI
8084           (match_operand:SWI 1 "nonimmediate_operand" "0,0,0,rm,rjM,r")
8085           (match_operand:SWI 2 "<general_operand>" "<r>,<i>,<m>,r,<i>,<m>")))]
8086   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
8087   && <nf_condition>"
8088   "@
8089   <nf_prefix>sub{<imodesuffix>}\t{%2, %0|%0, %2}
8090   <nf_prefix>sub{<imodesuffix>}\t{%2, %0|%0, %2}
8091   <nf_prefix>sub{<imodesuffix>}\t{%2, %0|%0, %2}
8092   <nf_prefix>sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8093   <nf_prefix>sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8094   <nf_prefix>sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8095   [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd")
8096    (set_attr "type" "alu")
8097    (set_attr "has_nf" "1")
8098    (set_attr "mode" "<MODE>")])
8100 (define_insn "*subqi_1_zext<mode><nf_name>"
8101   [(set (match_operand:SWI248x 0 "register_operand" "=r,r")
8102         (zero_extend:SWI248x
8103           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "rm,r")
8104                     (match_operand:QI 2 "x86_64_general_operand" "rn,m"))))]
8105   "TARGET_APX_NDD && <nf_condition>
8106    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8107   "@
8108   <nf_prefix>sub{b}\t{%2, %1, %b0|%b0, %1, %2}
8109   <nf_prefix>sub{b}\t{%2, %1, %b0|%b0, %1, %2}"
8110   [(set_attr "type" "alu")
8111    (set_attr "has_nf" "1")
8112    (set_attr "mode" "QI")])
8114 (define_insn "*subhi_1_zext<mode><nf_name>"
8115   [(set (match_operand:SWI48x 0 "register_operand" "=r,r")
8116         (zero_extend:SWI48x
8117           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "rm,r")
8118                     (match_operand:HI 2 "x86_64_general_operand" "rn,m"))))]
8119   "TARGET_APX_NDD && <nf_condition>
8120    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8121   "@
8122   <nf_prefix>sub{w}\t{%2, %1, %w0|%w0, %1, %2}
8123   <nf_prefix>sub{w}\t{%2, %1, %w0|%w0, %1, %2}"
8124   [(set_attr "type" "alu")
8125    (set_attr "has_nf" "1")
8126    (set_attr "mode" "HI")])
8128 (define_insn "*subsi_1_zext"
8129   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8130         (zero_extend:DI
8131           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,r,rm")
8132                     (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))))
8133    (clobber (reg:CC FLAGS_REG))]
8134   "TARGET_64BIT
8135    && ix86_binary_operator_ok (MINUS, SImode, operands, TARGET_APX_NDD)"
8136   "@
8137   sub{l}\t{%2, %k0|%k0, %2}
8138   sub{l}\t{%2, %1, %k0|%k0, %1, %2}
8139   sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
8140   [(set_attr "isa" "*,apx_ndd,apx_ndd")
8141    (set_attr "type" "alu")
8142    (set_attr "mode" "SI")])
8144 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
8145 (define_insn_and_split "*sub<mode>_1_slp"
8146   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
8147         (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
8148                      (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
8149    (clobber (reg:CC FLAGS_REG))]
8150   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8151   "@
8152    sub{<imodesuffix>}\t{%2, %0|%0, %2}
8153    #"
8154   "&& reload_completed
8155    && !(rtx_equal_p (operands[0], operands[1]))"
8156   [(set (strict_low_part (match_dup 0)) (match_dup 1))
8157    (parallel
8158      [(set (strict_low_part (match_dup 0))
8159            (minus:SWI12 (match_dup 0) (match_dup 2)))
8160       (clobber (reg:CC FLAGS_REG))])]
8161   ""
8162   [(set_attr "type" "alu")
8163    (set_attr "mode" "<MODE>")])
8165 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
8166 (define_insn_and_split "*subqi_ext<mode>_1_slp"
8167   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
8168         (minus:QI
8169           (match_operand:QI 1 "nonimmediate_operand" "0,!qm")
8170           (subreg:QI
8171             (match_operator:SWI248 3 "extract_operator"
8172               [(match_operand 2 "int248_register_operand" "Q,Q")
8173                (const_int 8)
8174                (const_int 8)]) 0)))
8175    (clobber (reg:CC FLAGS_REG))]
8176   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8177   "@
8178    sub{b}\t{%h2, %0|%0, %h2}
8179    #"
8180   "&& reload_completed
8181    && !rtx_equal_p (operands[0], operands[1])"
8182   [(set (strict_low_part (match_dup 0)) (match_dup 1))
8183    (parallel
8184      [(set (strict_low_part (match_dup 0))
8185            (minus:QI
8186              (match_dup 0)
8187              (subreg:QI
8188                (match_op_dup 3
8189                  [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
8190       (clobber (reg:CC FLAGS_REG))])]
8191   ""
8192   [(set_attr "type" "alu")
8193    (set_attr "mode" "QI")])
8195 (define_insn_and_split "*subqi_ext<mode>_2_slp"
8196   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
8197         (minus:QI
8198           (subreg:QI
8199             (match_operator:SWI248 3 "extract_operator"
8200               [(match_operand 1 "int248_register_operand" "Q")
8201                (const_int 8)
8202                (const_int 8)]) 0)
8203           (subreg:QI
8204             (match_operator:SWI248 4 "extract_operator"
8205               [(match_operand 2 "int248_register_operand" "Q")
8206                (const_int 8)
8207                (const_int 8)]) 0)))
8208    (clobber (reg:CC FLAGS_REG))]
8209   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8210   "#"
8211   "&& reload_completed"
8212   [(set (strict_low_part (match_dup 0))
8213         (subreg:QI
8214           (match_op_dup 3
8215             [(match_dup 1) (const_int 8) (const_int 8)]) 0))
8216    (parallel
8217      [(set (strict_low_part (match_dup 0))
8218            (minus:QI
8219            (match_dup 0)
8220              (subreg:QI
8221                (match_op_dup 4
8222                  [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
8223       (clobber (reg:CC FLAGS_REG))])]
8224   ""
8225   [(set_attr "type" "alu")
8226    (set_attr "mode" "QI")])
8228 (define_insn "*sub<mode>_2"
8229   [(set (reg FLAGS_REG)
8230         (compare
8231           (minus:SWI
8232             (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r")
8233             (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>"))
8234           (const_int 0)))
8235    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
8236         (minus:SWI (match_dup 1) (match_dup 2)))]
8237   "ix86_match_ccmode (insn, CCGOCmode)
8238    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
8239   "@
8240   sub{<imodesuffix>}\t{%2, %0|%0, %2}
8241   sub{<imodesuffix>}\t{%2, %0|%0, %2}
8242   sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8243   sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8244   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
8245    (set_attr "type" "alu")
8246    (set_attr "mode" "<MODE>")])
8248 (define_insn "*subsi_2_zext"
8249   [(set (reg FLAGS_REG)
8250         (compare
8251           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,r,rm")
8252                     (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))
8253           (const_int 0)))
8254    (set (match_operand:DI 0 "register_operand" "=r,r,r")
8255         (zero_extend:DI
8256           (minus:SI (match_dup 1)
8257                     (match_dup 2))))]
8258   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
8259    && ix86_binary_operator_ok (MINUS, SImode, operands, TARGET_APX_NDD)"
8260   "@
8261   sub{l}\t{%2, %k0|%k0, %2}
8262   sub{l}\t{%2, %1, %k0|%k0, %1, %2}
8263   sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
8264   [(set_attr "isa" "*,apx_ndd,apx_ndd")
8265    (set_attr "type" "alu")
8266    (set_attr "mode" "SI")])
8268 (define_insn "*subqi_ext<mode>_0"
8269   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
8270         (minus:QI
8271           (match_operand:QI 1 "nonimmediate_operand" "0")
8272           (subreg:QI
8273             (match_operator:SWI248 3 "extract_operator"
8274               [(match_operand 2 "int248_register_operand" "Q")
8275                (const_int 8)
8276                (const_int 8)]) 0)))
8277    (clobber (reg:CC FLAGS_REG))]
8278   ""
8279   "sub{b}\t{%h2, %0|%0, %h2}"
8280   [(set_attr "addr" "gpr8")
8281    (set_attr "type" "alu")
8282    (set_attr "mode" "QI")])
8284 (define_insn_and_split "*subqi_ext2<mode>_0"
8285   [(set (match_operand:QI 0 "register_operand" "=&Q")
8286         (minus:QI
8287           (subreg:QI
8288             (match_operator:SWI248 3 "extract_operator"
8289               [(match_operand 1 "int248_register_operand" "Q")
8290                (const_int 8)
8291                (const_int 8)]) 0)
8292           (subreg:QI
8293             (match_operator:SWI248 4 "extract_operator"
8294               [(match_operand 2 "int248_register_operand" "Q")
8295                (const_int 8)
8296                (const_int 8)]) 0)))
8297    (clobber (reg:CC FLAGS_REG))]
8298   ""
8299   "#"
8300   "&& reload_completed"
8301   [(set (match_dup 0)
8302         (subreg:QI
8303           (match_op_dup 3
8304             [(match_dup 1) (const_int 8) (const_int 8)]) 0))
8305    (parallel
8306      [(set (match_dup 0)
8307            (minus:QI
8308              (match_dup 0)
8309              (subreg:QI
8310                (match_op_dup 4
8311                  [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
8312       (clobber (reg:CC FLAGS_REG))])]
8313   ""
8314   [(set_attr "type" "alu")
8315    (set_attr "mode" "QI")])
8317 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
8318 (define_insn_and_split "*subqi_ext<mode>_1"
8319   [(set (zero_extract:SWI248
8320           (match_operand 0 "int248_register_operand" "+Q,&Q")
8321           (const_int 8)
8322           (const_int 8))
8323         (subreg:SWI248
8324           (minus:QI
8325             (subreg:QI
8326               (match_operator:SWI248 3 "extract_operator"
8327                 [(match_operand 1 "int248_register_operand" "0,!Q")
8328                  (const_int 8)
8329                  (const_int 8)]) 0)
8330             (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
8331    (clobber (reg:CC FLAGS_REG))]
8332   ""
8333   "@
8334    sub{b}\t{%2, %h0|%h0, %2}
8335    #"
8336   "reload_completed
8337    && !(rtx_equal_p (operands[0], operands[1]))"
8338   [(set (zero_extract:SWI248
8339           (match_dup 0) (const_int 8) (const_int 8))
8340         (zero_extract:SWI248
8341           (match_dup 1) (const_int 8) (const_int 8)))
8342    (parallel
8343      [(set (zero_extract:SWI248
8344              (match_dup 0) (const_int 8) (const_int 8))
8345            (subreg:SWI248
8346              (minus:QI
8347                (subreg:QI
8348                  (match_op_dup 3
8349                    [(match_dup 0) (const_int 8) (const_int 8)]) 0)
8350                (match_dup 2)) 0))
8351       (clobber (reg:CC FLAGS_REG))])]
8352   ""
8353   [(set_attr "addr" "gpr8")
8354    (set_attr "type" "alu")
8355    (set_attr "mode" "QI")])
8357 ;; Subtract with jump on overflow.
8358 (define_expand "subv<mode>4"
8359   [(parallel [(set (reg:CCO FLAGS_REG)
8360                    (eq:CCO
8361                      (minus:<DPWI>
8362                        (sign_extend:<DPWI>
8363                          (match_operand:SWIDWI 1 "nonimmediate_operand"))
8364                        (match_dup 4))
8365                      (sign_extend:<DPWI>
8366                        (minus:SWIDWI (match_dup 1)
8367                                      (match_operand:SWIDWI 2
8368                                                 "<general_hilo_operand>")))))
8369               (set (match_operand:SWIDWI 0 "register_operand")
8370                    (minus:SWIDWI (match_dup 1) (match_dup 2)))])
8371    (set (pc) (if_then_else
8372                (eq (reg:CCO FLAGS_REG) (const_int 0))
8373                (label_ref (match_operand 3))
8374                (pc)))]
8375   ""
8377   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands,
8378                                       TARGET_APX_NDD);
8379   if (CONST_SCALAR_INT_P (operands[2]))
8380     operands[4] = operands[2];
8381   else
8382     operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
8385 (define_insn "*subv<mode>4"
8386   [(set (reg:CCO FLAGS_REG)
8387         (eq:CCO (minus:<DWI>
8388                    (sign_extend:<DWI>
8389                       (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r"))
8390                    (sign_extend:<DWI>
8391                       (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m,rWe,m")))
8392                 (sign_extend:<DWI>
8393                    (minus:SWI (match_dup 1) (match_dup 2)))))
8394    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
8395         (minus:SWI (match_dup 1) (match_dup 2)))]
8396   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
8397   "@
8398   sub{<imodesuffix>}\t{%2, %0|%0, %2}
8399   sub{<imodesuffix>}\t{%2, %0|%0, %2}
8400   sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8401   sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8402   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
8403    (set_attr "type" "alu")
8404    (set_attr "mode" "<MODE>")])
8406 (define_insn "subv<mode>4_1"
8407   [(set (reg:CCO FLAGS_REG)
8408         (eq:CCO (minus:<DWI>
8409                    (sign_extend:<DWI>
8410                       (match_operand:SWI 1 "nonimmediate_operand" "0,rm"))
8411                    (match_operand:<DWI> 3 "const_int_operand"))
8412                 (sign_extend:<DWI>
8413                    (minus:SWI
8414                      (match_dup 1)
8415                      (match_operand:SWI 2 "x86_64_immediate_operand" "<i>,<i>")))))
8416    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
8417         (minus:SWI (match_dup 1) (match_dup 2)))]
8418   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
8419    && CONST_INT_P (operands[2])
8420    && INTVAL (operands[2]) == INTVAL (operands[3])"
8421   "@
8422   sub{<imodesuffix>}\t{%2, %0|%0, %2}
8423   sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8424   [(set_attr "isa" "*,apx_ndd")
8425    (set_attr "type" "alu")
8426    (set_attr "mode" "<MODE>")
8427    (set (attr "length_immediate")
8428         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8429                   (const_string "1")
8430                (match_test "<MODE_SIZE> == 8")
8431                   (const_string "4")]
8432               (const_string "<MODE_SIZE>")))])
8434 (define_insn_and_split "*subv<dwi>4_doubleword"
8435   [(set (reg:CCO FLAGS_REG)
8436         (eq:CCO
8437           (minus:<QPWI>
8438             (sign_extend:<QPWI>
8439               (match_operand:<DWI> 1 "nonimmediate_operand" "0,0,ro,r"))
8440             (sign_extend:<QPWI>
8441               (match_operand:<DWI> 2 "nonimmediate_operand" "r,o,r,o")))
8442           (sign_extend:<QPWI>
8443             (minus:<DWI> (match_dup 1) (match_dup 2)))))
8444    (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r")
8445         (minus:<DWI> (match_dup 1) (match_dup 2)))]
8446   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
8447   "#"
8448   "&& reload_completed"
8449   [(parallel [(set (reg:CC FLAGS_REG)
8450                    (compare:CC (match_dup 1) (match_dup 2)))
8451               (set (match_dup 0)
8452                    (minus:DWIH (match_dup 1) (match_dup 2)))])
8453    (parallel [(set (reg:CCO FLAGS_REG)
8454                    (eq:CCO
8455                      (minus:<DWI>
8456                        (minus:<DWI>
8457                          (sign_extend:<DWI> (match_dup 4))
8458                          (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
8459                        (sign_extend:<DWI> (match_dup 5)))
8460                      (sign_extend:<DWI>
8461                        (minus:DWIH
8462                          (minus:DWIH
8463                            (match_dup 4)
8464                            (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
8465                          (match_dup 5)))))
8466               (set (match_dup 3)
8467                    (minus:DWIH
8468                      (minus:DWIH
8469                        (match_dup 4)
8470                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
8471                      (match_dup 5)))])]
8473   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
8475 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
8477 (define_insn_and_split "*subv<dwi>4_doubleword_1"
8478   [(set (reg:CCO FLAGS_REG)
8479         (eq:CCO
8480           (minus:<QPWI>
8481             (sign_extend:<QPWI>
8482               (match_operand:<DWI> 1 "nonimmediate_operand" "0,ro"))
8483             (match_operand:<QPWI> 3 "const_scalar_int_operand"))
8484           (sign_extend:<QPWI>
8485             (minus:<DWI>
8486               (match_dup 1)
8487               (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>,<di>")))))
8488    (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,&r")
8489         (minus:<DWI> (match_dup 1) (match_dup 2)))]
8490   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
8491    && CONST_SCALAR_INT_P (operands[2])
8492    && rtx_equal_p (operands[2], operands[3])"
8493   "#"
8494   "&& reload_completed"
8495   [(parallel [(set (reg:CC FLAGS_REG)
8496                    (compare:CC (match_dup 1) (match_dup 2)))
8497               (set (match_dup 0)
8498                    (minus:DWIH (match_dup 1) (match_dup 2)))])
8499    (parallel [(set (reg:CCO FLAGS_REG)
8500                    (eq:CCO
8501                      (minus:<DWI>
8502                        (minus:<DWI>
8503                          (sign_extend:<DWI> (match_dup 4))
8504                          (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
8505                        (match_dup 5))
8506                      (sign_extend:<DWI>
8507                        (minus:DWIH
8508                          (minus:DWIH
8509                            (match_dup 4)
8510                            (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
8511                          (match_dup 5)))))
8512               (set (match_dup 3)
8513                    (minus:DWIH
8514                      (minus:DWIH
8515                        (match_dup 4)
8516                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
8517                      (match_dup 5)))])]
8519   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
8520   if (operands[2] == const0_rtx)
8521     {
8522       if (!rtx_equal_p (operands[0], operands[1]))
8523         emit_move_insn (operands[0], operands[1]);
8524       emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
8525                                     operands[5]));
8526       DONE;
8527     }
8529 [(set_attr "isa" "*,apx_ndd")])
8531 (define_insn "*subv<mode>4_overflow_1"
8532   [(set (reg:CCO FLAGS_REG)
8533         (eq:CCO
8534           (minus:<DWI>
8535             (minus:<DWI>
8536               (sign_extend:<DWI>
8537                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r"))
8538               (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8539                 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8540             (sign_extend:<DWI>
8541               (match_operand:SWI 2 "<general_sext_operand>" "rWe,m,rWe,m")))
8542           (sign_extend:<DWI>
8543             (minus:SWI
8544               (minus:SWI
8545                 (match_dup 1)
8546                 (match_operator:SWI 5 "ix86_carry_flag_operator"
8547                   [(match_dup 3) (const_int 0)]))
8548               (match_dup 2)))))
8549    (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r,r,r")
8550         (minus:SWI
8551           (minus:SWI
8552             (match_dup 1)
8553             (match_op_dup 5 [(match_dup 3) (const_int 0)]))
8554           (match_dup 2)))]
8555   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
8556   "@
8557   sbb{<imodesuffix>}\t{%2, %0|%0, %2}
8558   sbb{<imodesuffix>}\t{%2, %0|%0, %2}
8559   sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8560   sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8561   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
8562    (set_attr "type" "alu")
8563    (set_attr "mode" "<MODE>")])
8565 (define_insn "*subv<mode>4_overflow_2"
8566   [(set (reg:CCO FLAGS_REG)
8567         (eq:CCO
8568           (minus:<DWI>
8569             (minus:<DWI>
8570               (sign_extend:<DWI>
8571                 (match_operand:SWI 1 "nonimmediate_operand" "%0,rm"))
8572               (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8573                 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8574             (match_operand:<DWI> 6 "const_int_operand" "n,n"))
8575           (sign_extend:<DWI>
8576             (minus:SWI
8577               (minus:SWI
8578                 (match_dup 1)
8579                 (match_operator:SWI 5 "ix86_carry_flag_operator"
8580                   [(match_dup 3) (const_int 0)]))
8581               (match_operand:SWI 2 "x86_64_immediate_operand" "e,e")))))
8582    (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
8583         (minus:SWI
8584           (minus:SWI
8585             (match_dup 1)
8586             (match_op_dup 5 [(match_dup 3) (const_int 0)]))
8587           (match_dup 2)))]
8588   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
8589    && CONST_INT_P (operands[2])
8590    && INTVAL (operands[2]) == INTVAL (operands[6])"
8591   "@
8592   sbb{<imodesuffix>}\t{%2, %0|%0, %2}
8593   sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8594   [(set_attr "isa" "*,apx_ndd")
8595    (set_attr "type" "alu")
8596    (set_attr "mode" "<MODE>")
8597    (set (attr "length_immediate")
8598      (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8599        (const_string "1")
8600        (const_string "4")))])
8602 (define_expand "usubv<mode>4"
8603   [(parallel [(set (reg:CC FLAGS_REG)
8604                    (compare:CC
8605                      (match_operand:SWI 1 "nonimmediate_operand")
8606                      (match_operand:SWI 2 "<general_operand>")))
8607               (set (match_operand:SWI 0 "register_operand")
8608                    (minus:SWI (match_dup 1) (match_dup 2)))])
8609    (set (pc) (if_then_else
8610                (ltu (reg:CC FLAGS_REG) (const_int 0))
8611                (label_ref (match_operand 3))
8612                (pc)))]
8613   ""
8614   "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands,
8615                                        TARGET_APX_NDD);")
8617 (define_expand "sub<mode>_3"
8618   [(parallel [(set (reg:CC FLAGS_REG)
8619                    (compare:CC
8620                      (match_operand:SWI 1 "nonimmediate_operand")
8621                      (match_operand:SWI 2 "<general_operand>")))
8622               (set (match_operand:SWI 0 "register_operand")
8623                    (minus:SWI (match_dup 1) (match_dup 2)))])])
8625 (define_insn "*sub<mode>_3"
8626   [(set (reg FLAGS_REG)
8627         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r")
8628                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>")))
8629    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>i,r,r")
8630         (minus:SWI (match_dup 1) (match_dup 2)))]
8631   "ix86_match_ccmode (insn, CCmode)
8632    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
8633   "@
8634   sub{<imodesuffix>}\t{%2, %0|%0, %2}
8635   sub{<imodesuffix>}\t{%2, %0|%0, %2}
8636   sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8637   sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8638   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
8639    (set_attr "type" "alu")
8640    (set_attr "mode" "<MODE>")])
8642 (define_peephole2
8643   [(parallel
8644      [(set (reg:CC FLAGS_REG)
8645            (compare:CC (match_operand:SWI 0 "general_reg_operand")
8646                        (match_operand:SWI 1 "general_gr_operand")))
8647       (set (match_dup 0)
8648            (minus:SWI (match_dup 0) (match_dup 1)))])]
8649   "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
8650   [(set (reg:CC FLAGS_REG)
8651         (compare:CC (match_dup 0) (match_dup 1)))])
8653 (define_peephole2
8654   [(set (match_operand:SWI 0 "general_reg_operand")
8655         (match_operand:SWI 1 "memory_operand"))
8656    (parallel [(set (reg:CC FLAGS_REG)
8657                    (compare:CC (match_dup 0)
8658                                (match_operand:SWI 2 "memory_operand")))
8659               (set (match_dup 0)
8660                    (minus:SWI (match_dup 0) (match_dup 2)))])
8661    (set (match_dup 1) (match_dup 0))]
8662   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8663    && peep2_reg_dead_p (3, operands[0])
8664    && !reg_overlap_mentioned_p (operands[0], operands[1])
8665    && !reg_overlap_mentioned_p (operands[0], operands[2])"
8666   [(set (match_dup 0) (match_dup 2))
8667    (parallel [(set (reg:CC FLAGS_REG)
8668                    (compare:CC (match_dup 1) (match_dup 0)))
8669               (set (match_dup 1)
8670                    (minus:SWI (match_dup 1) (match_dup 0)))])])
8672 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
8673 ;; subl $1, %eax; jnc .Lxx;
8674 (define_peephole2
8675   [(parallel
8676      [(set (match_operand:SWI 0 "general_reg_operand")
8677            (plus:SWI (match_dup 0) (const_int -1)))
8678       (clobber (reg FLAGS_REG))])
8679    (set (reg:CCZ FLAGS_REG)
8680         (compare:CCZ (match_dup 0) (const_int -1)))
8681    (set (pc)
8682         (if_then_else (match_operator 1 "bt_comparison_operator"
8683                         [(reg:CCZ FLAGS_REG) (const_int 0)])
8684                       (match_operand 2)
8685                       (pc)))]
8686    "peep2_regno_dead_p (3, FLAGS_REG)"
8687    [(parallel
8688       [(set (reg:CC FLAGS_REG)
8689             (compare:CC (match_dup 0) (const_int 1)))
8690        (set (match_dup 0)
8691             (minus:SWI (match_dup 0) (const_int 1)))])
8692     (set (pc)
8693          (if_then_else (match_dup 3)
8694                        (match_dup 2)
8695                        (pc)))]
8697   rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
8698   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
8699                                 ? GEU : LTU, VOIDmode, cc, const0_rtx);
8702 ;; Help combine use borrow flag to test for -1 after dec (add $-1).
8703 (define_insn_and_split "*dec_cmov<mode>"
8704   [(set (match_operand:SWI248 0 "register_operand" "=r")
8705         (if_then_else:SWI248
8706          (match_operator 1 "bt_comparison_operator"
8707           [(match_operand:SWI248 2 "register_operand" "0") (const_int 0)])
8708          (plus:SWI248 (match_dup 2) (const_int -1))
8709          (match_operand:SWI248 3 "nonimmediate_operand" "rm")))
8710    (clobber (reg:CC FLAGS_REG))]
8711   "TARGET_CMOVE"
8712   "#"
8713   "&& reload_completed"
8714   [(parallel [(set (reg:CC FLAGS_REG)
8715                    (compare:CC (match_dup 2) (const_int 1)))
8716               (set (match_dup 0) (minus:SWI248 (match_dup 2) (const_int 1)))])
8717    (set (match_dup 0)
8718         (if_then_else:SWI248 (match_dup 4) (match_dup 0) (match_dup 3)))]
8720   rtx cc = gen_rtx_REG (CCCmode, FLAGS_REG);
8721   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
8722                                 ? GEU : LTU, VOIDmode, cc, const0_rtx);
8725 (define_insn "*subsi_3_zext"
8726   [(set (reg FLAGS_REG)
8727         (compare (match_operand:SI 1 "nonimmediate_operand" "0,r,rm")
8728                  (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re")))
8729    (set (match_operand:DI 0 "register_operand" "=r,r,r")
8730         (zero_extend:DI
8731           (minus:SI (match_dup 1)
8732                     (match_dup 2))))]
8733   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
8734    && ix86_binary_operator_ok (MINUS, SImode, operands, TARGET_APX_NDD)"
8735   "@
8736   sub{l}\t{%2, %1|%1, %2}
8737   sub{l}\t{%2, %1, %k0|%k0, %1, %2}
8738   sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
8739   [(set_attr "isa" "*,apx_ndd,apx_ndd")
8740    (set_attr "type" "alu")
8741    (set_attr "mode" "SI")])
8743 ;; Add with carry and subtract with borrow
8745 (define_insn "@add<mode>3_carry"
8746   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
8747         (plus:SWI
8748           (plus:SWI
8749             (match_operator:SWI 4 "ix86_carry_flag_operator"
8750              [(match_operand 3 "flags_reg_operand") (const_int 0)])
8751             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r"))
8752           (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>")))
8753    (clobber (reg:CC FLAGS_REG))]
8754   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
8755   "@
8756    adc{<imodesuffix>}\t{%2, %0|%0, %2}
8757    adc{<imodesuffix>}\t{%2, %0|%0, %2}
8758    adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8759    adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8760   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
8761    (set_attr "type" "alu")
8762    (set_attr "use_carry" "1")
8763    (set_attr "pent_pair" "pu")
8764    (set_attr "mode" "<MODE>")])
8766 (define_peephole2
8767   [(set (match_operand:SWI 0 "general_reg_operand")
8768         (match_operand:SWI 1 "memory_operand"))
8769    (parallel [(set (match_dup 0)
8770                    (plus:SWI
8771                      (plus:SWI
8772                        (match_operator:SWI 4 "ix86_carry_flag_operator"
8773                          [(match_operand 3 "flags_reg_operand")
8774                           (const_int 0)])
8775                        (match_dup 0))
8776                      (match_operand:SWI 2 "memory_operand")))
8777               (clobber (reg:CC FLAGS_REG))])
8778    (set (match_dup 1) (match_dup 0))]
8779   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8780    && peep2_reg_dead_p (3, operands[0])
8781    && !reg_overlap_mentioned_p (operands[0], operands[1])
8782    && !reg_overlap_mentioned_p (operands[0], operands[2])"
8783   [(set (match_dup 0) (match_dup 2))
8784    (parallel [(set (match_dup 1)
8785                    (plus:SWI (plus:SWI (match_op_dup 4
8786                                          [(match_dup 3) (const_int 0)])
8787                                        (match_dup 1))
8788                              (match_dup 0)))
8789               (clobber (reg:CC FLAGS_REG))])])
8791 (define_peephole2
8792   [(set (match_operand:SWI 0 "general_reg_operand")
8793         (match_operand:SWI 1 "memory_operand"))
8794    (parallel [(set (match_dup 0)
8795                    (plus:SWI
8796                      (plus:SWI
8797                        (match_operator:SWI 4 "ix86_carry_flag_operator"
8798                          [(match_operand 3 "flags_reg_operand")
8799                           (const_int 0)])
8800                        (match_dup 0))
8801                      (match_operand:SWI 2 "memory_operand")))
8802               (clobber (reg:CC FLAGS_REG))])
8803    (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8804    (set (match_dup 1) (match_dup 5))]
8805   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8806    && peep2_reg_dead_p (3, operands[0])
8807    && peep2_reg_dead_p (4, operands[5])
8808    && !reg_overlap_mentioned_p (operands[0], operands[1])
8809    && !reg_overlap_mentioned_p (operands[0], operands[2])
8810    && !reg_overlap_mentioned_p (operands[5], operands[1])"
8811   [(set (match_dup 0) (match_dup 2))
8812    (parallel [(set (match_dup 1)
8813                    (plus:SWI (plus:SWI (match_op_dup 4
8814                                          [(match_dup 3) (const_int 0)])
8815                                        (match_dup 1))
8816                              (match_dup 0)))
8817               (clobber (reg:CC FLAGS_REG))])])
8819 (define_insn "*add<mode>3_carry_0"
8820   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8821         (plus:SWI
8822           (match_operator:SWI 2 "ix86_carry_flag_operator"
8823             [(reg FLAGS_REG) (const_int 0)])
8824           (match_operand:SWI 1 "nonimmediate_operand" "0")))
8825    (clobber (reg:CC FLAGS_REG))]
8826   "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8827   "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
8828   [(set_attr "type" "alu")
8829    (set_attr "use_carry" "1")
8830    (set_attr "pent_pair" "pu")
8831    (set_attr "mode" "<MODE>")])
8833 (define_insn "*add<mode>3_carry_0r"
8834   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8835         (plus:SWI
8836           (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8837             [(reg FLAGS_REG) (const_int 0)])
8838           (match_operand:SWI 1 "nonimmediate_operand" "0")))
8839    (clobber (reg:CC FLAGS_REG))]
8840   "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8841   "sbb{<imodesuffix>}\t{$-1, %0|%0, -1}"
8842   [(set_attr "type" "alu")
8843    (set_attr "use_carry" "1")
8844    (set_attr "pent_pair" "pu")
8845    (set_attr "mode" "<MODE>")])
8847 (define_insn "*addqi3_carry_zext<mode>"
8848   [(set (match_operand:SWI248x 0 "register_operand" "=r,r")
8849         (zero_extend:SWI248x
8850           (plus:QI
8851             (plus:QI (match_operator:QI 3 "ix86_carry_flag_operator"
8852                       [(reg FLAGS_REG) (const_int 0)])
8853                      (match_operand:QI 1 "nonimmediate_operand" "%rm,r"))
8854             (match_operand:QI 2 "x86_64_general_operand" "rn,m"))))
8855    (clobber (reg:CC FLAGS_REG))]
8856   "TARGET_APX_NDD
8857    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8858   "@
8859   adc{b}\t{%2, %1, %b0|%b0, %1, %2}
8860   adc{b}\t{%2, %1, %b0|%b0, %1, %2}"
8861   [(set_attr "type" "alu")
8862    (set_attr "use_carry" "1")
8863    (set_attr "pent_pair" "pu")
8864    (set_attr "mode" "QI")])
8866 (define_insn "*addhi3_carry_zext<mode>"
8867   [(set (match_operand:SWI48x 0 "register_operand" "=r,r")
8868         (zero_extend:SWI48x
8869           (plus:HI
8870             (plus:HI (match_operator:HI 3 "ix86_carry_flag_operator"
8871                       [(reg FLAGS_REG) (const_int 0)])
8872                      (match_operand:HI 1 "nonimmediate_operand" "%rm,r"))
8873             (match_operand:HI 2 "x86_64_general_operand" "rn,m"))))
8874    (clobber (reg:CC FLAGS_REG))]
8875   "TARGET_APX_NDD
8876    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8877   "@
8878   adc{w}\t{%2, %1, %w0|%w0, %1, %2}
8879   adc{w}\t{%2, %1, %w0|%w0, %1, %2}"
8880   [(set_attr "type" "alu")
8881    (set_attr "use_carry" "1")
8882    (set_attr "pent_pair" "pu")
8883    (set_attr "mode" "HI")])
8885 (define_insn "*addsi3_carry_zext"
8886   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8887         (zero_extend:DI
8888           (plus:SI
8889             (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
8890                       [(reg FLAGS_REG) (const_int 0)])
8891                      (match_operand:SI 1 "nonimmediate_operand" "%0,r,rm"))
8892             (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))))
8893    (clobber (reg:CC FLAGS_REG))]
8894   "TARGET_64BIT
8895    && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
8896   "@
8897   adc{l}\t{%2, %k0|%k0, %2}
8898   adc{l}\t{%2, %1, %k0|%k0, %1, %2}
8899   adc{l}\t{%2, %1, %k0|%k0, %1, %2}"
8900   [(set_attr "isa" "*,apx_ndd,apx_ndd")
8901    (set_attr "type" "alu")
8902    (set_attr "use_carry" "1")
8903    (set_attr "pent_pair" "pu")
8904    (set_attr "mode" "SI")])
8906 (define_insn "*addqi3_carry_zext<mode>_0"
8907   [(set (match_operand:SWI248x 0 "register_operand" "=r")
8908         (zero_extend:SWI248x
8909           (plus:QI (match_operator:QI 2 "ix86_carry_flag_operator"
8910                     [(reg FLAGS_REG) (const_int 0)])
8911                    (match_operand:QI 1 "nonimmediate_operand" "rm"))))
8912    (clobber (reg:CC FLAGS_REG))]
8913   "TARGET_APX_NDD"
8914   "adc{b}\t{$0, %1, %b0|%b0, %1, 0}"
8915   [(set_attr "type" "alu")
8916    (set_attr "use_carry" "1")
8917    (set_attr "pent_pair" "pu")
8918    (set_attr "mode" "QI")])
8920 (define_insn "*addhi3_carry_zext<mode>_0"
8921   [(set (match_operand:SWI48x 0 "register_operand" "=r")
8922         (zero_extend:SWI48x
8923           (plus:HI (match_operator:HI 2 "ix86_carry_flag_operator"
8924                     [(reg FLAGS_REG) (const_int 0)])
8925                    (match_operand:HI 1 "nonimmediate_operand" "rm"))))
8926    (clobber (reg:CC FLAGS_REG))]
8927   "TARGET_APX_NDD"
8928   "adc{w}\t{$0, %1, %w0|%w0, %1, 0}"
8929   [(set_attr "type" "alu")
8930    (set_attr "use_carry" "1")
8931    (set_attr "pent_pair" "pu")
8932    (set_attr "mode" "HI")])
8934 (define_insn "*addsi3_carry_zext_0"
8935   [(set (match_operand:DI 0 "register_operand" "=r,r")
8936         (zero_extend:DI
8937           (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
8938                     [(reg FLAGS_REG) (const_int 0)])
8939                    (match_operand:SI 1 "nonimmediate_operand" "0,rm"))))
8940    (clobber (reg:CC FLAGS_REG))]
8941   "TARGET_64BIT"
8942   "@
8943   adc{l}\t{$0, %k0|%k0, 0}
8944   adc{l}\t{$0, %1, %k0|%k0, %1, 0}"
8945   [(set_attr "isa" "*,apx_ndd")
8946    (set_attr "type" "alu")
8947    (set_attr "use_carry" "1")
8948    (set_attr "pent_pair" "pu")
8949    (set_attr "mode" "SI")])
8951 (define_insn "*addqi3_carry_zext<mode>_0r"
8952   [(set (match_operand:SWI248x 0 "register_operand" "=r")
8953         (zero_extend:SWI248x
8954           (plus:QI (match_operator:QI 2 "ix86_carry_flag_unset_operator"
8955                     [(reg FLAGS_REG) (const_int 0)])
8956                    (match_operand:QI 1 "nonimmediate_operand" "rm"))))
8957    (clobber (reg:CC FLAGS_REG))]
8958   "TARGET_APX_NDD"
8959   "sbb{b}\t{$-1, %1, %b0|%b0, %1, -1}"
8960   [(set_attr "type" "alu")
8961    (set_attr "use_carry" "1")
8962    (set_attr "pent_pair" "pu")
8963    (set_attr "mode" "QI")])
8965 (define_insn "*addhi3_carry_zext<mode>_0r"
8966   [(set (match_operand:SWI48x 0 "register_operand" "=r")
8967         (zero_extend:SWI48x
8968           (plus:HI (match_operator:HI 2 "ix86_carry_flag_unset_operator"
8969                     [(reg FLAGS_REG) (const_int 0)])
8970                    (match_operand:HI 1 "nonimmediate_operand" "rm"))))
8971    (clobber (reg:CC FLAGS_REG))]
8972   "TARGET_APX_NDD"
8973   "sbb{w}\t{$-1, %1, %w0|%w0, %1, -1}"
8974   [(set_attr "type" "alu")
8975    (set_attr "use_carry" "1")
8976    (set_attr "pent_pair" "pu")
8977    (set_attr "mode" "HI")])
8979 (define_insn "*addsi3_carry_zext_0r"
8980   [(set (match_operand:DI 0 "register_operand" "=r,r")
8981         (zero_extend:DI
8982           (plus:SI (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8983                     [(reg FLAGS_REG) (const_int 0)])
8984                    (match_operand:SI 1 "nonimmediate_operand" "0,rm"))))
8985    (clobber (reg:CC FLAGS_REG))]
8986   "TARGET_64BIT"
8987   "@
8988   sbb{l}\t{$-1, %k0|%k0, -1}
8989   sbb{l}\t{$-1, %1, %k0|%k0, %1, -1}"
8990   [(set_attr "isa" "*,apx_ndd")
8991    (set_attr "type" "alu")
8992    (set_attr "use_carry" "1")
8993    (set_attr "pent_pair" "pu")
8994    (set_attr "mode" "SI")])
8996 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
8998 (define_insn "addcarry<mode>"
8999   [(set (reg:CCC FLAGS_REG)
9000         (compare:CCC
9001           (zero_extend:<DWI>
9002             (plus:SWI48
9003               (plus:SWI48
9004                 (match_operator:SWI48 5 "ix86_carry_flag_operator"
9005                   [(match_operand 3 "flags_reg_operand") (const_int 0)])
9006                 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,rm,r"))
9007               (match_operand:SWI48 2 "nonimmediate_operand" "r,rm,r,m")))
9008           (plus:<DWI>
9009             (zero_extend:<DWI> (match_dup 2))
9010             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
9011               [(match_dup 3) (const_int 0)]))))
9012    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
9013         (plus:SWI48 (plus:SWI48 (match_op_dup 5
9014                                  [(match_dup 3) (const_int 0)])
9015                                 (match_dup 1))
9016                     (match_dup 2)))]
9017   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
9018   "@
9019   adc{<imodesuffix>}\t{%2, %0|%0, %2}
9020   adc{<imodesuffix>}\t{%2, %0|%0, %2}
9021   adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9022   adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9023   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
9024    (set_attr "type" "alu")
9025    (set_attr "use_carry" "1")
9026    (set_attr "pent_pair" "pu")
9027    (set_attr "mode" "<MODE>")])
9029 (define_peephole2
9030   [(parallel [(set (reg:CCC FLAGS_REG)
9031                    (compare:CCC
9032                      (zero_extend:<DWI>
9033                        (plus:SWI48
9034                          (plus:SWI48
9035                            (match_operator:SWI48 4 "ix86_carry_flag_operator"
9036                              [(match_operand 2 "flags_reg_operand")
9037                               (const_int 0)])
9038                            (match_operand:SWI48 0 "general_reg_operand"))
9039                          (match_operand:SWI48 1 "memory_operand")))
9040                      (plus:<DWI>
9041                        (zero_extend:<DWI> (match_dup 1))
9042                        (match_operator:<DWI> 3 "ix86_carry_flag_operator"
9043                          [(match_dup 2) (const_int 0)]))))
9044               (set (match_dup 0)
9045                    (plus:SWI48 (plus:SWI48 (match_op_dup 4
9046                                              [(match_dup 2) (const_int 0)])
9047                                            (match_dup 0))
9048                                (match_dup 1)))])
9049    (set (match_dup 1) (match_dup 0))]
9050   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9051    && peep2_reg_dead_p (2, operands[0])
9052    && !reg_overlap_mentioned_p (operands[0], operands[1])"
9053   [(parallel [(set (reg:CCC FLAGS_REG)
9054                    (compare:CCC
9055                      (zero_extend:<DWI>
9056                        (plus:SWI48
9057                          (plus:SWI48
9058                            (match_op_dup 4
9059                              [(match_dup 2) (const_int 0)])
9060                            (match_dup 1))
9061                          (match_dup 0)))
9062                      (plus:<DWI>
9063                        (zero_extend:<DWI> (match_dup 0))
9064                        (match_op_dup 3
9065                          [(match_dup 2) (const_int 0)]))))
9066               (set (match_dup 1)
9067                    (plus:SWI48 (plus:SWI48 (match_op_dup 4
9068                                              [(match_dup 2) (const_int 0)])
9069                                            (match_dup 1))
9070                                (match_dup 0)))])])
9072 (define_peephole2
9073   [(set (match_operand:SWI48 0 "general_reg_operand")
9074         (match_operand:SWI48 1 "memory_operand"))
9075    (parallel [(set (reg:CCC FLAGS_REG)
9076                    (compare:CCC
9077                      (zero_extend:<DWI>
9078                        (plus:SWI48
9079                          (plus:SWI48
9080                            (match_operator:SWI48 5 "ix86_carry_flag_operator"
9081                              [(match_operand 3 "flags_reg_operand")
9082                               (const_int 0)])
9083                            (match_dup 0))
9084                          (match_operand:SWI48 2 "memory_operand")))
9085                      (plus:<DWI>
9086                        (zero_extend:<DWI> (match_dup 2))
9087                        (match_operator:<DWI> 4 "ix86_carry_flag_operator"
9088                          [(match_dup 3) (const_int 0)]))))
9089               (set (match_dup 0)
9090                    (plus:SWI48 (plus:SWI48 (match_op_dup 5
9091                                              [(match_dup 3) (const_int 0)])
9092                                            (match_dup 0))
9093                                (match_dup 2)))])
9094    (set (match_dup 1) (match_dup 0))]
9095   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9096    && peep2_reg_dead_p (3, operands[0])
9097    && !reg_overlap_mentioned_p (operands[0], operands[1])
9098    && !reg_overlap_mentioned_p (operands[0], operands[2])"
9099   [(set (match_dup 0) (match_dup 2))
9100    (parallel [(set (reg:CCC FLAGS_REG)
9101                    (compare:CCC
9102                      (zero_extend:<DWI>
9103                        (plus:SWI48
9104                          (plus:SWI48
9105                            (match_op_dup 5
9106                              [(match_dup 3) (const_int 0)])
9107                            (match_dup 1))
9108                          (match_dup 0)))
9109                      (plus:<DWI>
9110                        (zero_extend:<DWI> (match_dup 0))
9111                        (match_op_dup 4
9112                          [(match_dup 3) (const_int 0)]))))
9113               (set (match_dup 1)
9114                    (plus:SWI48 (plus:SWI48 (match_op_dup 5
9115                                              [(match_dup 3) (const_int 0)])
9116                                            (match_dup 1))
9117                                (match_dup 0)))])])
9119 (define_peephole2
9120   [(parallel [(set (reg:CCC FLAGS_REG)
9121                    (compare:CCC
9122                      (zero_extend:<DWI>
9123                        (plus:SWI48
9124                          (plus:SWI48
9125                            (match_operator:SWI48 4 "ix86_carry_flag_operator"
9126                              [(match_operand 2 "flags_reg_operand")
9127                               (const_int 0)])
9128                            (match_operand:SWI48 0 "general_reg_operand"))
9129                          (match_operand:SWI48 1 "memory_operand")))
9130                      (plus:<DWI>
9131                        (zero_extend:<DWI> (match_dup 1))
9132                        (match_operator:<DWI> 3 "ix86_carry_flag_operator"
9133                          [(match_dup 2) (const_int 0)]))))
9134               (set (match_dup 0)
9135                    (plus:SWI48 (plus:SWI48 (match_op_dup 4
9136                                              [(match_dup 2) (const_int 0)])
9137                                            (match_dup 0))
9138                                (match_dup 1)))])
9139    (set (match_operand:QI 5 "general_reg_operand")
9140         (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
9141    (set (match_operand:SWI48 6 "general_reg_operand")
9142         (zero_extend:SWI48 (match_dup 5)))
9143    (set (match_dup 1) (match_dup 0))]
9144   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9145    && peep2_reg_dead_p (4, operands[0])
9146    && !reg_overlap_mentioned_p (operands[0], operands[1])
9147    && !reg_overlap_mentioned_p (operands[0], operands[5])
9148    && !reg_overlap_mentioned_p (operands[5], operands[1])
9149    && !reg_overlap_mentioned_p (operands[0], operands[6])
9150    && !reg_overlap_mentioned_p (operands[6], operands[1])"
9151   [(parallel [(set (reg:CCC FLAGS_REG)
9152                    (compare:CCC
9153                      (zero_extend:<DWI>
9154                        (plus:SWI48
9155                          (plus:SWI48
9156                            (match_op_dup 4
9157                              [(match_dup 2) (const_int 0)])
9158                            (match_dup 1))
9159                          (match_dup 0)))
9160                      (plus:<DWI>
9161                        (zero_extend:<DWI> (match_dup 0))
9162                        (match_op_dup 3
9163                          [(match_dup 2) (const_int 0)]))))
9164               (set (match_dup 1)
9165                    (plus:SWI48 (plus:SWI48 (match_op_dup 4
9166                                              [(match_dup 2) (const_int 0)])
9167                                            (match_dup 1))
9168                                (match_dup 0)))])
9169    (set (match_dup 5) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
9170    (set (match_dup 6) (zero_extend:SWI48 (match_dup 5)))])
9172 (define_expand "addcarry<mode>_0"
9173   [(parallel
9174      [(set (reg:CCC FLAGS_REG)
9175            (compare:CCC
9176              (plus:SWI48
9177                (match_operand:SWI48 1 "nonimmediate_operand")
9178                (match_operand:SWI48 2 "x86_64_general_operand"))
9179              (match_dup 1)))
9180       (set (match_operand:SWI48 0 "nonimmediate_operand")
9181            (plus:SWI48 (match_dup 1) (match_dup 2)))])]
9182   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)")
9184 (define_insn "*addcarry<mode>_1"
9185   [(set (reg:CCC FLAGS_REG)
9186         (compare:CCC
9187           (zero_extend:<DWI>
9188             (plus:SWI48
9189               (plus:SWI48
9190                 (match_operator:SWI48 5 "ix86_carry_flag_operator"
9191                   [(match_operand 3 "flags_reg_operand") (const_int 0)])
9192                 (match_operand:SWI48 1 "nonimmediate_operand" "%0,rm"))
9193               (match_operand:SWI48 2 "x86_64_immediate_operand" "e,e")))
9194           (plus:<DWI>
9195             (match_operand:<DWI> 6 "const_scalar_int_operand")
9196             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
9197               [(match_dup 3) (const_int 0)]))))
9198    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9199         (plus:SWI48 (plus:SWI48 (match_op_dup 5
9200                                  [(match_dup 3) (const_int 0)])
9201                                 (match_dup 1))
9202                     (match_dup 2)))]
9203   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
9204    && CONST_INT_P (operands[2])
9205    /* Check that operands[6] is operands[2] zero extended from
9206       <MODE>mode to <DWI>mode.  */
9207    && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0)
9208        ? (CONST_INT_P (operands[6])
9209           && UINTVAL (operands[6]) == (UINTVAL (operands[2])
9210                                        & GET_MODE_MASK (<MODE>mode)))
9211        : (CONST_WIDE_INT_P (operands[6])
9212           && CONST_WIDE_INT_NUNITS (operands[6]) == 2
9213           && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
9214               == UINTVAL (operands[2]))
9215           && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
9216   "@
9217   adc{<imodesuffix>}\t{%2, %0|%0, %2}
9218   adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9219   [(set_attr "isa" "*,apx_ndd")
9220    (set_attr "type" "alu")
9221    (set_attr "use_carry" "1")
9222    (set_attr "pent_pair" "pu")
9223    (set_attr "mode" "<MODE>")
9224    (set (attr "length_immediate")
9225      (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
9226        (const_string "1")
9227        (const_string "4")))])
9229 (define_insn "@sub<mode>3_carry"
9230   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
9231         (minus:SWI
9232           (minus:SWI
9233             (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r")
9234             (match_operator:SWI 4 "ix86_carry_flag_operator"
9235              [(match_operand 3 "flags_reg_operand") (const_int 0)]))
9236           (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>")))
9237    (clobber (reg:CC FLAGS_REG))]
9238   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
9239   "@
9240   sbb{<imodesuffix>}\t{%2, %0|%0, %2}
9241   sbb{<imodesuffix>}\t{%2, %0|%0, %2}
9242   sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9243   sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9244   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
9245    (set_attr "type" "alu")
9246    (set_attr "use_carry" "1")
9247    (set_attr "pent_pair" "pu")
9248    (set_attr "mode" "<MODE>")])
9250 (define_peephole2
9251   [(set (match_operand:SWI 0 "general_reg_operand")
9252         (match_operand:SWI 1 "memory_operand"))
9253    (parallel [(set (match_dup 0)
9254                    (minus:SWI
9255                      (minus:SWI
9256                        (match_dup 0)
9257                        (match_operator:SWI 4 "ix86_carry_flag_operator"
9258                          [(match_operand 3 "flags_reg_operand")
9259                           (const_int 0)]))
9260                      (match_operand:SWI 2 "memory_operand")))
9261               (clobber (reg:CC FLAGS_REG))])
9262    (set (match_dup 1) (match_dup 0))]
9263   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9264    && peep2_reg_dead_p (3, operands[0])
9265    && !reg_overlap_mentioned_p (operands[0], operands[1])
9266    && !reg_overlap_mentioned_p (operands[0], operands[2])"
9267   [(set (match_dup 0) (match_dup 2))
9268    (parallel [(set (match_dup 1)
9269                    (minus:SWI (minus:SWI (match_dup 1)
9270                                          (match_op_dup 4
9271                                            [(match_dup 3) (const_int 0)]))
9272                               (match_dup 0)))
9273               (clobber (reg:CC FLAGS_REG))])])
9275 (define_peephole2
9276   [(set (match_operand:SWI 0 "general_reg_operand")
9277         (match_operand:SWI 1 "memory_operand"))
9278    (parallel [(set (match_dup 0)
9279                    (minus:SWI
9280                      (minus:SWI
9281                        (match_dup 0)
9282                        (match_operator:SWI 4 "ix86_carry_flag_operator"
9283                          [(match_operand 3 "flags_reg_operand")
9284                           (const_int 0)]))
9285                      (match_operand:SWI 2 "memory_operand")))
9286               (clobber (reg:CC FLAGS_REG))])
9287    (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
9288    (set (match_dup 1) (match_dup 5))]
9289   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9290    && peep2_reg_dead_p (3, operands[0])
9291    && peep2_reg_dead_p (4, operands[5])
9292    && !reg_overlap_mentioned_p (operands[0], operands[1])
9293    && !reg_overlap_mentioned_p (operands[0], operands[2])
9294    && !reg_overlap_mentioned_p (operands[5], operands[1])"
9295   [(set (match_dup 0) (match_dup 2))
9296    (parallel [(set (match_dup 1)
9297                    (minus:SWI (minus:SWI (match_dup 1)
9298                                          (match_op_dup 4
9299                                            [(match_dup 3) (const_int 0)]))
9300                               (match_dup 0)))
9301               (clobber (reg:CC FLAGS_REG))])])
9303 (define_insn "*sub<mode>3_carry_0"
9304   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9305         (minus:SWI
9306           (match_operand:SWI 1 "nonimmediate_operand" "0")
9307           (match_operator:SWI 2 "ix86_carry_flag_operator"
9308             [(reg FLAGS_REG) (const_int 0)])))
9309    (clobber (reg:CC FLAGS_REG))]
9310   "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
9311   "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
9312   [(set_attr "type" "alu")
9313    (set_attr "use_carry" "1")
9314    (set_attr "pent_pair" "pu")
9315    (set_attr "mode" "<MODE>")])
9317 (define_insn "*sub<mode>3_carry_0r"
9318   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9319         (minus:SWI
9320           (match_operand:SWI 1 "nonimmediate_operand" "0")
9321           (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
9322             [(reg FLAGS_REG) (const_int 0)])))
9323    (clobber (reg:CC FLAGS_REG))]
9324   "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
9325   "adc{<imodesuffix>}\t{$-1, %0|%0, -1}"
9326   [(set_attr "type" "alu")
9327    (set_attr "use_carry" "1")
9328    (set_attr "pent_pair" "pu")
9329    (set_attr "mode" "<MODE>")])
9331 (define_insn "*subqi3_carry_zext<mode>"
9332   [(set (match_operand:SWI248x 0 "register_operand" "=r,r")
9333         (zero_extend:SWI248x
9334           (minus:QI
9335             (minus:QI
9336               (match_operand:QI 1 "nonimmediate_operand" "r,rm")
9337               (match_operator:QI 3 "ix86_carry_flag_operator"
9338                [(reg FLAGS_REG) (const_int 0)]))
9339             (match_operand:QI 2 "x86_64_general_operand" "rBMe,re"))))
9340    (clobber (reg:CC FLAGS_REG))]
9341   "TARGET_APX_NDD
9342    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9343   "@
9344   sbb{b}\t{%2, %1, %b0|%b0, %1, %2}
9345   sbb{b}\t{%2, %1, %b0|%b0, %1, %2}"
9346   [(set_attr "type" "alu")
9347    (set_attr "use_carry" "1")
9348    (set_attr "pent_pair" "pu")
9349    (set_attr "mode" "QI")])
9351 (define_insn "*subhi3_carry_zext<mode>"
9352   [(set (match_operand:SWI48x 0 "register_operand" "=r,r")
9353         (zero_extend:SWI48x
9354           (minus:HI
9355             (minus:HI
9356               (match_operand:HI 1 "nonimmediate_operand" "r,rm")
9357               (match_operator:HI 3 "ix86_carry_flag_operator"
9358                [(reg FLAGS_REG) (const_int 0)]))
9359             (match_operand:HI 2 "x86_64_general_operand" "rBMe,re"))))
9360    (clobber (reg:CC FLAGS_REG))]
9361   "TARGET_APX_NDD
9362    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9363   "@
9364   sbb{w}\t{%2, %1, %w0|%w0, %1, %2}
9365   sbb{w}\t{%2, %1, %w0|%w0, %1, %2}"
9366   [(set_attr "type" "alu")
9367    (set_attr "use_carry" "1")
9368    (set_attr "pent_pair" "pu")
9369    (set_attr "mode" "HI")])
9371 (define_insn "*subsi3_carry_zext"
9372   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9373         (zero_extend:DI
9374           (minus:SI
9375             (minus:SI
9376               (match_operand:SI 1 "nonimmediate_operand" "0,r,rm")
9377               (match_operator:SI 3 "ix86_carry_flag_operator"
9378                [(reg FLAGS_REG) (const_int 0)]))
9379             (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))))
9380    (clobber (reg:CC FLAGS_REG))]
9381   "TARGET_64BIT
9382    && ix86_binary_operator_ok (MINUS, SImode, operands, TARGET_APX_NDD)"
9383   "@
9384   sbb{l}\t{%2, %k0|%k0, %2}
9385   sbb{l}\t{%2, %1, %k0|%k0, %1, %2}
9386   sbb{l}\t{%2, %1, %k0|%k0, %1, %2}"
9387   [(set_attr "isa" "*,apx_ndd,apx_ndd")
9388    (set_attr "type" "alu")
9389    (set_attr "use_carry" "1")
9390    (set_attr "pent_pair" "pu")
9391    (set_attr "mode" "SI")])
9393 (define_insn "*subqi3_carry_zext<mode>_0"
9394   [(set (match_operand:SWI248x 0 "register_operand" "=r")
9395         (zero_extend:SWI248x
9396           (minus:QI
9397             (match_operand:QI 1 "nonimmediate_operand" "rm")
9398             (match_operator:QI 2 "ix86_carry_flag_operator"
9399               [(reg FLAGS_REG) (const_int 0)]))))
9400    (clobber (reg:CC FLAGS_REG))]
9401   "TARGET_APX_NDD"
9402   "sbb{b}\t{$0, %1, %b0|%b0, %1, 0}"
9403   [(set_attr "type" "alu")
9404    (set_attr "use_carry" "1")
9405    (set_attr "pent_pair" "pu")
9406    (set_attr "mode" "QI")])
9408 (define_insn "*subhi3_carry_zext<mode>_0"
9409   [(set (match_operand:SWI48x 0 "register_operand" "=r")
9410         (zero_extend:SWI48x
9411           (minus:HI
9412             (match_operand:HI 1 "nonimmediate_operand" "rm")
9413             (match_operator:HI 2 "ix86_carry_flag_operator"
9414               [(reg FLAGS_REG) (const_int 0)]))))
9415    (clobber (reg:CC FLAGS_REG))]
9416   "TARGET_APX_NDD"
9417   "sbb{w}\t{$0, %1, %w0|%w0, %1, 0}"
9418   [(set_attr "type" "alu")
9419    (set_attr "use_carry" "1")
9420    (set_attr "pent_pair" "pu")
9421    (set_attr "mode" "HI")])
9423 (define_insn "*subsi3_carry_zext_0"
9424   [(set (match_operand:DI 0 "register_operand" "=r,r")
9425         (zero_extend:DI
9426           (minus:SI
9427             (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9428             (match_operator:SI 2 "ix86_carry_flag_operator"
9429               [(reg FLAGS_REG) (const_int 0)]))))
9430    (clobber (reg:CC FLAGS_REG))]
9431   "TARGET_64BIT"
9432   "@
9433   sbb{l}\t{$0, %k0|%k0, 0}
9434   sbb{l}\t{$0, %1, %k0|%k0, %1, 0}"
9435   [(set_attr "isa" "*,apx_ndd")
9436    (set_attr "type" "alu")
9437    (set_attr "use_carry" "1")
9438    (set_attr "pent_pair" "pu")
9439    (set_attr "mode" "SI")])
9441 (define_insn "*subqi3_carry_zext<mode>_0r"
9442   [(set (match_operand:SWI248x 0 "register_operand" "=r")
9443         (zero_extend:SWI248x
9444           (minus:QI
9445             (match_operand:QI 1 "nonimmediate_operand" "rm")
9446             (match_operator:QI 2 "ix86_carry_flag_unset_operator"
9447               [(reg FLAGS_REG) (const_int 0)]))))
9448    (clobber (reg:CC FLAGS_REG))]
9449   "TARGET_APX_NDD"
9450   "adc{b}\t{$-1, %1, %b0|%b0, %1, -1}"
9451   [(set_attr "type" "alu")
9452    (set_attr "use_carry" "1")
9453    (set_attr "pent_pair" "pu")
9454    (set_attr "mode" "QI")])
9456 (define_insn "*subhi3_carry_zext<mode>_0r"
9457   [(set (match_operand:SWI48x 0 "register_operand" "=r")
9458         (zero_extend:SWI48x
9459           (minus:HI
9460             (match_operand:HI 1 "nonimmediate_operand" "rm")
9461             (match_operator:HI 2 "ix86_carry_flag_unset_operator"
9462               [(reg FLAGS_REG) (const_int 0)]))))
9463    (clobber (reg:CC FLAGS_REG))]
9464   "TARGET_APX_NDD"
9465   "adc{w}\t{$-1, %1, %w0|%w0, %1, -1}"
9466   [(set_attr "type" "alu")
9467    (set_attr "use_carry" "1")
9468    (set_attr "pent_pair" "pu")
9469    (set_attr "mode" "HI")])
9471 (define_insn "*subsi3_carry_zext_0r"
9472   [(set (match_operand:DI 0 "register_operand" "=r,r")
9473         (zero_extend:DI
9474           (minus:SI
9475             (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9476             (match_operator:SI 2 "ix86_carry_flag_unset_operator"
9477               [(reg FLAGS_REG) (const_int 0)]))))
9478    (clobber (reg:CC FLAGS_REG))]
9479   "TARGET_64BIT"
9480   "@
9481   adc{l}\t{$-1, %k0|%k0, -1}
9482   adc{l}\t{$-1, %1, %k0|%k0, %1, -1}"
9483   [(set_attr "isa" "*,apx_ndd")
9484    (set_attr "type" "alu")
9485    (set_attr "use_carry" "1")
9486    (set_attr "pent_pair" "pu")
9487    (set_attr "mode" "SI")])
9489 (define_insn "@sub<mode>3_carry_ccc"
9490   [(set (reg:CCC FLAGS_REG)
9491         (compare:CCC
9492           (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
9493           (plus:<DWI>
9494             (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
9495             (zero_extend:<DWI>
9496               (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
9497    (clobber (match_scratch:DWIH 0 "=r"))]
9498   ""
9499   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
9500   [(set_attr "type" "alu")
9501    (set_attr "mode" "<MODE>")])
9503 (define_insn "*sub<mode>3_carry_ccc_1"
9504   [(set (reg:CCC FLAGS_REG)
9505         (compare:CCC
9506           (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
9507           (plus:<DWI>
9508             (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
9509             (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
9510    (clobber (match_scratch:DWIH 0 "=r"))]
9511   ""
9513   operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
9514   return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
9516   [(set_attr "type" "alu")
9517    (set_attr "mode" "<MODE>")])
9519 ;; The sign flag is set from the
9520 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
9521 ;; result, the overflow flag likewise, but the overflow flag is also
9522 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
9523 (define_insn "@sub<mode>3_carry_ccgz"
9524   [(set (reg:CCGZ FLAGS_REG)
9525         (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
9526                       (match_operand:DWIH 2 "x86_64_general_operand" "rBMe")
9527                       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
9528                      UNSPEC_SBB))
9529    (clobber (match_scratch:DWIH 0 "=r"))]
9530   ""
9531   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
9532   [(set_attr "type" "alu")
9533    (set_attr "mode" "<MODE>")])
9535 (define_insn "subborrow<mode>"
9536   [(set (reg:CCC FLAGS_REG)
9537         (compare:CCC
9538           (zero_extend:<DWI>
9539             (match_operand:SWI48 1 "nonimmediate_operand" "0,0,r,rm"))
9540           (plus:<DWI>
9541             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
9542               [(match_operand 3 "flags_reg_operand") (const_int 0)])
9543             (zero_extend:<DWI>
9544               (match_operand:SWI48 2 "nonimmediate_operand" "r,rm,rm,r")))))
9545    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
9546         (minus:SWI48 (minus:SWI48
9547                        (match_dup 1)
9548                        (match_operator:SWI48 5 "ix86_carry_flag_operator"
9549                          [(match_dup 3) (const_int 0)]))
9550                      (match_dup 2)))]
9551   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
9552   "@
9553   sbb{<imodesuffix>}\t{%2, %0|%0, %2}
9554   sbb{<imodesuffix>}\t{%2, %0|%0, %2}
9555   sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9556   sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9557   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
9558    (set_attr "type" "alu")
9559    (set_attr "use_carry" "1")
9560    (set_attr "pent_pair" "pu")
9561    (set_attr "mode" "<MODE>")])
9563 (define_peephole2
9564   [(set (match_operand:SWI48 0 "general_reg_operand")
9565         (match_operand:SWI48 1 "memory_operand"))
9566    (parallel [(set (reg:CCC FLAGS_REG)
9567                    (compare:CCC
9568                      (zero_extend:<DWI> (match_dup 0))
9569                      (plus:<DWI>
9570                        (match_operator:<DWI> 4 "ix86_carry_flag_operator"
9571                          [(match_operand 3 "flags_reg_operand") (const_int 0)])
9572                        (zero_extend:<DWI>
9573                          (match_operand:SWI48 2 "memory_operand")))))
9574               (set (match_dup 0)
9575                    (minus:SWI48
9576                      (minus:SWI48
9577                        (match_dup 0)
9578                        (match_operator:SWI48 5 "ix86_carry_flag_operator"
9579                          [(match_dup 3) (const_int 0)]))
9580                      (match_dup 2)))])
9581    (set (match_dup 1) (match_dup 0))]
9582   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9583    && peep2_reg_dead_p (3, operands[0])
9584    && !reg_overlap_mentioned_p (operands[0], operands[1])
9585    && !reg_overlap_mentioned_p (operands[0], operands[2])"
9586   [(set (match_dup 0) (match_dup 2))
9587    (parallel [(set (reg:CCC FLAGS_REG)
9588                    (compare:CCC
9589                      (zero_extend:<DWI> (match_dup 1))
9590                      (plus:<DWI> (match_op_dup 4
9591                                    [(match_dup 3) (const_int 0)])
9592                                  (zero_extend:<DWI> (match_dup 0)))))
9593               (set (match_dup 1)
9594                    (minus:SWI48 (minus:SWI48 (match_dup 1)
9595                                              (match_op_dup 5
9596                                                [(match_dup 3) (const_int 0)]))
9597                                 (match_dup 0)))])])
9599 (define_peephole2
9600   [(set (match_operand:SWI48 6 "general_reg_operand")
9601         (match_operand:SWI48 7 "memory_operand"))
9602    (set (match_operand:SWI48 8 "general_reg_operand")
9603         (match_operand:SWI48 9 "memory_operand"))
9604    (parallel [(set (reg:CCC FLAGS_REG)
9605                    (compare:CCC
9606                      (zero_extend:<DWI>
9607                        (match_operand:SWI48 0 "general_reg_operand"))
9608                      (plus:<DWI>
9609                        (match_operator:<DWI> 4 "ix86_carry_flag_operator"
9610                          [(match_operand 3 "flags_reg_operand") (const_int 0)])
9611                        (zero_extend:<DWI>
9612                          (match_operand:SWI48 2 "general_reg_operand")))))
9613               (set (match_dup 0)
9614                    (minus:SWI48
9615                      (minus:SWI48
9616                        (match_dup 0)
9617                        (match_operator:SWI48 5 "ix86_carry_flag_operator"
9618                          [(match_dup 3) (const_int 0)]))
9619                      (match_dup 2)))])
9620    (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
9621   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9622    && peep2_reg_dead_p (4, operands[0])
9623    && peep2_reg_dead_p (3, operands[2])
9624    && !reg_overlap_mentioned_p (operands[0], operands[1])
9625    && !reg_overlap_mentioned_p (operands[2], operands[1])
9626    && !reg_overlap_mentioned_p (operands[6], operands[9])
9627    && (rtx_equal_p (operands[6], operands[0])
9628        ? (rtx_equal_p (operands[7], operands[1])
9629           && rtx_equal_p (operands[8], operands[2]))
9630        : (rtx_equal_p (operands[8], operands[0])
9631           && rtx_equal_p (operands[9], operands[1])
9632           && rtx_equal_p (operands[6], operands[2])))"
9633   [(set (match_dup 0) (match_dup 9))
9634    (parallel [(set (reg:CCC FLAGS_REG)
9635                    (compare:CCC
9636                      (zero_extend:<DWI> (match_dup 1))
9637                      (plus:<DWI> (match_op_dup 4
9638                                    [(match_dup 3) (const_int 0)])
9639                                  (zero_extend:<DWI> (match_dup 0)))))
9640               (set (match_dup 1)
9641                    (minus:SWI48 (minus:SWI48 (match_dup 1)
9642                                              (match_op_dup 5
9643                                                [(match_dup 3) (const_int 0)]))
9644                                 (match_dup 0)))])]
9646   if (!rtx_equal_p (operands[6], operands[0]))
9647     operands[9] = operands[7];
9650 (define_peephole2
9651   [(set (match_operand:SWI48 6 "general_reg_operand")
9652         (match_operand:SWI48 7 "memory_operand"))
9653    (set (match_operand:SWI48 8 "general_reg_operand")
9654         (match_operand:SWI48 9 "memory_operand"))
9655    (parallel [(set (reg:CCC FLAGS_REG)
9656                    (compare:CCC
9657                      (zero_extend:<DWI>
9658                        (match_operand:SWI48 0 "general_reg_operand"))
9659                      (plus:<DWI>
9660                        (match_operator:<DWI> 4 "ix86_carry_flag_operator"
9661                          [(match_operand 3 "flags_reg_operand") (const_int 0)])
9662                        (zero_extend:<DWI>
9663                          (match_operand:SWI48 2 "general_reg_operand")))))
9664               (set (match_dup 0)
9665                    (minus:SWI48
9666                      (minus:SWI48
9667                        (match_dup 0)
9668                        (match_operator:SWI48 5 "ix86_carry_flag_operator"
9669                          [(match_dup 3) (const_int 0)]))
9670                      (match_dup 2)))])
9671    (set (match_operand:QI 10 "general_reg_operand")
9672         (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
9673    (set (match_operand:SWI48 11 "general_reg_operand")
9674         (zero_extend:SWI48 (match_dup 10)))
9675    (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
9676   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9677    && peep2_reg_dead_p (6, operands[0])
9678    && peep2_reg_dead_p (3, operands[2])
9679    && !reg_overlap_mentioned_p (operands[0], operands[1])
9680    && !reg_overlap_mentioned_p (operands[2], operands[1])
9681    && !reg_overlap_mentioned_p (operands[6], operands[9])
9682    && !reg_overlap_mentioned_p (operands[0], operands[10])
9683    && !reg_overlap_mentioned_p (operands[10], operands[1])
9684    && !reg_overlap_mentioned_p (operands[0], operands[11])
9685    && !reg_overlap_mentioned_p (operands[11], operands[1])
9686    && (rtx_equal_p (operands[6], operands[0])
9687        ? (rtx_equal_p (operands[7], operands[1])
9688           && rtx_equal_p (operands[8], operands[2]))
9689        : (rtx_equal_p (operands[8], operands[0])
9690           && rtx_equal_p (operands[9], operands[1])
9691           && rtx_equal_p (operands[6], operands[2])))"
9692   [(set (match_dup 0) (match_dup 9))
9693    (parallel [(set (reg:CCC FLAGS_REG)
9694                    (compare:CCC
9695                      (zero_extend:<DWI> (match_dup 1))
9696                      (plus:<DWI> (match_op_dup 4
9697                                    [(match_dup 3) (const_int 0)])
9698                                  (zero_extend:<DWI> (match_dup 0)))))
9699               (set (match_dup 1)
9700                    (minus:SWI48 (minus:SWI48 (match_dup 1)
9701                                              (match_op_dup 5
9702                                                [(match_dup 3) (const_int 0)]))
9703                                 (match_dup 0)))])
9704    (set (match_dup 10) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
9705    (set (match_dup 11) (zero_extend:SWI48 (match_dup 10)))]
9707   if (!rtx_equal_p (operands[6], operands[0]))
9708     operands[9] = operands[7];
9711 (define_expand "subborrow<mode>_0"
9712   [(parallel
9713      [(set (reg:CC FLAGS_REG)
9714            (compare:CC
9715              (match_operand:SWI48 1 "nonimmediate_operand")
9716              (match_operand:SWI48 2 "<general_operand>")))
9717       (set (match_operand:SWI48 0 "register_operand")
9718            (minus:SWI48 (match_dup 1) (match_dup 2)))])]
9719   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)")
9721 (define_expand "uaddc<mode>5"
9722   [(match_operand:SWI48 0 "register_operand")
9723    (match_operand:SWI48 1 "register_operand")
9724    (match_operand:SWI48 2 "register_operand")
9725    (match_operand:SWI48 3 "register_operand")
9726    (match_operand:SWI48 4 "nonmemory_operand")]
9727   ""
9729   rtx cf = gen_rtx_REG (CCCmode, FLAGS_REG), pat, pat2;
9730   if (operands[4] == const0_rtx)
9731     emit_insn (gen_addcarry<mode>_0 (operands[0], operands[2], operands[3]));
9732   else
9733     {
9734       ix86_expand_carry (operands[4]);
9735       pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
9736       pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
9737       emit_insn (gen_addcarry<mode> (operands[0], operands[2], operands[3],
9738                                      cf, pat, pat2));
9739     }
9740   rtx cc = gen_reg_rtx (QImode);
9741   pat = gen_rtx_LTU (QImode, cf, const0_rtx);
9742   emit_insn (gen_rtx_SET (cc, pat));
9743   emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
9744   DONE;
9747 (define_expand "usubc<mode>5"
9748   [(match_operand:SWI48 0 "register_operand")
9749    (match_operand:SWI48 1 "register_operand")
9750    (match_operand:SWI48 2 "register_operand")
9751    (match_operand:SWI48 3 "register_operand")
9752    (match_operand:SWI48 4 "nonmemory_operand")]
9753   ""
9755   rtx cf, pat, pat2;
9756   if (operands[4] == const0_rtx)
9757     {
9758       cf = gen_rtx_REG (CCmode, FLAGS_REG);
9759       emit_insn (gen_subborrow<mode>_0 (operands[0], operands[2],
9760                                         operands[3]));
9761     }
9762   else
9763     {
9764       cf = gen_rtx_REG (CCCmode, FLAGS_REG);
9765       ix86_expand_carry (operands[4]);
9766       pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
9767       pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
9768       emit_insn (gen_subborrow<mode> (operands[0], operands[2], operands[3],
9769                                       cf, pat, pat2));
9770     }
9771   rtx cc = gen_reg_rtx (QImode);
9772   pat = gen_rtx_LTU (QImode, cf, const0_rtx);
9773   emit_insn (gen_rtx_SET (cc, pat));
9774   emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
9775   DONE;
9778 (define_mode_iterator CC_CCC [CC CCC])
9780 ;; Pre-reload splitter to optimize
9781 ;; *setcc_qi followed by *addqi3_cconly_overflow_1 with the same QI
9782 ;; operand and no intervening flags modifications into nothing.
9783 (define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1_<mode>"
9784   [(set (reg:CCC FLAGS_REG)
9785         (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
9786                      (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))))]
9787   "ix86_pre_reload_split ()"
9788   "#"
9789   "&& 1"
9790   [(const_int 0)]
9791   "emit_note (NOTE_INSN_DELETED); DONE;")
9793 ;; Set the carry flag from the carry flag.
9794 (define_insn_and_split "*setccc"
9795   [(set (reg:CCC FLAGS_REG)
9796         (reg:CCC FLAGS_REG))]
9797   "ix86_pre_reload_split ()"
9798   "#"
9799   "&& 1"
9800   [(const_int 0)]
9801   "emit_note (NOTE_INSN_DELETED); DONE;")
9803 ;; Set the carry flag from the carry flag.
9804 (define_insn_and_split "*setcc_qi_negqi_ccc_1_<mode>"
9805   [(set (reg:CCC FLAGS_REG)
9806         (ltu:CCC (reg:CC_CCC FLAGS_REG) (const_int 0)))]
9807   "ix86_pre_reload_split ()"
9808   "#"
9809   "&& 1"
9810   [(const_int 0)]
9811   "emit_note (NOTE_INSN_DELETED); DONE;")
9813 ;; Set the carry flag from the carry flag.
9814 (define_insn_and_split "*setcc_qi_negqi_ccc_2_<mode>"
9815   [(set (reg:CCC FLAGS_REG)
9816         (unspec:CCC [(ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
9817                      (const_int 0)] UNSPEC_CC_NE))]
9818   "ix86_pre_reload_split ()"
9819   "#"
9820   "&& 1"
9821   [(const_int 0)]
9822   "emit_note (NOTE_INSN_DELETED); DONE;")
9824 ;; Overflow setting add instructions
9826 (define_expand "addqi3_cconly_overflow"
9827   [(parallel
9828      [(set (reg:CCC FLAGS_REG)
9829            (compare:CCC
9830              (plus:QI
9831                (match_operand:QI 0 "nonimmediate_operand")
9832                (match_operand:QI 1 "general_operand"))
9833              (match_dup 0)))
9834       (clobber (scratch:QI))])]
9835   "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
9837 (define_insn "*add<mode>3_cconly_overflow_1"
9838   [(set (reg:CCC FLAGS_REG)
9839         (compare:CCC
9840           (plus:SWI
9841             (match_operand:SWI 1 "nonimmediate_operand" "%0,r,rm")
9842             (match_operand:SWI 2 "<general_operand>" "<g>,<g>,re"))
9843           (match_dup 1)))
9844    (clobber (match_scratch:SWI 0 "=<r>,r,r"))]
9845   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9846   "@
9847   add{<imodesuffix>}\t{%2, %0|%0, %2}
9848   add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9849   add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9850   [(set_attr "isa" "*,apx_ndd,apx_ndd")
9851    (set_attr "type" "alu")
9852    (set_attr "mode" "<MODE>")])
9854 (define_insn "@add<mode>3_cc_overflow_1"
9855   [(set (reg:CCC FLAGS_REG)
9856         (compare:CCC
9857             (plus:SWI
9858                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,rjM,r")
9859                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r,<i>,<m>"))
9860             (match_dup 1)))
9861    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r,r")
9862         (plus:SWI (match_dup 1) (match_dup 2)))]
9863   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
9864   "@
9865    add{<imodesuffix>}\t{%2, %0|%0, %2}
9866    add{<imodesuffix>}\t{%2, %0|%0, %2}
9867    add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9868    add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9869    add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9870   [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd")
9871    (set_attr "type" "alu")
9872    (set_attr "mode" "<MODE>")])
9874 (define_peephole2
9875   [(parallel [(set (reg:CCC FLAGS_REG)
9876                    (compare:CCC
9877                      (plus:SWI (match_operand:SWI 0 "general_reg_operand")
9878                                (match_operand:SWI 1 "memory_operand"))
9879                      (match_dup 0)))
9880               (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 1)))])
9881    (set (match_dup 1) (match_dup 0))]
9882   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9883    && peep2_reg_dead_p (2, operands[0])
9884    && !reg_overlap_mentioned_p (operands[0], operands[1])"
9885   [(parallel [(set (reg:CCC FLAGS_REG)
9886                    (compare:CCC
9887                      (plus:SWI (match_dup 1) (match_dup 0))
9888                      (match_dup 1)))
9889               (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
9891 (define_peephole2
9892   [(set (match_operand:SWI 0 "general_reg_operand")
9893         (match_operand:SWI 1 "memory_operand"))
9894    (parallel [(set (reg:CCC FLAGS_REG)
9895                    (compare:CCC
9896                      (plus:SWI (match_dup 0)
9897                                (match_operand:SWI 2 "memory_operand"))
9898                      (match_dup 0)))
9899               (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 2)))])
9900    (set (match_dup 1) (match_dup 0))]
9901   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9902    && peep2_reg_dead_p (3, operands[0])
9903    && !reg_overlap_mentioned_p (operands[0], operands[1])
9904    && !reg_overlap_mentioned_p (operands[0], operands[2])"
9905   [(set (match_dup 0) (match_dup 2))
9906    (parallel [(set (reg:CCC FLAGS_REG)
9907                    (compare:CCC
9908                      (plus:SWI (match_dup 1) (match_dup 0))
9909                      (match_dup 1)))
9910               (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
9912 (define_insn "*addsi3_zext_cc_overflow_1"
9913   [(set (reg:CCC FLAGS_REG)
9914         (compare:CCC
9915           (plus:SI
9916             (match_operand:SI 1 "nonimmediate_operand" "%0,r,rm")
9917             (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))
9918           (match_dup 1)))
9919    (set (match_operand:DI 0 "register_operand" "=r,r,r")
9920         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9921   "TARGET_64BIT
9922    && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
9923   "@
9924   add{l}\t{%2, %k0|%k0, %2}
9925   add{l}\t{%2, %1, %k0|%k0, %1, %2}
9926   add{l}\t{%2, %1, %k0|%k0, %1, %2}"
9927   [(set_attr "isa" "*,apx_ndd,apx_ndd")
9928    (set_attr "type" "alu")
9929    (set_attr "mode" "SI")])
9931 (define_insn "*add<mode>3_cconly_overflow_2"
9932   [(set (reg:CCC FLAGS_REG)
9933         (compare:CCC
9934           (plus:SWI
9935             (match_operand:SWI 1 "nonimmediate_operand" "%0,r,rm")
9936             (match_operand:SWI 2 "<general_operand>" "<g>,<g>,re"))
9937           (match_dup 2)))
9938    (clobber (match_scratch:SWI 0 "=<r>,r,r"))]
9939   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9940   "@
9941   add{<imodesuffix>}\t{%2, %0|%0, %2}
9942   add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9943   add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9944   [(set_attr "isa" "*,apx_ndd,apx_ndd")
9945    (set_attr "type" "alu")
9946    (set_attr "mode" "<MODE>")])
9948 (define_insn "*add<mode>3_cc_overflow_2"
9949   [(set (reg:CCC FLAGS_REG)
9950         (compare:CCC
9951             (plus:SWI
9952                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r")
9953                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>"))
9954             (match_dup 2)))
9955    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
9956         (plus:SWI (match_dup 1) (match_dup 2)))]
9957   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
9958   "@
9959   add{<imodesuffix>}\t{%2, %0|%0, %2}
9960   add{<imodesuffix>}\t{%2, %0|%0, %2}
9961   add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9962   add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9963   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
9964    (set_attr "type" "alu")
9965    (set_attr "mode" "<MODE>")])
9967 (define_insn "*addsi3_zext_cc_overflow_2"
9968   [(set (reg:CCC FLAGS_REG)
9969         (compare:CCC
9970           (plus:SI
9971             (match_operand:SI 1 "nonimmediate_operand" "%0,r,rm")
9972             (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))
9973           (match_dup 2)))
9974    (set (match_operand:DI 0 "register_operand" "=r,r,r")
9975         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9976   "TARGET_64BIT
9977    && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
9978   "@
9979   add{l}\t{%2, %k0|%k0, %2}
9980   add{l}\t{%2, %1, %k0|%k0, %1, %2}
9981   add{l}\t{%2, %1, %k0|%k0, %1, %2}"
9982   [(set_attr "isa" "*,apx_ndd,apx_ndd")
9983    (set_attr "type" "alu")
9984    (set_attr "mode" "SI")])
9986 (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
9987   [(set (reg:CCC FLAGS_REG)
9988         (compare:CCC
9989           (plus:<DWI>
9990             (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r,ro,jO,r")
9991             (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r,<di>,K,<di>,o"))
9992           (match_dup 1)))
9993    (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r,&r,&r,&r")
9994         (plus:<DWI> (match_dup 1) (match_dup 2)))]
9995   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands, TARGET_APX_NDD)"
9996   "#"
9997   "&& reload_completed"
9998   [(parallel [(set (reg:CCC FLAGS_REG)
9999                    (compare:CCC
10000                      (plus:DWIH (match_dup 1) (match_dup 2))
10001                      (match_dup 1)))
10002               (set (match_dup 0)
10003                    (plus:DWIH (match_dup 1) (match_dup 2)))])
10004    (parallel [(set (reg:CCC FLAGS_REG)
10005                    (compare:CCC
10006                      (zero_extend:<DWI>
10007                        (plus:DWIH
10008                          (plus:DWIH
10009                            (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
10010                            (match_dup 4))
10011                          (match_dup 5)))
10012                      (plus:<DWI>
10013                        (match_dup 6)
10014                        (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))))
10015               (set (match_dup 3)
10016                    (plus:DWIH
10017                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
10018                                 (match_dup 4))
10019                      (match_dup 5)))])]
10021   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
10022   if (operands[2] == const0_rtx)
10023     {
10024       if (!rtx_equal_p (operands[0], operands[1]))
10025         emit_move_insn (operands[0], operands[1]);
10026       emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
10027       DONE;
10028     }
10029   if (CONST_INT_P (operands[5]))
10030     operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode,
10031                                             operands[5], <MODE>mode);
10032   else
10033     operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
10035 [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd_64,apx_ndd")])
10037 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
10038 ;; test, where the latter is preferrable if we have some carry consuming
10039 ;; instruction.
10040 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
10041 ;; + (1 - CF).
10042 (define_insn_and_split "*add<mode>3_eq"
10043   [(set (match_operand:SWI 0 "nonimmediate_operand")
10044         (plus:SWI
10045           (plus:SWI
10046             (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
10047             (match_operand:SWI 1 "nonimmediate_operand"))
10048           (match_operand:SWI 2 "<general_operand>")))
10049    (clobber (reg:CC FLAGS_REG))]
10050   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
10051    && ix86_pre_reload_split ()"
10052   "#"
10053   "&& 1"
10054   [(set (reg:CC FLAGS_REG)
10055         (compare:CC (match_dup 3) (const_int 1)))
10056    (parallel [(set (match_dup 0)
10057                    (plus:SWI
10058                      (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
10059                                (match_dup 1))
10060                      (match_dup 2)))
10061               (clobber (reg:CC FLAGS_REG))])])
10063 (define_insn_and_split "*add<mode>3_ne"
10064   [(set (match_operand:SWI 0 "nonimmediate_operand")
10065         (plus:SWI
10066           (plus:SWI
10067             (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
10068             (match_operand:SWI 1 "nonimmediate_operand"))
10069           (match_operand:SWI 2 "<immediate_operand>")))
10070    (clobber (reg:CC FLAGS_REG))]
10071   "CONST_INT_P (operands[2])
10072    && (<MODE>mode != DImode
10073        || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
10074    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
10075    && ix86_pre_reload_split ()"
10076   "#"
10077   "&& 1"
10078   [(set (reg:CC FLAGS_REG)
10079         (compare:CC (match_dup 3) (const_int 1)))
10080    (parallel [(set (match_dup 0)
10081                    (minus:SWI
10082                      (minus:SWI (match_dup 1)
10083                                 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
10084                      (match_dup 2)))
10085               (clobber (reg:CC FLAGS_REG))])]
10087   operands[2] = gen_int_mode (~INTVAL (operands[2]),
10088                               <MODE>mode == DImode ? SImode : <MODE>mode);
10091 (define_insn_and_split "*add<mode>3_eq_0"
10092   [(set (match_operand:SWI 0 "nonimmediate_operand")
10093         (plus:SWI
10094           (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
10095           (match_operand:SWI 1 "<general_operand>")))
10096    (clobber (reg:CC FLAGS_REG))]
10097   "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
10098    && ix86_pre_reload_split ()"
10099   "#"
10100   "&& 1"
10101   [(set (reg:CC FLAGS_REG)
10102         (compare:CC (match_dup 2) (const_int 1)))
10103    (parallel [(set (match_dup 0)
10104                    (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
10105                              (match_dup 1)))
10106               (clobber (reg:CC FLAGS_REG))])]
10108   if (!nonimmediate_operand (operands[1], <MODE>mode))
10109     operands[1] = force_reg (<MODE>mode, operands[1]);
10112 (define_insn_and_split "*add<mode>3_ne_0"
10113   [(set (match_operand:SWI 0 "nonimmediate_operand")
10114         (plus:SWI
10115           (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
10116           (match_operand:SWI 1 "<general_operand>")))
10117    (clobber (reg:CC FLAGS_REG))]
10118   "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
10119    && ix86_pre_reload_split ()"
10120   "#"
10121   "&& 1"
10122   [(set (reg:CC FLAGS_REG)
10123         (compare:CC (match_dup 2) (const_int 1)))
10124    (parallel [(set (match_dup 0)
10125                    (minus:SWI (minus:SWI
10126                                 (match_dup 1)
10127                                 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
10128                               (const_int -1)))
10129               (clobber (reg:CC FLAGS_REG))])]
10131   if (!nonimmediate_operand (operands[1], <MODE>mode))
10132     operands[1] = force_reg (<MODE>mode, operands[1]);
10135 (define_insn_and_split "*sub<mode>3_eq"
10136   [(set (match_operand:SWI 0 "nonimmediate_operand")
10137         (minus:SWI
10138           (minus:SWI
10139             (match_operand:SWI 1 "nonimmediate_operand")
10140             (eq:SWI (match_operand 3 "int_nonimmediate_operand")
10141                     (const_int 0)))
10142           (match_operand:SWI 2 "<general_operand>")))
10143    (clobber (reg:CC FLAGS_REG))]
10144   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
10145    && ix86_pre_reload_split ()"
10146   "#"
10147   "&& 1"
10148   [(set (reg:CC FLAGS_REG)
10149         (compare:CC (match_dup 3) (const_int 1)))
10150    (parallel [(set (match_dup 0)
10151                    (minus:SWI
10152                      (minus:SWI (match_dup 1)
10153                                 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
10154                      (match_dup 2)))
10155               (clobber (reg:CC FLAGS_REG))])])
10157 (define_insn_and_split "*sub<mode>3_ne"
10158   [(set (match_operand:SWI 0 "nonimmediate_operand")
10159         (plus:SWI
10160           (minus:SWI
10161             (match_operand:SWI 1 "nonimmediate_operand")
10162             (ne:SWI (match_operand 3 "int_nonimmediate_operand")
10163                     (const_int 0)))
10164           (match_operand:SWI 2 "<immediate_operand>")))
10165    (clobber (reg:CC FLAGS_REG))]
10166   "CONST_INT_P (operands[2])
10167    && (<MODE>mode != DImode
10168        || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
10169    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
10170    && ix86_pre_reload_split ()"
10171   "#"
10172   "&& 1"
10173   [(set (reg:CC FLAGS_REG)
10174         (compare:CC (match_dup 3) (const_int 1)))
10175    (parallel [(set (match_dup 0)
10176                    (plus:SWI
10177                      (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
10178                                (match_dup 1))
10179                      (match_dup 2)))
10180               (clobber (reg:CC FLAGS_REG))])]
10182   operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
10183                               <MODE>mode == DImode ? SImode : <MODE>mode);
10186 (define_insn_and_split "*sub<mode>3_eq_1"
10187   [(set (match_operand:SWI 0 "nonimmediate_operand")
10188         (plus:SWI
10189           (minus:SWI
10190             (match_operand:SWI 1 "nonimmediate_operand")
10191             (eq:SWI (match_operand 3 "int_nonimmediate_operand")
10192                     (const_int 0)))
10193           (match_operand:SWI 2 "<immediate_operand>")))
10194    (clobber (reg:CC FLAGS_REG))]
10195   "CONST_INT_P (operands[2])
10196    && (<MODE>mode != DImode
10197        || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
10198    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
10199    && ix86_pre_reload_split ()"
10200   "#"
10201   "&& 1"
10202   [(set (reg:CC FLAGS_REG)
10203         (compare:CC (match_dup 3) (const_int 1)))
10204    (parallel [(set (match_dup 0)
10205                    (minus:SWI
10206                      (minus:SWI (match_dup 1)
10207                                 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
10208                      (match_dup 2)))
10209               (clobber (reg:CC FLAGS_REG))])]
10211   operands[2] = gen_int_mode (-INTVAL (operands[2]),
10212                               <MODE>mode == DImode ? SImode : <MODE>mode);
10215 (define_insn_and_split "*sub<mode>3_eq_0"
10216   [(set (match_operand:SWI 0 "nonimmediate_operand")
10217         (minus:SWI
10218           (match_operand:SWI 1 "<general_operand>")
10219           (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
10220    (clobber (reg:CC FLAGS_REG))]
10221   "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
10222    && ix86_pre_reload_split ()"
10223   "#"
10224   "&& 1"
10225   [(set (reg:CC FLAGS_REG)
10226         (compare:CC (match_dup 2) (const_int 1)))
10227    (parallel [(set (match_dup 0)
10228                    (minus:SWI (match_dup 1)
10229                               (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
10230               (clobber (reg:CC FLAGS_REG))])]
10232   if (!nonimmediate_operand (operands[1], <MODE>mode))
10233     operands[1] = force_reg (<MODE>mode, operands[1]);
10236 (define_insn_and_split "*sub<mode>3_ne_0"
10237   [(set (match_operand:SWI 0 "nonimmediate_operand")
10238         (minus:SWI
10239           (match_operand:SWI 1 "<general_operand>")
10240           (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
10241    (clobber (reg:CC FLAGS_REG))]
10242   "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
10243    && ix86_pre_reload_split ()"
10244   "#"
10245   "&& 1"
10246   [(set (reg:CC FLAGS_REG)
10247         (compare:CC (match_dup 2) (const_int 1)))
10248    (parallel [(set (match_dup 0)
10249                    (plus:SWI (plus:SWI
10250                                (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
10251                                (match_dup 1))
10252                              (const_int -1)))
10253               (clobber (reg:CC FLAGS_REG))])]
10255   if (!nonimmediate_operand (operands[1], <MODE>mode))
10256     operands[1] = force_reg (<MODE>mode, operands[1]);
10259 (define_expand "usadd<mode>3"
10260   [(set (match_operand:SWI 0 "register_operand")
10261         (us_plus:SWI (match_operand:SWI 1 "register_operand")
10262                      (match_operand:SWI 2 "<general_operand>")))]
10263   ""
10265   rtx res = gen_reg_rtx (<MODE>mode);
10266   rtx dst;
10268   emit_insn (gen_add<mode>3_cc_overflow_1 (res, operands[1], operands[2]));
10270   if (TARGET_CMOVE)
10271     {
10272       rtx cmp = gen_rtx_GEU (VOIDmode, gen_rtx_REG (CCCmode, FLAGS_REG),
10273                              const0_rtx);
10275       if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
10276         {
10277           dst = force_reg (<MODE>mode, operands[0]);
10278           emit_insn (gen_movsicc (gen_lowpart (SImode, dst), cmp,
10279                                   gen_lowpart (SImode, res), constm1_rtx));
10280         }
10281        else
10282         {
10283           dst = operands[0];
10284           emit_insn (gen_mov<mode>cc (dst, cmp, res, constm1_rtx));
10285         }
10286     }
10287   else
10288     {
10289       rtx msk = gen_reg_rtx (<MODE>mode);
10291       emit_insn (gen_x86_mov<mode>cc_0_m1_neg (msk));
10292       dst = expand_simple_binop (<MODE>mode, IOR, res, msk,
10293                                  operands[0], 1, OPTAB_WIDEN);
10294     }
10296   if (!rtx_equal_p (dst, operands[0]))
10297     emit_move_insn (operands[0], dst);
10298   DONE;
10301 (define_expand "ussub<mode>3"
10302   [(set (match_operand:SWI 0 "register_operand")
10303         (us_minus:SWI (match_operand:SWI 1 "register_operand")
10304                       (match_operand:SWI 2 "<general_operand>")))]
10305   ""
10307   rtx res = gen_reg_rtx (<MODE>mode);
10308   rtx dst;
10310   emit_insn (gen_sub<mode>_3 (res, operands[1], operands[2]));
10312   if (TARGET_CMOVE)
10313     {
10314       rtx cmp = gen_rtx_GEU (VOIDmode, gen_rtx_REG (CCCmode, FLAGS_REG),
10315                              const0_rtx);
10317       if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
10318         {
10319           dst = force_reg (<MODE>mode, operands[0]);
10320           emit_insn (gen_movsicc (gen_lowpart (SImode, dst), cmp,
10321                                   gen_lowpart (SImode, res), const0_rtx));
10322         }
10323        else
10324         {
10325           dst = operands[0];
10326           emit_insn (gen_mov<mode>cc (dst, cmp, res, const0_rtx));
10327         }
10328     }
10329   else
10330     {
10331       rtx msk = gen_reg_rtx (<MODE>mode);
10333       emit_insn (gen_x86_mov<mode>cc_0_m1_neg (msk));
10334       msk = expand_simple_unop (<MODE>mode, NOT, msk, NULL, 1);
10335       dst = expand_simple_binop (<MODE>mode, AND, res, msk,
10336                                  operands[0], 1, OPTAB_WIDEN);
10337     }
10339   if (!rtx_equal_p (dst, operands[0]))
10340     emit_move_insn (operands[0], dst);
10341   DONE;
10344 (define_expand "ustruncdi<mode>2"
10345   [(set (match_operand:SWI124 0 "register_operand")
10346         (us_truncate:DI (match_operand:DI 1 "nonimmediate_operand")))]
10347   "TARGET_64BIT"
10349   rtx op1 = force_reg (DImode, operands[1]);
10350   rtx sat = force_reg (DImode, GEN_INT (GET_MODE_MASK (<MODE>mode)));
10351   rtx dst;
10353   emit_insn (gen_cmpdi_1 (sat, op1));
10355   if (TARGET_CMOVE)
10356     {
10357       rtx cmp = gen_rtx_GEU (VOIDmode, gen_rtx_REG (CCCmode, FLAGS_REG),
10358                              const0_rtx);
10360       dst = force_reg (<MODE>mode, operands[0]);
10361       emit_insn (gen_movsicc (gen_lowpart (SImode, dst), cmp,
10362                               gen_lowpart (SImode, op1),
10363                               gen_lowpart (SImode, sat)));
10364     }
10365   else
10366     {
10367       rtx msk = gen_reg_rtx (<MODE>mode);
10369       emit_insn (gen_x86_mov<mode>cc_0_m1_neg (msk));
10370       dst = expand_simple_binop (<MODE>mode, IOR,
10371                                  gen_lowpart (<MODE>mode, op1), msk,
10372                                  operands[0], 1, OPTAB_WIDEN);
10373     }
10375   if (!rtx_equal_p (dst, operands[0]))
10376     emit_move_insn (operands[0], dst);
10377   DONE;
10380 (define_expand "ustruncsi<mode>2"
10381   [(set (match_operand:SWI12 0 "register_operand")
10382         (us_truncate:SI (match_operand:SI 1 "nonimmediate_operand")))]
10383   ""
10385   rtx op1 = force_reg (SImode, operands[1]);
10386   rtx sat = force_reg (SImode, GEN_INT (GET_MODE_MASK (<MODE>mode)));
10387   rtx dst;
10389   emit_insn (gen_cmpsi_1 (sat, op1));
10391   if (TARGET_CMOVE)
10392     {
10393       rtx cmp = gen_rtx_GEU (VOIDmode, gen_rtx_REG (CCCmode, FLAGS_REG),
10394                              const0_rtx);
10396       dst = force_reg (<MODE>mode, operands[0]);
10397       emit_insn (gen_movsicc (gen_lowpart (SImode, dst), cmp,
10398                               gen_lowpart (SImode, op1),
10399                               gen_lowpart (SImode, sat)));
10400     }
10401   else
10402     {
10403       rtx msk = gen_reg_rtx (<MODE>mode);
10405       emit_insn (gen_x86_mov<mode>cc_0_m1_neg (msk));
10406       dst = expand_simple_binop (<MODE>mode, IOR,
10407                                  gen_lowpart (<MODE>mode, op1), msk,
10408                                  operands[0], 1, OPTAB_WIDEN);
10409     }
10411   if (!rtx_equal_p (dst, operands[0]))
10412     emit_move_insn (operands[0], dst);
10413   DONE;
10416 (define_expand "ustrunchiqi2"
10417   [(set (match_operand:QI 0 "register_operand")
10418         (us_truncate:HI (match_operand:HI 1 "nonimmediate_operand")))]
10419   ""
10421   rtx op1 = force_reg (HImode, operands[1]);
10422   rtx sat = force_reg (HImode, GEN_INT (GET_MODE_MASK (QImode)));
10423   rtx dst;
10425   emit_insn (gen_cmphi_1 (sat, op1));
10427   if (TARGET_CMOVE)
10428     {
10429       rtx cmp = gen_rtx_GEU (VOIDmode, gen_rtx_REG (CCCmode, FLAGS_REG),
10430                              const0_rtx);
10432       dst = force_reg (QImode, operands[0]);
10433       emit_insn (gen_movsicc (gen_lowpart (SImode, dst), cmp,
10434                               gen_lowpart (SImode, op1),
10435                               gen_lowpart (SImode, sat)));
10436     }
10437   else
10438     {
10439       rtx msk = gen_reg_rtx (QImode);
10441       emit_insn (gen_x86_movqicc_0_m1_neg (msk));
10442       dst = expand_simple_binop (QImode, IOR,
10443                                  gen_lowpart (QImode, op1), msk,
10444                                  operands[0], 1, OPTAB_WIDEN);
10445     }
10447   if (!rtx_equal_p (dst, operands[0]))
10448     emit_move_insn (operands[0], dst);
10449   DONE;
10452 ;; The patterns that match these are at the end of this file.
10454 (define_expand "<insn>xf3"
10455   [(set (match_operand:XF 0 "register_operand")
10456         (plusminus:XF
10457           (match_operand:XF 1 "register_operand")
10458           (match_operand:XF 2 "register_operand")))]
10459   "TARGET_80387")
10461 (define_expand "<insn>hf3"
10462   [(set (match_operand:HF 0 "register_operand")
10463         (plusminus:HF
10464           (match_operand:HF 1 "register_operand")
10465           (match_operand:HF 2 "nonimmediate_operand")))]
10466   "TARGET_AVX512FP16")
10468 (define_expand "<insn><mode>3"
10469   [(set (match_operand:MODEF 0 "register_operand")
10470         (plusminus:MODEF
10471           (match_operand:MODEF 1 "register_operand")
10472           (match_operand:MODEF 2 "nonimmediate_operand")))]
10473   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
10474     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
10476 ;; Multiply instructions
10478 (define_expand "mul<mode>3"
10479   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
10480                    (mult:SWIM248
10481                      (match_operand:SWIM248 1 "register_operand")
10482                      (match_operand:SWIM248 2 "<general_operand>")))
10483               (clobber (reg:CC FLAGS_REG))])])
10485 (define_expand "mulqi3"
10486   [(parallel [(set (match_operand:QI 0 "register_operand")
10487                    (mult:QI
10488                      (match_operand:QI 1 "register_operand")
10489                      (match_operand:QI 2 "nonimmediate_operand")))
10490               (clobber (reg:CC FLAGS_REG))])]
10491   "TARGET_QIMODE_MATH")
10493 ;; On AMDFAM10
10494 ;; IMUL reg32/64, reg32/64, imm8        Direct
10495 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
10496 ;; IMUL reg32/64, reg32/64, imm32       Direct
10497 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
10498 ;; IMUL reg32/64, reg32/64              Direct
10499 ;; IMUL reg32/64, mem32/64              Direct
10501 ;; On BDVER1, all above IMULs use DirectPath
10503 ;; On AMDFAM10
10504 ;; IMUL reg16, reg16, imm8      VectorPath
10505 ;; IMUL reg16, mem16, imm8      VectorPath
10506 ;; IMUL reg16, reg16, imm16     VectorPath
10507 ;; IMUL reg16, mem16, imm16     VectorPath
10508 ;; IMUL reg16, reg16            Direct
10509 ;; IMUL reg16, mem16            Direct
10511 ;; On BDVER1, all HI MULs use DoublePath
10513 (define_insn "*mul<mode>3_1<nf_name>"
10514   [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r,r")
10515         (mult:SWIM248
10516           (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0,r")
10517           (match_operand:SWIM248 2 "<general_operand>" "K,<i>,<m>r,<m>r")))]
10518   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
10519    && <nf_condition>"
10520   "@
10521    <nf_prefix>imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
10522    <nf_prefix>imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
10523    <nf_prefix>imul{<imodesuffix>}\t{%2, %0|%0, %2}
10524    <nf_prefix>imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
10525   [(set_attr "type" "imul")
10526    (set_attr "prefix_0f" "0,0,1,1")
10527    (set_attr "isa" "*,*,*,apx_ndd")
10528    (set (attr "athlon_decode")
10529         (cond [(eq_attr "cpu" "athlon")
10530                   (const_string "vector")
10531                (eq_attr "alternative" "1")
10532                   (const_string "vector")
10533                (and (eq_attr "alternative" "2,3")
10534                     (ior (match_test "<MODE>mode == HImode")
10535                          (match_operand 1 "memory_operand")))
10536                   (const_string "vector")]
10537               (const_string "direct")))
10538    (set (attr "amdfam10_decode")
10539         (cond [(and (eq_attr "alternative" "0,1")
10540                     (ior (match_test "<MODE>mode == HImode")
10541                          (match_operand 1 "memory_operand")))
10542                   (const_string "vector")]
10543               (const_string "direct")))
10544    (set (attr "bdver1_decode")
10545         (if_then_else
10546           (match_test "<MODE>mode == HImode")
10547             (const_string "double")
10548             (const_string "direct")))
10549    (set_attr "has_nf" "1")
10550    (set_attr "mode" "<MODE>")])
10552 (define_insn "*imulhi<mode>zu<nf_name>"
10553   [(set (match_operand:SWI48x 0 "register_operand" "=r,r")
10554         (zero_extend:SWI48x
10555           (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm")
10556                    (match_operand:HI 2 "immediate_operand" "K,n"))))]
10557   "TARGET_APX_ZU && <nf_condition>"
10558   "@
10559    <nf_prefix>imulzu{w}\t{%2, %1, %w0|%w0, %1, %2}
10560    <nf_prefix>imulzu{w}\t{%2, %1, %w0|%w0, %1, %2}"
10561   [(set_attr "type" "imul")
10562    (set_attr "mode" "HI")])
10564 (define_insn "*mulsi3_1_zext<nf_name>"
10565   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
10566         (zero_extend:DI
10567           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0,r")
10568                    (match_operand:SI 2 "x86_64_general_operand" "K,e,BMr,BMr"))))]
10569   "TARGET_64BIT
10570    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
10571    && <nf_condition>"
10572   "@
10573    <nf_prefix>imul{l}\t{%2, %1, %k0|%k0, %1, %2}
10574    <nf_prefix>imul{l}\t{%2, %1, %k0|%k0, %1, %2}
10575    <nf_prefix>imul{l}\t{%2, %k0|%k0, %2}
10576    <nf_prefix>imul{l}\t{%2, %1, %k0|%k0, %1, %2}"
10577   [(set_attr "type" "imul")
10578    (set_attr "prefix_0f" "0,0,1,1")
10579    (set_attr "isa" "*,*,*,apx_ndd")
10580    (set (attr "athlon_decode")
10581         (cond [(eq_attr "cpu" "athlon")
10582                   (const_string "vector")
10583                (eq_attr "alternative" "1")
10584                   (const_string "vector")
10585                (and (eq_attr "alternative" "2")
10586                     (match_operand 1 "memory_operand"))
10587                   (const_string "vector")]
10588               (const_string "direct")))
10589    (set (attr "amdfam10_decode")
10590         (cond [(and (eq_attr "alternative" "0,1")
10591                     (match_operand 1 "memory_operand"))
10592                   (const_string "vector")]
10593               (const_string "direct")))
10594    (set_attr "bdver1_decode" "direct")
10595    (set_attr "mode" "SI")])
10597 ;;On AMDFAM10 and BDVER1
10598 ;; MUL reg8     Direct
10599 ;; MUL mem8     Direct
10601 (define_insn "*mulqi3_1<nf_name>"
10602   [(set (match_operand:QI 0 "register_operand" "=a")
10603         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10604                  (match_operand:QI 2 "nonimmediate_operand" "qm")))]
10605   "TARGET_QIMODE_MATH
10606    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
10607    && <nf_condition>"
10608   "<nf_prefix>mul{b}\t%2"
10609   [(set_attr "type" "imul")
10610    (set_attr "length_immediate" "0")
10611    (set (attr "athlon_decode")
10612      (if_then_else (eq_attr "cpu" "athlon")
10613         (const_string "vector")
10614         (const_string "direct")))
10615    (set_attr "amdfam10_decode" "direct")
10616    (set_attr "bdver1_decode" "direct")
10617    (set_attr "has_nf" "1")
10618    (set_attr "mode" "QI")])
10620 ;; Multiply with jump on overflow.
10621 (define_expand "mulv<mode>4"
10622   [(parallel [(set (reg:CCO FLAGS_REG)
10623                    (eq:CCO (mult:<DWI>
10624                               (sign_extend:<DWI>
10625                                  (match_operand:SWI248 1 "register_operand"))
10626                               (match_dup 4))
10627                            (sign_extend:<DWI>
10628                               (mult:SWI248 (match_dup 1)
10629                                            (match_operand:SWI248 2
10630                                               "<general_operand>")))))
10631               (set (match_operand:SWI248 0 "register_operand")
10632                    (mult:SWI248 (match_dup 1) (match_dup 2)))])
10633    (set (pc) (if_then_else
10634                (eq (reg:CCO FLAGS_REG) (const_int 0))
10635                (label_ref (match_operand 3))
10636                (pc)))]
10637   ""
10639   if (CONST_INT_P (operands[2]))
10640     operands[4] = operands[2];
10641   else
10642     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
10645 (define_insn "*mulv<mode>4"
10646   [(set (reg:CCO FLAGS_REG)
10647         (eq:CCO (mult:<DWI>
10648                    (sign_extend:<DWI>
10649                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0,r"))
10650                    (sign_extend:<DWI>
10651                       (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr,mr")))
10652                 (sign_extend:<DWI>
10653                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
10654    (set (match_operand:SWI48 0 "register_operand" "=r,r,r")
10655         (mult:SWI48 (match_dup 1) (match_dup 2)))]
10656   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
10657   "@
10658    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
10659    imul{<imodesuffix>}\t{%2, %0|%0, %2}
10660    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
10661   [(set_attr "type" "imul")
10662    (set_attr "prefix_0f" "0,1,1")
10663    (set_attr "isa" "*,*,apx_ndd")
10664    (set (attr "athlon_decode")
10665         (cond [(eq_attr "cpu" "athlon")
10666                   (const_string "vector")
10667                (eq_attr "alternative" "0")
10668                   (const_string "vector")
10669                (and (eq_attr "alternative" "1,2")
10670                     (match_operand 1 "memory_operand"))
10671                   (const_string "vector")]
10672               (const_string "direct")))
10673    (set (attr "amdfam10_decode")
10674         (cond [(and (eq_attr "alternative" "1,2")
10675                     (match_operand 1 "memory_operand"))
10676                   (const_string "vector")]
10677               (const_string "direct")))
10678    (set_attr "bdver1_decode" "direct")
10679    (set_attr "mode" "<MODE>")])
10681 (define_insn "*mulvhi4"
10682   [(set (reg:CCO FLAGS_REG)
10683         (eq:CCO (mult:SI
10684                    (sign_extend:SI
10685                       (match_operand:HI 1 "nonimmediate_operand" "%0,r"))
10686                    (sign_extend:SI
10687                       (match_operand:HI 2 "nonimmediate_operand" "mr,mr")))
10688                 (sign_extend:SI
10689                    (mult:HI (match_dup 1) (match_dup 2)))))
10690    (set (match_operand:HI 0 "register_operand" "=r,r")
10691         (mult:HI (match_dup 1) (match_dup 2)))]
10692   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
10693   "@
10694    imul{w}\t{%2, %0|%0, %2}
10695    imul{w}\t{%2, %1, %0|%0, %1, %2}"
10696   [(set_attr "type" "imul")
10697    (set_attr "prefix_0f" "1")
10698    (set_attr "isa" "*,apx_ndd")
10699    (set_attr "athlon_decode" "vector")
10700    (set_attr "amdfam10_decode" "direct")
10701    (set_attr "bdver1_decode" "double")
10702    (set_attr "mode" "HI")])
10704 (define_insn "*mulv<mode>4_1"
10705   [(set (reg:CCO FLAGS_REG)
10706         (eq:CCO (mult:<DWI>
10707                    (sign_extend:<DWI>
10708                       (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
10709                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
10710                 (sign_extend:<DWI>
10711                    (mult:SWI248 (match_dup 1)
10712                                 (match_operand:SWI248 2
10713                                    "<immediate_operand>" "K,<i>")))))
10714    (set (match_operand:SWI248 0 "register_operand" "=r,r")
10715         (mult:SWI248 (match_dup 1) (match_dup 2)))]
10716   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
10717    && CONST_INT_P (operands[2])
10718    && INTVAL (operands[2]) == INTVAL (operands[3])"
10719   "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
10720   [(set_attr "type" "imul")
10721    (set (attr "prefix_0f")
10722         (if_then_else
10723           (match_test "<MODE>mode == HImode")
10724             (const_string "0")
10725             (const_string "*")))
10726    (set (attr "athlon_decode")
10727         (cond [(eq_attr "cpu" "athlon")
10728                   (const_string "vector")
10729                (eq_attr "alternative" "1")
10730                   (const_string "vector")]
10731               (const_string "direct")))
10732    (set (attr "amdfam10_decode")
10733         (cond [(ior (match_test "<MODE>mode == HImode")
10734                     (match_operand 1 "memory_operand"))
10735                   (const_string "vector")]
10736               (const_string "direct")))
10737    (set (attr "bdver1_decode")
10738         (if_then_else
10739           (match_test "<MODE>mode == HImode")
10740             (const_string "double")
10741             (const_string "direct")))
10742    (set_attr "mode" "<MODE>")
10743    (set (attr "length_immediate")
10744         (cond [(eq_attr "alternative" "0")
10745                   (const_string "1")
10746                (match_test "<MODE_SIZE> == 8")
10747                   (const_string "4")]
10748               (const_string "<MODE_SIZE>")))])
10750 (define_expand "umulv<mode>4"
10751   [(parallel [(set (reg:CCO FLAGS_REG)
10752                    (eq:CCO (mult:<DWI>
10753                               (zero_extend:<DWI>
10754                                  (match_operand:SWI248 1
10755                                                       "nonimmediate_operand"))
10756                               (zero_extend:<DWI>
10757                                  (match_operand:SWI248 2
10758                                                       "nonimmediate_operand")))
10759                            (zero_extend:<DWI>
10760                               (mult:SWI248 (match_dup 1) (match_dup 2)))))
10761               (set (match_operand:SWI248 0 "register_operand")
10762                    (mult:SWI248 (match_dup 1) (match_dup 2)))
10763               (clobber (scratch:SWI248))])
10764    (set (pc) (if_then_else
10765                (eq (reg:CCO FLAGS_REG) (const_int 0))
10766                (label_ref (match_operand 3))
10767                (pc)))]
10768   ""
10770   if (MEM_P (operands[1]) && MEM_P (operands[2]))
10771     operands[1] = force_reg (<MODE>mode, operands[1]);
10774 (define_insn "*umulv<mode>4"
10775   [(set (reg:CCO FLAGS_REG)
10776         (eq:CCO (mult:<DWI>
10777                    (zero_extend:<DWI>
10778                       (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
10779                    (zero_extend:<DWI>
10780                       (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
10781                 (zero_extend:<DWI>
10782                    (mult:SWI248 (match_dup 1) (match_dup 2)))))
10783    (set (match_operand:SWI248 0 "register_operand" "=a")
10784         (mult:SWI248 (match_dup 1) (match_dup 2)))
10785    (clobber (match_scratch:SWI248 3 "=d"))]
10786   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
10787   "mul{<imodesuffix>}\t%2"
10788   [(set_attr "type" "imul")
10789    (set_attr "length_immediate" "0")
10790    (set (attr "athlon_decode")
10791      (if_then_else (eq_attr "cpu" "athlon")
10792        (const_string "vector")
10793        (const_string "double")))
10794    (set_attr "amdfam10_decode" "double")
10795    (set_attr "bdver1_decode" "direct")
10796    (set_attr "mode" "<MODE>")])
10798 (define_expand "<u>mulvqi4"
10799   [(parallel [(set (reg:CCO FLAGS_REG)
10800                    (eq:CCO (mult:HI
10801                               (any_extend:HI
10802                                  (match_operand:QI 1 "nonimmediate_operand"))
10803                               (any_extend:HI
10804                                  (match_operand:QI 2 "nonimmediate_operand")))
10805                            (any_extend:HI
10806                               (mult:QI (match_dup 1) (match_dup 2)))))
10807               (set (match_operand:QI 0 "register_operand")
10808                    (mult:QI (match_dup 1) (match_dup 2)))])
10809    (set (pc) (if_then_else
10810                (eq (reg:CCO FLAGS_REG) (const_int 0))
10811                (label_ref (match_operand 3))
10812                (pc)))]
10813   "TARGET_QIMODE_MATH"
10815   if (MEM_P (operands[1]) && MEM_P (operands[2]))
10816     operands[1] = force_reg (QImode, operands[1]);
10819 (define_insn "*<u>mulvqi4"
10820   [(set (reg:CCO FLAGS_REG)
10821         (eq:CCO (mult:HI
10822                    (any_extend:HI
10823                       (match_operand:QI 1 "nonimmediate_operand" "%0"))
10824                    (any_extend:HI
10825                       (match_operand:QI 2 "nonimmediate_operand" "qm")))
10826                 (any_extend:HI
10827                    (mult:QI (match_dup 1) (match_dup 2)))))
10828    (set (match_operand:QI 0 "register_operand" "=a")
10829         (mult:QI (match_dup 1) (match_dup 2)))]
10830   "TARGET_QIMODE_MATH
10831    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10832   "<sgnprefix>mul{b}\t%2"
10833   [(set_attr "type" "imul")
10834    (set_attr "length_immediate" "0")
10835    (set (attr "athlon_decode")
10836      (if_then_else (eq_attr "cpu" "athlon")
10837         (const_string "vector")
10838         (const_string "direct")))
10839    (set_attr "amdfam10_decode" "direct")
10840    (set_attr "bdver1_decode" "direct")
10841    (set_attr "mode" "QI")])
10843 (define_expand "<u>mul<mode><dwi>3"
10844   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
10845                    (mult:<DWI>
10846                      (any_extend:<DWI>
10847                        (match_operand:DWIH 1 "register_operand"))
10848                      (any_extend:<DWI>
10849                        (match_operand:DWIH 2 "nonimmediate_operand"))))
10850               (clobber (reg:CC FLAGS_REG))])])
10852 (define_expand "<u>mulqihi3"
10853   [(parallel [(set (match_operand:HI 0 "register_operand")
10854                    (mult:HI
10855                      (any_extend:HI
10856                        (match_operand:QI 1 "register_operand"))
10857                      (any_extend:HI
10858                        (match_operand:QI 2 "nonimmediate_operand"))))
10859               (clobber (reg:CC FLAGS_REG))])]
10860   "TARGET_QIMODE_MATH")
10862 (define_insn "*bmi2_umul<mode><dwi>3_1"
10863   [(set (match_operand:DWIH 0 "register_operand" "=r")
10864         (mult:DWIH
10865           (match_operand:DWIH 2 "register_operand" "%d")
10866           (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
10867    (set (match_operand:DWIH 1 "register_operand" "=r")
10868         (umul_highpart:DWIH (match_dup 2) (match_dup 3)))]
10869   "TARGET_BMI2"
10870   "mulx\t{%3, %0, %1|%1, %0, %3}"
10871   [(set_attr "type" "imulx")
10872    (set_attr "prefix" "vex")
10873    (set_attr "mode" "<MODE>")])
10875 ;; Tweak *bmi2_umul<mode><dwi>3_1 to eliminate following mov.
10876 (define_peephole2
10877   [(parallel [(set (match_operand:DWIH 0 "general_reg_operand")
10878                    (mult:DWIH (match_operand:DWIH 2 "register_operand")
10879                               (match_operand:DWIH 3 "nonimmediate_operand")))
10880               (set (match_operand:DWIH 1 "general_reg_operand")
10881                    (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])
10882    (set (match_operand:DWIH 4 "general_reg_operand")
10883         (match_operand:DWIH 5 "general_reg_operand"))]
10884   "TARGET_BMI2
10885    && ((REGNO (operands[5]) == REGNO (operands[0])
10886         && REGNO (operands[1]) != REGNO (operands[4]))
10887        || (REGNO (operands[5]) == REGNO (operands[1])
10888            && REGNO (operands[0]) != REGNO (operands[4])))
10889    && peep2_reg_dead_p (2, operands[5])"
10890   [(parallel [(set (match_dup 0) (mult:DWIH (match_dup 2) (match_dup 3)))
10891               (set (match_dup 1)
10892                    (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])]
10894   if (REGNO (operands[5]) == REGNO (operands[0]))
10895     operands[0] = operands[4];
10896   else
10897     operands[1] = operands[4];
10900 (define_insn "*umul<mode><dwi>3_1"
10901   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
10902         (mult:<DWI>
10903           (zero_extend:<DWI>
10904             (match_operand:DWIH 1 "register_operand" "%d,a"))
10905           (zero_extend:<DWI>
10906             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
10907    (clobber (reg:CC FLAGS_REG))]
10908   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
10909   "@
10910    #
10911    mul{<imodesuffix>}\t%2"
10912   [(set_attr "isa" "bmi2,*")
10913    (set_attr "type" "imulx,imul")
10914    (set_attr "length_immediate" "*,0")
10915    (set (attr "athlon_decode")
10916         (cond [(eq_attr "alternative" "1")
10917                  (if_then_else (eq_attr "cpu" "athlon")
10918                    (const_string "vector")
10919                    (const_string "double"))]
10920               (const_string "*")))
10921    (set_attr "amdfam10_decode" "*,double")
10922    (set_attr "bdver1_decode" "*,direct")
10923    (set_attr "prefix" "vex,orig")
10924    (set_attr "mode" "<MODE>")])
10926 ;; Convert mul to the mulx pattern to avoid flags dependency.
10927 (define_split
10928  [(set (match_operand:<DWI> 0 "register_operand")
10929        (mult:<DWI>
10930          (zero_extend:<DWI>
10931            (match_operand:DWIH 1 "register_operand"))
10932          (zero_extend:<DWI>
10933            (match_operand:DWIH 2 "nonimmediate_operand"))))
10934   (clobber (reg:CC FLAGS_REG))]
10935  "TARGET_BMI2 && reload_completed
10936   && REGNO (operands[1]) == DX_REG"
10937   [(parallel [(set (match_dup 3)
10938                    (mult:DWIH (match_dup 1) (match_dup 2)))
10939               (set (match_dup 4)
10940                    (umul_highpart:DWIH (match_dup 1) (match_dup 2)))])]
10942   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
10944   operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10947 (define_insn "*mul<mode><dwi>3_1<nf_name>"
10948   [(set (match_operand:<DWI> 0 "register_operand" "=A")
10949         (mult:<DWI>
10950           (sign_extend:<DWI>
10951             (match_operand:DWIH 1 "register_operand" "%a"))
10952           (sign_extend:<DWI>
10953             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))]
10954   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
10955    && <nf_condition>"
10956   "<nf_prefix>imul{<imodesuffix>}\t%2"
10957   [(set_attr "type" "imul")
10958    (set_attr "length_immediate" "0")
10959    (set (attr "athlon_decode")
10960      (if_then_else (eq_attr "cpu" "athlon")
10961         (const_string "vector")
10962         (const_string "double")))
10963    (set_attr "amdfam10_decode" "double")
10964    (set_attr "bdver1_decode" "direct")
10965    (set_attr "mode" "<MODE>")])
10967 (define_insn "*<u>mulqihi3_1<nf_name>"
10968   [(set (match_operand:HI 0 "register_operand" "=a")
10969         (mult:HI
10970           (any_extend:HI
10971             (match_operand:QI 1 "register_operand" "%0"))
10972           (any_extend:HI
10973             (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
10974   "TARGET_QIMODE_MATH
10975    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
10976    && <nf_condition>"
10977   "<nf_prefix><sgnprefix>mul{b}\t%2"
10978   [(set_attr "type" "imul")
10979    (set_attr "length_immediate" "0")
10980    (set (attr "athlon_decode")
10981      (if_then_else (eq_attr "cpu" "athlon")
10982         (const_string "vector")
10983         (const_string "direct")))
10984    (set_attr "amdfam10_decode" "direct")
10985    (set_attr "bdver1_decode" "direct")
10986    (set_attr "mode" "QI")])
10988 ;; Widening multiplication peephole2s to tweak register allocation.
10989 ;; mov imm,%rdx; mov %rdi,%rax; mulq %rdx  ->  mov imm,%rax; mulq %rdi
10990 (define_peephole2
10991   [(set (match_operand:DWIH 0 "general_reg_operand")
10992         (match_operand:DWIH 1 "immediate_operand"))
10993    (set (match_operand:DWIH 2 "general_reg_operand")
10994         (match_operand:DWIH 3 "general_reg_operand"))
10995    (parallel [(set (match_operand:<DWI> 4 "general_reg_operand")
10996                    (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
10997                                (zero_extend:<DWI> (match_dup 0))))
10998               (clobber (reg:CC FLAGS_REG))])]
10999   "REGNO (operands[3]) != AX_REG
11000    && REGNO (operands[0]) != REGNO (operands[2])
11001    && REGNO (operands[0]) != REGNO (operands[3])
11002    && (REGNO (operands[0]) == REGNO (operands[4])
11003        || REGNO (operands[0]) == DX_REG
11004        || peep2_reg_dead_p (3, operands[0]))"
11005   [(set (match_dup 2) (match_dup 1))
11006    (parallel [(set (match_dup 4)
11007                    (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
11008                                (zero_extend:<DWI> (match_dup 3))))
11009               (clobber (reg:CC FLAGS_REG))])])
11011 ;; mov imm,%rax; mov %rdi,%rdx; mulx %rax  ->  mov imm,%rdx; mulx %rdi
11012 (define_peephole2
11013   [(set (match_operand:DWIH 0 "general_reg_operand")
11014         (match_operand:DWIH 1 "immediate_operand"))
11015    (set (match_operand:DWIH 2 "general_reg_operand")
11016         (match_operand:DWIH 3 "general_reg_operand"))
11017    (parallel [(set (match_operand:DWIH 4 "general_reg_operand")
11018                    (mult:DWIH (match_dup 2) (match_dup 0)))
11019               (set (match_operand:DWIH 5 "general_reg_operand")
11020                    (umul_highpart:DWIH (match_dup 2) (match_dup 0)))])]
11021   "REGNO (operands[3]) != DX_REG
11022    && REGNO (operands[0]) != REGNO (operands[2])
11023    && REGNO (operands[0]) != REGNO (operands[3])
11024    && (REGNO (operands[0]) == REGNO (operands[4])
11025        || REGNO (operands[0]) == REGNO (operands[5])
11026        || peep2_reg_dead_p (3, operands[0]))
11027    && (REGNO (operands[2]) == REGNO (operands[4])
11028        || REGNO (operands[2]) == REGNO (operands[5])
11029        || peep2_reg_dead_p (3, operands[2]))"
11030   [(set (match_dup 2) (match_dup 1))
11031    (parallel [(set (match_dup 4)
11032                    (mult:DWIH (match_dup 2) (match_dup 3)))
11033               (set (match_dup 5)
11034                    (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])])
11036 ;; Highpart multiplication patterns
11037 (define_insn "<s>mul<mode>3_highpart"
11038   [(set (match_operand:DWIH 0 "register_operand" "=d")
11039         (any_mul_highpart:DWIH
11040           (match_operand:DWIH 1 "register_operand" "%a")
11041           (match_operand:DWIH 2 "nonimmediate_operand" "rm")))
11042    (clobber (match_scratch:DWIH 3 "=1"))
11043    (clobber (reg:CC FLAGS_REG))]
11044   ""
11045   "<sgnprefix>mul{<imodesuffix>}\t%2"
11046   [(set_attr "type" "imul")
11047    (set_attr "length_immediate" "0")
11048    (set (attr "athlon_decode")
11049      (if_then_else (eq_attr "cpu" "athlon")
11050         (const_string "vector")
11051         (const_string "double")))
11052    (set_attr "amdfam10_decode" "double")
11053    (set_attr "bdver1_decode" "direct")
11054    (set_attr "mode" "<MODE>")])
11056 (define_insn "*<s>mulsi3_highpart_zext"
11057   [(set (match_operand:DI 0 "register_operand" "=d")
11058         (zero_extend:DI 
11059           (any_mul_highpart:SI
11060             (match_operand:SI 1 "register_operand" "%a")
11061             (match_operand:SI 2 "nonimmediate_operand" "rm"))))
11062    (clobber (match_scratch:SI 3 "=1"))
11063    (clobber (reg:CC FLAGS_REG))]
11064   "TARGET_64BIT"
11065   "<sgnprefix>mul{l}\t%2"
11066   [(set_attr "type" "imul")
11067    (set_attr "length_immediate" "0")
11068    (set (attr "athlon_decode")
11069      (if_then_else (eq_attr "cpu" "athlon")
11070         (const_string "vector")
11071         (const_string "double")))
11072    (set_attr "amdfam10_decode" "double")
11073    (set_attr "bdver1_decode" "direct")
11074    (set_attr "mode" "SI")])
11076 (define_insn "*<s>muldi3_highpart_1"
11077   [(set (match_operand:DI 0 "register_operand" "=d")
11078         (truncate:DI
11079           (lshiftrt:TI
11080             (mult:TI
11081               (any_extend:TI
11082                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
11083               (any_extend:TI
11084                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
11085             (const_int 64))))
11086    (clobber (match_scratch:DI 3 "=1"))
11087    (clobber (reg:CC FLAGS_REG))]
11088   "TARGET_64BIT
11089    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
11090   "<sgnprefix>mul{q}\t%2"
11091   [(set_attr "type" "imul")
11092    (set_attr "length_immediate" "0")
11093    (set (attr "athlon_decode")
11094      (if_then_else (eq_attr "cpu" "athlon")
11095         (const_string "vector")
11096         (const_string "double")))
11097    (set_attr "amdfam10_decode" "double")
11098    (set_attr "bdver1_decode" "direct")
11099    (set_attr "mode" "DI")])
11101 (define_insn "*<s>mulsi3_highpart_zext"
11102   [(set (match_operand:DI 0 "register_operand" "=d")
11103         (zero_extend:DI (truncate:SI
11104           (lshiftrt:DI
11105             (mult:DI (any_extend:DI
11106                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
11107                      (any_extend:DI
11108                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
11109             (const_int 32)))))
11110    (clobber (match_scratch:SI 3 "=1"))
11111    (clobber (reg:CC FLAGS_REG))]
11112   "TARGET_64BIT
11113    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
11114   "<sgnprefix>mul{l}\t%2"
11115   [(set_attr "type" "imul")
11116    (set_attr "length_immediate" "0")
11117    (set (attr "athlon_decode")
11118      (if_then_else (eq_attr "cpu" "athlon")
11119         (const_string "vector")
11120         (const_string "double")))
11121    (set_attr "amdfam10_decode" "double")
11122    (set_attr "bdver1_decode" "direct")
11123    (set_attr "mode" "SI")])
11125 (define_insn "*<s>mulsi3_highpart_1"
11126   [(set (match_operand:SI 0 "register_operand" "=d")
11127         (truncate:SI
11128           (lshiftrt:DI
11129             (mult:DI
11130               (any_extend:DI
11131                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
11132               (any_extend:DI
11133                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
11134             (const_int 32))))
11135    (clobber (match_scratch:SI 3 "=1"))
11136    (clobber (reg:CC FLAGS_REG))]
11137   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
11138   "<sgnprefix>mul{l}\t%2"
11139   [(set_attr "type" "imul")
11140    (set_attr "length_immediate" "0")
11141    (set (attr "athlon_decode")
11142      (if_then_else (eq_attr "cpu" "athlon")
11143         (const_string "vector")
11144         (const_string "double")))
11145    (set_attr "amdfam10_decode" "double")
11146    (set_attr "bdver1_decode" "direct")
11147    (set_attr "mode" "SI")])
11149 ;; Highpart multiplication peephole2s to tweak register allocation.
11150 ;; mov imm,%rdx; mov %rdi,%rax; imulq %rdx  ->  mov imm,%rax; imulq %rdi
11151 (define_peephole2
11152   [(set (match_operand:SWI48 0 "general_reg_operand")
11153         (match_operand:SWI48 1 "immediate_operand"))
11154    (set (match_operand:SWI48 2 "general_reg_operand")
11155         (match_operand:SWI48 3 "general_reg_operand"))
11156    (parallel [(set (match_operand:SWI48 4 "general_reg_operand")
11157                    (any_mul_highpart:SWI48 (match_dup 2) (match_dup 0)))
11158               (clobber (match_dup 2))
11159               (clobber (reg:CC FLAGS_REG))])]
11160   "REGNO (operands[3]) != AX_REG
11161    && REGNO (operands[0]) != REGNO (operands[2])
11162    && REGNO (operands[0]) != REGNO (operands[3])
11163    && (REGNO (operands[0]) == REGNO (operands[4])
11164        || peep2_reg_dead_p (3, operands[0]))"
11165   [(set (match_dup 2) (match_dup 1))
11166    (parallel [(set (match_dup 4)
11167                    (any_mul_highpart:SWI48 (match_dup 2) (match_dup 3)))
11168               (clobber (match_dup 2))
11169               (clobber (reg:CC FLAGS_REG))])])
11171 (define_peephole2
11172   [(set (match_operand:SI 0 "general_reg_operand")
11173         (match_operand:SI 1 "immediate_operand"))
11174    (set (match_operand:SI 2 "general_reg_operand")
11175         (match_operand:SI 3 "general_reg_operand"))
11176    (parallel [(set (match_operand:DI 4 "general_reg_operand")
11177                    (zero_extend:DI
11178                      (any_mul_highpart:SI (match_dup 2) (match_dup 0))))
11179               (clobber (match_dup 2))
11180               (clobber (reg:CC FLAGS_REG))])]
11181   "TARGET_64BIT
11182    && REGNO (operands[3]) != AX_REG
11183    && REGNO (operands[0]) != REGNO (operands[2])
11184    && REGNO (operands[2]) != REGNO (operands[3])
11185    && REGNO (operands[0]) != REGNO (operands[3])
11186    && (REGNO (operands[0]) == REGNO (operands[4])
11187        || peep2_reg_dead_p (3, operands[0]))"
11188   [(set (match_dup 2) (match_dup 1))
11189    (parallel [(set (match_dup 4)
11190                    (zero_extend:DI
11191                      (any_mul_highpart:SI (match_dup 2) (match_dup 3))))
11192               (clobber (match_dup 2))
11193               (clobber (reg:CC FLAGS_REG))])])
11195 ;; The patterns that match these are at the end of this file.
11197 (define_expand "mulxf3"
11198   [(set (match_operand:XF 0 "register_operand")
11199         (mult:XF (match_operand:XF 1 "register_operand")
11200                  (match_operand:XF 2 "register_operand")))]
11201   "TARGET_80387")
11203 (define_expand "mulhf3"
11204   [(set (match_operand:HF 0 "register_operand")
11205         (mult:HF (match_operand:HF 1 "register_operand")
11206                     (match_operand:HF 2 "nonimmediate_operand")))]
11207   "TARGET_AVX512FP16")
11209 (define_expand "mul<mode>3"
11210   [(set (match_operand:MODEF 0 "register_operand")
11211         (mult:MODEF (match_operand:MODEF 1 "register_operand")
11212                     (match_operand:MODEF 2 "nonimmediate_operand")))]
11213   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
11214     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
11216 ;; Divide instructions
11218 ;; The patterns that match these are at the end of this file.
11220 (define_expand "divxf3"
11221   [(set (match_operand:XF 0 "register_operand")
11222         (div:XF (match_operand:XF 1 "register_operand")
11223                 (match_operand:XF 2 "register_operand")))]
11224   "TARGET_80387")
11226 /* There is no more precision loss than Newton-Rhapson approximation
11227   when using HFmode rcp/rsqrt, so do the transformation directly under
11228   TARGET_RECIP_DIV and fast-math.  */
11229 (define_expand "divhf3"
11230   [(set (match_operand:HF 0 "register_operand")
11231         (div:HF (match_operand:HF 1 "register_operand")
11232                    (match_operand:HF 2 "nonimmediate_operand")))]
11233   "TARGET_AVX512FP16"
11235   if (TARGET_RECIP_DIV
11236       && optimize_insn_for_speed_p ()
11237       && flag_finite_math_only && !flag_trapping_math
11238       && flag_unsafe_math_optimizations)
11239     {
11240       rtx op = gen_reg_rtx (HFmode);
11241       operands[2] = force_reg (HFmode, operands[2]);
11242       emit_insn (gen_rcphf2 (op, operands[2]));
11243       emit_insn (gen_mulhf3 (operands[0], operands[1], op));
11244       DONE;
11245     }
11248 (define_expand "div<mode>3"
11249   [(set (match_operand:MODEF 0 "register_operand")
11250         (div:MODEF (match_operand:MODEF 1 "register_operand")
11251                    (match_operand:MODEF 2 "nonimmediate_operand")))]
11252   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
11253     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
11255   if (<MODE>mode == SFmode
11256       && TARGET_SSE && TARGET_SSE_MATH
11257       && TARGET_RECIP_DIV
11258       && optimize_insn_for_speed_p ()
11259       && flag_finite_math_only && !flag_trapping_math
11260       && flag_unsafe_math_optimizations)
11261     {
11262       ix86_emit_swdivsf (operands[0], operands[1],
11263                          operands[2], SFmode);
11264       DONE;
11265     }
11268 ;; Divmod instructions.
11270 (define_code_iterator any_div [div udiv])
11271 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
11273 (define_expand "<u>divmod<mode>4"
11274   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
11275                    (any_div:SWIM248
11276                      (match_operand:SWIM248 1 "register_operand")
11277                      (match_operand:SWIM248 2 "nonimmediate_operand")))
11278               (set (match_operand:SWIM248 3 "register_operand")
11279                    (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
11280               (clobber (reg:CC FLAGS_REG))])])
11282 ;; Split with 8bit unsigned divide:
11283 ;;      if (dividend an divisor are in [0-255])
11284 ;;         use 8bit unsigned integer divide
11285 ;;       else
11286 ;;         use original integer divide
11287 (define_split
11288   [(set (match_operand:SWI48 0 "register_operand")
11289         (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
11290                        (match_operand:SWI48 3 "nonimmediate_operand")))
11291    (set (match_operand:SWI48 1 "register_operand")
11292         (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
11293    (clobber (reg:CC FLAGS_REG))]
11294   "TARGET_USE_8BIT_IDIV
11295    && TARGET_QIMODE_MATH
11296    && can_create_pseudo_p ()
11297    && !optimize_insn_for_size_p ()"
11298   [(const_int 0)]
11299   "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
11301 (define_split
11302   [(set (match_operand:DI 0 "register_operand")
11303         (zero_extend:DI
11304           (any_div:SI (match_operand:SI 2 "register_operand")
11305                       (match_operand:SI 3 "nonimmediate_operand"))))
11306    (set (match_operand:SI 1 "register_operand")
11307         (<paired_mod>:SI (match_dup 2) (match_dup 3)))
11308    (clobber (reg:CC FLAGS_REG))]
11309   "TARGET_64BIT
11310    && TARGET_USE_8BIT_IDIV
11311    && TARGET_QIMODE_MATH
11312    && can_create_pseudo_p ()
11313    && !optimize_insn_for_size_p ()"
11314   [(const_int 0)]
11315   "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
11317 (define_split
11318   [(set (match_operand:DI 1 "register_operand")
11319         (zero_extend:DI
11320           (<paired_mod>:SI (match_operand:SI 2 "register_operand")
11321                            (match_operand:SI 3 "nonimmediate_operand"))))
11322    (set (match_operand:SI 0 "register_operand")
11323         (any_div:SI  (match_dup 2) (match_dup 3)))
11324    (clobber (reg:CC FLAGS_REG))]
11325   "TARGET_64BIT
11326    && TARGET_USE_8BIT_IDIV
11327    && TARGET_QIMODE_MATH
11328    && can_create_pseudo_p ()
11329    && !optimize_insn_for_size_p ()"
11330   [(const_int 0)]
11331   "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
11333 (define_insn_and_split "divmod<mode>4_1"
11334   [(set (match_operand:SWI48 0 "register_operand" "=a")
11335         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
11336                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
11337    (set (match_operand:SWI48 1 "register_operand" "=&d")
11338         (mod:SWI48 (match_dup 2) (match_dup 3)))
11339    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
11340    (clobber (reg:CC FLAGS_REG))]
11341   ""
11342   "#"
11343   "reload_completed"
11344   [(parallel [(set (match_dup 1)
11345                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
11346               (clobber (reg:CC FLAGS_REG))])
11347    (parallel [(set (match_dup 0)
11348                    (div:SWI48 (match_dup 2) (match_dup 3)))
11349               (set (match_dup 1)
11350                    (mod:SWI48 (match_dup 2) (match_dup 3)))
11351               (use (match_dup 1))
11352               (clobber (reg:CC FLAGS_REG))])]
11354   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11356   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
11357     operands[4] = operands[2];
11358   else
11359     {
11360       /* Avoid use of cltd in favor of a mov+shift.  */
11361       emit_move_insn (operands[1], operands[2]);
11362       operands[4] = operands[1];
11363     }
11365   [(set_attr "type" "multi")
11366    (set_attr "mode" "<MODE>")])
11368 (define_insn_and_split "udivmod<mode>4_1"
11369   [(set (match_operand:SWI48 0 "register_operand" "=a")
11370         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
11371                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
11372    (set (match_operand:SWI48 1 "register_operand" "=&d")
11373         (umod:SWI48 (match_dup 2) (match_dup 3)))
11374    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
11375    (clobber (reg:CC FLAGS_REG))]
11376   ""
11377   "#"
11378   "reload_completed"
11379   [(set (match_dup 1) (const_int 0))
11380    (parallel [(set (match_dup 0)
11381                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
11382               (set (match_dup 1)
11383                    (umod:SWI48 (match_dup 2) (match_dup 3)))
11384               (use (match_dup 1))
11385               (clobber (reg:CC FLAGS_REG))])]
11386   ""
11387   [(set_attr "type" "multi")
11388    (set_attr "mode" "<MODE>")])
11390 (define_insn_and_split "divmodsi4_zext_1"
11391   [(set (match_operand:DI 0 "register_operand" "=a")
11392         (zero_extend:DI
11393           (div:SI (match_operand:SI 2 "register_operand" "0")
11394                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11395    (set (match_operand:SI 1 "register_operand" "=&d")
11396         (mod:SI (match_dup 2) (match_dup 3)))
11397    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
11398    (clobber (reg:CC FLAGS_REG))]
11399   "TARGET_64BIT"
11400   "#"
11401   "&& reload_completed"
11402   [(parallel [(set (match_dup 1)
11403                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
11404               (clobber (reg:CC FLAGS_REG))])
11405    (parallel [(set (match_dup 0)
11406                    (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
11407               (set (match_dup 1)
11408                    (mod:SI (match_dup 2) (match_dup 3)))
11409               (use (match_dup 1))
11410               (clobber (reg:CC FLAGS_REG))])]
11412   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
11414   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
11415     operands[4] = operands[2];
11416   else
11417     {
11418       /* Avoid use of cltd in favor of a mov+shift.  */
11419       emit_move_insn (operands[1], operands[2]);
11420       operands[4] = operands[1];
11421     }
11423   [(set_attr "type" "multi")
11424    (set_attr "mode" "SI")])
11426 (define_insn_and_split "udivmodsi4_zext_1"
11427   [(set (match_operand:DI 0 "register_operand" "=a")
11428         (zero_extend:DI
11429           (udiv:SI (match_operand:SI 2 "register_operand" "0")
11430                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11431    (set (match_operand:SI 1 "register_operand" "=&d")
11432         (umod:SI (match_dup 2) (match_dup 3)))
11433    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
11434    (clobber (reg:CC FLAGS_REG))]
11435   "TARGET_64BIT"
11436   "#"
11437   "&& reload_completed"
11438   [(set (match_dup 1) (const_int 0))
11439    (parallel [(set (match_dup 0)
11440                    (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
11441               (set (match_dup 1)
11442                    (umod:SI (match_dup 2) (match_dup 3)))
11443               (use (match_dup 1))
11444               (clobber (reg:CC FLAGS_REG))])]
11445   ""
11446   [(set_attr "type" "multi")
11447    (set_attr "mode" "SI")])
11449 (define_insn_and_split "divmodsi4_zext_2"
11450   [(set (match_operand:DI 1 "register_operand" "=&d")
11451         (zero_extend:DI
11452           (mod:SI (match_operand:SI 2 "register_operand" "0")
11453                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11454    (set (match_operand:SI 0 "register_operand" "=a")
11455         (div:SI (match_dup 2) (match_dup 3)))
11456    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
11457    (clobber (reg:CC FLAGS_REG))]
11458   "TARGET_64BIT"
11459   "#"
11460   "&& reload_completed"
11461   [(parallel [(set (match_dup 6)
11462                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
11463               (clobber (reg:CC FLAGS_REG))])
11464    (parallel [(set (match_dup 1)
11465                    (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
11466               (set (match_dup 0)
11467                    (div:SI (match_dup 2) (match_dup 3)))
11468               (use (match_dup 6))
11469               (clobber (reg:CC FLAGS_REG))])]
11471   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
11472   operands[6] = gen_lowpart (SImode, operands[1]);
11474   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
11475     operands[4] = operands[2];
11476   else
11477     {
11478       /* Avoid use of cltd in favor of a mov+shift.  */
11479       emit_move_insn (operands[6], operands[2]);
11480       operands[4] = operands[6];
11481     }
11483   [(set_attr "type" "multi")
11484    (set_attr "mode" "SI")])
11486 (define_insn_and_split "udivmodsi4_zext_2"
11487   [(set (match_operand:DI 1 "register_operand" "=&d")
11488         (zero_extend:DI
11489           (umod:SI (match_operand:SI 2 "register_operand" "0")
11490                  (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11491    (set (match_operand:SI 0 "register_operand" "=a")
11492         (udiv:SI (match_dup 2) (match_dup 3)))
11493    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
11494    (clobber (reg:CC FLAGS_REG))]
11495   "TARGET_64BIT"
11496   "#"
11497   "&& reload_completed"
11498   [(set (match_dup 4) (const_int 0))
11499    (parallel [(set (match_dup 1)
11500                    (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
11501               (set (match_dup 0)
11502                    (udiv:SI (match_dup 2) (match_dup 3)))
11503               (use (match_dup 4))
11504               (clobber (reg:CC FLAGS_REG))])]
11505   "operands[4] = gen_lowpart (SImode, operands[1]);"
11506   [(set_attr "type" "multi")
11507    (set_attr "mode" "SI")])
11509 (define_insn_and_split "*divmod<mode>4"
11510   [(set (match_operand:SWIM248 0 "register_operand" "=a")
11511         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
11512                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
11513    (set (match_operand:SWIM248 1 "register_operand" "=&d")
11514         (mod:SWIM248 (match_dup 2) (match_dup 3)))
11515    (clobber (reg:CC FLAGS_REG))]
11516   ""
11517   "#"
11518   "reload_completed"
11519   [(parallel [(set (match_dup 1)
11520                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
11521               (clobber (reg:CC FLAGS_REG))])
11522    (parallel [(set (match_dup 0)
11523                    (div:SWIM248 (match_dup 2) (match_dup 3)))
11524               (set (match_dup 1)
11525                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
11526               (use (match_dup 1))
11527               (clobber (reg:CC FLAGS_REG))])]
11529   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11531   if (<MODE>mode != HImode
11532       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
11533     operands[4] = operands[2];
11534   else
11535     {
11536       /* Avoid use of cltd in favor of a mov+shift.  */
11537       emit_move_insn (operands[1], operands[2]);
11538       operands[4] = operands[1];
11539     }
11541   [(set_attr "type" "multi")
11542    (set_attr "mode" "<MODE>")])
11544 (define_insn_and_split "*udivmod<mode>4"
11545   [(set (match_operand:SWIM248 0 "register_operand" "=a")
11546         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
11547                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
11548    (set (match_operand:SWIM248 1 "register_operand" "=&d")
11549         (umod:SWIM248 (match_dup 2) (match_dup 3)))
11550    (clobber (reg:CC FLAGS_REG))]
11551   ""
11552   "#"
11553   "reload_completed"
11554   [(set (match_dup 1) (const_int 0))
11555    (parallel [(set (match_dup 0)
11556                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
11557               (set (match_dup 1)
11558                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
11559               (use (match_dup 1))
11560               (clobber (reg:CC FLAGS_REG))])]
11561   ""
11562   [(set_attr "type" "multi")
11563    (set_attr "mode" "<MODE>")])
11565 ;; Optimize division or modulo by constant power of 2, if the constant
11566 ;; materializes only after expansion.
11567 (define_insn_and_split "*udivmod<mode>4_pow2"
11568   [(set (match_operand:SWI48 0 "register_operand" "=r")
11569         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
11570                     (match_operand:SWI48 3 "const_int_operand")))
11571    (set (match_operand:SWI48 1 "register_operand" "=r")
11572         (umod:SWI48 (match_dup 2) (match_dup 3)))
11573    (clobber (reg:CC FLAGS_REG))]
11574   "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
11575   "#"
11576   "&& reload_completed"
11577   [(set (match_dup 1) (match_dup 2))
11578    (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
11579               (clobber (reg:CC FLAGS_REG))])
11580    (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
11581               (clobber (reg:CC FLAGS_REG))])]
11583   int v = exact_log2 (UINTVAL (operands[3]));
11584   operands[4] = GEN_INT (v);
11585   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
11587   [(set_attr "type" "multi")
11588    (set_attr "mode" "<MODE>")])
11590 (define_insn_and_split "*divmodsi4_zext_1"
11591   [(set (match_operand:DI 0 "register_operand" "=a")
11592         (zero_extend:DI
11593           (div:SI (match_operand:SI 2 "register_operand" "0")
11594                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11595    (set (match_operand:SI 1 "register_operand" "=&d")
11596         (mod:SI (match_dup 2) (match_dup 3)))
11597    (clobber (reg:CC FLAGS_REG))]
11598   "TARGET_64BIT"
11599   "#"
11600   "&& reload_completed"
11601   [(parallel [(set (match_dup 1)
11602                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
11603               (clobber (reg:CC FLAGS_REG))])
11604    (parallel [(set (match_dup 0)
11605                    (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
11606               (set (match_dup 1)
11607                    (mod:SI (match_dup 2) (match_dup 3)))
11608               (use (match_dup 1))
11609               (clobber (reg:CC FLAGS_REG))])]
11611   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
11613   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
11614     operands[4] = operands[2];
11615   else
11616     {
11617       /* Avoid use of cltd in favor of a mov+shift.  */
11618       emit_move_insn (operands[1], operands[2]);
11619       operands[4] = operands[1];
11620     }
11622   [(set_attr "type" "multi")
11623    (set_attr "mode" "SI")])
11625 (define_insn_and_split "*udivmodsi4_zext_1"
11626   [(set (match_operand:DI 0 "register_operand" "=a")
11627         (zero_extend:DI
11628           (udiv:SI (match_operand:SI 2 "register_operand" "0")
11629                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11630    (set (match_operand:SI 1 "register_operand" "=&d")
11631         (umod:SI (match_dup 2) (match_dup 3)))
11632    (clobber (reg:CC FLAGS_REG))]
11633   "TARGET_64BIT"
11634   "#"
11635   "&& reload_completed"
11636   [(set (match_dup 1) (const_int 0))
11637    (parallel [(set (match_dup 0)
11638                    (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
11639               (set (match_dup 1)
11640                    (umod:SI (match_dup 2) (match_dup 3)))
11641               (use (match_dup 1))
11642               (clobber (reg:CC FLAGS_REG))])]
11643   ""
11644   [(set_attr "type" "multi")
11645    (set_attr "mode" "SI")])
11647 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
11648   [(set (match_operand:DI 0 "register_operand" "=r")
11649         (zero_extend:DI
11650           (udiv:SI (match_operand:SI 2 "register_operand" "0")
11651                    (match_operand:SI 3 "const_int_operand"))))
11652    (set (match_operand:SI 1 "register_operand" "=r")
11653         (umod:SI (match_dup 2) (match_dup 3)))
11654    (clobber (reg:CC FLAGS_REG))]
11655   "TARGET_64BIT
11656    && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
11657   "#"
11658   "&& reload_completed"
11659   [(set (match_dup 1) (match_dup 2))
11660    (parallel [(set (match_dup 0)
11661                    (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
11662               (clobber (reg:CC FLAGS_REG))])
11663    (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
11664               (clobber (reg:CC FLAGS_REG))])]
11666   int v = exact_log2 (UINTVAL (operands[3]));
11667   operands[4] = GEN_INT (v);
11668   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
11670   [(set_attr "type" "multi")
11671    (set_attr "mode" "SI")])
11673 (define_insn_and_split "*divmodsi4_zext_2"
11674   [(set (match_operand:DI 1 "register_operand" "=&d")
11675         (zero_extend:DI
11676           (mod:SI (match_operand:SI 2 "register_operand" "0")
11677                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11678    (set (match_operand:SI 0 "register_operand" "=a")
11679         (div:SI (match_dup 2) (match_dup 3)))
11680    (clobber (reg:CC FLAGS_REG))]
11681   "TARGET_64BIT"
11682   "#"
11683   "&& reload_completed"
11684   [(parallel [(set (match_dup 6)
11685                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
11686               (clobber (reg:CC FLAGS_REG))])
11687    (parallel [(set (match_dup 1)
11688                    (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
11689               (set (match_dup 0)
11690                    (div:SI (match_dup 2) (match_dup 3)))
11691               (use (match_dup 6))
11692               (clobber (reg:CC FLAGS_REG))])]
11694   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
11695   operands[6] = gen_lowpart (SImode, operands[1]);
11697   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
11698     operands[4] = operands[2];
11699   else
11700     {
11701       /* Avoid use of cltd in favor of a mov+shift.  */
11702       emit_move_insn (operands[6], operands[2]);
11703       operands[4] = operands[6];
11704     }
11706   [(set_attr "type" "multi")
11707    (set_attr "mode" "SI")])
11709 (define_insn_and_split "*udivmodsi4_zext_2"
11710   [(set (match_operand:DI 1 "register_operand" "=&d")
11711         (zero_extend:DI
11712           (umod:SI (match_operand:SI 2 "register_operand" "0")
11713                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11714    (set (match_operand:SI 0 "register_operand" "=a")
11715         (udiv:SI (match_dup 2) (match_dup 3)))
11716    (clobber (reg:CC FLAGS_REG))]
11717   "TARGET_64BIT"
11718   "#"
11719   "&& reload_completed"
11720   [(set (match_dup 4) (const_int 0))
11721    (parallel [(set (match_dup 1)
11722                    (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
11723               (set (match_dup 0)
11724                    (udiv:SI (match_dup 2) (match_dup 3)))
11725               (use (match_dup 4))
11726               (clobber (reg:CC FLAGS_REG))])]
11727   "operands[4] = gen_lowpart (SImode, operands[1]);"
11728   [(set_attr "type" "multi")
11729    (set_attr "mode" "SI")])
11731 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
11732   [(set (match_operand:DI 1 "register_operand" "=r")
11733         (zero_extend:DI
11734           (umod:SI (match_operand:SI 2 "register_operand" "0")
11735                    (match_operand:SI 3 "const_int_operand"))))
11736    (set (match_operand:SI 0 "register_operand" "=r")
11737         (udiv:SI (match_dup 2) (match_dup 3)))
11738    (clobber (reg:CC FLAGS_REG))]
11739   "TARGET_64BIT
11740    && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
11741   "#"
11742   "&& reload_completed"
11743   [(set (match_dup 1) (match_dup 2))
11744    (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
11745               (clobber (reg:CC FLAGS_REG))])
11746    (parallel [(set (match_dup 1)
11747                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
11748               (clobber (reg:CC FLAGS_REG))])]
11750   int v = exact_log2 (UINTVAL (operands[3]));
11751   operands[4] = GEN_INT (v);
11752   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
11754   [(set_attr "type" "multi")
11755    (set_attr "mode" "SI")])
11757 (define_insn "*<u>divmod<mode>4_noext_nf"
11758   [(set (match_operand:SWIM248 0 "register_operand" "=a")
11759         (any_div:SWIM248
11760           (match_operand:SWIM248 2 "register_operand" "0")
11761           (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
11762    (set (match_operand:SWIM248 1 "register_operand" "=d")
11763         (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
11764    (use (match_operand:SWIM248 4 "register_operand" "1"))]
11765   "TARGET_APX_NF"
11766   "%{nf%} <sgnprefix>div{<imodesuffix>}\t%3"
11767   [(set_attr "type" "idiv")
11768    (set_attr "mode" "<MODE>")])
11770 (define_insn "*<u>divmod<mode>4_noext"
11771   [(set (match_operand:SWIM248 0 "register_operand" "=a")
11772         (any_div:SWIM248
11773           (match_operand:SWIM248 2 "register_operand" "0")
11774           (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
11775    (set (match_operand:SWIM248 1 "register_operand" "=d")
11776         (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
11777    (use (match_operand:SWIM248 4 "register_operand" "1"))
11778    (clobber (reg:CC FLAGS_REG))]
11779   ""
11780   "<sgnprefix>div{<imodesuffix>}\t%3"
11781   [(set_attr "type" "idiv")
11782    (set_attr "has_nf" "1")
11783    (set_attr "mode" "<MODE>")])
11785 (define_insn "*<u>divmodsi4_noext_zext_1"
11786   [(set (match_operand:DI 0 "register_operand" "=a")
11787         (zero_extend:DI
11788           (any_div:SI (match_operand:SI 2 "register_operand" "0")
11789                       (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11790    (set (match_operand:SI 1 "register_operand" "=d")
11791         (<paired_mod>:SI (match_dup 2) (match_dup 3)))
11792    (use (match_operand:SI 4 "register_operand" "1"))
11793    (clobber (reg:CC FLAGS_REG))]
11794   "TARGET_64BIT"
11795   "<sgnprefix>div{l}\t%3"
11796   [(set_attr "type" "idiv")
11797    (set_attr "mode" "SI")])
11799 (define_insn "*<u>divmodsi4_noext_zext_2"
11800   [(set (match_operand:DI 1 "register_operand" "=d")
11801         (zero_extend:DI
11802           (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
11803                            (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11804    (set (match_operand:SI 0 "register_operand" "=a")
11805         (any_div:SI (match_dup 2) (match_dup 3)))
11806    (use (match_operand:SI 4 "register_operand" "1"))
11807    (clobber (reg:CC FLAGS_REG))]
11808   "TARGET_64BIT"
11809   "<sgnprefix>div{l}\t%3"
11810   [(set_attr "type" "idiv")
11811    (set_attr "mode" "SI")])
11813 ;; Avoid sign-extension (using cdq) for constant numerators.
11814 (define_insn_and_split "*divmodsi4_const"
11815   [(set (match_operand:SI 0 "register_operand" "=&a")
11816         (div:SI (match_operand:SI 2 "const_int_operand")
11817                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
11818    (set (match_operand:SI 1 "register_operand" "=&d")
11819         (mod:SI (match_dup 2) (match_dup 3)))
11820    (clobber (reg:CC FLAGS_REG))]
11821   "!optimize_function_for_size_p (cfun)"
11822   "#"
11823   "&& reload_completed"
11824   [(set (match_dup 0) (match_dup 2))
11825    (set (match_dup 1) (match_dup 4))
11826    (parallel [(set (match_dup 0)
11827                    (div:SI (match_dup 0) (match_dup 3)))
11828               (set (match_dup 1)
11829                    (mod:SI (match_dup 0) (match_dup 3)))
11830               (use (match_dup 1))
11831               (clobber (reg:CC FLAGS_REG))])]
11833   operands[4] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
11835   [(set_attr "type" "multi")
11836    (set_attr "mode" "SI")])
11838 (define_expand "divmodqi4"
11839   [(parallel [(set (match_operand:QI 0 "register_operand")
11840                    (div:QI
11841                      (match_operand:QI 1 "register_operand")
11842                      (match_operand:QI 2 "nonimmediate_operand")))
11843               (set (match_operand:QI 3 "register_operand")
11844                    (mod:QI (match_dup 1) (match_dup 2)))
11845               (clobber (reg:CC FLAGS_REG))])]
11846   "TARGET_QIMODE_MATH"
11848   rtx div, mod;
11849   rtx tmp0, tmp1;
11851   tmp0 = gen_reg_rtx (HImode);
11852   tmp1 = gen_reg_rtx (HImode);
11854   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
11855   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
11856   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
11858   /* Extract remainder from AH.  */
11859   tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
11860   tmp1 = lowpart_subreg (QImode, tmp1, HImode);
11861   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
11863   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
11864   set_unique_reg_note (insn, REG_EQUAL, mod);
11866   /* Extract quotient from AL.  */
11867   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
11869   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
11870   set_unique_reg_note (insn, REG_EQUAL, div);
11872   DONE;
11875 (define_expand "udivmodqi4"
11876   [(parallel [(set (match_operand:QI 0 "register_operand")
11877                    (udiv:QI
11878                      (match_operand:QI 1 "register_operand")
11879                      (match_operand:QI 2 "nonimmediate_operand")))
11880               (set (match_operand:QI 3 "register_operand")
11881                    (umod:QI (match_dup 1) (match_dup 2)))
11882               (clobber (reg:CC FLAGS_REG))])]
11883   "TARGET_QIMODE_MATH"
11885   rtx div, mod;
11886   rtx tmp0, tmp1;
11888   tmp0 = gen_reg_rtx (HImode);
11889   tmp1 = gen_reg_rtx (HImode);
11891   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
11892   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
11893   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
11895   /* Extract remainder from AH.  */
11896   tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
11897   tmp1 = lowpart_subreg (QImode, tmp1, HImode);
11898   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
11900   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
11901   set_unique_reg_note (insn, REG_EQUAL, mod);
11903   /* Extract quotient from AL.  */
11904   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
11906   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
11907   set_unique_reg_note (insn, REG_EQUAL, div);
11909   DONE;
11912 ;; Divide AX by r/m8, with result stored in
11913 ;; AL <- Quotient
11914 ;; AH <- Remainder
11915 ;; Change div/mod to HImode and extend the second argument to HImode
11916 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
11917 ;; combine may fail.
11918 (define_insn "<u>divmodhiqi3<nf_name>"
11919   [(set (match_operand:HI 0 "register_operand" "=a")
11920         (ior:HI
11921           (ashift:HI
11922             (zero_extend:HI
11923               (truncate:QI
11924                 (mod:HI (match_operand:HI 1 "register_operand" "0")
11925                         (any_extend:HI
11926                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
11927             (const_int 8))
11928           (zero_extend:HI
11929             (truncate:QI
11930               (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))]
11931   "TARGET_QIMODE_MATH
11932    && <nf_condition>"
11933   "<nf_prefix><sgnprefix>div{b}\t%2"
11934   [(set_attr "type" "idiv")
11935    (set_attr "has_nf" "1")
11936    (set_attr "mode" "QI")])
11938 ;; We cannot use div/idiv for double division, because it causes
11939 ;; "division by zero" on the overflow and that's not what we expect
11940 ;; from truncate.  Because true (non truncating) double division is
11941 ;; never generated, we can't create this insn anyway.
11943 ;(define_insn ""
11944 ;  [(set (match_operand:SI 0 "register_operand" "=a")
11945 ;       (truncate:SI
11946 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
11947 ;                  (zero_extend:DI
11948 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
11949 ;   (set (match_operand:SI 3 "register_operand" "=d")
11950 ;       (truncate:SI
11951 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
11952 ;   (clobber (reg:CC FLAGS_REG))]
11953 ;  ""
11954 ;  "div{l}\t{%2, %0|%0, %2}"
11955 ;  [(set_attr "type" "idiv")])
11957 ;;- Logical AND instructions
11959 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
11960 ;; Note that this excludes ah.
11962 (define_expand "@test<mode>_ccno_1"
11963   [(set (reg:CCNO FLAGS_REG)
11964         (compare:CCNO
11965           (and:SWI48
11966             (match_operand:SWI48 0 "nonimmediate_operand")
11967             (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
11968           (const_int 0)))])
11970 (define_expand "testqi_ccz_1"
11971   [(set (reg:CCZ FLAGS_REG)
11972         (compare:CCZ
11973           (and:QI
11974             (match_operand:QI 0 "nonimmediate_operand")
11975             (match_operand:QI 1 "nonmemory_operand"))
11976           (const_int 0)))])
11978 (define_insn "*testdi_1"
11979   [(set (reg FLAGS_REG)
11980         (compare
11981           (and:DI
11982             (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
11983             (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
11984          (const_int 0)))]
11985   "TARGET_64BIT
11986    && ix86_match_ccmode
11987         (insn,
11988          /* If we are going to emit testl instead of testq, and the operands[1]
11989             constant might have the SImode sign bit set, make sure the sign
11990             flag isn't tested, because the instruction will set the sign flag
11991             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
11992             conservatively assume it might have bit 31 set.  */
11993          (satisfies_constraint_Z (operands[1])
11994           && (!CONST_INT_P (operands[1])
11995               || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
11996          ? CCZmode : CCNOmode)"
11997   "@
11998    test{l}\t{%k1, %k0|%k0, %k1}
11999    test{q}\t{%1, %0|%0, %1}"
12000   [(set_attr "type" "test")
12001    (set_attr "mode" "SI,DI")])
12003 (define_insn "*testqi_1_maybe_si"
12004   [(set (reg FLAGS_REG)
12005         (compare
12006           (and:QI
12007             (match_operand:QI 0 "nonimmediate_operand" "%qm,qm,r")
12008             (match_operand:QI 1 "nonmemory_operand" "q,n,n"))
12009           (const_int 0)))]
12010   "ix86_match_ccmode (insn,
12011                       CONST_INT_P (operands[1])
12012                       && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
12014   if (get_attr_mode (insn) == MODE_SI)
12015     {
12016       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
12017         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
12018       return "test{l}\t{%1, %k0|%k0, %1}";
12019     }
12020   return "test{b}\t{%1, %0|%0, %1}";
12022   [(set_attr "type" "test")
12023    (set (attr "mode")
12024      (cond [(eq_attr "alternative" "2")
12025               (const_string "SI")
12026             (and (match_test "optimize_insn_for_size_p ()")
12027                  (and (match_operand 0 "ext_QIreg_operand")
12028                       (match_operand 1 "const_0_to_127_operand")))
12029               (const_string "SI")
12030            ]
12031            (const_string "QI")))
12032    (set_attr "pent_pair" "uv,np,np")])
12034 (define_insn "*test<mode>_1"
12035   [(set (reg FLAGS_REG)
12036         (compare
12037           (and:SWI124
12038             (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
12039             (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
12040          (const_int 0)))]
12041   "ix86_match_ccmode (insn, CCNOmode)"
12042   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
12043   [(set_attr "type" "test")
12044    (set_attr "mode" "<MODE>")
12045    (set_attr "pent_pair" "uv,uv,np")])
12047 (define_expand "testqi_ext_1_ccno"
12048   [(set (reg:CCNO FLAGS_REG)
12049         (compare:CCNO
12050           (and:QI
12051             (subreg:QI
12052               (zero_extract:HI
12053                 (match_operand:HI 0 "register_operand")
12054                 (const_int 8)
12055                 (const_int 8)) 0)
12056               (match_operand:QI 1 "const_int_operand"))
12057           (const_int 0)))])
12059 (define_insn "*testqi_ext<mode>_1"
12060   [(set (reg FLAGS_REG)
12061         (compare
12062           (and:QI
12063             (subreg:QI
12064               (match_operator:SWI248 2 "extract_operator"
12065                 [(match_operand 0 "int248_register_operand" "Q")
12066                  (const_int 8)
12067                  (const_int 8)]) 0)
12068             (match_operand:QI 1 "general_operand" "QnBn"))
12069           (const_int 0)))]
12070   "ix86_match_ccmode (insn, CCNOmode)"
12071   "test{b}\t{%1, %h0|%h0, %1}"
12072   [(set_attr "addr" "gpr8")
12073    (set_attr "type" "test")
12074    (set_attr "mode" "QI")])
12076 (define_insn "*testqi_ext<mode>_2"
12077   [(set (reg FLAGS_REG)
12078         (compare
12079           (and:QI
12080             (subreg:QI
12081               (match_operator:SWI248 2 "extract_operator"
12082                 [(match_operand 0 "int248_register_operand" "Q")
12083                  (const_int 8)
12084                  (const_int 8)]) 0)
12085             (subreg:QI
12086               (match_operator:SWI248 3 "extract_operator"
12087                 [(match_operand 1 "int248_register_operand" "Q")
12088                  (const_int 8)
12089                  (const_int 8)]) 0))
12090           (const_int 0)))]
12091   "ix86_match_ccmode (insn, CCNOmode)"
12092   "test{b}\t{%h1, %h0|%h0, %h1}"
12093   [(set_attr "type" "test")
12094    (set_attr "mode" "QI")])
12096 ;; Provide a *testti instruction that STV can implement using ptest.
12097 ;; This pattern splits into *andti3_doubleword and *cmpti_doubleword.
12098 (define_insn_and_split "*testti_doubleword"
12099   [(set (reg:CCZ FLAGS_REG)
12100         (compare:CCZ
12101           (and:TI (match_operand:TI 0 "register_operand")
12102                   (match_operand:TI 1 "general_operand"))
12103           (const_int 0)))]
12104   "TARGET_64BIT
12105    && ix86_pre_reload_split ()"
12106   "#"
12107   "&& 1"
12108   [(parallel [(set (match_dup 2) (and:TI (match_dup 0) (match_dup 1)))
12109               (clobber (reg:CC FLAGS_REG))])
12110    (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
12112   operands[2] = gen_reg_rtx (TImode);
12113   if (!x86_64_hilo_general_operand (operands[1], TImode))
12114     operands[1] = force_reg (TImode, operands[1]);
12117 ;; Combine likes to form bit extractions for some tests.  Humor it.
12118 (define_insn_and_split "*testqi_ext_3"
12119   [(set (match_operand 0 "flags_reg_operand")
12120         (match_operator 1 "compare_operator"
12121           [(zero_extract:SWI248
12122              (match_operand 2 "int_nonimmediate_operand" "rm")
12123              (match_operand:QI 3 "const_int_operand")
12124              (match_operand:QI 4 "const_int_operand"))
12125            (const_int 0)]))]
12126   "/* Ensure that resulting mask is zero or sign extended operand.  */
12127    INTVAL (operands[4]) >= 0
12128    && ((INTVAL (operands[3]) > 0
12129         && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
12130        || (<MODE>mode == DImode
12131            && INTVAL (operands[3]) > 32
12132            && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
12133    && ix86_match_ccmode (insn,
12134                          /* If zero_extract mode precision is the same
12135                             as len, the SF of the zero_extract
12136                             comparison will be the most significant
12137                             extracted bit, but this could be matched
12138                             after splitting only for pos 0 len all bits
12139                             trivial extractions.  Require CCZmode.  */
12140                          (GET_MODE_PRECISION (<MODE>mode)
12141                           == INTVAL (operands[3]))
12142                          /* Otherwise, require CCZmode if we'd use a mask
12143                             with the most significant bit set and can't
12144                             widen it to wider mode.  *testdi_1 also
12145                             requires CCZmode if the mask has bit
12146                             31 set and all bits above it clear.  */
12147                          || (INTVAL (operands[3]) + INTVAL (operands[4])
12148                              >= 32)
12149                          /* We can't widen also if val is not a REG.  */
12150                          || (INTVAL (operands[3]) + INTVAL (operands[4])
12151                              == GET_MODE_PRECISION (GET_MODE (operands[2]))
12152                              && !register_operand (operands[2],
12153                                                    GET_MODE (operands[2])))
12154                          /* And we shouldn't widen if
12155                             TARGET_PARTIAL_REG_STALL.  */
12156                          || (TARGET_PARTIAL_REG_STALL
12157                              && (INTVAL (operands[3]) + INTVAL (operands[4])
12158                                  >= (paradoxical_subreg_p (operands[2])
12159                                      && (GET_MODE_CLASS
12160                                           (GET_MODE (SUBREG_REG (operands[2])))
12161                                          == MODE_INT)
12162                                      ? GET_MODE_PRECISION
12163                                          (GET_MODE (SUBREG_REG (operands[2])))
12164                                      : GET_MODE_PRECISION
12165                                          (GET_MODE (operands[2])))))
12166                          ? CCZmode : CCNOmode)"
12167   "#"
12168   "&& 1"
12169   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12171   rtx val = operands[2];
12172   HOST_WIDE_INT len = INTVAL (operands[3]);
12173   HOST_WIDE_INT pos = INTVAL (operands[4]);
12174   machine_mode mode = GET_MODE (val);
12176   if (SUBREG_P (val))
12177     {
12178       machine_mode submode = GET_MODE (SUBREG_REG (val));
12180       /* Narrow paradoxical subregs to prevent partial register stalls.  */
12181       if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
12182           && GET_MODE_CLASS (submode) == MODE_INT
12183           && (GET_MODE (operands[0]) == CCZmode
12184               || pos + len < GET_MODE_PRECISION (submode)
12185               || REG_P (SUBREG_REG (val))))
12186         {
12187           val = SUBREG_REG (val);
12188           mode = submode;
12189         }
12190     }
12192   /* Small HImode tests can be converted to QImode.  */
12193   if (pos + len <= 8
12194       && register_operand (val, HImode))
12195     {
12196       rtx nval = gen_lowpart (QImode, val);
12197       if (!MEM_P (nval)
12198           || GET_MODE (operands[0]) == CCZmode
12199           || pos + len < 8)
12200         {
12201           val = nval;
12202           mode = QImode;
12203         }
12204     }
12206   gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
12208   /* If the mask is going to have the sign bit set in the mode
12209      we want to do the comparison in and user isn't interested just
12210      in the zero flag, then we must widen the target mode.  */
12211   if (pos + len == GET_MODE_PRECISION (mode)
12212       && GET_MODE (operands[0]) != CCZmode)
12213     {
12214       gcc_assert (pos + len < 32 && !MEM_P (val));
12215       mode = SImode;
12216       val = gen_lowpart (mode, val);
12217     }
12219   wide_int mask
12220     = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
12222   operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
12225 ;; Split and;cmp (as optimized by combine) into not;test
12226 ;; Except when TARGET_BMI provides andn (*andn_<mode>_ccno).
12227 (define_insn_and_split "*test<mode>_not"
12228   [(set (reg:CCZ FLAGS_REG)
12229         (compare:CCZ
12230           (and:SWI
12231             (not:SWI (match_operand:SWI 0 "register_operand"))
12232             (match_operand:SWI 1 "<nonmemory_szext_operand>"))
12233           (const_int 0)))]
12234   "ix86_pre_reload_split ()
12235    && (!TARGET_BMI || !REG_P (operands[1]))"
12236   "#"
12237   "&& 1"
12238   [(set (match_dup 2) (not:SWI (match_dup 0)))
12239    (set (reg:CCZ FLAGS_REG)
12240         (compare:CCZ (and:SWI (match_dup 2) (match_dup 1))
12241                      (const_int 0)))]
12242   "operands[2] = gen_reg_rtx (<MODE>mode);")
12244 ;; Split and;cmp (as optimized by combine) into andn;cmp $0
12245 (define_insn_and_split "*test<mode>_not_doubleword"
12246   [(set (reg:CCZ FLAGS_REG)
12247         (compare:CCZ
12248           (and:DWI
12249             (not:DWI (match_operand:DWI 0 "nonimmediate_operand"))
12250             (match_operand:DWI 1 "nonimmediate_operand"))
12251           (const_int 0)))]
12252   "ix86_pre_reload_split ()"
12253   "#"
12254   "&& 1"
12255   [(parallel
12256       [(set (match_dup 2) (and:DWI (not:DWI (match_dup 0)) (match_dup 1)))
12257        (clobber (reg:CC FLAGS_REG))])
12258    (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
12260   operands[0] = force_reg (<MODE>mode, operands[0]);
12261   operands[2] = gen_reg_rtx (<MODE>mode);
12264 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
12265 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
12266 ;; this is relatively important trick.
12267 ;; Do the conversion only post-reload to avoid limiting of the register class
12268 ;; to QI regs.
12269 (define_split
12270   [(set (match_operand 0 "flags_reg_operand")
12271         (match_operator 1 "compare_operator"
12272           [(and (match_operand 2 "QIreg_operand")
12273                 (match_operand 3 "const_int_operand"))
12274            (const_int 0)]))]
12275    "reload_completed
12276     && GET_MODE (operands[2]) != QImode
12277     && ((ix86_match_ccmode (insn, CCZmode)
12278          && !(INTVAL (operands[3]) & ~(255 << 8)))
12279         || (ix86_match_ccmode (insn, CCNOmode)
12280             && !(INTVAL (operands[3]) & ~(127 << 8))))"
12281   [(set (match_dup 0)
12282         (match_op_dup 1
12283           [(and:QI
12284              (subreg:QI
12285                (zero_extract:HI (match_dup 2)
12286                                 (const_int 8)
12287                                 (const_int 8)) 0)
12288              (match_dup 3))
12289            (const_int 0)]))]
12291   operands[2] = gen_lowpart (HImode, operands[2]);
12292   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
12295 (define_split
12296   [(set (match_operand 0 "flags_reg_operand")
12297         (match_operator 1 "compare_operator"
12298           [(and (match_operand 2 "nonimmediate_operand")
12299                 (match_operand 3 "const_int_operand"))
12300            (const_int 0)]))]
12301    "reload_completed
12302     && GET_MODE (operands[2]) != QImode
12303     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
12304     && ((ix86_match_ccmode (insn, CCZmode)
12305          && !(INTVAL (operands[3]) & ~255))
12306         || (ix86_match_ccmode (insn, CCNOmode)
12307             && !(INTVAL (operands[3]) & ~127)))"
12308   [(set (match_dup 0)
12309         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
12310                          (const_int 0)]))]
12312   operands[2] = gen_lowpart (QImode, operands[2]);
12313   operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
12316 ;; Narrow test instructions with immediate operands that test
12317 ;; memory locations for zero.  E.g. testl $0x00aa0000, mem can be
12318 ;; converted to testb $0xaa, mem+2.  Reject volatile locations and
12319 ;; targets where reading (possibly unaligned) part of memory
12320 ;; location after a large write to the same address causes
12321 ;; store-to-load forwarding stall.
12322 (define_peephole2
12323   [(set (reg:CCZ FLAGS_REG)
12324         (compare:CCZ
12325           (and:SWI248 (match_operand:SWI248 0 "memory_operand")
12326                       (match_operand 1 "const_int_operand"))
12327           (const_int 0)))]
12328   "!TARGET_PARTIAL_MEMORY_READ_STALL && !MEM_VOLATILE_P (operands[0])"
12329   [(set (reg:CCZ FLAGS_REG)
12330         (compare:CCZ (match_dup 2) (const_int 0)))]
12332   unsigned HOST_WIDE_INT ival = UINTVAL (operands[1]);
12333   int first_nonzero_byte, bitsize;
12334   rtx new_addr, new_const;
12335   machine_mode new_mode;
12337   if (ival == 0)
12338     FAIL;
12340   /* Clear bits outside mode width.  */
12341   ival &= GET_MODE_MASK (<MODE>mode);
12343   first_nonzero_byte = ctz_hwi (ival) / BITS_PER_UNIT;
12345   ival >>= first_nonzero_byte * BITS_PER_UNIT;
12347   bitsize = sizeof (ival) * BITS_PER_UNIT - clz_hwi (ival);
12349   if (bitsize <= GET_MODE_BITSIZE (QImode))
12350     new_mode = QImode;
12351   else if (bitsize <= GET_MODE_BITSIZE (HImode))
12352     new_mode = HImode;
12353   else if (bitsize <= GET_MODE_BITSIZE (SImode))
12354     new_mode = SImode;
12355   else
12356     new_mode = DImode;
12358   if (GET_MODE_SIZE (new_mode) >= GET_MODE_SIZE (<MODE>mode))
12359     FAIL;
12361   new_addr = adjust_address (operands[0], new_mode, first_nonzero_byte);
12362   new_const = gen_int_mode (ival, new_mode);
12364   operands[2] = gen_rtx_AND (new_mode, new_addr, new_const);
12367 ;; %%% This used to optimize known byte-wide and operations to memory,
12368 ;; and sometimes to QImode registers.  If this is considered useful,
12369 ;; it should be done with splitters.
12371 (define_expand "and<mode>3"
12372   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12373         (and:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
12374                    (match_operand:SDWIM 2 "<general_szext_operand>")))]
12375   ""
12377   machine_mode mode = <MODE>mode;
12379   if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
12380       && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
12381     operands[2] = force_reg (<MODE>mode, operands[2]);
12383   if (GET_MODE_SIZE (<MODE>mode) <= UNITS_PER_WORD
12384       && const_int_operand (operands[2], <MODE>mode)
12385       && register_operand (operands[0], <MODE>mode)
12386       && !(TARGET_ZERO_EXTEND_WITH_AND
12387            && optimize_function_for_speed_p (cfun)))
12388     {
12389       unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
12391       if (ival == GET_MODE_MASK (SImode))
12392         mode = SImode;
12393       else if (ival == GET_MODE_MASK (HImode))
12394         mode = HImode;
12395       else if (ival == GET_MODE_MASK (QImode))
12396         mode = QImode;
12397     }
12399   if (mode != <MODE>mode)
12400     emit_insn (gen_extend_insn
12401                (operands[0], gen_lowpart (mode, operands[1]),
12402                 <MODE>mode, mode, 1));
12403   else
12404     ix86_expand_binary_operator (AND, <MODE>mode, operands, TARGET_APX_NDD);
12406   DONE;
12409 (define_insn_and_split "*and<dwi>3_doubleword"
12410   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r,&r,&r,&r")
12411         (and:<DWI>
12412          (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r,ro,jO,r")
12413          (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r,<di>,K,<di>,o")))
12414    (clobber (reg:CC FLAGS_REG))]
12415   "ix86_binary_operator_ok (AND, <DWI>mode, operands, TARGET_APX_NDD)"
12416   "#"
12417   "&& reload_completed"
12418   [(const_int:DWIH 0)]
12420   bool emit_insn_deleted_note_p = false;
12422   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
12424   if (operands[2] == const0_rtx)
12425     emit_move_insn (operands[0], const0_rtx);
12426   else if (operands[2] == constm1_rtx)
12427     {
12428       if (!rtx_equal_p (operands[0], operands[1]))
12429         emit_move_insn (operands[0], operands[1]);
12430       else
12431         emit_insn_deleted_note_p = true;
12432     }
12433   else
12434     ix86_expand_binary_operator (AND, <MODE>mode, &operands[0], TARGET_APX_NDD);
12436   if (operands[5] == const0_rtx)
12437     emit_move_insn (operands[3], const0_rtx);
12438   else if (operands[5] == constm1_rtx)
12439     {
12440       if (!rtx_equal_p (operands[3], operands[4]))
12441         emit_move_insn (operands[3], operands[4]);
12442       else if (emit_insn_deleted_note_p)
12443         emit_note (NOTE_INSN_DELETED);
12444     }
12445   else
12446     ix86_expand_binary_operator (AND, <MODE>mode, &operands[3], TARGET_APX_NDD);
12448   DONE;
12450 [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd_64,apx_ndd")])
12452 (define_insn "*anddi_1<nf_name>"
12453   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm,r<nf_mem_constraint>,r,r,r,r,r,?k")
12454         (and:DI
12455          (match_operand:DI 1 "nonimmediate_operand" "%0,r,0,0,0,rm,rjM,r,qm,k")
12456          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,Z,r,e,m,r,e,m,L,k")))]
12457   "TARGET_64BIT
12458    && ix86_binary_operator_ok (AND, DImode, operands, TARGET_APX_NDD)
12459    && <nf_condition>"
12460   "@
12461    <nf_prefix>and{l}\t{%k2, %k0|%k0, %k2}
12462    <nf_prefix>and{l}\t{%k2, %k1, %k0|%k0, %k1, %k2}
12463    <nf_prefix>and{q}\t{%2, %0|%0, %2}
12464    <nf_prefix>and{q}\t{%2, %0|%0, %2}
12465    <nf_prefix>and{q}\t{%2, %0|%0, %2}
12466    <nf_prefix>and{q}\t{%2, %1, %0|%0, %1, %2}
12467    <nf_prefix>and{q}\t{%2, %1, %0|%0, %1, %2}
12468    <nf_prefix>and{q}\t{%2, %1, %0|%0, %1, %2}
12469    #
12470    #"
12471   [(set_attr "isa" "x64,apx_ndd,x64,x64,x64,apx_ndd,apx_ndd,apx_ndd,<nf_nonf_x64_attr>,avx512bw")
12472    (set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,imovx,msklog")
12473    (set_attr "length_immediate" "*,*,*,*,*,*,*,*,0,*")
12474    (set (attr "prefix_rex")
12475      (if_then_else
12476        (and (eq_attr "type" "imovx")
12477             (and (match_test "INTVAL (operands[2]) == 0xff")
12478                  (match_operand 1 "ext_QIreg_operand")))
12479        (const_string "1")
12480        (const_string "*")))
12481    (set_attr "has_nf" "1")
12482    (set_attr "mode" "SI,SI,DI,DI,DI,DI,DI,DI,SI,DI")])
12484 (define_insn_and_split "*anddi_1_btr"
12485   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12486         (and:DI
12487          (match_operand:DI 1 "nonimmediate_operand" "%0")
12488          (match_operand:DI 2 "const_int_operand" "n")))
12489    (clobber (reg:CC FLAGS_REG))]
12490   "TARGET_64BIT && TARGET_USE_BT
12491    && ix86_binary_operator_ok (AND, DImode, operands)
12492    && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
12493   "#"
12494   "&& reload_completed"
12495   [(parallel [(set (zero_extract:DI (match_dup 0)
12496                                     (const_int 1)
12497                                     (match_dup 3))
12498                    (const_int 0))
12499               (clobber (reg:CC FLAGS_REG))])]
12500   "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
12501   [(set_attr "type" "alu1")
12502    (set_attr "prefix_0f" "1")
12503    (set_attr "znver1_decode" "double")
12504    (set_attr "mode" "DI")])
12506 ;; Turn *anddi_1 into *andsi_1_zext if possible.
12507 (define_split
12508   [(set (match_operand:DI 0 "register_operand")
12509         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
12510                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
12511    (clobber (reg:CC FLAGS_REG))]
12512   "TARGET_64BIT"
12513   [(parallel [(set (match_dup 0)
12514                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
12515               (clobber (reg:CC FLAGS_REG))])]
12517   if (GET_CODE (operands[2]) == SYMBOL_REF
12518       || GET_CODE (operands[2]) == LABEL_REF)
12519     {
12520       operands[2] = shallow_copy_rtx (operands[2]);
12521       PUT_MODE (operands[2], SImode);
12522     }
12523   else if (GET_CODE (operands[2]) == CONST)
12524     {
12525       /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
12526       operands[2] = copy_rtx (operands[2]);
12527       PUT_MODE (operands[2], SImode);
12528       PUT_MODE (XEXP (operands[2], 0), SImode);
12529       PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
12530     }    
12531   else
12532     operands[2] = gen_lowpart (SImode, operands[2]);
12535 (define_insn "*andqi_1_zext<mode><nf_name>"
12536   [(set (match_operand:SWI248x 0 "register_operand" "=r,r")
12537         (zero_extend:SWI248x
12538           (and:QI (match_operand:QI 1 "nonimmediate_operand" "%rm,r")
12539                   (match_operand:QI 2 "x86_64_general_operand" "rn,m"))))]
12540   "TARGET_APX_NDD && <nf_condition>
12541    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12542   "@
12543   <nf_prefix>and{b}\t{%2, %1, %b0|%b0, %1, %2}
12544   <nf_prefix>and{b}\t{%2, %1, %b0|%b0, %1, %2}"
12545   [(set_attr "type" "alu")
12546    (set_attr "has_nf" "1")
12547    (set_attr "mode" "QI")])
12549 (define_insn "*andhi_1_zext<mode><nf_name>"
12550   [(set (match_operand:SWI48x 0 "register_operand" "=r,r")
12551         (zero_extend:SWI48x
12552           (and:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,r")
12553                   (match_operand:HI 2 "x86_64_general_operand" "rn,m"))))]
12554   "TARGET_APX_NDD && <nf_condition>
12555    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12556   "@
12557   <nf_prefix>and{w}\t{%2, %1, %w0|%w0, %1, %2}
12558   <nf_prefix>and{w}\t{%2, %1, %w0|%w0, %1, %2}"
12559   [(set_attr "type" "alu")
12560    (set_attr "has_nf" "1")
12561    (set_attr "mode" "HI")])
12563 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12564 (define_insn "*andsi_1_zext"
12565   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
12566         (zero_extend:DI
12567           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm,rjM,r")
12568                   (match_operand:SI 2 "x86_64_general_operand" "rBMe,r,e,BM"))))
12569    (clobber (reg:CC FLAGS_REG))]
12570   "TARGET_64BIT
12571    && ix86_binary_operator_ok (AND, SImode, operands, TARGET_APX_NDD)"
12572   "@
12573   and{l}\t{%2, %k0|%k0, %2}
12574   and{l}\t{%2, %1, %k0|%k0, %1, %2}
12575   and{l}\t{%2, %1, %k0|%k0, %1, %2}
12576   and{l}\t{%2, %1, %k0|%k0, %1, %2}"
12577   [(set_attr "type" "alu")
12578    (set_attr "isa" "*,apx_ndd,apx_ndd,apx_ndd")
12579    (set_attr "mode" "SI")])
12581 (define_insn "*and<mode>_1<nf_name>"
12582   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r<nf_mem_constraint>,r,r,r,r,Ya,?k")
12583         (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,0,rm,rjM,r,qm,k")
12584                    (match_operand:SWI24 2 "<general_operand>" "r,<i>,<m>,r,<i>,<m>,L,k")))]
12585   "ix86_binary_operator_ok (AND, <MODE>mode, operands, TARGET_APX_NDD)
12586    && <nf_condition>"
12587   "@
12588    <nf_prefix>and{<imodesuffix>}\t{%2, %0|%0, %2}
12589    <nf_prefix>and{<imodesuffix>}\t{%2, %0|%0, %2}
12590    <nf_prefix>and{<imodesuffix>}\t{%2, %0|%0, %2}
12591    <nf_prefix>and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
12592    <nf_prefix>and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
12593    <nf_prefix>and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
12594    #
12595    #"
12596   [(set (attr "isa")
12597         (cond [(eq_attr "alternative" "3,4,5")
12598                  (const_string "apx_ndd")
12599                (eq_attr "alternative" "6")
12600                  (const_string "<nf_nonf_attr>")
12601                (eq_attr "alternative" "7")
12602                  (if_then_else (eq_attr "mode" "SI")
12603                    (const_string "avx512bw")
12604                    (const_string "avx512f"))
12605               ]
12606               (const_string "*")))
12607    (set_attr "type" "alu,alu,alu,alu,alu,alu,imovx,msklog")
12608    (set_attr "length_immediate" "*,*,*,*,*,*,0,*")
12609    (set (attr "prefix_rex")
12610      (if_then_else
12611        (and (eq_attr "type" "imovx")
12612             (and (match_test "INTVAL (operands[2]) == 0xff")
12613                  (match_operand 1 "ext_QIreg_operand")))
12614        (const_string "1")
12615        (const_string "*")))
12616    (set_attr "has_nf" "1")
12617    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<MODE>,<MODE>,SI,<MODE>")])
12619 (define_insn "*andqi_1<nf_name>"
12620   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r,?k")
12621         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r,k")
12622                 (match_operand:QI 2 "general_operand" "qn,m,rn,rn,m,k")))]
12623   "ix86_binary_operator_ok (AND, QImode, operands, TARGET_APX_NDD)
12624    && <nf_condition>"
12625   "@
12626    <nf_prefix>and{b}\t{%2, %0|%0, %2}
12627    <nf_prefix>and{b}\t{%2, %0|%0, %2}
12628    <nf_prefix>and{l}\t{%k2, %k0|%k0, %k2}
12629    <nf_prefix>and{b}\t{%2, %1, %0|%0, %1, %2}
12630    <nf_prefix>and{b}\t{%2, %1, %0|%0, %1, %2}
12631    #"
12632   [(set_attr "type" "alu,alu,alu,alu,alu,msklog")
12633    (set_attr "isa" "*,*,*,apx_ndd,apx_ndd,*")
12634    (set_attr "has_nf" "1")
12635    (set (attr "mode")
12636         (cond [(eq_attr "alternative" "2")
12637                  (const_string "SI")
12638                 (and (eq_attr "alternative" "5")
12639                      (match_test "!TARGET_AVX512DQ"))
12640                  (const_string "HI")
12641                ]
12642                (const_string "QI")))
12643    ;; Potential partial reg stall on alternative 2.
12644    (set (attr "preferred_for_speed")
12645      (cond [(eq_attr "alternative" "2")
12646               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12647            (symbol_ref "true")))])
12649 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12650 (define_insn_and_split "*<code><mode>_1_slp"
12651   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
12652         (any_logic:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
12653                       (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
12654    (clobber (reg:CC FLAGS_REG))]
12655   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12656   "@
12657    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12658    #"
12659   "&& reload_completed
12660    && !(rtx_equal_p (operands[0], operands[1])
12661         || rtx_equal_p (operands[0], operands[2]))"
12662   [(set (strict_low_part (match_dup 0)) (match_dup 1))
12663    (parallel
12664      [(set (strict_low_part (match_dup 0))
12665            (any_logic:SWI12 (match_dup 0) (match_dup 2)))
12666       (clobber (reg:CC FLAGS_REG))])]
12667   ""
12668   [(set_attr "type" "alu")
12669    (set_attr "mode" "<MODE>")])
12671 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12672 (define_insn_and_split "*<code>qi_ext<mode>_1_slp"
12673   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
12674         (any_logic:QI
12675           (subreg:QI
12676             (match_operator:SWI248 3 "extract_operator"
12677               [(match_operand 2 "int248_register_operand" "Q,Q")
12678                (const_int 8)
12679                (const_int 8)]) 0)
12680           (match_operand:QI 1 "nonimmediate_operand" "0,!qm")))
12681    (clobber (reg:CC FLAGS_REG))]
12682   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12683   "@
12684    <logic>{b}\t{%h2, %0|%0, %h2}
12685    #"
12686   "&& reload_completed
12687    && !rtx_equal_p (operands[0], operands[1])"
12688   [(set (strict_low_part (match_dup 0)) (match_dup 1))
12689    (parallel
12690      [(set (strict_low_part (match_dup 0))
12691            (any_logic:QI
12692              (subreg:QI
12693                (match_op_dup 3
12694                  [(match_dup 2) (const_int 8) (const_int 8)]) 0)
12695              (match_dup 0)))
12696       (clobber (reg:CC FLAGS_REG))])]
12697   ""
12698   [(set_attr "type" "alu")
12699    (set_attr "mode" "QI")])
12701 (define_insn_and_split "*<code>qi_ext<mode>_2_slp"
12702   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
12703         (any_logic:QI
12704           (subreg:QI
12705             (match_operator:SWI248 3 "extract_operator"
12706               [(match_operand 1 "int248_register_operand" "Q")
12707                (const_int 8)
12708                (const_int 8)]) 0)
12709           (subreg:QI
12710             (match_operator:SWI248 4 "extract_operator"
12711               [(match_operand 2 "int248_register_operand" "Q")
12712                (const_int 8)
12713                (const_int 8)]) 0)))
12714    (clobber (reg:CC FLAGS_REG))]
12715   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12716   "#"
12717   "&& reload_completed"
12718   [(set (strict_low_part (match_dup 0))
12719         (subreg:QI
12720           (match_op_dup 4
12721             [(match_dup 2) (const_int 8) (const_int 8)]) 0))
12722    (parallel
12723      [(set (strict_low_part (match_dup 0))
12724            (any_logic:QI
12725              (subreg:QI
12726                (match_op_dup 3
12727                  [(match_dup 1) (const_int 8) (const_int 8)]) 0)
12728              (match_dup 0)))
12729       (clobber (reg:CC FLAGS_REG))])]
12730   ""
12731   [(set_attr "type" "alu")
12732    (set_attr "mode" "QI")])
12734 (define_split
12735   [(set (match_operand:SWI248 0 "register_operand")
12736         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
12737                     (match_operand:SWI248 2 "const_int_operand")))
12738    (clobber (reg:CC FLAGS_REG))]
12739   "reload_completed
12740    && (!REG_P (operands[1])
12741        || REGNO (operands[0]) != REGNO (operands[1]))
12742    && (UINTVAL (operands[2]) == GET_MODE_MASK (SImode)
12743        || UINTVAL (operands[2]) == GET_MODE_MASK (HImode)
12744        || UINTVAL (operands[2]) == GET_MODE_MASK (QImode))"
12745   [(const_int 0)]
12747   unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
12748   machine_mode mode;
12750   if (ival == GET_MODE_MASK (SImode))
12751     mode = SImode;
12752   else if (ival == GET_MODE_MASK (HImode))
12753     mode = HImode;
12754   else if (ival == GET_MODE_MASK (QImode))
12755     mode = QImode;
12756   else
12757     gcc_unreachable ();
12759   /* Zero extend to SImode to avoid partial register stalls.  */
12760   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
12761     operands[0] = gen_lowpart (SImode, operands[0]);
12763   emit_insn (gen_extend_insn
12764              (operands[0], gen_lowpart (mode, operands[1]),
12765               GET_MODE (operands[0]), mode, 1));
12766   DONE;
12769 (define_split
12770   [(set (match_operand:SWI48 0 "register_operand")
12771         (and:SWI48 (match_dup 0)
12772                    (const_int -65536)))
12773    (clobber (reg:CC FLAGS_REG))]
12774   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
12775     || optimize_function_for_size_p (cfun)"
12776   [(set (strict_low_part (match_dup 1)) (const_int 0))]
12777   "operands[1] = gen_lowpart (HImode, operands[0]);")
12779 (define_split
12780   [(set (match_operand:SWI248 0 "any_QIreg_operand")
12781         (and:SWI248 (match_dup 0)
12782                     (const_int -256)))
12783    (clobber (reg:CC FLAGS_REG))]
12784   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12785    && reload_completed"
12786   [(set (strict_low_part (match_dup 1)) (const_int 0))]
12787   "operands[1] = gen_lowpart (QImode, operands[0]);")
12789 (define_split
12790   [(set (match_operand:SWI248 0 "QIreg_operand")
12791         (and:SWI248 (match_dup 0)
12792                     (const_int -65281)))
12793    (clobber (reg:CC FLAGS_REG))]
12794   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12795    && reload_completed"
12796   [(parallel
12797      [(set (zero_extract:HI (match_dup 0)
12798                             (const_int 8)
12799                             (const_int 8))
12800            (subreg:HI
12801              (xor:QI
12802                (subreg:QI
12803                  (zero_extract:HI (match_dup 0)
12804                                   (const_int 8)
12805                                   (const_int 8)) 0)
12806                (subreg:QI
12807                  (zero_extract:HI (match_dup 0)
12808                                   (const_int 8)
12809                                   (const_int 8)) 0)) 0))
12810       (clobber (reg:CC FLAGS_REG))])]
12811   "operands[0] = gen_lowpart (HImode, operands[0]);")
12813 (define_insn "*anddi_2"
12814   [(set (reg FLAGS_REG)
12815         (compare
12816          (and:DI
12817           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,r,rm,r")
12818           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,Z,re,m"))
12819          (const_int 0)))
12820    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,r,r")
12821         (and:DI (match_dup 1) (match_dup 2)))]
12822   "TARGET_64BIT
12823    && ix86_match_ccmode
12824         (insn,
12825          /* If we are going to emit andl instead of andq, and the operands[2]
12826             constant might have the SImode sign bit set, make sure the sign
12827             flag isn't tested, because the instruction will set the sign flag
12828             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
12829             conservatively assume it might have bit 31 set.  */
12830          (satisfies_constraint_Z (operands[2])
12831           && (!CONST_INT_P (operands[2])
12832               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
12833          ? CCZmode : CCNOmode)
12834    && ix86_binary_operator_ok (AND, DImode, operands, TARGET_APX_NDD)"
12835   "@
12836    and{l}\t{%k2, %k0|%k0, %k2}
12837    and{q}\t{%2, %0|%0, %2}
12838    and{q}\t{%2, %0|%0, %2}
12839    and{l}\t{%k2, %k1, %k0|%k0, %k1, %k2}
12840    and{q}\t{%2, %1, %0|%0, %1, %2}
12841    and{q}\t{%2, %1, %0|%0, %1, %2}"
12842   [(set_attr "type" "alu")
12843    (set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd")
12844    (set_attr "mode" "SI,DI,DI,SI,DI,DI")])
12846 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12847 (define_insn "*andsi_2_zext"
12848   [(set (reg FLAGS_REG)
12849         (compare (and:SI
12850                   (match_operand:SI 1 "nonimmediate_operand" "%0,rm,r")
12851                   (match_operand:SI 2 "x86_64_general_operand" "rBMe,re,BM"))
12852                  (const_int 0)))
12853    (set (match_operand:DI 0 "register_operand" "=r,r,r")
12854         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
12855   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12856    && ix86_binary_operator_ok (AND, SImode, operands, TARGET_APX_NDD)"
12857   "@
12858   and{l}\t{%2, %k0|%k0, %2}
12859   and{l}\t{%2, %1, %k0|%k0, %1, %2}
12860   and{l}\t{%2, %1, %k0|%k0, %1, %2}"
12861   [(set_attr "type" "alu")
12862    (set_attr "isa" "*,apx_ndd,apx_ndd")
12863    (set_attr "mode" "SI")])
12865 (define_insn "*andqi_2_maybe_si"
12866   [(set (reg FLAGS_REG)
12867         (compare (and:QI
12868                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r")
12869                   (match_operand:QI 2 "general_operand" "qn,m,n,rn,m"))
12870                  (const_int 0)))
12871    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r")
12872         (and:QI (match_dup 1) (match_dup 2)))]
12873   "ix86_binary_operator_ok (AND, QImode, operands, TARGET_APX_NDD)
12874    && ix86_match_ccmode (insn,
12875                          CONST_INT_P (operands[2])
12876                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
12878   if (get_attr_mode (insn) == MODE_SI)
12879     {
12880       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
12881         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
12882       return "and{l}\t{%2, %k0|%k0, %2}";
12883     }
12884   if (which_alternative > 2)
12885     return "and{b}\t{%2, %1, %0|%0, %1, %2}";
12886   return "and{b}\t{%2, %0|%0, %2}";
12888   [(set_attr "type" "alu")
12889    (set_attr "isa" "*,*,*,apx_ndd,apx_ndd")
12890    (set (attr "mode")
12891      (cond [(eq_attr "alternative" "3,4")
12892               (const_string "QI")
12893             (eq_attr "alternative" "2")
12894               (const_string "SI")
12895             (and (match_test "optimize_insn_for_size_p ()")
12896                  (and (match_operand 0 "ext_QIreg_operand")
12897                       (match_operand 2 "const_0_to_127_operand")))
12898               (const_string "SI")
12899            ]
12900            (const_string "QI")))
12901    ;; Potential partial reg stall on alternative 2.
12902    (set (attr "preferred_for_speed")
12903      (cond [(eq_attr "alternative" "2")
12904               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12905            (symbol_ref "true")))])
12907 (define_insn "*and<mode>_2"
12908   [(set (reg FLAGS_REG)
12909         (compare (and:SWI124
12910                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0,rm,r")
12911                   (match_operand:SWI124 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>"))
12912                  (const_int 0)))
12913    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
12914         (and:SWI124 (match_dup 1) (match_dup 2)))]
12915   "ix86_match_ccmode (insn, CCNOmode)
12916    && ix86_binary_operator_ok (AND, <MODE>mode, operands, TARGET_APX_NDD)"
12917   "@
12918   and{<imodesuffix>}\t{%2, %0|%0, %2}
12919   and{<imodesuffix>}\t{%2, %0|%0, %2}
12920   and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
12921   and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
12922   [(set_attr "type" "alu")
12923    (set_attr "isa" "*,*,apx_ndd,apx_ndd")
12924    (set_attr "mode" "<MODE>")])
12926 (define_insn "*<code>qi_ext<mode>_0"
12927   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
12928         (any_logic:QI
12929           (subreg:QI
12930             (match_operator:SWI248 3 "extract_operator"
12931               [(match_operand 2 "int248_register_operand" "Q")
12932                (const_int 8)
12933                (const_int 8)]) 0)
12934           (match_operand:QI 1 "nonimmediate_operand" "0")))
12935    (clobber (reg:CC FLAGS_REG))]
12936   ""
12937   "<logic>{b}\t{%h2, %0|%0, %h2}"
12938   [(set_attr "addr" "gpr8")
12939    (set_attr "type" "alu")
12940    (set_attr "mode" "QI")])
12942 (define_insn_and_split "*<code>qi_ext2<mode>_0"
12943   [(set (match_operand:QI 0 "register_operand" "=&Q")
12944         (any_logic:QI
12945           (subreg:QI
12946             (match_operator:SWI248 3 "extract_operator"
12947               [(match_operand 1 "int248_register_operand" "Q")
12948                (const_int 8)
12949                (const_int 8)]) 0)
12950           (subreg:QI
12951             (match_operator:SWI248 4 "extract_operator"
12952               [(match_operand 2 "int248_register_operand" "Q")
12953                (const_int 8)
12954                (const_int 8)]) 0)))
12955    (clobber (reg:CC FLAGS_REG))]
12956   ""
12957   "#"
12958   "&& reload_completed"
12959   [(set (match_dup 0)
12960         (subreg:QI
12961           (match_op_dup 4
12962             [(match_dup 2) (const_int 8) (const_int 8)]) 0))
12963    (parallel
12964      [(set (match_dup 0)
12965            (any_logic:QI
12966              (subreg:QI
12967                (match_op_dup 3
12968                  [(match_dup 1) (const_int 8) (const_int 8)]) 0)
12969            (match_dup 0)))
12970       (clobber (reg:CC FLAGS_REG))])]
12971   ""
12972   [(set_attr "type" "alu")
12973    (set_attr "mode" "QI")])
12975 (define_expand "andqi_ext_1"
12976   [(parallel
12977      [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
12978                             (const_int 8)
12979                             (const_int 8))
12980            (subreg:HI
12981              (and:QI
12982                (subreg:QI
12983                  (zero_extract:HI (match_operand:HI 1 "register_operand")
12984                                   (const_int 8)
12985                                   (const_int 8)) 0)
12986                (match_operand:QI 2 "const_int_operand")) 0))
12987       (clobber (reg:CC FLAGS_REG))])])
12989 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12990 (define_insn_and_split "*<code>qi_ext<mode>_1"
12991   [(set (zero_extract:SWI248
12992           (match_operand 0 "int248_register_operand" "+Q,&Q")
12993           (const_int 8)
12994           (const_int 8))
12995         (subreg:SWI248
12996           (any_logic:QI
12997             (subreg:QI
12998               (match_operator:SWI248 3 "extract_operator"
12999                 [(match_operand 1 "int248_register_operand" "0,!Q")
13000                  (const_int 8)
13001                  (const_int 8)]) 0)
13002             (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
13003    (clobber (reg:CC FLAGS_REG))]
13004   ""
13005   "@
13006    <logic>{b}\t{%2, %h0|%h0, %2}
13007    #"
13008   "reload_completed
13009    && !(rtx_equal_p (operands[0], operands[1]))"
13010   [(set (zero_extract:SWI248
13011           (match_dup 0) (const_int 8) (const_int 8))
13012         (zero_extract:SWI248
13013           (match_dup 1) (const_int 8) (const_int 8)))
13014    (parallel
13015      [(set (zero_extract:SWI248
13016              (match_dup 0) (const_int 8) (const_int 8))
13017            (subreg:SWI248
13018              (any_logic:QI
13019                (subreg:QI
13020                  (match_op_dup 3
13021                    [(match_dup 0) (const_int 8) (const_int 8)]) 0)
13022                (match_dup 2)) 0))
13023       (clobber (reg:CC FLAGS_REG))])]
13024   ""
13025   [(set_attr "addr" "gpr8")
13026    (set_attr "type" "alu")
13027    (set_attr "mode" "QI")])
13029 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13030 (define_insn_and_split "*<code>qi_ext<mode>_1_cc"
13031   [(set (match_operand 4 "flags_reg_operand")
13032         (match_operator 5 "compare_operator"
13033           [(any_logic:QI
13034              (subreg:QI
13035                (match_operator:SWI248 3 "extract_operator"
13036                  [(match_operand 1 "int248_register_operand" "0,!Q")
13037                   (const_int 8)
13038                   (const_int 8)]) 0)
13039              (match_operand:QI 2 "general_operand" "QnBn,QnBn"))
13040           (const_int 0)]))
13041    (set (zero_extract:SWI248
13042           (match_operand 0 "int248_register_operand" "+Q,&Q")
13043           (const_int 8)
13044           (const_int 8))
13045         (subreg:SWI248
13046           (any_logic:QI
13047             (subreg:QI
13048               (match_op_dup 3
13049                 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
13050             (match_dup 2)) 0))]
13051   "ix86_match_ccmode (insn, CCNOmode)"
13052   "@
13053    <logic>{b}\t{%2, %h0|%h0, %2}
13054    #"
13055   "&& reload_completed
13056    && !(rtx_equal_p (operands[0], operands[1]))"
13057   [(set (zero_extract:SWI248
13058           (match_dup 0) (const_int 8) (const_int 8))
13059         (zero_extract:SWI248
13060           (match_dup 1) (const_int 8) (const_int 8)))
13061    (parallel
13062      [(set (match_dup 4)
13063            (match_op_dup 5
13064              [(any_logic:QI
13065                 (subreg:QI
13066                   (match_op_dup 3
13067                     [(match_dup 0) (const_int 8) (const_int 8)]) 0)
13068                 (match_dup 2))
13069               (const_int 0)]))
13070       (set (zero_extract:SWI248
13071              (match_dup 0) (const_int 8) (const_int 8))
13072            (subreg:SWI248
13073              (any_logic:QI
13074                (subreg:QI
13075                  (match_op_dup 3
13076                    [(match_dup 1) (const_int 8) (const_int 8)]) 0)
13077                (match_dup 2)) 0))])]
13078   ""
13079   [(set_attr "addr" "gpr8")
13080    (set_attr "type" "alu")
13081    (set_attr "mode" "QI")])
13083 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13084 (define_insn_and_split "*<code>qi_ext<mode>_2"
13085   [(set (zero_extract:SWI248
13086           (match_operand 0 "int248_register_operand" "+Q,&Q")
13087           (const_int 8)
13088           (const_int 8))
13089         (subreg:SWI248
13090           (any_logic:QI
13091             (subreg:QI
13092               (match_operator:SWI248 3 "extract_operator"
13093                 [(match_operand 1 "int248_register_operand" "%0,!Q")
13094                  (const_int 8)
13095                  (const_int 8)]) 0)
13096             (subreg:QI
13097               (match_operator:SWI248 4 "extract_operator"
13098                 [(match_operand 2 "int248_register_operand" "Q,Q")
13099                  (const_int 8)
13100                  (const_int 8)]) 0)) 0))
13101    (clobber (reg:CC FLAGS_REG))]
13102   ""
13103   "@
13104    <logic>{b}\t{%h2, %h0|%h0, %h2}
13105    #"
13106   "reload_completed
13107    && !(rtx_equal_p (operands[0], operands[1])
13108         || rtx_equal_p (operands[0], operands[2]))"
13109   [(set (zero_extract:SWI248
13110           (match_dup 0) (const_int 8) (const_int 8))
13111         (zero_extract:SWI248
13112           (match_dup 1) (const_int 8) (const_int 8)))
13113    (parallel
13114      [(set (zero_extract:SWI248
13115              (match_dup 0) (const_int 8) (const_int 8))
13116            (subreg:SWI248
13117              (any_logic:QI
13118                (subreg:QI
13119                  (match_op_dup 3
13120                    [(match_dup 0) (const_int 8) (const_int 8)]) 0)
13121                (subreg:QI
13122                  (match_op_dup 4
13123                    [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
13124       (clobber (reg:CC FLAGS_REG))])]
13125   ""
13126   [(set_attr "type" "alu")
13127    (set_attr "mode" "QI")])
13129 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13130 (define_insn_and_split "*<code>qi_ext<mode>_3"
13131   [(set (zero_extract:SWI248
13132           (match_operand 0 "int248_register_operand" "+Q,&Q")
13133           (const_int 8)
13134           (const_int 8))
13135         (match_operator:SWI248 3 "extract_operator"
13136           [(any_logic
13137              (match_operand 1 "int248_register_operand" "%0,!Q")
13138              (match_operand 2 "int248_register_operand" "Q,Q"))
13139            (const_int 8)
13140            (const_int 8)]))
13141    (clobber (reg:CC FLAGS_REG))]
13142   "GET_MODE (operands[1]) == GET_MODE (operands[2])"
13143   "@
13144    <logic>{b}\t{%h2, %h0|%h0, %h2}
13145    #"
13146   "&& reload_completed
13147    && !(rtx_equal_p (operands[0], operands[1])
13148         || rtx_equal_p (operands[0], operands[2]))"
13149   [(set (zero_extract:SWI248
13150           (match_dup 0) (const_int 8) (const_int 8))
13151         (zero_extract:SWI248
13152           (match_dup 1) (const_int 8) (const_int 8)))
13153    (parallel
13154      [(set (zero_extract:SWI248
13155              (match_dup 0) (const_int 8) (const_int 8))
13156            (match_op_dup 3
13157              [(any_logic (match_dup 4) (match_dup 2))
13158               (const_int 8) (const_int 8)]))
13159       (clobber (reg:CC FLAGS_REG))])]
13160   "operands[4] = gen_lowpart (GET_MODE (operands[1]), operands[0]);"
13161   [(set_attr "type" "alu")
13162    (set_attr "mode" "QI")])
13164 ;; Convert wide AND instructions with immediate operand to shorter QImode
13165 ;; equivalents when possible.
13166 ;; Don't do the splitting with memory operands, since it introduces risk
13167 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
13168 ;; for size, but that can (should?) be handled by generic code instead.
13169 ;; Don't do the splitting for APX NDD as NDD does not support *h registers.
13170 (define_split
13171   [(set (match_operand:SWI248 0 "QIreg_operand")
13172         (and:SWI248 (match_operand:SWI248 1 "register_operand")
13173                     (match_operand:SWI248 2 "const_int_operand")))
13174    (clobber (reg:CC FLAGS_REG))]
13175    "reload_completed
13176     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13177     && !(~INTVAL (operands[2]) & ~(255 << 8))
13178     && !(TARGET_APX_NDD && REGNO (operands[0]) != REGNO (operands[1]))"
13179   [(parallel
13180      [(set (zero_extract:HI (match_dup 0)
13181                             (const_int 8)
13182                             (const_int 8))
13183            (subreg:HI
13184              (and:QI
13185                (subreg:QI
13186                  (zero_extract:HI (match_dup 1)
13187                                   (const_int 8)
13188                                   (const_int 8)) 0)
13189                (match_dup 2)) 0))
13190       (clobber (reg:CC FLAGS_REG))])]
13192   operands[0] = gen_lowpart (HImode, operands[0]);
13193   operands[1] = gen_lowpart (HImode, operands[1]);
13194   operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
13197 ;; Since AND can be encoded with sign extended immediate, this is only
13198 ;; profitable when 7th bit is not set.
13199 (define_split
13200   [(set (match_operand:SWI248 0 "any_QIreg_operand")
13201         (and:SWI248 (match_operand:SWI248 1 "general_operand")
13202                     (match_operand:SWI248 2 "const_int_operand")))
13203    (clobber (reg:CC FLAGS_REG))]
13204    "reload_completed
13205     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13206     && !(~INTVAL (operands[2]) & ~255)
13207     && !(INTVAL (operands[2]) & 128)
13208     && !(TARGET_APX_NDD
13209          && !rtx_equal_p (operands[0], operands[1]))"
13210   [(parallel [(set (strict_low_part (match_dup 0))
13211                    (and:QI (match_dup 1)
13212                            (match_dup 2)))
13213               (clobber (reg:CC FLAGS_REG))])]
13215   operands[0] = gen_lowpart (QImode, operands[0]);
13216   operands[1] = gen_lowpart (QImode, operands[1]);
13217   operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
13220 (define_insn_and_split "*andn<dwi>3_doubleword_bmi"
13221   [(set (match_operand:<DWI> 0 "register_operand" "=&r,&r,r,r")
13222         (and:<DWI>
13223           (not:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r,0,r"))
13224           (match_operand:<DWI> 2 "nonimmediate_operand" "r,o,ro,0")))
13225    (clobber (reg:CC FLAGS_REG))]
13226   "TARGET_BMI"
13227   "#"
13228   "&& reload_completed"
13229   [(parallel [(set (match_dup 0)
13230                    (and:DWIH (not:DWIH (match_dup 1)) (match_dup 2)))
13231               (clobber (reg:CC FLAGS_REG))])
13232    (parallel [(set (match_dup 3)
13233                    (and:DWIH (not:DWIH (match_dup 4)) (match_dup 5)))
13234               (clobber (reg:CC FLAGS_REG))])]
13235   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);"
13236   [(set_attr "isa" "x64,*,*,*")])
13238 (define_insn_and_split "*andn<mode>3_doubleword"
13239   [(set (match_operand:DWI 0 "register_operand")
13240         (and:DWI
13241           (not:DWI (match_operand:DWI 1 "register_operand"))
13242           (match_operand:DWI 2 "nonimmediate_operand")))
13243    (clobber (reg:CC FLAGS_REG))]
13244   "!TARGET_BMI
13245    && ix86_pre_reload_split ()"
13246   "#"
13247   "&& 1"
13248   [(set (match_dup 3) (not:DWI (match_dup 1)))
13249    (parallel [(set (match_dup 0)
13250                    (and:DWI (match_dup 3) (match_dup 2)))
13251               (clobber (reg:CC FLAGS_REG))])]
13252   "operands[3] = gen_reg_rtx (<MODE>mode);")
13254 (define_insn "*andn<mode>_1"
13255   [(set (match_operand:SWI48 0 "register_operand" "=r,r,?k")
13256         (and:SWI48
13257           (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r,k"))
13258           (match_operand:SWI48 2 "nonimmediate_operand" "r,m,k")))
13259    (clobber (reg:CC FLAGS_REG))]
13260   "TARGET_BMI || TARGET_AVX512BW"
13261   "@
13262    andn\t{%2, %1, %0|%0, %1, %2}
13263    andn\t{%2, %1, %0|%0, %1, %2}
13264    #"
13265   [(set_attr "isa" "bmi,bmi,avx512bw")
13266    (set_attr "type" "bitmanip,bitmanip,msklog")
13267    (set_attr "btver2_decode" "direct, double,*")
13268    (set_attr "mode" "<MODE>")])
13270 (define_insn "*andn<mode>_1"
13271   [(set (match_operand:SWI12 0 "register_operand" "=r,?k")
13272         (and:SWI12
13273           (not:SWI12 (match_operand:SWI12 1 "register_operand" "r,k"))
13274           (match_operand:SWI12 2 "register_operand" "r,k")))
13275    (clobber (reg:CC FLAGS_REG))]
13276   "TARGET_BMI || TARGET_AVX512BW"
13277   "@
13278    andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
13279    #"
13280   [(set_attr "isa" "bmi,avx512f")
13281    (set_attr "type" "bitmanip,msklog")
13282    (set_attr "btver2_decode" "direct,*")
13283    (set (attr "mode")
13284         (cond [(eq_attr "alternative" "0")
13285                  (const_string "SI")
13286                (and (eq_attr "alternative" "1")
13287                     (match_test "!TARGET_AVX512DQ"))
13288                   (const_string "HI")
13289               ]
13290               (const_string "<MODE>")))])
13292 (define_insn "*andn_<mode>_ccno"
13293   [(set (reg FLAGS_REG)
13294         (compare
13295           (and:SWI48
13296             (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
13297             (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
13298           (const_int 0)))
13299    (clobber (match_scratch:SWI48 0 "=r,r"))]
13300   "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
13301   "andn\t{%2, %1, %0|%0, %1, %2}"
13302   [(set_attr "type" "bitmanip")
13303    (set_attr "btver2_decode" "direct, double")
13304    (set_attr "mode" "<MODE>")])
13306 ;; Split *andnsi_1 after reload with -Oz when not;and is shorter.
13307 (define_split
13308   [(set (match_operand:SI 0 "register_operand")
13309         (and:SI (not:SI (match_operand:SI 1 "register_operand"))
13310                 (match_operand:SI 2 "nonimmediate_operand")))
13311    (clobber (reg:CC FLAGS_REG))]
13312   "reload_completed
13313    && optimize_insn_for_size_p () && optimize_size > 1
13314    && REGNO (operands[0]) == REGNO (operands[1])
13315    && LEGACY_INT_REG_P (operands[0])
13316    && !REX_INT_REG_P (operands[2])
13317    && !reg_overlap_mentioned_p (operands[0], operands[2])"
13318   [(set (match_dup 0) (not:SI (match_dup 1)))
13319    (parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
13320               (clobber (reg:CC FLAGS_REG))])])
13322 ;; Split *andn_si_ccno with -Oz when not;test is shorter.
13323 (define_split
13324   [(set (match_operand 0 "flags_reg_operand")
13325         (match_operator 1 "compare_operator"
13326           [(and:SI (not:SI (match_operand:SI 2 "general_reg_operand"))
13327                    (match_operand:SI 3 "nonimmediate_operand"))
13328            (const_int 0)]))
13329    (clobber (match_dup 2))]
13330   "reload_completed
13331    && optimize_insn_for_size_p () && optimize_size > 1
13332    && LEGACY_INT_REG_P (operands[2])
13333    && !REX_INT_REG_P (operands[3])
13334    && !reg_overlap_mentioned_p (operands[2], operands[3])"
13335   [(set (match_dup 2) (not:SI (match_dup 2)))
13336    (set (match_dup 0) (match_op_dup 1
13337                         [(and:SI (match_dup 3) (match_dup 2))
13338                          (const_int 0)]))])
13340 ;; Variant 1 of 4: Split ((A | B) ^ A) ^ C as (B & ~A) ^ C.
13341 (define_split
13342   [(set (match_operand:SWI48 0 "register_operand")
13343         (xor:SWI48
13344            (xor:SWI48
13345               (ior:SWI48 (match_operand:SWI48 1 "register_operand")
13346                          (match_operand:SWI48 2 "nonimmediate_operand"))
13347               (match_dup 1))
13348            (match_operand:SWI48 3 "nonimmediate_operand")))
13349    (clobber (reg:CC FLAGS_REG))]
13350   "TARGET_BMI"
13351   [(parallel
13352       [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
13353        (clobber (reg:CC FLAGS_REG))])
13354    (parallel
13355       [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
13356        (clobber (reg:CC FLAGS_REG))])]
13357   "operands[4] = gen_reg_rtx (<MODE>mode);")
13359 ;; Variant 2 of 4: Split ((A | B) ^ B) ^ C as (A & ~B) ^ C.
13360 (define_split
13361   [(set (match_operand:SWI48 0 "register_operand")
13362         (xor:SWI48
13363            (xor:SWI48
13364               (ior:SWI48 (match_operand:SWI48 1 "register_operand")
13365                          (match_operand:SWI48 2 "register_operand"))
13366               (match_dup 2))
13367            (match_operand:SWI48 3 "nonimmediate_operand")))
13368    (clobber (reg:CC FLAGS_REG))]
13369   "TARGET_BMI"
13370   [(parallel
13371       [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
13372        (clobber (reg:CC FLAGS_REG))])
13373    (parallel
13374       [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
13375        (clobber (reg:CC FLAGS_REG))])]
13376   "operands[4] = gen_reg_rtx (<MODE>mode);")
13378 ;; Variant 3 of 4: Split ((A | B) ^ C) ^ A as (B & ~A) ^ C.
13379 (define_split
13380   [(set (match_operand:SWI48 0 "register_operand")
13381         (xor:SWI48
13382            (xor:SWI48
13383               (ior:SWI48 (match_operand:SWI48 1 "register_operand")
13384                          (match_operand:SWI48 2 "nonimmediate_operand"))
13385               (match_operand:SWI48 3 "nonimmediate_operand"))
13386            (match_dup 1)))
13387    (clobber (reg:CC FLAGS_REG))]
13388   "TARGET_BMI"
13389   [(parallel
13390       [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
13391        (clobber (reg:CC FLAGS_REG))])
13392    (parallel
13393       [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
13394        (clobber (reg:CC FLAGS_REG))])]
13395   "operands[4] = gen_reg_rtx (<MODE>mode);")
13397 ;; Variant 4 of 4: Split ((A | B) ^ C) ^ B as (A & ~B) ^ C.
13398 (define_split
13399   [(set (match_operand:SWI48 0 "register_operand")
13400         (xor:SWI48
13401            (xor:SWI48
13402               (ior:SWI48 (match_operand:SWI48 1 "register_operand")
13403                          (match_operand:SWI48 2 "register_operand"))
13404               (match_operand:SWI48 3 "nonimmediate_operand"))
13405            (match_dup 2)))
13406    (clobber (reg:CC FLAGS_REG))]
13407   "TARGET_BMI"
13408   [(parallel
13409       [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
13410        (clobber (reg:CC FLAGS_REG))])
13411    (parallel
13412       [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
13413        (clobber (reg:CC FLAGS_REG))])]
13414   "operands[4] = gen_reg_rtx (<MODE>mode);")
13416 ;; Logical inclusive and exclusive OR instructions
13418 ;; %%% This used to optimize known byte-wide and operations to memory.
13419 ;; If this is considered useful, it should be done with splitters.
13421 (define_expand "<code><mode>3"
13422   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
13423         (any_or:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
13424                       (match_operand:SDWIM 2 "<general_operand>")))]
13425   ""
13427   if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
13428       && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
13429     operands[2] = force_reg (<MODE>mode, operands[2]);
13431   ix86_expand_binary_operator (<CODE>, <MODE>mode, operands, TARGET_APX_NDD);
13432   DONE;
13435 (define_insn_and_split "*<code><dwi>3_doubleword"
13436   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r,&r,&r,&r")
13437         (any_or:<DWI>
13438          (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r,ro,jO,r")
13439          (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r,<di>,K,<di>,o")))
13440    (clobber (reg:CC FLAGS_REG))]
13441   "ix86_binary_operator_ok (<CODE>, <DWI>mode, operands, TARGET_APX_NDD)"
13442   "#"
13443   "&& reload_completed"
13444   [(const_int:DWIH 0)]
13446   /* This insn may disappear completely when operands[2] == const0_rtx
13447      and operands[0] == operands[1], which requires a NOTE_INSN_DELETED.  */
13448   bool emit_insn_deleted_note_p = false;
13450   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13452   if (operands[2] == const0_rtx)
13453     {
13454       if (!rtx_equal_p (operands[0], operands[1]))
13455         emit_move_insn (operands[0], operands[1]);
13456       else
13457         emit_insn_deleted_note_p = true;
13458     }
13459   else if (operands[2] == constm1_rtx)
13460     {
13461       if (<CODE> == IOR)
13462         emit_move_insn (operands[0], constm1_rtx);
13463       else
13464         ix86_expand_unary_operator (NOT, <MODE>mode, &operands[0],
13465                                     TARGET_APX_NDD);
13466     }
13467   else
13468     ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[0],
13469                                  TARGET_APX_NDD);
13471   if (operands[5] == const0_rtx)
13472     {
13473       if (!rtx_equal_p (operands[3], operands[4]))
13474         emit_move_insn (operands[3], operands[4]);
13475       else if (emit_insn_deleted_note_p)
13476         emit_note (NOTE_INSN_DELETED);
13477     }
13478   else if (operands[5] == constm1_rtx)
13479     {
13480       if (<CODE> == IOR)
13481         emit_move_insn (operands[3], constm1_rtx);
13482       else
13483         ix86_expand_unary_operator (NOT, <MODE>mode, &operands[3],
13484                                     TARGET_APX_NDD);
13485     }
13486   else
13487     ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[3],
13488                                  TARGET_APX_NDD);
13490   DONE;
13492 [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd_64,apx_ndd")])
13494 (define_insn "*<code><mode>_1<nf_name>"
13495   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r<nf_mem_constraint>,r,r,r,r,?k")
13496         (any_or:SWI248
13497          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,0,rm,rjM,r,k")
13498          (match_operand:SWI248 2 "<general_operand>" "r,<i>,<m>,r,<i>,<m>,k")))]
13499   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)
13500    && <nf_condition>"
13501   "@
13502    <nf_prefix><logic>{<imodesuffix>}\t{%2, %0|%0, %2}
13503    <nf_prefix><logic>{<imodesuffix>}\t{%2, %0|%0, %2}
13504    <nf_prefix><logic>{<imodesuffix>}\t{%2, %0|%0, %2}
13505    <nf_prefix><logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
13506    <nf_prefix><logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
13507    <nf_prefix><logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
13508    #"
13509   [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd,<kmov_isa>")
13510    (set_attr "type" "alu,alu, alu, alu, alu, alu, msklog")
13511    (set_attr "has_nf" "1")
13512    (set_attr "mode" "<MODE>")])
13514 (define_insn_and_split "*notxor<mode>_1"
13515   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,r,r,?k")
13516         (not:SWI248
13517           (xor:SWI248
13518             (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,rm,r,k")
13519             (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,r<i>,<m>,k"))))
13520    (clobber (reg:CC FLAGS_REG))]
13521   "ix86_binary_operator_ok (XOR, <MODE>mode, operands, TARGET_APX_NDD)"
13522   "#"
13523   "&& reload_completed"
13524   [(parallel
13525     [(set (match_dup 0)
13526           (xor:SWI248 (match_dup 1) (match_dup 2)))
13527      (clobber (reg:CC FLAGS_REG))])
13528    (set (match_dup 0)
13529         (not:SWI248 (match_dup 0)))]
13531   if (MASK_REG_P (operands[0]))
13532     {
13533       emit_insn (gen_kxnor<mode> (operands[0], operands[1], operands[2]));
13534       DONE;
13535     }
13537   [(set_attr "isa" "*,*,apx_ndd,apx_ndd,<kmov_isa>")
13538    (set_attr "type" "alu, alu, alu, alu, msklog")
13539    (set_attr "mode" "<MODE>")])
13541 (define_insn_and_split "*iordi_1_bts"
13542   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13543         (ior:DI
13544          (match_operand:DI 1 "nonimmediate_operand" "%0")
13545          (match_operand:DI 2 "const_int_operand" "n")))
13546    (clobber (reg:CC FLAGS_REG))]
13547   "TARGET_64BIT && TARGET_USE_BT
13548    && ix86_binary_operator_ok (IOR, DImode, operands)
13549    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
13550   "#"
13551   "&& reload_completed"
13552   [(parallel [(set (zero_extract:DI (match_dup 0)
13553                                     (const_int 1)
13554                                     (match_dup 3))
13555                    (const_int 1))
13556               (clobber (reg:CC FLAGS_REG))])]
13557   "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
13558   [(set_attr "type" "alu1")
13559    (set_attr "prefix_0f" "1")
13560    (set_attr "znver1_decode" "double")
13561    (set_attr "mode" "DI")])
13563 (define_insn_and_split "*xordi_1_btc"
13564   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13565         (xor:DI
13566          (match_operand:DI 1 "nonimmediate_operand" "%0")
13567          (match_operand:DI 2 "const_int_operand" "n")))
13568    (clobber (reg:CC FLAGS_REG))]
13569   "TARGET_64BIT && TARGET_USE_BT
13570    && ix86_binary_operator_ok (XOR, DImode, operands)
13571    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
13572   "#"
13573   "&& reload_completed"
13574   [(parallel [(set (zero_extract:DI (match_dup 0)
13575                                     (const_int 1)
13576                                     (match_dup 3))
13577                    (not:DI (zero_extract:DI (match_dup 0)
13578                                             (const_int 1)
13579                                             (match_dup 3))))
13580               (clobber (reg:CC FLAGS_REG))])]
13581   "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
13582   [(set_attr "type" "alu1")
13583    (set_attr "prefix_0f" "1")
13584    (set_attr "znver1_decode" "double")
13585    (set_attr "mode" "DI")])
13587 ;; Optimize a ^ ((a ^ b) & mask) to (~mask & a) | (b & mask)
13588 (define_insn_and_split "*xor2andn"
13589   [(set (match_operand:SWI248 0 "register_operand")
13590         (xor:SWI248
13591           (and:SWI248
13592             (xor:SWI248
13593               (match_operand:SWI248 1 "nonimmediate_operand")
13594               (match_operand:SWI248 2 "nonimmediate_operand"))
13595             (match_operand:SWI248 3 "nonimmediate_operand"))
13596           (match_dup 1)))
13597     (clobber (reg:CC FLAGS_REG))]
13598   "TARGET_BMI && ix86_pre_reload_split ()"
13599   "#"
13600   "&& 1"
13601   [(parallel [(set (match_dup 4)
13602                 (and:SWI248
13603                   (not:SWI248
13604                     (match_dup 3))
13605                   (match_dup 1)))
13606               (clobber (reg:CC FLAGS_REG))])
13607    (parallel [(set (match_dup 5)
13608                 (and:SWI248
13609                   (match_dup 3)
13610                   (match_dup 2)))
13611               (clobber (reg:CC FLAGS_REG))])
13612    (parallel [(set (match_dup 0)
13613                 (ior:SWI248
13614                   (match_dup 4)
13615                   (match_dup 5)))
13616               (clobber (reg:CC FLAGS_REG))])]
13618   operands[1] = force_reg (<MODE>mode, operands[1]);
13619   operands[3] = force_reg (<MODE>mode, operands[3]);
13620   operands[4] = gen_reg_rtx (<MODE>mode);
13621   operands[5] = gen_reg_rtx (<MODE>mode);
13624 (define_insn "*<code>qi_1_zext<mode><nf_name>"
13625   [(set (match_operand:SWI248x 0 "register_operand" "=r,r")
13626         (zero_extend:SWI248x
13627          (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%rm,r")
13628                     (match_operand:QI 2 "x86_64_general_operand" "rn,m"))))]
13629   "TARGET_APX_NDD && <nf_condition>
13630    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13631   "@
13632   <nf_prefix><logic>{b}\t{%2, %1, %b0|%b0, %1, %2}
13633   <nf_prefix><logic>{b}\t{%2, %1, %b0|%b0, %1, %2}"
13634   [(set_attr "type" "alu")
13635    (set_attr "has_nf" "1")
13636    (set_attr "mode" "QI")])
13638 (define_insn "*<code>hi_1_zext<mode><nf_name>"
13639   [(set (match_operand:SWI48x 0 "register_operand" "=r,r")
13640         (zero_extend:SWI48x
13641          (any_or:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,r")
13642                     (match_operand:HI 2 "x86_64_general_operand" "rn,m"))))]
13643   "TARGET_APX_NDD && <nf_condition>
13644    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13645   "@
13646   <nf_prefix><logic>{w}\t{%2, %1, %w0|%w0, %1, %2}
13647   <nf_prefix><logic>{w}\t{%2, %1, %w0|%w0, %1, %2}"
13648   [(set_attr "type" "alu")
13649    (set_attr "has_nf" "1")
13650    (set_attr "mode" "HI")])
13652 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
13653 (define_insn "*<code>si_1_zext"
13654   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
13655         (zero_extend:DI
13656          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm,rjM,r")
13657                     (match_operand:SI 2 "x86_64_general_operand" "rBMe,r,e,BM"))))
13658    (clobber (reg:CC FLAGS_REG))]
13659   "TARGET_64BIT
13660    && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
13661   "@
13662   <logic>{l}\t{%2, %k0|%k0, %2}
13663   <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}
13664   <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}
13665   <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}"
13666   [(set_attr "type" "alu")
13667    (set_attr "isa" "*,apx_ndd,apx_ndd,apx_ndd")
13668    (set_attr "mode" "SI")])
13670 (define_insn "*<code>si_1_zext_imm"
13671   [(set (match_operand:DI 0 "register_operand" "=r,r")
13672         (any_or:DI
13673          (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0,rm"))
13674          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z,Z")))
13675    (clobber (reg:CC FLAGS_REG))]
13676   "TARGET_64BIT
13677    && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
13678   "@
13679   <logic>{l}\t{%2, %k0|%k0, %2}
13680   <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}"
13681   [(set_attr "type" "alu")
13682    (set_attr "isa" "*,apx_ndd")
13683    (set_attr "mode" "SI")])
13685 (define_insn "*<code>qi_1<nf_name>"
13686   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r,?k")
13687         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r,k")
13688                    (match_operand:QI 2 "general_operand" "qn,m,rn,rn,m,k")))]
13689   "ix86_binary_operator_ok (<CODE>, QImode, operands, TARGET_APX_NDD)
13690    && <nf_condition>"
13691   "@
13692    <nf_prefix><logic>{b}\t{%2, %0|%0, %2}
13693    <nf_prefix><logic>{b}\t{%2, %0|%0, %2}
13694    <nf_prefix><logic>{l}\t{%k2, %k0|%k0, %k2}
13695    <nf_prefix><logic>{b}\t{%2, %1, %0|%0, %1, %2}
13696    <nf_prefix><logic>{b}\t{%2, %1, %0|%0, %1, %2}
13697    #"
13698   [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,avx512f")
13699    (set_attr "type" "alu,alu,alu,alu,alu,msklog")
13700    (set_attr "has_nf" "1")
13701    (set (attr "mode")
13702         (cond [(eq_attr "alternative" "2")
13703                  (const_string "SI")
13704                 (and (eq_attr "alternative" "5")
13705                      (match_test "!TARGET_AVX512DQ"))
13706                  (const_string "HI")
13707                ]
13708                (const_string "QI")))
13709    ;; Potential partial reg stall on alternative 2.
13710    (set (attr "preferred_for_speed")
13711      (cond [(eq_attr "alternative" "2")
13712               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
13713            (symbol_ref "true")))])
13715 (define_insn_and_split "*notxorqi_1"
13716   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r,?k")
13717         (not:QI
13718           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r,k")
13719                   (match_operand:QI 2 "general_operand" "qn,m,rn,rn,m,k"))))
13720    (clobber (reg:CC FLAGS_REG))]
13721   "ix86_binary_operator_ok (XOR, QImode, operands, TARGET_APX_NDD)"
13722   "#"
13723   "&& reload_completed"
13724   [(parallel
13725     [(set (match_dup 0)
13726           (xor:QI (match_dup 1) (match_dup 2)))
13727      (clobber (reg:CC FLAGS_REG))])
13728    (set (match_dup 0)
13729         (not:QI (match_dup 0)))]
13731   if (mask_reg_operand (operands[0], QImode))
13732     {
13733       emit_insn (gen_kxnorqi (operands[0], operands[1], operands[2]));
13734       DONE;
13735     }
13737   [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,avx512f")
13738    (set_attr "type" "alu,alu,alu,alu,alu,msklog")
13739    (set (attr "mode")
13740         (cond [(eq_attr "alternative" "2")
13741                  (const_string "SI")
13742                 (and (eq_attr "alternative" "5")
13743                      (match_test "!TARGET_AVX512DQ"))
13744                  (const_string "HI")
13745                ]
13746                (const_string "QI")))
13747    ;; Potential partial reg stall on alternative 2.
13748    (set (attr "preferred_for_speed")
13749      (cond [(eq_attr "alternative" "2")
13750               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
13751            (symbol_ref "true")))])
13753 ;; convert (sign_extend:WIDE (any_logic:NARROW (memory, immediate)))
13754 ;; to (any_logic:WIDE (sign_extend (memory)), (sign_extend (immediate))).
13755 ;; This eliminates sign extension after logic operation.
13757 (define_split
13758   [(set (match_operand:SWI248 0 "register_operand")
13759         (sign_extend:SWI248
13760           (any_logic:QI (match_operand:QI 1 "memory_operand")
13761                         (match_operand:QI 2 "const_int_operand"))))]
13762   ""
13763   [(set (match_dup 3) (sign_extend:SWI248 (match_dup 1)))
13764    (set (match_dup 0) (any_logic:SWI248 (match_dup 3) (match_dup 2)))]
13765   "operands[3] = gen_reg_rtx (<MODE>mode);")
13767 (define_split
13768   [(set (match_operand:SWI48 0 "register_operand")
13769         (sign_extend:SWI48
13770           (any_logic:HI (match_operand:HI 1 "memory_operand")
13771                         (match_operand:HI 2 "const_int_operand"))))]
13772   ""
13773   [(set (match_dup 3) (sign_extend:SWI48 (match_dup 1)))
13774    (set (match_dup 0) (any_logic:SWI48 (match_dup 3) (match_dup 2)))]
13775   "operands[3] = gen_reg_rtx (<MODE>mode);")
13777 (define_split
13778   [(set (match_operand:DI 0 "register_operand")
13779         (sign_extend:DI
13780           (any_logic:SI (match_operand:SI 1 "memory_operand")
13781                         (match_operand:SI 2 "const_int_operand"))))]
13782   "TARGET_64BIT"
13783   [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
13784    (set (match_dup 0) (any_logic:DI (match_dup 3) (match_dup 2)))]
13785   "operands[3] = gen_reg_rtx (DImode);")
13787 (define_insn "*<code><mode>_2"
13788   [(set (reg FLAGS_REG)
13789         (compare (any_or:SWI
13790                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r")
13791                   (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>"))
13792                  (const_int 0)))
13793    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
13794         (any_or:SWI (match_dup 1) (match_dup 2)))]
13795   "ix86_match_ccmode (insn, CCNOmode)
13796    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)"
13797   "@
13798   <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
13799   <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
13800   <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
13801   <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
13802   [(set_attr "type" "alu")
13803    (set_attr "isa" "*,*,apx_ndd,apx_ndd")
13804    (set_attr "mode" "<MODE>")])
13806 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
13807 ;; ??? Special case for immediate operand is missing - it is tricky.
13808 (define_insn "*<code>si_2_zext"
13809   [(set (reg FLAGS_REG)
13810         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm,r")
13811                             (match_operand:SI 2 "x86_64_general_operand" "rBMe,re,BM"))
13812                  (const_int 0)))
13813    (set (match_operand:DI 0 "register_operand" "=r,r,r")
13814         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
13815   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
13816    && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
13817   "@
13818   <logic>{l}\t{%2, %k0|%k0, %2}
13819   <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}
13820   <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}"
13821   [(set_attr "type" "alu")
13822    (set_attr "isa" "*,apx_ndd,apx_ndd")
13823    (set_attr "mode" "SI")])
13825 (define_insn "*<code>si_2_zext_imm"
13826   [(set (reg FLAGS_REG)
13827         (compare (any_or:SI
13828                   (match_operand:SI 1 "nonimmediate_operand" "%0,rm")
13829                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z,Z"))
13830                  (const_int 0)))
13831    (set (match_operand:DI 0 "register_operand" "=r,r")
13832         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13833   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
13834    && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
13835   "@
13836   <logic>{l}\t{%2, %k0|%k0, %2}
13837   <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}"
13838   [(set_attr "type" "alu")
13839    (set_attr "isa" "*,apx_ndd")
13840    (set_attr "mode" "SI")])
13842 (define_insn "*<code><mode>_3"
13843   [(set (reg FLAGS_REG)
13844         (compare (any_or:SWI
13845                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
13846                   (match_operand:SWI 2 "<general_operand>" "<g>"))
13847                  (const_int 0)))
13848    (clobber (match_scratch:SWI 0 "=<r>"))]
13849   "ix86_match_ccmode (insn, CCNOmode)
13850    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13851   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
13852   [(set_attr "type" "alu")
13853    (set_attr "mode" "<MODE>")])
13855 ;; Convert wide OR instructions with immediate operand to shorter QImode
13856 ;; equivalents when possible.
13857 ;; Don't do the splitting with memory operands, since it introduces risk
13858 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
13859 ;; for size, but that can (should?) be handled by generic code instead.
13860 ;; Don't do the splitting for APX NDD as NDD does not support *h registers.
13861 (define_split
13862   [(set (match_operand:SWI248 0 "QIreg_operand")
13863         (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
13864                        (match_operand:SWI248 2 "const_int_operand")))
13865    (clobber (reg:CC FLAGS_REG))]
13866    "reload_completed
13867     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13868     && !(INTVAL (operands[2]) & ~(255 << 8))
13869     && !(TARGET_APX_NDD && REGNO (operands[0]) != REGNO (operands[1]))"
13870   [(parallel
13871      [(set (zero_extract:HI (match_dup 0)
13872                             (const_int 8)
13873                             (const_int 8))
13874            (subreg:HI
13875              (any_or:QI
13876                (subreg:QI
13877                  (zero_extract:HI (match_dup 1)
13878                                   (const_int 8)
13879                                   (const_int 8)) 0)
13880                (match_dup 2)) 0))
13881       (clobber (reg:CC FLAGS_REG))])]
13883   /* Handle the case where INTVAL (operands[2]) == 0.  */
13884   if (operands[2] == const0_rtx)
13885     {
13886       if (!rtx_equal_p (operands[0], operands[1]))
13887         emit_move_insn (operands[0], operands[1]);
13888       else
13889         emit_note (NOTE_INSN_DELETED);
13890       DONE;
13891     }
13892   operands[0] = gen_lowpart (HImode, operands[0]);
13893   operands[1] = gen_lowpart (HImode, operands[1]);
13894   operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
13897 ;; Since OR can be encoded with sign extended immediate, this is only
13898 ;; profitable when 7th bit is set.
13899 (define_split
13900   [(set (match_operand:SWI248 0 "any_QIreg_operand")
13901         (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
13902                        (match_operand:SWI248 2 "const_int_operand")))
13903    (clobber (reg:CC FLAGS_REG))]
13904    "reload_completed
13905     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13906     && !(INTVAL (operands[2]) & ~255)
13907     && (INTVAL (operands[2]) & 128)
13908     && !(TARGET_APX_NDD
13909          && !rtx_equal_p (operands[0], operands[1]))"
13910   [(parallel [(set (strict_low_part (match_dup 0))
13911                    (any_or:QI (match_dup 1)
13912                               (match_dup 2)))
13913               (clobber (reg:CC FLAGS_REG))])]
13915   operands[0] = gen_lowpart (QImode, operands[0]);
13916   operands[1] = gen_lowpart (QImode, operands[1]);
13917   operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
13920 (define_expand "xorqi_ext_1_cc"
13921   [(parallel
13922      [(set (reg:CCNO FLAGS_REG)
13923            (compare:CCNO
13924              (xor:QI
13925                (subreg:QI
13926                  (zero_extract:HI (match_operand:HI 1 "register_operand")
13927                                   (const_int 8)
13928                                   (const_int 8)) 0)
13929                (match_operand:QI 2 "const_int_operand"))
13930              (const_int 0)))
13931       (set (zero_extract:HI (match_operand:HI 0 "register_operand")
13932                             (const_int 8)
13933                             (const_int 8))
13934            (subreg:HI
13935              (xor:QI
13936                (subreg:QI
13937                  (zero_extract:HI (match_dup 1)
13938                                   (const_int 8)
13939                                   (const_int 8)) 0)
13940              (match_dup 2)) 0))])])
13942 ;; Peephole2 rega = 0; rega op= regb into rega = regb.
13943 (define_peephole2
13944   [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
13945                    (const_int 0))
13946               (clobber (reg:CC FLAGS_REG))])
13947    (parallel [(set (match_dup 0)
13948                    (any_or_plus:SWI (match_dup 0)
13949                                     (match_operand:SWI 1 "<general_operand>")))
13950               (clobber (reg:CC FLAGS_REG))])]
13951   "!reg_mentioned_p (operands[0], operands[1])"
13952   [(set (match_dup 0) (match_dup 1))])
13954 ;; Peephole2 dead instruction in rega = 0; rega op= rega.
13955 (define_peephole2
13956   [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
13957                    (const_int 0))
13958               (clobber (reg:CC FLAGS_REG))])
13959    (parallel [(set (match_dup 0)
13960                    (any_or_plus:SWI (match_dup 0) (match_dup 0)))
13961               (clobber (reg:CC FLAGS_REG))])]
13962   ""
13963   [(parallel [(set (match_dup 0) (const_int 0))
13964               (clobber (reg:CC FLAGS_REG))])])
13966 ;; Split DST = (HI<<32)|LO early to minimize register usage.
13967 (define_insn_and_split "*concat<mode><dwi>3_1"
13968   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
13969         (any_or_plus:<DWI>
13970           (ashift:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r")
13971                         (match_operand:QI 2 "const_int_operand"))
13972           (zero_extend:<DWI>
13973             (match_operand:DWIH 3 "nonimmediate_operand" "r,m"))))]
13974   "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
13975   "#"
13976   "&& reload_completed"
13977   [(const_int 0)]
13979   split_double_concat (<DWI>mode, operands[0], operands[3],
13980                        gen_lowpart (<MODE>mode, operands[1]));
13981   DONE;
13984 (define_insn_and_split "*concat<mode><dwi>3_2"
13985   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
13986         (any_or_plus:<DWI>
13987           (zero_extend:<DWI>
13988             (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
13989           (ashift:<DWI> (match_operand:<DWI> 2 "register_operand" "r,r")
13990                         (match_operand:QI 3 "const_int_operand"))))]
13991   "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13992   "#"
13993   "&& reload_completed"
13994   [(const_int 0)]
13996   split_double_concat (<DWI>mode, operands[0], operands[1],
13997                        gen_lowpart (<MODE>mode, operands[2]));
13998   DONE;
14001 (define_insn_and_split "*concat<mode><dwi>3_3"
14002   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r,x")
14003         (any_or_plus:<DWI>
14004           (ashift:<DWI>
14005             (any_extend:<DWI>
14006               (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m,x"))
14007             (match_operand:QI 2 "const_int_operand"))
14008           (zero_extend:<DWI>
14009             (match_operand:DWIH 3 "nonimmediate_operand" "r,r,m,m,0"))))]
14010   "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
14011   "#"
14012   "&& reload_completed"
14013   [(const_int 0)]
14015   if (SSE_REG_P (operands[0]))
14016     {
14017       rtx tmp = gen_rtx_REG (V2DImode, REGNO (operands[0]));
14018       emit_insn (gen_vec_concatv2di (tmp, operands[3], operands[1]));
14019     }
14020   else
14021     split_double_concat (<DWI>mode, operands[0], operands[3], operands[1]);
14022   DONE;
14024   [(set_attr "isa" "*,*,*,x64,x64")])
14026 (define_insn_and_split "*concat<mode><dwi>3_4"
14027   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
14028         (any_or_plus:<DWI>
14029           (zero_extend:<DWI>
14030             (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
14031           (ashift:<DWI>
14032             (any_extend:<DWI>
14033               (match_operand:DWIH 2 "nonimmediate_operand" "r,r,m,m"))
14034             (match_operand:QI 3 "const_int_operand"))))]
14035   "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14036   "#"
14037   "&& reload_completed"
14038   [(const_int 0)]
14040   split_double_concat (<DWI>mode, operands[0], operands[1], operands[2]);
14041   DONE;
14043   [(set_attr "isa" "*,*,*,x64")])
14045 (define_insn_and_split "*concat<half><mode>3_5"
14046   [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o,o")
14047         (any_or_plus:DWI
14048           (ashift:DWI (match_operand:DWI 1 "register_operand" "r,r,r")
14049                       (match_operand:QI 2 "const_int_operand"))
14050           (match_operand:DWI 3 "const_scalar_int_operand" "n,n,Wd")))]
14051   "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT / 2
14052    && (<MODE>mode == DImode
14053        ? CONST_INT_P (operands[3])
14054          && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
14055        : CONST_INT_P (operands[3])
14056        ? INTVAL (operands[3]) >= 0
14057        : CONST_WIDE_INT_NUNITS (operands[3]) == 2
14058          && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
14059    && !(CONST_INT_P (operands[3])
14060         ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
14061         : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
14062                                                                      0)),
14063                                         VOIDmode))"
14064   "#"
14065   "&& reload_completed"
14066   [(const_int 0)]
14068   rtx op3 = simplify_subreg (<HALF>mode, operands[3], <MODE>mode, 0);
14069   split_double_concat (<MODE>mode, operands[0], op3,
14070                        gen_lowpart (<HALF>mode, operands[1]));
14071   DONE;
14073   [(set_attr "isa" "*,nox64,x64")])
14075 (define_insn_and_split "*concat<mode><dwi>3_6"
14076   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
14077         (any_or_plus:<DWI>
14078           (ashift:<DWI>
14079             (any_extend:<DWI>
14080               (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
14081             (match_operand:QI 2 "const_int_operand"))
14082           (match_operand:<DWI> 3 "const_scalar_int_operand" "n,n,Wd,n")))]
14083   "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT
14084    && (<DWI>mode == DImode
14085        ? CONST_INT_P (operands[3])
14086          && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
14087        : CONST_INT_P (operands[3])
14088        ? INTVAL (operands[3]) >= 0
14089        : CONST_WIDE_INT_NUNITS (operands[3]) == 2
14090          && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
14091    && !(CONST_INT_P (operands[3])
14092         ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
14093         : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
14094                                                                      0)),
14095                                         VOIDmode))"
14096   "#"
14097   "&& reload_completed"
14098   [(const_int 0)]
14100   rtx op3 = simplify_subreg (<MODE>mode, operands[3], <DWI>mode, 0);
14101   split_double_concat (<DWI>mode, operands[0], op3, operands[1]);
14102   DONE;
14104   [(set_attr "isa" "*,nox64,x64,*")])
14106 (define_insn_and_split "*concat<mode><dwi>3_7"
14107   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
14108         (any_or_plus:<DWI>
14109           (zero_extend:<DWI>
14110             (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
14111           (match_operand:<DWI> 2 "const_scalar_int_operand" "n,n,Wd,n")))]
14112   "<DWI>mode == DImode
14113    ? CONST_INT_P (operands[2])
14114      && (UINTVAL (operands[2]) & GET_MODE_MASK (SImode)) == 0
14115      && !ix86_endbr_immediate_operand (operands[2], VOIDmode)
14116    : CONST_WIDE_INT_P (operands[2])
14117      && CONST_WIDE_INT_NUNITS (operands[2]) == 2
14118      && CONST_WIDE_INT_ELT (operands[2], 0) == 0
14119      && !ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[2],
14120                                                                     1)),
14121                                        VOIDmode)"
14122   "#"
14123   "&& reload_completed"
14124   [(const_int 0)]
14126   rtx op2;
14127   if (<DWI>mode == DImode)
14128     op2 = gen_int_mode (INTVAL (operands[2]) >> 32, <MODE>mode);
14129   else
14130     op2 = gen_int_mode (CONST_WIDE_INT_ELT (operands[2], 1), <MODE>mode);
14131   split_double_concat (<DWI>mode, operands[0], operands[1], op2);
14132   DONE;
14134   [(set_attr "isa" "*,nox64,x64,*")])
14136 ;; Negation instructions
14138 (define_expand "neg<mode>2"
14139   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
14140         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
14141   ""
14143   ix86_expand_unary_operator (NEG, <MODE>mode, operands, TARGET_APX_NDD);
14144   DONE;
14147 (define_insn_and_split "*neg<dwi>2_doubleword"
14148   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,&r")
14149         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0,ro")))
14150    (clobber (reg:CC FLAGS_REG))]
14151   "ix86_unary_operator_ok (NEG, <DWI>mode, operands, TARGET_APX_NDD)"
14152   "#"
14153   "&& reload_completed"
14154   [(parallel
14155     [(set (reg:CCC FLAGS_REG)
14156           (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
14157      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
14158    (parallel
14159     [(set (match_dup 2)
14160           (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
14161                                 (match_dup 3))
14162                      (const_int 0)))
14163      (clobber (reg:CC FLAGS_REG))])
14164    (parallel
14165     [(set (match_dup 2)
14166           (neg:DWIH (match_dup 2)))
14167      (clobber (reg:CC FLAGS_REG))])]
14168   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);"
14169   [(set_attr "isa" "*,apx_ndd")])
14171 ;; Convert:
14172 ;;   mov %esi, %edx
14173 ;;   negl %eax
14174 ;;   adcl $0, %edx
14175 ;;   negl %edx
14176 ;; to:
14177 ;;   xorl %edx, %edx
14178 ;;   negl %eax
14179 ;;   sbbl %esi, %edx
14181 (define_peephole2
14182   [(set (match_operand:SWI48 0 "general_reg_operand")
14183         (match_operand:SWI48 1 "nonimmediate_gr_operand"))
14184    (parallel
14185     [(set (reg:CCC FLAGS_REG)
14186           (unspec:CCC [(match_operand:SWI48 2 "general_reg_operand")
14187                        (const_int 0)] UNSPEC_CC_NE))
14188      (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
14189    (parallel
14190     [(set (match_dup 0)
14191           (plus:SWI48 (plus:SWI48
14192                         (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
14193                         (match_dup 0))
14194                       (const_int 0)))
14195      (clobber (reg:CC FLAGS_REG))])
14196    (parallel
14197     [(set (match_dup 0)
14198           (neg:SWI48 (match_dup 0)))
14199      (clobber (reg:CC FLAGS_REG))])]
14200   "REGNO (operands[0]) != REGNO (operands[2])
14201    && !reg_mentioned_p (operands[0], operands[1])
14202    && !reg_mentioned_p (operands[2], operands[1])"
14203   [(parallel
14204     [(set (reg:CCC FLAGS_REG)
14205           (unspec:CCC [(match_dup 2) (const_int 0)] UNSPEC_CC_NE))
14206      (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
14207    (parallel
14208     [(set (match_dup 0)
14209           (minus:SWI48 (minus:SWI48
14210                          (match_dup 0)
14211                          (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0)))
14212                        (match_dup 1)))
14213      (clobber (reg:CC FLAGS_REG))])]
14214   "ix86_expand_clear (operands[0]);")
14216 ;; Convert:
14217 ;;   xorl %edx, %edx
14218 ;;   negl %eax
14219 ;;   adcl $0, %edx
14220 ;;   negl %edx
14221 ;; to:
14222 ;;   negl %eax
14223 ;;   sbbl %edx, %edx    // *x86_mov<mode>cc_0_m1
14225 (define_peephole2
14226   [(parallel
14227     [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
14228      (clobber (reg:CC FLAGS_REG))])
14229    (parallel
14230     [(set (reg:CCC FLAGS_REG)
14231           (unspec:CCC [(match_operand:SWI48 1 "general_reg_operand")
14232                        (const_int 0)] UNSPEC_CC_NE))
14233      (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
14234    (parallel
14235     [(set (match_dup 0)
14236           (plus:SWI48 (plus:SWI48
14237                         (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
14238                         (match_dup 0))
14239                       (const_int 0)))
14240      (clobber (reg:CC FLAGS_REG))])
14241    (parallel
14242     [(set (match_dup 0)
14243           (neg:SWI48 (match_dup 0)))
14244      (clobber (reg:CC FLAGS_REG))])]
14245   "REGNO (operands[0]) != REGNO (operands[1])"
14246   [(parallel
14247     [(set (reg:CCC FLAGS_REG)
14248           (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
14249      (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
14250    (parallel
14251     [(set (match_dup 0)
14252           (if_then_else:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
14253                               (const_int -1)
14254                               (const_int 0)))
14255      (clobber (reg:CC FLAGS_REG))])])
14257 (define_insn "*neg<mode>_1<nf_name>"
14258   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
14259         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm")))]
14260   "ix86_unary_operator_ok (NEG, <MODE>mode, operands, TARGET_APX_NDD)
14261    && <nf_condition>"
14262   "@
14263   <nf_prefix>neg{<imodesuffix>}\t%0
14264   <nf_prefix>neg{<imodesuffix>}\t{%1, %0|%0, %1}"
14265   [(set_attr "type" "negnot")
14266    (set_attr "isa" "*,apx_ndd")
14267    (set_attr "has_nf" "1")
14268    (set_attr "mode" "<MODE>")])
14270 (define_insn "*negqi_1_zext<mode><nf_name>"
14271   [(set (match_operand:SWI248x 0 "register_operand" "=r")
14272         (zero_extend:SWI248x
14273           (neg:QI (match_operand:QI 1 "nonimmediate_operand" "rm"))))]
14274   "TARGET_APX_NDD && <nf_condition>"
14275   "<nf_prefix>neg{b}\t{%b1, %b0|%b0, %b1}"
14276   [(set_attr "type" "negnot")
14277    (set_attr "has_nf" "1")
14278    (set_attr "mode" "QI")])
14280 (define_insn "*neghi_1_zext<mode><nf_name>"
14281   [(set (match_operand:SWI48x 0 "register_operand" "=r")
14282         (zero_extend:SWI48x
14283           (neg:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))]
14284   "TARGET_APX_NDD && <nf_condition>"
14285   "<nf_prefix>neg{w}\t{%w1, %w0|%w0, %w1}"
14286   [(set_attr "type" "negnot")
14287    (set_attr "has_nf" "1")
14288    (set_attr "mode" "HI")])
14290 (define_insn "*negsi_1_zext"
14291   [(set (match_operand:DI 0 "register_operand" "=r,r")
14292         (zero_extend:DI
14293           (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm"))))
14294    (clobber (reg:CC FLAGS_REG))]
14295   "TARGET_64BIT
14296    && ix86_unary_operator_ok (NEG, SImode, operands, TARGET_APX_NDD)"
14297   "@
14298   neg{l}\t%k0
14299   neg{l}\t{%k1, %k0|%k0, %k1}"
14300   [(set_attr "type" "negnot")
14301    (set_attr "isa" "*,apx_ndd")
14302    (set_attr "mode" "SI")])
14304 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14305 (define_insn_and_split "*neg<mode>_1_slp"
14306   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
14307         (neg:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))
14308    (clobber (reg:CC FLAGS_REG))]
14309   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
14310   "@
14311    neg{<imodesuffix>}\t%0
14312    #"
14313   "&& reload_completed
14314    && !(rtx_equal_p (operands[0], operands[1]))"
14315   [(set (strict_low_part (match_dup 0)) (match_dup 1))
14316    (parallel
14317      [(set (strict_low_part (match_dup 0))
14318            (neg:SWI12 (match_dup 0)))
14319       (clobber (reg:CC FLAGS_REG))])]
14320   ""
14321   [(set_attr "type" "negnot")
14322    (set_attr "mode" "<MODE>")])
14324 (define_insn "*neg<mode>_2"
14325   [(set (reg FLAGS_REG)
14326         (compare
14327           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm"))
14328           (const_int 0)))
14329    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
14330         (neg:SWI (match_dup 1)))]
14331   "ix86_match_ccmode (insn, CCGOCmode)
14332    && ix86_unary_operator_ok (NEG, <MODE>mode, operands, TARGET_APX_NDD)"
14333   "@
14334    neg{<imodesuffix>}\t%0
14335    neg{<imodesuffix>}\t{%1, %0|%0, %1}"
14336   [(set_attr "type" "negnot")
14337    (set_attr "isa" "*,apx_ndd")
14338    (set_attr "mode" "<MODE>")])
14340 (define_insn "*negsi_2_zext"
14341   [(set (reg FLAGS_REG)
14342         (compare
14343           (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm"))
14344           (const_int 0)))
14345    (set (match_operand:DI 0 "register_operand" "=r,r")
14346         (zero_extend:DI
14347           (neg:SI (match_dup 1))))]
14348   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
14349    && ix86_unary_operator_ok (NEG, SImode, operands, TARGET_APX_NDD)"
14350   "@
14351    neg{l}\t%k0
14352    neg{l}\t{%1, %k0|%k0, %1}"
14353   [(set_attr "type" "negnot")
14354    (set_attr "isa" "*,apx_ndd")
14355    (set_attr "mode" "SI")])
14357 (define_insn "*neg<mode>_ccc_1"
14358   [(set (reg:CCC FLAGS_REG)
14359         (unspec:CCC
14360           [(match_operand:SWI 1 "nonimmediate_operand" "0,rm")
14361            (const_int 0)] UNSPEC_CC_NE))
14362    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
14363         (neg:SWI (match_dup 1)))]
14364   ""
14365   "@
14366   neg{<imodesuffix>}\t%0
14367   neg{<imodesuffix>}\t{%1, %0|%0, %1}"
14368   [(set_attr "type" "negnot")
14369    (set_attr "isa" "*,apx_ndd")
14370    (set_attr "mode" "<MODE>")])
14372 (define_insn "*neg<mode>_ccc_2"
14373   [(set (reg:CCC FLAGS_REG)
14374         (unspec:CCC
14375           [(match_operand:SWI 1 "nonimmediate_operand" "0,rm")
14376            (const_int 0)] UNSPEC_CC_NE))
14377    (clobber (match_scratch:SWI 0 "=<r>,r"))]
14378   ""
14379   "@
14380   neg{<imodesuffix>}\t%0
14381   neg{<imodesuffix>}\t{%1, %0|%0, %1}"
14382   [(set_attr "type" "negnot")
14383    (set_attr "isa" "*,apx_ndd")
14384    (set_attr "mode" "<MODE>")])
14386 (define_expand "x86_neg<mode>_ccc"
14387   [(parallel
14388     [(set (reg:CCC FLAGS_REG)
14389           (unspec:CCC [(match_operand:SWI48 1 "register_operand")
14390                        (const_int 0)] UNSPEC_CC_NE))
14391      (set (match_operand:SWI48 0 "register_operand")
14392           (neg:SWI48 (match_dup 1)))])])
14394 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14395 (define_insn_and_split "*negqi_ext<mode>_1"
14396   [(set (zero_extract:SWI248
14397           (match_operand 0 "int248_register_operand" "+Q,&Q")
14398           (const_int 8)
14399           (const_int 8))
14400         (subreg:SWI248
14401           (neg:QI
14402             (subreg:QI
14403               (match_operator:SWI248 2 "extract_operator"
14404                 [(match_operand 1 "int248_register_operand" "0,!Q")
14405                  (const_int 8)
14406                  (const_int 8)]) 0)) 0))
14407    (clobber (reg:CC FLAGS_REG))]
14408   ""
14409   "@
14410    neg{b}\t%h0
14411    #"
14412   "reload_completed
14413    && !(rtx_equal_p (operands[0], operands[1]))"
14414   [(set (zero_extract:SWI248
14415           (match_dup 0) (const_int 8) (const_int 8))
14416         (zero_extract:SWI248
14417           (match_dup 1) (const_int 8) (const_int 8)))
14418    (parallel
14419      [(set (zero_extract:SWI248
14420              (match_dup 0) (const_int 8) (const_int 8))
14421            (subreg:SWI248
14422              (neg:QI
14423                (subreg:QI
14424                  (match_op_dup 2
14425                    [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))
14426       (clobber (reg:CC FLAGS_REG))])]
14427   ""
14428   [(set_attr "type" "negnot")
14429    (set_attr "mode" "QI")])
14431 ;; Negate with jump on overflow.
14432 (define_expand "negv<mode>3"
14433   [(parallel [(set (reg:CCO FLAGS_REG)
14434                    (unspec:CCO
14435                      [(match_operand:SWI 1 "register_operand")
14436                       (match_dup 3)] UNSPEC_CC_NE))
14437               (set (match_operand:SWI 0 "register_operand")
14438                    (neg:SWI (match_dup 1)))])
14439    (set (pc) (if_then_else
14440                (eq (reg:CCO FLAGS_REG) (const_int 0))
14441                (label_ref (match_operand 2))
14442                (pc)))]
14443   ""
14445   operands[3]
14446     = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
14447                     <MODE>mode);
14450 (define_insn "*negv<mode>3"
14451   [(set (reg:CCO FLAGS_REG)
14452         (unspec:CCO [(match_operand:SWI 1 "nonimmediate_operand" "0")
14453                      (match_operand:SWI 2 "const_int_operand")]
14454                     UNSPEC_CC_NE))
14455    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
14456         (neg:SWI (match_dup 1)))]
14457   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
14458    && mode_signbit_p (<MODE>mode, operands[2])"
14459   "neg{<imodesuffix>}\t%0"
14460   [(set_attr "type" "negnot")
14461    (set_attr "mode" "<MODE>")])
14463 ;; Optimize *negsi_1 followed by *cmpsi_ccno_1 (PR target/91384)
14464 (define_peephole2
14465   [(set (match_operand:SWI 0 "general_reg_operand")
14466         (match_operand:SWI 1 "general_reg_operand"))
14467    (parallel [(set (match_dup 0) (neg:SWI (match_dup 0)))
14468               (clobber (reg:CC FLAGS_REG))])
14469    (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))]
14470   ""
14471   [(set (match_dup 0) (match_dup 1))
14472    (parallel [(set (reg:CCZ FLAGS_REG)
14473                    (compare:CCZ (neg:SWI (match_dup 0)) (const_int 0)))
14474               (set (match_dup 0) (neg:SWI (match_dup 0)))])])
14476 ;; Special expand pattern to handle integer mode abs
14478 (define_expand "abs<mode>2"
14479   [(parallel
14480     [(set (match_operand:SDWIM 0 "register_operand")
14481           (abs:SDWIM
14482             (match_operand:SDWIM 1 "general_operand")))
14483      (clobber (reg:CC FLAGS_REG))])]
14484   "TARGET_CMOVE
14485    && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)"
14487   if (TARGET_EXPAND_ABS)
14488     {
14489       machine_mode mode = <MODE>mode;
14490       operands[1] = force_reg (mode, operands[1]);
14492       /* Generate rtx abs using:
14493          abs (x) = (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)) */
14495       rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
14496       rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
14497                                            shift_amount, NULL_RTX,
14498                                            0, OPTAB_DIRECT);
14499       rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
14500                                          operands[0], 0, OPTAB_DIRECT);
14501       rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
14502                                            operands[0], 0, OPTAB_DIRECT);
14503       if (!rtx_equal_p (minus_dst, operands[0]))
14504         emit_move_insn (operands[0], minus_dst);
14505       DONE;
14506     }
14509 (define_insn_and_split "*abs<dwi>2_doubleword"
14510   [(set (match_operand:<DWI> 0 "register_operand")
14511         (abs:<DWI>
14512           (match_operand:<DWI> 1 "general_operand")))
14513    (clobber (reg:CC FLAGS_REG))]
14514   "TARGET_CMOVE
14515    && ix86_pre_reload_split ()"
14516    "#"
14517    "&& 1"
14518   [(parallel
14519     [(set (reg:CCC FLAGS_REG)
14520           (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
14521      (set (match_dup 2) (neg:DWIH (match_dup 1)))])
14522    (parallel
14523     [(set (match_dup 5)
14524           (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
14525                                 (match_dup 4))
14526                      (const_int 0)))
14527      (clobber (reg:CC FLAGS_REG))])
14528    (parallel
14529      [(set (reg:CCGOC FLAGS_REG)
14530            (compare:CCGOC
14531              (neg:DWIH (match_dup 5))
14532              (const_int 0)))
14533       (set (match_dup 5)
14534            (neg:DWIH (match_dup 5)))])
14535    (set (match_dup 0)
14536         (if_then_else:DWIH
14537           (ge (reg:CCGOC FLAGS_REG) (const_int 0))
14538           (match_dup 2)
14539           (match_dup 1)))
14540    (set (match_dup 3)
14541         (if_then_else:DWIH
14542           (ge (reg:CCGOC FLAGS_REG) (const_int 0))
14543           (match_dup 5)
14544           (match_dup 4)))]
14546   operands[1] = force_reg (<DWI>mode, operands[1]);
14547   operands[2] = gen_reg_rtx (<DWI>mode);
14549   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
14552 (define_insn_and_split "*nabs<dwi>2_doubleword"
14553   [(set (match_operand:<DWI> 0 "register_operand")
14554         (neg:<DWI>
14555           (abs:<DWI>
14556             (match_operand:<DWI> 1 "general_operand"))))
14557    (clobber (reg:CC FLAGS_REG))]
14558   "TARGET_CMOVE
14559    && ix86_pre_reload_split ()"
14560    "#"
14561    "&& 1"
14562   [(parallel
14563     [(set (reg:CCC FLAGS_REG)
14564           (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
14565      (set (match_dup 2) (neg:DWIH (match_dup 1)))])
14566    (parallel
14567     [(set (match_dup 5)
14568           (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
14569                                 (match_dup 4))
14570                      (const_int 0)))
14571      (clobber (reg:CC FLAGS_REG))])
14572    (parallel
14573      [(set (reg:CCGOC FLAGS_REG)
14574            (compare:CCGOC
14575              (neg:DWIH (match_dup 5))
14576              (const_int 0)))
14577       (set (match_dup 5)
14578            (neg:DWIH (match_dup 5)))])
14579    (set (match_dup 0)
14580         (if_then_else:DWIH
14581           (lt (reg:CCGOC FLAGS_REG) (const_int 0))
14582           (match_dup 2)
14583           (match_dup 1)))
14584    (set (match_dup 3)
14585         (if_then_else:DWIH
14586           (lt (reg:CCGOC FLAGS_REG) (const_int 0))
14587           (match_dup 5)
14588           (match_dup 4)))]
14590   operands[1] = force_reg (<DWI>mode, operands[1]);
14591   operands[2] = gen_reg_rtx (<DWI>mode);
14593   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
14596 (define_insn_and_split "*abs<mode>2_1"
14597   [(set (match_operand:SWI 0 "register_operand")
14598         (abs:SWI
14599           (match_operand:SWI 1 "general_operand")))
14600    (clobber (reg:CC FLAGS_REG))]
14601   "TARGET_CMOVE
14602    && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
14603    && ix86_pre_reload_split ()"
14604    "#"
14605    "&& 1"
14606   [(parallel
14607      [(set (reg:CCGOC FLAGS_REG)
14608            (compare:CCGOC
14609              (neg:SWI (match_dup 1))
14610              (const_int 0)))
14611       (set (match_dup 2)
14612            (neg:SWI (match_dup 1)))])
14613    (set (match_dup 0)
14614         (if_then_else:SWI
14615           (ge (reg:CCGOC FLAGS_REG) (const_int 0))
14616           (match_dup 2)
14617           (match_dup 1)))]
14619   operands[1] = force_reg (<MODE>mode, operands[1]);
14620   operands[2] = gen_reg_rtx (<MODE>mode);
14623 (define_insn_and_split "*nabs<mode>2_1"
14624   [(set (match_operand:SWI 0 "register_operand")
14625         (neg:SWI
14626           (abs:SWI
14627             (match_operand:SWI 1 "general_operand"))))
14628    (clobber (reg:CC FLAGS_REG))]
14629   "TARGET_CMOVE
14630    && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
14631    && ix86_pre_reload_split ()"
14632    "#"
14633    "&& 1"
14634   [(parallel
14635      [(set (reg:CCGOC FLAGS_REG)
14636            (compare:CCGOC
14637              (neg:SWI (match_dup 1))
14638              (const_int 0)))
14639       (set (match_dup 2)
14640            (neg:SWI (match_dup 1)))])
14641    (set (match_dup 0)
14642         (if_then_else:SWI
14643           (lt (reg:CCGOC FLAGS_REG) (const_int 0))
14644           (match_dup 2)
14645           (match_dup 1)))]
14647   operands[1] = force_reg (<MODE>mode, operands[1]);
14648   operands[2] = gen_reg_rtx (<MODE>mode);
14651 (define_expand "<code>tf2"
14652   [(set (match_operand:TF 0 "register_operand")
14653         (absneg:TF (match_operand:TF 1 "register_operand")))]
14654   "TARGET_SSE"
14655   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
14657 (define_insn_and_split "*<code>tf2_1"
14658   [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
14659         (absneg:TF
14660           (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
14661    (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
14662   "TARGET_SSE"
14663   "#"
14664   "&& reload_completed"
14665   [(set (match_dup 0)
14666         (<absneg_op>:TF (match_dup 1) (match_dup 2)))]
14668   if (TARGET_AVX)
14669     {
14670       if (MEM_P (operands[1]))
14671         std::swap (operands[1], operands[2]);
14672     }
14673   else
14674    {
14675      if (operands_match_p (operands[0], operands[2]))
14676        std::swap (operands[1], operands[2]);
14677    }
14679   [(set_attr "isa" "noavx,noavx,avx,avx")])
14681 (define_insn_and_split "*nabstf2_1"
14682   [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
14683         (neg:TF
14684           (abs:TF
14685             (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
14686    (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
14687   "TARGET_SSE"
14688   "#"
14689   "&& reload_completed"
14690   [(set (match_dup 0)
14691         (ior:TF (match_dup 1) (match_dup 2)))]
14693   if (TARGET_AVX)
14694     {
14695       if (MEM_P (operands[1]))
14696         std::swap (operands[1], operands[2]);
14697     }
14698   else
14699    {
14700      if (operands_match_p (operands[0], operands[2]))
14701        std::swap (operands[1], operands[2]);
14702    }
14704   [(set_attr "isa" "noavx,noavx,avx,avx")])
14706 (define_expand "<code>hf2"
14707   [(set (match_operand:HF 0 "register_operand")
14708         (absneg:HF (match_operand:HF 1 "register_operand")))]
14709   "TARGET_AVX512FP16"
14710   "ix86_expand_fp_absneg_operator (<CODE>, HFmode, operands); DONE;")
14712 (define_expand "<code><mode>2"
14713   [(set (match_operand:X87MODEF 0 "register_operand")
14714         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
14715   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14716   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
14718 ;; Changing of sign for FP values is doable using integer unit too.
14719 (define_insn "*<code><mode>2_i387_1"
14720   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
14721         (absneg:X87MODEF
14722           (match_operand:X87MODEF 1 "register_operand" "0,0")))
14723    (clobber (reg:CC FLAGS_REG))]
14724   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14725   "#")
14727 (define_split
14728   [(set (match_operand:X87MODEF 0 "fp_register_operand")
14729         (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
14730    (clobber (reg:CC FLAGS_REG))]
14731   "TARGET_80387 && reload_completed"
14732   [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
14734 (define_split
14735   [(set (match_operand:X87MODEF 0 "general_reg_operand")
14736         (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
14737    (clobber (reg:CC FLAGS_REG))]
14738   "TARGET_80387 && reload_completed"
14739   [(const_int 0)]
14740   "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
14742 (define_insn_and_split "*<code>hf2_1"
14743   [(set (match_operand:HF 0 "register_operand" "=Yv")
14744         (absneg:HF
14745           (match_operand:HF 1 "register_operand" "Yv")))
14746    (use (match_operand:V8HF 2 "vector_operand" "Yvm"))
14747    (clobber (reg:CC FLAGS_REG))]
14748   "TARGET_AVX512FP16"
14749   "#"
14750   "&& reload_completed"
14751   [(set (match_dup 0)
14752         (<absneg_op>:V8HF (match_dup 1) (match_dup 2)))]
14754   operands[0] = lowpart_subreg (V8HFmode, operands[0], HFmode);
14755   operands[1] = lowpart_subreg (V8HFmode, operands[1], HFmode);
14758 (define_insn "*<code><mode>2_1"
14759   [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
14760         (absneg:MODEF
14761           (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
14762    (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
14763    (clobber (reg:CC FLAGS_REG))]
14764   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14765   "#"
14766   [(set_attr "isa" "noavx,noavx,avx,*,*")
14767    (set (attr "enabled")
14768      (if_then_else
14769        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14770        (if_then_else
14771          (eq_attr "alternative" "3,4")
14772          (symbol_ref "TARGET_MIX_SSE_I387")
14773          (const_string "*"))
14774        (if_then_else
14775          (eq_attr "alternative" "3,4")
14776          (symbol_ref "true")
14777          (symbol_ref "false"))))])
14779 (define_split
14780   [(set (match_operand:MODEF 0 "sse_reg_operand")
14781         (absneg:MODEF
14782           (match_operand:MODEF 1 "sse_reg_operand")))
14783    (use (match_operand:<ssevecmodef> 2 "vector_operand"))
14784    (clobber (reg:CC FLAGS_REG))]
14785   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14786    && reload_completed"
14787   [(set (match_dup 0)
14788         (<absneg_op>:<ssevecmodef> (match_dup 1) (match_dup 2)))]
14790   machine_mode mode = <MODE>mode;
14791   machine_mode vmode = <ssevecmodef>mode;
14793   operands[0] = lowpart_subreg (vmode, operands[0], mode);
14794   operands[1] = lowpart_subreg (vmode, operands[1], mode);
14796   if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
14797     std::swap (operands[1], operands[2]);
14800 (define_split
14801   [(set (match_operand:MODEF 0 "fp_register_operand")
14802         (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
14803    (use (match_operand 2))
14804    (clobber (reg:CC FLAGS_REG))]
14805   "TARGET_80387 && reload_completed"
14806   [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
14808 (define_split
14809   [(set (match_operand:MODEF 0 "general_reg_operand")
14810         (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
14811    (use (match_operand 2))
14812    (clobber (reg:CC FLAGS_REG))]
14813   "TARGET_80387 && reload_completed"
14814   [(const_int 0)]
14815   "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
14817 (define_insn_and_split "*nabs<mode>2_1"
14818   [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
14819         (neg:MODEF
14820           (abs:MODEF
14821             (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
14822    (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
14823   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14824   "#"
14825   "&& reload_completed"
14826   [(set (match_dup 0)
14827         (ior:<ssevecmodef> (match_dup 1) (match_dup 2)))]
14829   machine_mode mode = <MODE>mode;
14830   machine_mode vmode = <ssevecmodef>mode;
14832   operands[0] = lowpart_subreg (vmode, operands[0], mode);
14833   operands[1] = lowpart_subreg (vmode, operands[1], mode);
14835   if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
14836     std::swap (operands[1], operands[2]);
14838   [(set_attr "isa" "noavx,noavx,avx")])
14840 ;; Conditionalize these after reload. If they match before reload, we
14841 ;; lose the clobber and ability to use integer instructions.
14843 (define_insn "*<code><mode>2_i387"
14844   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
14845         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
14846   "TARGET_80387 && reload_completed"
14847   "<absneg_mnemonic>"
14848   [(set_attr "type" "fsgn")
14849    (set_attr "mode" "<MODE>")])
14851 ;; Copysign instructions
14853 (define_expand "copysign<mode>3"
14854   [(match_operand:SSEMODEF 0 "register_operand")
14855    (match_operand:SSEMODEF 1 "nonmemory_operand")
14856    (match_operand:SSEMODEF 2 "register_operand")]
14857   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14858    || (TARGET_SSE && (<MODE>mode == TFmode))
14859    || (TARGET_AVX512FP16 && (<MODE>mode ==HFmode))"
14860   "ix86_expand_copysign (operands); DONE;")
14862 (define_expand "xorsign<mode>3"
14863   [(match_operand:MODEFH 0 "register_operand")
14864    (match_operand:MODEFH 1 "register_operand")
14865    (match_operand:MODEFH 2 "register_operand")]
14866   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14867   || <MODE>mode == HFmode"
14869   if (rtx_equal_p (operands[1], operands[2]))
14870     emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
14871   else
14872     ix86_expand_xorsign (operands);
14873   DONE;
14876 ;; One complement instructions
14878 (define_expand "one_cmpl<mode>2"
14879   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
14880         (not:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
14881   ""
14883   ix86_expand_unary_operator (NOT, <MODE>mode, operands, TARGET_APX_NDD);
14884   DONE;
14887 (define_insn_and_split "*one_cmpl<dwi>2_doubleword"
14888   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,&r")
14889         (not:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0,ro")))]
14890   "ix86_unary_operator_ok (NOT, <DWI>mode, operands, TARGET_APX_NDD)"
14891   "#"
14892   "&& reload_completed"
14893   [(set (match_dup 0)
14894         (not:DWIH (match_dup 1)))
14895    (set (match_dup 2)
14896         (not:DWIH (match_dup 3)))]
14897   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);"
14898   [(set_attr "isa" "*,apx_ndd")])
14900 (define_insn "*one_cmpl<mode>2_1"
14901   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
14902         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,rm,k")))]
14903   "ix86_unary_operator_ok (NOT, <MODE>mode, operands, TARGET_APX_NDD)"
14904   "@
14905    not{<imodesuffix>}\t%0
14906    not{<imodesuffix>}\t{%1, %0|%0, %1}
14907    #"
14908   [(set_attr "isa" "*,apx_ndd,<kmov_isa>")
14909    (set_attr "type" "negnot,negnot,msklog")
14910    (set_attr "mode" "<MODE>")])
14912 (define_insn "*one_cmplqi2_1_zext<mode>"
14913   [(set (match_operand:SWI248x 0 "register_operand" "=r")
14914         (zero_extend:SWI248x
14915           (not:QI (match_operand:QI 1 "nonimmediate_operand" "rm"))))]
14916   "TARGET_APX_NDD"
14917   "not{b}\t{%1, %b0|%b0, %1}"
14918   [(set_attr "type" "negnot")
14919    (set_attr "mode" "QI")])
14921 (define_insn "*one_cmplhi2_1_zext<mode>"
14922   [(set (match_operand:SWI48x 0 "register_operand" "=r")
14923         (zero_extend:SWI48x
14924           (not:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))]
14925   "TARGET_APX_NDD"
14926   "not{w}\t{%1, %w0|%w0, %1}"
14927   [(set_attr "type" "negnot")
14928    (set_attr "mode" "HI")])
14930 (define_insn "*one_cmplsi2_1_zext"
14931   [(set (match_operand:DI 0 "register_operand" "=r,r,?k")
14932         (zero_extend:DI
14933           (not:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm,k"))))]
14934   "TARGET_64BIT
14935    && ix86_unary_operator_ok (NOT, SImode, operands, TARGET_APX_NDD)"
14936   "@
14937    not{l}\t%k0
14938    not{l}\t{%1, %k0|%k0, %1}
14939    #"
14940   [(set_attr "isa" "x64,apx_ndd,avx512bw")
14941    (set_attr "type" "negnot,negnot,msklog")
14942    (set_attr "mode" "SI,SI,SI")])
14944 (define_insn "*one_cmplqi2_1"
14945   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r,?k")
14946         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,rm,k")))]
14947   "ix86_unary_operator_ok (NOT, QImode, operands, TARGET_APX_NDD)"
14948   "@
14949    not{b}\t%0
14950    not{l}\t%k0
14951    not{b}\t{%1, %0|%0, %1}
14952    #"
14953   [(set_attr "isa" "*,*,apx_ndd,avx512f")
14954    (set_attr "type" "negnot,negnot,negnot,msklog")
14955    (set (attr "mode")
14956         (cond [(eq_attr "alternative" "1")
14957                  (const_string "SI")
14958                 (and (eq_attr "alternative" "3")
14959                      (match_test "!TARGET_AVX512DQ"))
14960                  (const_string "HI")
14961                ]
14962                (const_string "QI")))
14963    ;; Potential partial reg stall on alternative 1.
14964    (set (attr "preferred_for_speed")
14965      (cond [(eq_attr "alternative" "1")
14966               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
14967            (symbol_ref "true")))])
14969 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14970 (define_insn_and_split "*one_cmpl<mode>_1_slp"
14971   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
14972         (not:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))]
14973   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
14974   "@
14975    not{<imodesuffix>}\t%0
14976    #"
14977   "&& reload_completed
14978    && !(rtx_equal_p (operands[0], operands[1]))"
14979   [(set (strict_low_part (match_dup 0)) (match_dup 1))
14980    (set (strict_low_part (match_dup 0))
14981         (not:SWI12 (match_dup 0)))]
14982   ""
14983   [(set_attr "type" "negnot")
14984    (set_attr "mode" "<MODE>")])
14986 (define_insn "*one_cmpl<mode>2_2"
14987   [(set (reg FLAGS_REG)
14988         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm"))
14989                  (const_int 0)))
14990    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
14991         (not:SWI (match_dup 1)))]
14992   "ix86_match_ccmode (insn, CCNOmode)
14993    && ix86_unary_operator_ok (NOT, <MODE>mode, operands, TARGET_APX_NDD)"
14994   "#"
14995   [(set_attr "type" "alu1")
14996    (set_attr "isa" "*,apx_ndd")
14997    (set_attr "mode" "<MODE>")])
14999 (define_split
15000   [(set (match_operand 0 "flags_reg_operand")
15001         (match_operator 2 "compare_operator"
15002           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
15003            (const_int 0)]))
15004    (set (match_operand:SWI 1 "nonimmediate_operand")
15005         (not:SWI (match_dup 3)))]
15006   "ix86_match_ccmode (insn, CCNOmode)"
15007   [(parallel [(set (match_dup 0)
15008                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
15009                                     (const_int 0)]))
15010               (set (match_dup 1)
15011                    (xor:SWI (match_dup 3) (const_int -1)))])])
15013 (define_insn "*one_cmplsi2_2_zext"
15014   [(set (reg FLAGS_REG)
15015         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm"))
15016                  (const_int 0)))
15017    (set (match_operand:DI 0 "register_operand" "=r,r")
15018         (zero_extend:DI (not:SI (match_dup 1))))]
15019   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
15020    && ix86_unary_operator_ok (NOT, SImode, operands, TARGET_APX_NDD)"
15021   "#"
15022   [(set_attr "type" "alu1")
15023    (set_attr "isa" "*,apx_ndd")
15024    (set_attr "mode" "SI")])
15026 (define_split
15027   [(set (match_operand 0 "flags_reg_operand")
15028         (match_operator 2 "compare_operator"
15029           [(not:SI (match_operand:SI 3 "nonimmediate_operand"))
15030            (const_int 0)]))
15031    (set (match_operand:DI 1 "register_operand")
15032         (zero_extend:DI (not:SI (match_dup 3))))]
15033   "ix86_match_ccmode (insn, CCNOmode)"
15034   [(parallel [(set (match_dup 0)
15035                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
15036                                     (const_int 0)]))
15037               (set (match_dup 1)
15038                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
15040 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15041 (define_insn_and_split "*one_cmplqi_ext<mode>_1"
15042   [(set (zero_extract:SWI248
15043           (match_operand 0 "int248_register_operand" "+Q,&Q")
15044           (const_int 8)
15045           (const_int 8))
15046         (subreg:SWI248
15047           (not:QI
15048             (subreg:QI
15049               (match_operator:SWI248 2 "extract_operator"
15050                 [(match_operand 1 "int248_register_operand" "0,!Q")
15051                  (const_int 8)
15052                  (const_int 8)]) 0)) 0))]
15053   ""
15054   "@
15055    not{b}\t%h0
15056    #"
15057   "reload_completed
15058    && !(rtx_equal_p (operands[0], operands[1]))"
15059   [(set (zero_extract:SWI248
15060           (match_dup 0) (const_int 8) (const_int 8))
15061         (zero_extract:SWI248
15062           (match_dup 1) (const_int 8) (const_int 8)))
15063    (set (zero_extract:SWI248
15064           (match_dup 0) (const_int 8) (const_int 8))
15065         (subreg:SWI248
15066           (not:QI
15067             (subreg:QI
15068               (match_op_dup 2
15069                 [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))]
15070   ""
15071   [(set_attr "type" "negnot")
15072    (set_attr "mode" "QI")])
15074 ;; Shift instructions
15076 ;; DImode shifts are implemented using the i386 "shift double" opcode,
15077 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
15078 ;; is variable, then the count is in %cl and the "imm" operand is dropped
15079 ;; from the assembler input.
15081 ;; This instruction shifts the target reg/mem as usual, but instead of
15082 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
15083 ;; is a left shift double, bits are taken from the high order bits of
15084 ;; reg, else if the insn is a shift right double, bits are taken from the
15085 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
15086 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
15088 ;; Since sh[lr]d does not change the `reg' operand, that is done
15089 ;; separately, making all shifts emit pairs of shift double and normal
15090 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
15091 ;; support a 63 bit shift, each shift where the count is in a reg expands
15092 ;; to a pair of shifts, a branch, a shift by 32 and a label.
15094 ;; If the shift count is a constant, we need never emit more than one
15095 ;; shift pair, instead using moves and sign extension for counts greater
15096 ;; than 31.
15098 (define_expand "ashl<mode>3"
15099   [(set (match_operand:SDWIM 0 "<shift_operand>")
15100         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
15101                       (match_operand:QI 2 "nonmemory_operand")))]
15102   ""
15104   ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands, TARGET_APX_NDD);
15105   DONE;
15108 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
15109   [(set (match_operand:<DWI> 0 "register_operand")
15110         (ashift:<DWI>
15111           (match_operand:<DWI> 1 "register_operand")
15112           (subreg:QI
15113             (and
15114               (match_operand 2 "int248_register_operand" "c")
15115               (match_operand 3 "const_int_operand")) 0)))
15116    (clobber (reg:CC FLAGS_REG))]
15117   "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
15118     || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
15119          == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
15120    && ix86_pre_reload_split ()"
15121   "#"
15122   "&& 1"
15123   [(parallel
15124      [(set (match_dup 6)
15125            (ior:DWIH (ashift:DWIH (match_dup 6)
15126                        (and:QI (match_dup 2) (match_dup 8)))
15127                      (subreg:DWIH
15128                        (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
15129                          (minus:QI (match_dup 9)
15130                                    (and:QI (match_dup 2) (match_dup 8)))) 0)))
15131       (clobber (reg:CC FLAGS_REG))])
15132    (parallel
15133      [(set (match_dup 4)
15134            (ashift:DWIH (match_dup 5) (match_dup 2)))
15135       (clobber (reg:CC FLAGS_REG))])]
15137   if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
15138     {
15139       operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15140       operands[2] = gen_lowpart (QImode, operands[2]);
15141       emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
15142                                             operands[2]));
15143       DONE;
15144     }
15146   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
15148   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
15149   operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
15151   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
15152       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
15153     {
15154       rtx xops[3];
15155       xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
15156       xops[1] = operands[2];
15157       xops[2] = GEN_INT (INTVAL (operands[3])
15158                          & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
15159       ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
15160       operands[2] = xops[0];
15161     }
15163   operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15164   operands[2] = gen_lowpart (QImode, operands[2]);
15166   if (!rtx_equal_p (operands[6], operands[7]))
15167     emit_move_insn (operands[6], operands[7]);
15170 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
15171   [(set (match_operand:<DWI> 0 "register_operand")
15172         (ashift:<DWI>
15173           (match_operand:<DWI> 1 "register_operand")
15174           (and:QI
15175             (match_operand:QI 2 "register_operand" "c")
15176             (match_operand:QI 3 "const_int_operand"))))
15177    (clobber (reg:CC FLAGS_REG))]
15178   "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
15179     || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
15180          == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
15181    && ix86_pre_reload_split ()"
15182   "#"
15183   "&& 1"
15184   [(parallel
15185      [(set (match_dup 6)
15186            (ior:DWIH (ashift:DWIH (match_dup 6)
15187                        (and:QI (match_dup 2) (match_dup 8)))
15188                      (subreg:DWIH
15189                        (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
15190                          (minus:QI (match_dup 9)
15191                                    (and:QI (match_dup 2) (match_dup 8)))) 0)))
15192       (clobber (reg:CC FLAGS_REG))])
15193    (parallel
15194      [(set (match_dup 4)
15195            (ashift:DWIH (match_dup 5) (match_dup 2)))
15196       (clobber (reg:CC FLAGS_REG))])]
15198   if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
15199     {
15200       emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
15201                                             operands[2]));
15202       DONE;
15203     }
15205   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
15207   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
15208   operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
15210   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
15211       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
15212     {
15213       rtx tem = gen_reg_rtx (QImode);
15214       emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
15215       operands[2] = tem;
15216     }
15218   if (!rtx_equal_p (operands[6], operands[7]))
15219     emit_move_insn (operands[6], operands[7]);
15222 (define_insn "ashl<mode>3_doubleword"
15223   [(set (match_operand:DWI 0 "register_operand" "=&r,&r")
15224         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0Wc,r")
15225                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
15226    (clobber (reg:CC FLAGS_REG))]
15227   ""
15228   "#"
15229   [(set_attr "type" "multi")
15230    (set_attr "isa" "*,apx_ndd")])
15232 (define_split
15233   [(set (match_operand:DWI 0 "register_operand")
15234         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
15235                     (match_operand:QI 2 "nonmemory_operand")))
15236    (clobber (reg:CC FLAGS_REG))]
15237   "epilogue_completed"
15238   [(const_int 0)]
15240   if (TARGET_APX_NDD
15241       && !rtx_equal_p (operands[0], operands[1])
15242       && REG_P (operands[1]))
15243     ix86_split_ashl_ndd (operands, NULL_RTX);
15244   else
15245     ix86_split_ashl (operands, NULL_RTX, <MODE>mode);
15246   DONE;
15249 ;; By default we don't ask for a scratch register, because when DWImode
15250 ;; values are manipulated, registers are already at a premium.  But if
15251 ;; we have one handy, we won't turn it away.
15253 (define_peephole2
15254   [(match_scratch:DWIH 3 "r")
15255    (parallel [(set (match_operand:<DWI> 0 "register_operand")
15256                    (ashift:<DWI>
15257                      (match_operand:<DWI> 1 "nonmemory_operand")
15258                      (match_operand:QI 2 "nonmemory_operand")))
15259               (clobber (reg:CC FLAGS_REG))])
15260    (match_dup 3)]
15261   "TARGET_CMOVE"
15262   [(const_int 0)]
15264   if (TARGET_APX_NDD
15265       && !rtx_equal_p (operands[0], operands[1])
15266       && (REG_P (operands[1])))
15267     ix86_split_ashl_ndd (operands, operands[3]);
15268   else
15269     ix86_split_ashl (operands, operands[3], <DWI>mode);
15270   DONE;
15273 (define_insn_and_split "*ashl<dwi>3_doubleword_highpart"
15274   [(set (match_operand:<DWI> 0 "register_operand" "=r")
15275         (ashift:<DWI>
15276           (any_extend:<DWI> (match_operand:DWIH 1 "nonimmediate_operand" "rm"))
15277           (match_operand:QI 2 "const_int_operand")))
15278    (clobber (reg:CC FLAGS_REG))]
15279   "INTVAL (operands[2]) >= <MODE_SIZE> * BITS_PER_UNIT
15280    && INTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT * 2"
15281   "#"
15282   "&& reload_completed"
15283   [(const_int 0)]
15285   split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[3]);
15286   int bits = INTVAL (operands[2]) - (<MODE_SIZE> * BITS_PER_UNIT);
15287   bool op_equal_p = rtx_equal_p (operands[3], operands[1]);
15288   if (bits == 0)
15289     {
15290       if (!op_equal_p)
15291         emit_move_insn (operands[3], operands[1]);
15292     }
15293   else
15294     {
15295       if (!op_equal_p && !TARGET_APX_NDD)
15296         emit_move_insn (operands[3], operands[1]);
15297       rtx op_tmp = TARGET_APX_NDD ? operands[1] : operands[3];
15298       emit_insn (gen_ashl<mode>3 (operands[3], op_tmp, GEN_INT (bits)));
15299     }
15300   ix86_expand_clear (operands[0]);
15301   DONE;
15304 (define_insn "x86_64_shld<nf_name>"
15305   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
15306         (ior:DI (ashift:DI (match_dup 0)
15307                   (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
15308                           (const_int 63)))
15309                 (subreg:DI
15310                   (lshiftrt:TI
15311                     (zero_extend:TI
15312                       (match_operand:DI 1 "register_operand" "r"))
15313                     (minus:QI (const_int 64)
15314                               (and:QI (match_dup 2) (const_int 63)))) 0)))]
15315   "TARGET_64BIT && <nf_condition>"
15316   "<nf_prefix>shld{q}\t{%2, %1, %0|%0, %1, %2}"
15317   [(set_attr "type" "ishift")
15318    (set_attr "prefix_0f" "1")
15319    (set_attr "has_nf" "1")
15320    (set_attr "mode" "DI")
15321    (set_attr "athlon_decode" "vector")
15322    (set_attr "amdfam10_decode" "vector")
15323    (set_attr "bdver1_decode" "vector")])
15325 (define_insn "x86_64_shld_ndd<nf_name>"
15326   [(set (match_operand:DI 0 "register_operand" "=r")
15327         (ior:DI (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "rm")
15328                   (and:QI (match_operand:QI 3 "nonmemory_operand" "Jc")
15329                           (const_int 63)))
15330                 (subreg:DI
15331                   (lshiftrt:TI
15332                     (zero_extend:TI
15333                       (match_operand:DI 2 "register_operand" "r"))
15334                     (minus:QI (const_int 64)
15335                               (and:QI (match_dup 3) (const_int 63)))) 0)))]
15336   "TARGET_APX_NDD && <nf_condition>"
15337   "<nf_prefix>shld{q}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
15338   [(set_attr "type" "ishift")
15339    (set_attr "has_nf" "1")
15340    (set_attr "mode" "DI")])
15342 (define_insn "x86_64_shld_1<nf_name>"
15343   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
15344         (ior:DI (ashift:DI (match_dup 0)
15345                            (match_operand:QI 2 "const_0_to_63_operand"))
15346                 (subreg:DI
15347                   (lshiftrt:TI
15348                     (zero_extend:TI
15349                       (match_operand:DI 1 "register_operand" "r"))
15350                     (match_operand:QI 3 "const_0_to_255_operand")) 0)))]
15351   "TARGET_64BIT
15352    && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
15353    && <nf_condition>"
15354   "<nf_prefix>shld{q}\t{%2, %1, %0|%0, %1, %2}"
15355   [(set_attr "type" "ishift")
15356    (set_attr "prefix_0f" "1")
15357    (set_attr "has_nf" "1")
15358    (set_attr "mode" "DI")
15359    (set_attr "length_immediate" "1")
15360    (set_attr "athlon_decode" "vector")
15361    (set_attr "amdfam10_decode" "vector")
15362    (set_attr "bdver1_decode" "vector")])
15364 (define_insn "x86_64_shld_ndd_1<nf_name>"
15365   [(set (match_operand:DI 0 "register_operand" "=r")
15366         (ior:DI (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "rm")
15367                            (match_operand:QI 3 "const_0_to_63_operand"))
15368                 (subreg:DI
15369                   (lshiftrt:TI
15370                     (zero_extend:TI
15371                       (match_operand:DI 2 "register_operand" "r"))
15372                     (match_operand:QI 4 "const_0_to_255_operand")) 0)))]
15373   "TARGET_APX_NDD
15374    && INTVAL (operands[4]) == 64 - INTVAL (operands[3])
15375    && <nf_condition>"
15376   "<nf_prefix>shld{q}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
15377   [(set_attr "type" "ishift")
15378    (set_attr "has_nf" "1")
15379    (set_attr "mode" "DI")
15380    (set_attr "length_immediate" "1")])
15382 (define_insn_and_split "*x86_64_shld_shrd_1_nozext_nf"
15383   [(set (match_operand:DI 0 "nonimmediate_operand")
15384         (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
15385                              (match_operand:QI 2 "const_0_to_63_operand"))
15386                 (lshiftrt:DI
15387                   (match_operand:DI 1 "nonimmediate_operand")
15388                   (match_operand:QI 3 "const_0_to_63_operand"))))]
15389   "TARGET_64BIT && TARGET_APX_NF
15390    && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
15391    && ix86_pre_reload_split ()"
15392   "#"
15393   "&& 1"
15394   [(const_int 0)]
15396   if (rtx_equal_p (operands[4], operands[0]))
15397     {
15398       operands[1] = force_reg (DImode, operands[1]);
15399       emit_insn (gen_x86_64_shld_1_nf (operands[0], operands[1],
15400                                        operands[2], operands[3]));
15401     }
15402   else if (rtx_equal_p (operands[1], operands[0]))
15403     {
15404       operands[4] = force_reg (DImode, operands[4]);
15405       emit_insn (gen_x86_64_shrd_1_nf (operands[0], operands[4],
15406                                        operands[3], operands[2]));
15407     }
15408   else if (TARGET_APX_NDD)
15409     {
15410      rtx tmp = gen_reg_rtx (DImode);
15411      if (MEM_P (operands[4]))
15412        {
15413          operands[1] = force_reg (DImode, operands[1]);
15414          emit_insn (gen_x86_64_shld_ndd_1_nf (tmp, operands[4], operands[1],
15415                                               operands[2], operands[3]));
15416        }
15417      else if (MEM_P (operands[1]))
15418        emit_insn (gen_x86_64_shrd_ndd_1_nf (tmp, operands[1], operands[4],
15419                                             operands[3], operands[2]));
15420      else
15421        emit_insn (gen_x86_64_shld_ndd_1_nf (tmp, operands[4], operands[1],
15422                                             operands[2], operands[3]));
15423      emit_move_insn (operands[0], tmp);
15424     }
15425   else
15426    {
15427      operands[1] = force_reg (DImode, operands[1]);
15428      rtx tmp = gen_reg_rtx (DImode);
15429      emit_move_insn (tmp, operands[4]);
15430      emit_insn (gen_x86_64_shld_1_nf (tmp, operands[1],
15431                                       operands[2], operands[3]));
15432      emit_move_insn (operands[0], tmp);
15433    }
15434    DONE;
15437 (define_insn_and_split "*x86_64_shld_shrd_1_nozext"
15438   [(set (match_operand:DI 0 "nonimmediate_operand")
15439         (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
15440                              (match_operand:QI 2 "const_0_to_63_operand"))
15441                 (lshiftrt:DI
15442                   (match_operand:DI 1 "nonimmediate_operand")
15443                   (match_operand:QI 3 "const_0_to_63_operand"))))
15444    (clobber (reg:CC FLAGS_REG))]
15445   "TARGET_64BIT
15446    && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
15447    && ix86_pre_reload_split ()"
15448   "#"
15449   "&& 1"
15450   [(const_int 0)]
15452   if (rtx_equal_p (operands[4], operands[0]))
15453     {
15454       operands[1] = force_reg (DImode, operands[1]);
15455       emit_insn (gen_x86_64_shld_1 (operands[0], operands[1], operands[2], operands[3]));
15456     }
15457   else if (rtx_equal_p (operands[1], operands[0]))
15458     {
15459       operands[4] = force_reg (DImode, operands[4]);
15460       emit_insn (gen_x86_64_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
15461     }
15462   else if (TARGET_APX_NDD)
15463     {
15464      rtx tmp = gen_reg_rtx (DImode);
15465      if (MEM_P (operands[4]))
15466        {
15467          operands[1] = force_reg (DImode, operands[1]);
15468          emit_insn (gen_x86_64_shld_ndd_1 (tmp, operands[4], operands[1],
15469                                            operands[2], operands[3]));
15470        }
15471      else if (MEM_P (operands[1]))
15472        emit_insn (gen_x86_64_shrd_ndd_1 (tmp, operands[1], operands[4],
15473                                          operands[3], operands[2]));
15474      else
15475        emit_insn (gen_x86_64_shld_ndd_1 (tmp, operands[4], operands[1],
15476                                          operands[2], operands[3]));
15477      emit_move_insn (operands[0], tmp);
15478     }
15479   else
15480    {
15481      operands[1] = force_reg (DImode, operands[1]);
15482      rtx tmp = gen_reg_rtx (DImode);
15483      emit_move_insn (tmp, operands[4]);
15484      emit_insn (gen_x86_64_shld_1 (tmp, operands[1], operands[2], operands[3]));
15485      emit_move_insn (operands[0], tmp);
15486    }
15487    DONE;
15489   [(set_attr "has_nf" "1")])
15491 (define_insn_and_split "*x86_64_shld_2"
15492   [(set (match_operand:DI 0 "nonimmediate_operand")
15493         (ior:DI (ashift:DI (match_dup 0)
15494                            (match_operand:QI 2 "nonmemory_operand"))
15495                 (lshiftrt:DI (match_operand:DI 1 "register_operand")
15496                              (minus:QI (const_int 64) (match_dup 2)))))
15497    (clobber (reg:CC FLAGS_REG))]
15498   "TARGET_64BIT && ix86_pre_reload_split ()"
15499   "#"
15500   "&& 1"
15501   [(parallel [(set (match_dup 0)
15502                    (ior:DI (ashift:DI (match_dup 0)
15503                                       (and:QI (match_dup 2) (const_int 63)))
15504                            (subreg:DI
15505                              (lshiftrt:TI
15506                                (zero_extend:TI (match_dup 1))
15507                                  (minus:QI (const_int 64)
15508                                            (and:QI (match_dup 2)
15509                                                    (const_int 63)))) 0)))
15510               (clobber (reg:CC FLAGS_REG))])])
15512 (define_insn_and_split "*x86_64_shld_ndd_2"
15513   [(set (match_operand:DI 0 "nonimmediate_operand")
15514         (ior:DI (ashift:DI (match_operand:DI 1 "nonimmediate_operand")
15515                            (match_operand:QI 3 "nonmemory_operand"))
15516                 (lshiftrt:DI (match_operand:DI 2 "register_operand")
15517                              (minus:QI (const_int 64) (match_dup 3)))))
15518    (clobber (reg:CC FLAGS_REG))]
15519   "TARGET_APX_NDD
15520    && ix86_pre_reload_split ()"
15521   "#"
15522   "&& 1"
15523   [(parallel [(set (match_dup 4)
15524                    (ior:DI (ashift:DI (match_dup 1)
15525                                       (and:QI (match_dup 3) (const_int 63)))
15526                            (subreg:DI
15527                              (lshiftrt:TI
15528                                (zero_extend:TI (match_dup 2))
15529                                  (minus:QI (const_int 64)
15530                                            (and:QI (match_dup 3)
15531                                                    (const_int 63)))) 0)))
15532               (clobber (reg:CC FLAGS_REG))
15533               (set (match_dup 0) (match_dup 4))])]
15535   operands[4] = gen_reg_rtx (DImode);
15536   emit_move_insn (operands[4], operands[0]);
15539 (define_insn "x86_shld<nf_name>"
15540   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
15541         (ior:SI (ashift:SI (match_dup 0)
15542                   (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
15543                           (const_int 31)))
15544                 (subreg:SI
15545                   (lshiftrt:DI
15546                     (zero_extend:DI
15547                       (match_operand:SI 1 "register_operand" "r"))
15548                     (minus:QI (const_int 32)
15549                               (and:QI (match_dup 2) (const_int 31)))) 0)))]
15550   "<nf_condition>"
15551   "<nf_prefix>shld{l}\t{%2, %1, %0|%0, %1, %2}"
15552   [(set_attr "type" "ishift")
15553    (set_attr "prefix_0f" "1")
15554    (set_attr "has_nf" "1")
15555    (set_attr "mode" "SI")
15556    (set_attr "pent_pair" "np")
15557    (set_attr "athlon_decode" "vector")
15558    (set_attr "amdfam10_decode" "vector")
15559    (set_attr "bdver1_decode" "vector")])
15561 (define_insn "x86_shld_ndd<nf_name>"
15562   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15563         (ior:SI (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15564                   (and:QI (match_operand:QI 3 "nonmemory_operand" "Ic")
15565                           (const_int 31)))
15566                 (subreg:SI
15567                   (lshiftrt:DI
15568                     (zero_extend:DI
15569                       (match_operand:SI 2 "register_operand" "r"))
15570                     (minus:QI (const_int 32)
15571                               (and:QI (match_dup 3) (const_int 31)))) 0)))]
15572   "TARGET_APX_NDD && <nf_condition>"
15573   "<nf_prefix>shld{l}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
15574   [(set_attr "type" "ishift")
15575    (set_attr "has_nf" "1")
15576    (set_attr "mode" "SI")])
15579 (define_insn "x86_shld_1<nf_name>"
15580   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
15581         (ior:SI (ashift:SI (match_dup 0)
15582                            (match_operand:QI 2 "const_0_to_31_operand"))
15583                 (subreg:SI
15584                   (lshiftrt:DI
15585                     (zero_extend:DI
15586                       (match_operand:SI 1 "register_operand" "r"))
15587                     (match_operand:QI 3 "const_0_to_63_operand")) 0)))]
15588   "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
15589   && <nf_condition>"
15590   "<nf_prefix>shld{l}\t{%2, %1, %0|%0, %1, %2}"
15591   [(set_attr "type" "ishift")
15592    (set_attr "prefix_0f" "1")
15593    (set_attr "length_immediate" "1")
15594    (set_attr "has_nf" "1")
15595    (set_attr "mode" "SI")
15596    (set_attr "pent_pair" "np")
15597    (set_attr "athlon_decode" "vector")
15598    (set_attr "amdfam10_decode" "vector")
15599    (set_attr "bdver1_decode" "vector")])
15601 (define_insn "x86_shld_ndd_1<nf_name>"
15602   [(set (match_operand:SI 0 "register_operand" "=r")
15603         (ior:SI (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15604                            (match_operand:QI 3 "const_0_to_31_operand"))
15605                 (subreg:SI
15606                   (lshiftrt:DI
15607                     (zero_extend:DI
15608                       (match_operand:SI 2 "register_operand" "r"))
15609                     (match_operand:QI 4 "const_0_to_63_operand")) 0)))]
15610   "TARGET_APX_NDD 
15611    && INTVAL (operands[4]) == 32 - INTVAL (operands[3])
15612    && <nf_condition>"
15613   "<nf_prefix>shld{l}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
15614   [(set_attr "type" "ishift")
15615    (set_attr "length_immediate" "1")
15616    (set_attr "has_nf" "1")
15617    (set_attr "mode" "SI")])
15619 (define_insn_and_split "*x86_shld_shrd_1_nozext_nf"
15620   [(set (match_operand:SI 0 "nonimmediate_operand")
15621         (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
15622                              (match_operand:QI 2 "const_0_to_31_operand"))
15623                (lshiftrt:SI
15624                    (match_operand:SI 1 "nonimmediate_operand")
15625                    (match_operand:QI 3 "const_0_to_31_operand"))))]
15626   "TARGET_APX_NF
15627    && INTVAL (operands[3]) == 32 - INTVAL (operands[2])
15628    && ix86_pre_reload_split ()"
15629   "#"
15630   "&& 1"
15631   [(const_int 0)]
15633   if (rtx_equal_p (operands[4], operands[0]))
15634     {
15635       operands[1] = force_reg (SImode, operands[1]);
15636       emit_insn (gen_x86_shld_1_nf (operands[0], operands[1],
15637                                     operands[2], operands[3]));
15638     }
15639   else if (rtx_equal_p (operands[1], operands[0]))
15640     {
15641       operands[4] = force_reg (SImode, operands[4]);
15642       emit_insn (gen_x86_shrd_1_nf (operands[0], operands[4],
15643                                     operands[3], operands[2]));
15644     }
15645   else if (TARGET_APX_NDD)
15646     {
15647      rtx tmp = gen_reg_rtx (SImode);
15648      if (MEM_P (operands[4]))
15649        {
15650          operands[1] = force_reg (SImode, operands[1]);
15651          emit_insn (gen_x86_shld_ndd_1_nf (tmp, operands[4], operands[1],
15652                                            operands[2], operands[3]));
15653        }
15654      else if (MEM_P (operands[1]))
15655        emit_insn (gen_x86_shrd_ndd_1_nf (tmp, operands[1], operands[4],
15656                                          operands[3], operands[2]));
15657      else
15658        emit_insn (gen_x86_shld_ndd_1_nf (tmp, operands[4], operands[1],
15659                                          operands[2], operands[3]));
15660      emit_move_insn (operands[0], tmp);
15661     }
15662  else
15663    {
15664      operands[1] = force_reg (SImode, operands[1]);
15665      rtx tmp = gen_reg_rtx (SImode);
15666      emit_move_insn (tmp, operands[4]);
15667      emit_insn (gen_x86_shld_1_nf (tmp, operands[1], operands[2],
15668                                    operands[3]));
15669      emit_move_insn (operands[0], tmp);
15670    }
15671    DONE;
15674 (define_insn_and_split "*x86_shld_shrd_1_nozext"
15675   [(set (match_operand:SI 0 "nonimmediate_operand")
15676         (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
15677                              (match_operand:QI 2 "const_0_to_31_operand"))
15678                (lshiftrt:SI
15679                    (match_operand:SI 1 "nonimmediate_operand")
15680                    (match_operand:QI 3 "const_0_to_31_operand"))))
15681    (clobber (reg:CC FLAGS_REG))]
15682   "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
15683    && ix86_pre_reload_split ()"
15684   "#"
15685   "&& 1"
15686   [(const_int 0)]
15688   if (rtx_equal_p (operands[4], operands[0]))
15689     {
15690       operands[1] = force_reg (SImode, operands[1]);
15691       emit_insn (gen_x86_shld_1 (operands[0], operands[1], operands[2], operands[3]));
15692     }
15693   else if (rtx_equal_p (operands[1], operands[0]))
15694     {
15695       operands[4] = force_reg (SImode, operands[4]);
15696       emit_insn (gen_x86_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
15697     }
15698   else if (TARGET_APX_NDD)
15699     {
15700      rtx tmp = gen_reg_rtx (SImode);
15701      if (MEM_P (operands[4]))
15702        {
15703          operands[1] = force_reg (SImode, operands[1]);
15704          emit_insn (gen_x86_shld_ndd_1 (tmp, operands[4], operands[1],
15705                                         operands[2], operands[3]));
15706        }
15707      else if (MEM_P (operands[1]))
15708        emit_insn (gen_x86_shrd_ndd_1 (tmp, operands[1], operands[4],
15709                                       operands[3], operands[2]));
15710      else
15711        emit_insn (gen_x86_shld_ndd_1 (tmp, operands[4], operands[1],
15712                                       operands[2], operands[3]));
15713      emit_move_insn (operands[0], tmp);
15714     }
15715  else
15716    {
15717      operands[1] = force_reg (SImode, operands[1]);
15718      rtx tmp = gen_reg_rtx (SImode);
15719      emit_move_insn (tmp, operands[4]);
15720      emit_insn (gen_x86_shld_1 (tmp, operands[1], operands[2], operands[3]));
15721      emit_move_insn (operands[0], tmp);
15722    }
15723    DONE;
15725   [(set_attr "has_nf" "1")])
15727 (define_insn_and_split "*x86_shld_2"
15728   [(set (match_operand:SI 0 "nonimmediate_operand")
15729         (ior:SI (ashift:SI (match_dup 0)
15730                            (match_operand:QI 2 "nonmemory_operand"))
15731                 (lshiftrt:SI (match_operand:SI 1 "register_operand")
15732                              (minus:QI (const_int 32) (match_dup 2)))))
15733    (clobber (reg:CC FLAGS_REG))]
15734   "TARGET_64BIT && ix86_pre_reload_split ()"
15735   "#"
15736   "&& 1"
15737   [(parallel [(set (match_dup 0)
15738                    (ior:SI (ashift:SI (match_dup 0)
15739                                       (and:QI (match_dup 2) (const_int 31)))
15740                            (subreg:SI
15741                              (lshiftrt:DI
15742                                (zero_extend:DI (match_dup 1))
15743                                  (minus:QI (const_int 32)
15744                                            (and:QI (match_dup 2)
15745                                                    (const_int 31)))) 0)))
15746               (clobber (reg:CC FLAGS_REG))])])
15748 (define_insn_and_split "*x86_shld_ndd_2"
15749   [(set (match_operand:SI 0 "nonimmediate_operand")
15750         (ior:SI (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
15751                            (match_operand:QI 3 "nonmemory_operand"))
15752                 (lshiftrt:SI (match_operand:SI 2 "register_operand")
15753                              (minus:QI (const_int 32) (match_dup 3)))))
15754    (clobber (reg:CC FLAGS_REG))]
15755   "TARGET_APX_NDD
15756    && ix86_pre_reload_split ()"
15757   "#"
15758   "&& 1"
15759   [(parallel [(set (match_dup 4)
15760                    (ior:SI (ashift:SI (match_dup 1)
15761                                       (and:QI (match_dup 3) (const_int 31)))
15762                            (subreg:SI
15763                              (lshiftrt:DI
15764                                (zero_extend:DI (match_dup 2))
15765                                  (minus:QI (const_int 32)
15766                                            (and:QI (match_dup 3)
15767                                                    (const_int 31)))) 0)))
15768               (clobber (reg:CC FLAGS_REG))
15769               (set (match_dup 0) (match_dup 4))])]
15771   operands[4] = gen_reg_rtx (SImode);
15772   emit_move_insn (operands[4], operands[0]);
15775 (define_expand "@x86_shift<mode>_adj_1"
15776   [(set (reg:CCZ FLAGS_REG)
15777         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
15778                              (match_dup 4))
15779                      (const_int 0)))
15780    (set (match_operand:SWI48 0 "register_operand")
15781         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
15782                             (match_operand:SWI48 1 "register_operand")
15783                             (match_dup 0)))
15784    (set (match_dup 1)
15785         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
15786                             (match_operand:SWI48 3 "register_operand")
15787                             (match_dup 1)))]
15788   "TARGET_CMOVE"
15789   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
15791 (define_expand "@x86_shift<mode>_adj_2"
15792   [(use (match_operand:SWI48 0 "register_operand"))
15793    (use (match_operand:SWI48 1 "register_operand"))
15794    (use (match_operand:QI 2 "register_operand"))]
15795   ""
15797   rtx_code_label *label = gen_label_rtx ();
15798   rtx tmp;
15800   emit_insn (gen_testqi_ccz_1 (operands[2],
15801                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
15803   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
15804   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
15805   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
15806                               gen_rtx_LABEL_REF (VOIDmode, label),
15807                               pc_rtx);
15808   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
15809   JUMP_LABEL (tmp) = label;
15811   emit_move_insn (operands[0], operands[1]);
15812   ix86_expand_clear (operands[1]);
15814   emit_label (label);
15815   LABEL_NUSES (label) = 1;
15817   DONE;
15820 ;; Avoid useless masking of count operand.
15821 (define_insn_and_split "*ashl<mode>3_mask"
15822   [(set (match_operand:SWI48 0 "nonimmediate_operand")
15823         (ashift:SWI48
15824           (match_operand:SWI48 1 "nonimmediate_operand")
15825           (subreg:QI
15826             (and
15827               (match_operand 2 "int248_register_operand" "c,r")
15828               (match_operand 3 "const_int_operand")) 0)))
15829    (clobber (reg:CC FLAGS_REG))]
15830   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
15831    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15832       == GET_MODE_BITSIZE (<MODE>mode)-1
15833    && ix86_pre_reload_split ()"
15834   "#"
15835   "&& 1"
15836   [(parallel
15837      [(set (match_dup 0)
15838            (ashift:SWI48 (match_dup 1)
15839                          (match_dup 2)))
15840       (clobber (reg:CC FLAGS_REG))])]
15842   operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15843   operands[2] = gen_lowpart (QImode, operands[2]);
15845   [(set_attr "isa" "*,bmi2")])
15847 (define_insn_and_split "*ashl<mode>3_mask_1"
15848   [(set (match_operand:SWI48 0 "nonimmediate_operand")
15849         (ashift:SWI48
15850           (match_operand:SWI48 1 "nonimmediate_operand")
15851           (and:QI
15852             (match_operand:QI 2 "register_operand" "c,r")
15853             (match_operand:QI 3 "const_int_operand"))))
15854    (clobber (reg:CC FLAGS_REG))]
15855   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
15856    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15857       == GET_MODE_BITSIZE (<MODE>mode)-1
15858    && ix86_pre_reload_split ()"
15859   "#"
15860   "&& 1"
15861   [(parallel
15862      [(set (match_dup 0)
15863            (ashift:SWI48 (match_dup 1)
15864                          (match_dup 2)))
15865       (clobber (reg:CC FLAGS_REG))])]
15866   ""
15867   [(set_attr "isa" "*,bmi2")])
15869 (define_insn "*bmi2_ashl<mode>3_1"
15870   [(set (match_operand:SWI48 0 "register_operand" "=r")
15871         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
15872                       (match_operand:SWI48 2 "register_operand" "r")))]
15873   "TARGET_BMI2"
15874   "shlx\t{%2, %1, %0|%0, %1, %2}"
15875   [(set_attr "type" "ishiftx")
15876    (set_attr "mode" "<MODE>")])
15878 (define_insn "*ashl<mode>3_1<nf_name>"
15879   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,?k,r")
15880         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm,k,rm")
15881                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r,<KS>,c<S>")))]
15882   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands, TARGET_APX_NDD)
15883    && <nf_condition>"
15885   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
15886   switch (get_attr_type (insn))
15887     {
15888     case TYPE_LEA:
15889       if (TARGET_APX_NDD && <nf_applied>)
15890         return "%{nf%} sal{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}";
15891       else
15892         return "#";
15894     case TYPE_ISHIFTX:
15895     case TYPE_MSKLOG:
15896       return "#";
15898     case TYPE_ALU:
15899       gcc_assert (operands[2] == const1_rtx);
15900       gcc_assert (rtx_equal_p (operands[0], operands[1]));
15901       return "<nf_prefix>add{<imodesuffix>}\t%0, %0";
15903     default:
15904       if (operands[2] == const1_rtx
15905           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
15906           /* For NDD form instructions related to TARGET_SHIFT1, the $1
15907              immediate do not need to be omitted as assembler will map it
15908              to use shorter encoding. */
15909           && !use_ndd && !<nf_applied>)
15910         return "sal{<imodesuffix>}\t%0";
15911       else
15912         return use_ndd ? "<nf_prefix>sal{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
15913                        : "<nf_prefix>sal{<imodesuffix>}\t{%2, %0|%0, %2}";
15914     }
15916   [(set_attr "isa" "*,*,bmi2,avx512bw,apx_ndd")
15917    (set (attr "type")
15918      (cond [(eq_attr "alternative" "1")
15919               (const_string "lea")
15920             (eq_attr "alternative" "2")
15921               (const_string "ishiftx")
15922             (eq_attr "alternative" "4")
15923               (const_string "ishift")
15924             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
15925                       (match_operand 0 "register_operand"))
15926                  (match_operand 2 "const1_operand"))
15927               (const_string "alu")
15928             (eq_attr "alternative" "3")
15929               (const_string "msklog")
15930            ]
15931            (const_string "ishift")))
15932    (set (attr "length_immediate")
15933      (if_then_else
15934        (ior (eq_attr "type" "alu")
15935             (and (eq_attr "type" "ishift")
15936                  (and (match_operand 2 "const1_operand")
15937                       (ior (match_test "TARGET_SHIFT1")
15938                            (match_test "optimize_function_for_size_p (cfun)")))))
15939        (const_string "0")
15940        (const_string "*")))
15941    (set_attr "has_nf" "1")
15942    (set_attr "mode" "<MODE>")])
15944 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15945 ;; For NF/NDD doesn't support shift count as r, it just support c<S>,
15946 ;; and it has no flag.
15947 (define_split
15948   [(set (match_operand:SWI48 0 "register_operand")
15949         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15950                       (match_operand:QI 2 "register_operand")))]
15951   "TARGET_BMI2 && reload_completed"
15952   [(set (match_dup 0)
15953         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
15954   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
15956 (define_split
15957   [(set (match_operand:SWI48 0 "register_operand")
15958         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15959                       (match_operand:QI 2 "register_operand")))
15960    (clobber (reg:CC FLAGS_REG))]
15961   "TARGET_BMI2 && reload_completed"
15962   [(set (match_dup 0)
15963         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
15964   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
15966 (define_insn "*bmi2_ashlsi3_1_zext"
15967   [(set (match_operand:DI 0 "register_operand" "=r")
15968         (zero_extend:DI
15969           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15970                      (match_operand:SI 2 "register_operand" "r"))))]
15971   "TARGET_64BIT && TARGET_BMI2"
15972   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
15973   [(set_attr "type" "ishiftx")
15974    (set_attr "mode" "SI")])
15976 (define_insn "*ashlqi3_1_zext<mode><nf_name>"
15977   [(set (match_operand:SWI248x 0 "register_operand" "=r")
15978         (zero_extend:SWI248x
15979           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "rm")
15980                      (match_operand:QI 2 "nonmemory_operand" "cI"))))]
15981   "TARGET_APX_NDD && <nf_condition>"
15982   "<nf_prefix>sal{b}\t{%2, %1, %b0|%b0, %1, %2}"
15983   [(set_attr "type" "ishiftx")
15984    (set_attr "has_nf" "1")
15985    (set_attr "mode" "QI")])
15987 (define_insn "*ashlhi3_1_zext<mode><nf_name>"
15988   [(set (match_operand:SWI48x 0 "register_operand" "=r")
15989         (zero_extend:SWI48x
15990           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "rm")
15991                      (match_operand:QI 2 "nonmemory_operand" "cI"))))]
15992   "TARGET_APX_NDD && <nf_condition>"
15993   "<nf_prefix>sal{w}\t{%2, %1, %w0|%w0, %1, %2}"
15994   [(set_attr "type" "ishiftx")
15995    (set_attr "has_nf" "1")
15996    (set_attr "mode" "HI")])
15998 (define_insn "*ashlsi3_1_zext"
15999   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
16000         (zero_extend:DI
16001           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm,rm")
16002                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r,cI"))))
16003    (clobber (reg:CC FLAGS_REG))]
16004   "TARGET_64BIT
16005    && ix86_binary_operator_ok (ASHIFT, SImode, operands, TARGET_APX_NDD)"
16007   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16008   switch (get_attr_type (insn))
16009     {
16010     case TYPE_LEA:
16011     case TYPE_ISHIFTX:
16012       return "#";
16014     case TYPE_ALU:
16015       gcc_assert (operands[2] == const1_rtx);
16016       return "add{l}\t%k0, %k0";
16018     default:
16019       if (operands[2] == const1_rtx
16020           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16021           && !use_ndd)
16022         return "sal{l}\t%k0";
16023       else
16024         return use_ndd ? "sal{l}\t{%2, %1, %k0|%k0, %1, %2}"
16025                        : "sal{l}\t{%2, %k0|%k0, %2}";
16026     }
16028   [(set_attr "isa" "*,*,bmi2,apx_ndd")
16029    (set (attr "type")
16030      (cond [(eq_attr "alternative" "1")
16031               (const_string "lea")
16032             (eq_attr "alternative" "2")
16033               (const_string "ishiftx")
16034             (eq_attr "alternative" "3")
16035               (const_string "ishift")
16036             (and (match_test "TARGET_DOUBLE_WITH_ADD")
16037                  (match_operand 2 "const1_operand"))
16038               (const_string "alu")
16039            ]
16040            (const_string "ishift")))
16041    (set (attr "length_immediate")
16042      (if_then_else
16043        (ior (eq_attr "type" "alu")
16044             (and (eq_attr "type" "ishift")
16045                  (and (match_operand 2 "const1_operand")
16046                       (ior (match_test "TARGET_SHIFT1")
16047                            (match_test "optimize_function_for_size_p (cfun)")))))
16048        (const_string "0")
16049        (const_string "*")))
16050    (set_attr "mode" "SI")])
16052 ;; Convert shift to the shiftx pattern to avoid flags dependency.
16053 (define_split
16054   [(set (match_operand:DI 0 "register_operand")
16055         (zero_extend:DI
16056           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
16057                      (match_operand:QI 2 "register_operand"))))
16058    (clobber (reg:CC FLAGS_REG))]
16059   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
16060   [(set (match_dup 0)
16061         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
16062   "operands[2] = gen_lowpart (SImode, operands[2]);")
16064 (define_insn "*ashlhi3_1<nf_name>"
16065   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp,?k,r")
16066         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l,k,rm")
16067                    (match_operand:QI 2 "nonmemory_operand" "cI,M,Ww,cI")))]
16068   "ix86_binary_operator_ok (ASHIFT, HImode, operands, TARGET_APX_NDD)
16069    && <nf_condition>"
16071   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16072   switch (get_attr_type (insn))
16073     {
16074     case TYPE_LEA:
16075       if (TARGET_APX_NDD && <nf_applied>)
16076         return "%{nf%} sal{w}\t{%2, %1, %0|%0, %1, %2}";
16077       else
16078         return "#";
16080     case TYPE_MSKLOG:
16081       return "#";
16083     case TYPE_ALU:
16084       gcc_assert (operands[2] == const1_rtx);
16085       return "<nf_prefix>add{w}\t%0, %0";
16087     default:
16088       if (operands[2] == const1_rtx
16089           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16090           && !use_ndd && !<nf_applied>)
16091         return "sal{w}\t%0";
16092       else
16093         return use_ndd ? "<nf_prefix>sal{w}\t{%2, %1, %0|%0, %1, %2}"
16094                        : "<nf_prefix>sal{w}\t{%2, %0|%0, %2}";
16095     }
16097   [(set_attr "isa" "*,*,avx512f,apx_ndd")
16098    (set (attr "type")
16099      (cond [(eq_attr "alternative" "1")
16100               (const_string "lea")
16101             (eq_attr "alternative" "2")
16102               (const_string "msklog")
16103             (eq_attr "alternative" "3")
16104               (const_string "ishift")
16105             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
16106                       (match_operand 0 "register_operand"))
16107                  (match_operand 2 "const1_operand"))
16108               (const_string "alu")
16109            ]
16110            (const_string "ishift")))
16111    (set (attr "length_immediate")
16112      (if_then_else
16113        (ior (eq_attr "type" "alu")
16114             (and (eq_attr "type" "ishift")
16115                  (and (match_operand 2 "const1_operand")
16116                       (ior (match_test "TARGET_SHIFT1")
16117                            (match_test "optimize_function_for_size_p (cfun)")))))
16118        (const_string "0")
16119        (const_string "*")))
16120    (set_attr "has_nf" "1")
16121    (set_attr "mode" "HI,SI,HI,HI")])
16123 (define_insn "*ashlqi3_1<nf_name>"
16124   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp,?k,r")
16125         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l,k,rm")
16126                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M,Wb,cI")))]
16127   "ix86_binary_operator_ok (ASHIFT, QImode, operands, TARGET_APX_NDD)
16128    && <nf_condition>"
16130   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16131   switch (get_attr_type (insn))
16132     {
16133     case TYPE_LEA:
16134       if (TARGET_APX_NDD && <nf_applied>)
16135         return "%{nf%} sal{b}\t{%2, %1, %0|%0, %1, %2}";
16136       else
16137         return "#";
16139     case TYPE_MSKLOG:
16140       return "#";
16142     case TYPE_ALU:
16143       gcc_assert (operands[2] == const1_rtx);
16144       if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
16145         return "<nf_prefix>add{l}\t%k0, %k0";
16146       else
16147         return "<nf_prefix>add{b}\t%0, %0";
16149     default:
16150       if (operands[2] == const1_rtx
16151           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16152           && !use_ndd && !<nf_applied>)
16153         {
16154           if (get_attr_mode (insn) == MODE_SI)
16155             return "sal{l}\t%k0";
16156           else
16157             return "sal{b}\t%0";
16158         }
16159       else
16160         {
16161           if (get_attr_mode (insn) == MODE_SI)
16162             return "<nf_prefix>sal{l}\t{%2, %k0|%k0, %2}";
16163           else
16164             return use_ndd ? "<nf_prefix>sal{b}\t{%2, %1, %0|%0, %1, %2}"
16165                            : "<nf_prefix>sal{b}\t{%2, %0|%0, %2}";
16166         }
16167     }
16169   [(set_attr "isa" "*,*,*,avx512dq,apx_ndd")
16170    (set (attr "type")
16171      (cond [(eq_attr "alternative" "2")
16172               (const_string "lea")
16173             (eq_attr "alternative" "3")
16174               (const_string "msklog")
16175             (eq_attr "alternative" "4")
16176               (const_string "ishift")
16177             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
16178                       (match_operand 0 "register_operand"))
16179                  (match_operand 2 "const1_operand"))
16180               (const_string "alu")
16181            ]
16182            (const_string "ishift")))
16183    (set (attr "length_immediate")
16184      (if_then_else
16185        (ior (eq_attr "type" "alu")
16186             (and (eq_attr "type" "ishift")
16187                  (and (match_operand 2 "const1_operand")
16188                       (ior (match_test "TARGET_SHIFT1")
16189                            (match_test "optimize_function_for_size_p (cfun)")))))
16190        (const_string "0")
16191        (const_string "*")))
16192    (set_attr "has_nf" "1")
16193    (set_attr "mode" "QI,SI,SI,QI,QI")
16194    ;; Potential partial reg stall on alternative 1.
16195    (set (attr "preferred_for_speed")
16196      (cond [(eq_attr "alternative" "1,4")
16197               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
16198            (symbol_ref "true")))])
16200 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
16201 (define_insn_and_split "*ashl<mode>3_1_slp"
16202   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
16203         (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
16204                       (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
16205    (clobber (reg:CC FLAGS_REG))]
16206   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
16208   if (which_alternative)
16209     return "#";
16211   switch (get_attr_type (insn))
16212     {
16213     case TYPE_ALU:
16214       gcc_assert (operands[2] == const1_rtx);
16215       return "add{<imodesuffix>}\t%0, %0";
16217     default:
16218       if (operands[2] == const1_rtx
16219           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
16220         return "sal{<imodesuffix>}\t%0";
16221       else
16222         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
16223     }
16225   "&& reload_completed
16226    && !(rtx_equal_p (operands[0], operands[1]))"
16227   [(set (strict_low_part (match_dup 0)) (match_dup 1))
16228    (parallel
16229      [(set (strict_low_part (match_dup 0))
16230            (ashift:SWI12 (match_dup 0) (match_dup 2)))
16231       (clobber (reg:CC FLAGS_REG))])]
16232   ""
16233   [(set (attr "type")
16234      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
16235                  (match_operand 2 "const1_operand"))
16236               (const_string "alu")
16237            ]
16238            (const_string "ishift")))
16239    (set (attr "length_immediate")
16240      (if_then_else
16241        (ior (eq_attr "type" "alu")
16242             (and (eq_attr "type" "ishift")
16243                  (and (match_operand 2 "const1_operand")
16244                       (ior (match_test "TARGET_SHIFT1")
16245                            (match_test "optimize_function_for_size_p (cfun)")))))
16246        (const_string "0")
16247        (const_string "*")))
16248    (set_attr "mode" "<MODE>")])
16250 ;; Convert ashift to the lea pattern to avoid flags dependency.
16251 (define_split
16252   [(set (match_operand:SWI 0 "general_reg_operand")
16253         (ashift:SWI (match_operand:SWI 1 "index_reg_operand")
16254                     (match_operand 2 "const_0_to_3_operand")))
16255    (clobber (reg:CC FLAGS_REG))]
16256   "reload_completed
16257    && REGNO (operands[0]) != REGNO (operands[1])"
16258   [(set (match_dup 0)
16259         (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
16261   if (<MODE>mode != <LEAMODE>mode)
16262     {
16263       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
16264       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
16265     }
16266   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
16269 (define_split
16270   [(set (match_operand:SWI 0 "general_reg_operand")
16271         (ashift:SWI (match_operand:SWI 1 "index_reg_operand")
16272                     (match_operand 2 "const_0_to_3_operand")))]
16273   "reload_completed
16274    && REGNO (operands[0]) != REGNO (operands[1])
16275    && !TARGET_APX_NDD"
16276   [(set (match_dup 0)
16277         (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
16279   if (<MODE>mode != <LEAMODE>mode)
16280     {
16281       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
16282       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
16283     }
16284   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
16287 ;; Convert ashift to the lea pattern to avoid flags dependency.
16288 (define_split
16289   [(set (match_operand:DI 0 "general_reg_operand")
16290         (zero_extend:DI
16291           (ashift:SI (match_operand:SI 1 "index_reg_operand")
16292                      (match_operand 2 "const_0_to_3_operand"))))
16293    (clobber (reg:CC FLAGS_REG))]
16294   "TARGET_64BIT && reload_completed
16295    && REGNO (operands[0]) != REGNO (operands[1])"
16296   [(set (match_dup 0)
16297         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
16299   operands[1] = gen_lowpart (SImode, operands[1]);
16300   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
16303 ;; This pattern can't accept a variable shift count, since shifts by
16304 ;; zero don't affect the flags.  We assume that shifts by constant
16305 ;; zero are optimized away.
16306 (define_insn "*ashl<mode>3_cmp"
16307   [(set (reg FLAGS_REG)
16308         (compare
16309           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm")
16310                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>,<S>"))
16311           (const_int 0)))
16312    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
16313         (ashift:SWI (match_dup 1) (match_dup 2)))]
16314   "(optimize_function_for_size_p (cfun)
16315     || !TARGET_PARTIAL_FLAG_REG_STALL
16316     || (operands[2] == const1_rtx
16317         && (TARGET_SHIFT1
16318             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
16319    && ix86_match_ccmode (insn, CCGOCmode)
16320    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands, TARGET_APX_NDD)"
16322   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16323   switch (get_attr_type (insn))
16324     {
16325     case TYPE_ALU:
16326       gcc_assert (operands[2] == const1_rtx);
16327       return "add{<imodesuffix>}\t%0, %0";
16329     default:
16330       if (operands[2] == const1_rtx
16331           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16332           && !use_ndd)
16333         return "sal{<imodesuffix>}\t%0";
16334       else
16335         return use_ndd ? "sal{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
16336                        : "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
16337     }
16339   [(set_attr "isa" "*,apx_ndd")
16340    (set (attr "type")
16341      (cond [(eq_attr "alternative" "1")
16342               (const_string "ishift")
16343             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
16344                       (match_operand 0 "register_operand"))
16345                  (match_operand 2 "const1_operand"))
16346               (const_string "alu")
16347            ]
16348            (const_string "ishift")))
16349    (set (attr "length_immediate")
16350      (if_then_else
16351        (ior (eq_attr "type" "alu")
16352             (and (eq_attr "type" "ishift")
16353                  (and (match_operand 2 "const1_operand")
16354                       (ior (match_test "TARGET_SHIFT1")
16355                            (match_test "optimize_function_for_size_p (cfun)")))))
16356        (const_string "0")
16357        (const_string "*")))
16358    (set_attr "mode" "<MODE>")])
16360 (define_insn "*ashlsi3_cmp_zext"
16361   [(set (reg FLAGS_REG)
16362         (compare
16363           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
16364                      (match_operand:QI 2 "const_1_to_31_operand"))
16365           (const_int 0)))
16366    (set (match_operand:DI 0 "register_operand" "=r,r")
16367         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
16368   "TARGET_64BIT
16369    && (optimize_function_for_size_p (cfun)
16370        || !TARGET_PARTIAL_FLAG_REG_STALL
16371        || (operands[2] == const1_rtx
16372            && (TARGET_SHIFT1
16373                || TARGET_DOUBLE_WITH_ADD)))
16374    && ix86_match_ccmode (insn, CCGOCmode)
16375    && ix86_binary_operator_ok (ASHIFT, SImode, operands, TARGET_APX_NDD)"
16377   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16378   switch (get_attr_type (insn))
16379     {
16380     case TYPE_ALU:
16381       gcc_assert (operands[2] == const1_rtx);
16382       return "add{l}\t%k0, %k0";
16384     default:
16385       if (operands[2] == const1_rtx
16386           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16387           && !use_ndd)
16388         return "sal{l}\t%k0";
16389       else
16390         return use_ndd ? "sal{l}\t{%2, %1, %k0|%k0, %1, %2}"
16391                        : "sal{l}\t{%2, %k0|%k0, %2}";
16392     }
16394   [(set_attr "isa" "*,apx_ndd")
16395    (set (attr "type")
16396      (cond [(eq_attr "alternative" "1")
16397               (const_string "ishift")
16398             (and (match_test "TARGET_DOUBLE_WITH_ADD")
16399                  (match_operand 2 "const1_operand"))
16400               (const_string "alu")
16401            ]
16402            (const_string "ishift")))
16403    (set (attr "length_immediate")
16404      (if_then_else
16405        (ior (eq_attr "type" "alu")
16406             (and (eq_attr "type" "ishift")
16407                  (and (match_operand 2 "const1_operand")
16408                       (ior (match_test "TARGET_SHIFT1")
16409                            (match_test "optimize_function_for_size_p (cfun)")))))
16410        (const_string "0")
16411        (const_string "*")))
16412    (set_attr "mode" "SI")])
16414 (define_insn "*ashl<mode>3_cconly"
16415   [(set (reg FLAGS_REG)
16416         (compare
16417           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm")
16418                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>,<S>"))
16419           (const_int 0)))
16420    (clobber (match_scratch:SWI 0 "=<r>,r"))]
16421   "(optimize_function_for_size_p (cfun)
16422     || !TARGET_PARTIAL_FLAG_REG_STALL
16423     || (operands[2] == const1_rtx
16424         && (TARGET_SHIFT1
16425             || TARGET_DOUBLE_WITH_ADD)))
16426    && ix86_match_ccmode (insn, CCGOCmode)"
16428   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16429   switch (get_attr_type (insn))
16430     {
16431     case TYPE_ALU:
16432       gcc_assert (operands[2] == const1_rtx);
16433       return "add{<imodesuffix>}\t%0, %0";
16435   default:
16436       if (operands[2] == const1_rtx
16437           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16438           && !use_ndd)
16439         return "sal{<imodesuffix>}\t%0";
16440       else
16441         return use_ndd ? "sal{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
16442                        : "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
16443     }
16445   [(set_attr "isa" "*,apx_ndd")
16446    (set (attr "type")
16447      (cond [(eq_attr "alternative" "1")
16448               (const_string "ishift")
16449             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
16450                       (match_operand 0 "register_operand"))
16451                  (match_operand 2 "const1_operand"))
16452               (const_string "alu")
16453            ]
16454            (const_string "ishift")))
16455    (set (attr "length_immediate")
16456      (if_then_else
16457        (ior (eq_attr "type" "alu")
16458             (and (eq_attr "type" "ishift")
16459                  (and (match_operand 2 "const1_operand")
16460                       (ior (match_test "TARGET_SHIFT1")
16461                            (match_test "optimize_function_for_size_p (cfun)")))))
16462        (const_string "0")
16463        (const_string "*")))
16464    (set_attr "mode" "<MODE>")])
16466 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
16467 (define_insn_and_split "*ashlqi_ext<mode>_1"
16468   [(set (zero_extract:SWI248
16469           (match_operand 0 "int248_register_operand" "+Q,&Q")
16470           (const_int 8)
16471           (const_int 8))
16472         (subreg:SWI248
16473           (ashift:QI
16474             (subreg:QI
16475               (match_operator:SWI248 3 "extract_operator"
16476                 [(match_operand 1 "int248_register_operand" "0,!Q")
16477                  (const_int 8)
16478                  (const_int 8)]) 0)
16479             (match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
16480    (clobber (reg:CC FLAGS_REG))]
16481   ""
16483   if (which_alternative)
16484     return "#";
16486   switch (get_attr_type (insn))
16487     {
16488     case TYPE_ALU:
16489       gcc_assert (operands[2] == const1_rtx);
16490       return "add{b}\t%h0, %h0";
16492     default:
16493       if (operands[2] == const1_rtx
16494           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
16495         return "sal{b}\t%h0";
16496       else
16497         return "sal{b}\t{%2, %h0|%h0, %2}";
16498     }
16500   "reload_completed
16501    && !(rtx_equal_p (operands[0], operands[1]))"
16502   [(set (zero_extract:SWI248
16503           (match_dup 0) (const_int 8) (const_int 8))
16504         (zero_extract:SWI248
16505           (match_dup 1) (const_int 8) (const_int 8)))
16506    (parallel
16507      [(set (zero_extract:SWI248
16508              (match_dup 0) (const_int 8) (const_int 8))
16509            (subreg:SWI248
16510              (ashift:QI
16511                (subreg:QI
16512                  (match_op_dup 3
16513                    [(match_dup 0) (const_int 8) (const_int 8)]) 0)
16514                (match_dup 2)) 0))
16515       (clobber (reg:CC FLAGS_REG))])]
16516   ""
16517   [(set (attr "type")
16518      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
16519                  (match_operand 2 "const1_operand"))
16520               (const_string "alu")
16521            ]
16522            (const_string "ishift")))
16523    (set (attr "length_immediate")
16524      (if_then_else
16525        (ior (eq_attr "type" "alu")
16526             (and (eq_attr "type" "ishift")
16527                  (and (match_operand 2 "const1_operand")
16528                       (ior (match_test "TARGET_SHIFT1")
16529                            (match_test "optimize_function_for_size_p (cfun)")))))
16530        (const_string "0")
16531        (const_string "*")))
16532    (set_attr "mode" "QI")])
16534 ;; See comment above `ashl<mode>3' about how this works.
16536 (define_expand "<insn><mode>3"
16537   [(set (match_operand:SDWIM 0 "<shift_operand>")
16538         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
16539                            (match_operand:QI 2 "nonmemory_operand")))]
16540   ""
16542   ix86_expand_binary_operator (<CODE>, <MODE>mode, operands, TARGET_APX_NDD);
16543   DONE;
16546 ;; Avoid useless masking of count operand.
16547 (define_insn_and_split "*<insn><mode>3_mask"
16548   [(set (match_operand:SWI48 0 "nonimmediate_operand")
16549         (any_shiftrt:SWI48
16550           (match_operand:SWI48 1 "nonimmediate_operand")
16551           (subreg:QI
16552             (and
16553               (match_operand 2 "int248_register_operand" "c,r")
16554               (match_operand 3 "const_int_operand")) 0)))
16555    (clobber (reg:CC FLAGS_REG))]
16556   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
16557    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16558       == GET_MODE_BITSIZE (<MODE>mode)-1
16559    && ix86_pre_reload_split ()"
16560   "#"
16561   "&& 1"
16562   [(parallel
16563      [(set (match_dup 0)
16564            (any_shiftrt:SWI48 (match_dup 1)
16565                               (match_dup 2)))
16566       (clobber (reg:CC FLAGS_REG))])]
16568   operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
16569   operands[2] = gen_lowpart (QImode, operands[2]);
16571   [(set_attr "isa" "*,bmi2")])
16573 (define_insn_and_split "*<insn><mode>3_mask_1"
16574   [(set (match_operand:SWI48 0 "nonimmediate_operand")
16575         (any_shiftrt:SWI48
16576           (match_operand:SWI48 1 "nonimmediate_operand")
16577           (and:QI
16578             (match_operand:QI 2 "register_operand" "c,r")
16579             (match_operand:QI 3 "const_int_operand"))))
16580    (clobber (reg:CC FLAGS_REG))]
16581   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
16582    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16583       == GET_MODE_BITSIZE (<MODE>mode)-1
16584    && ix86_pre_reload_split ()"
16585   "#"
16586   "&& 1"
16587   [(parallel
16588      [(set (match_dup 0)
16589            (any_shiftrt:SWI48 (match_dup 1)
16590                               (match_dup 2)))
16591       (clobber (reg:CC FLAGS_REG))])]
16592   ""
16593   [(set_attr "isa" "*,bmi2")])
16595 (define_insn_and_split "*<insn><dwi>3_doubleword_mask"
16596   [(set (match_operand:<DWI> 0 "register_operand")
16597         (any_shiftrt:<DWI>
16598           (match_operand:<DWI> 1 "register_operand")
16599           (subreg:QI
16600             (and
16601               (match_operand 2 "int248_register_operand" "c")
16602               (match_operand 3 "const_int_operand")) 0)))
16603    (clobber (reg:CC FLAGS_REG))]
16604   "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
16605     || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
16606          == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
16607    && ix86_pre_reload_split ()"
16608   "#"
16609   "&& 1"
16610   [(parallel
16611      [(set (match_dup 4)
16612            (ior:DWIH (lshiftrt:DWIH (match_dup 4)
16613                        (and:QI (match_dup 2) (match_dup 8)))
16614                      (subreg:DWIH
16615                        (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
16616                          (minus:QI (match_dup 9)
16617                                    (and:QI (match_dup 2) (match_dup 8)))) 0)))
16618       (clobber (reg:CC FLAGS_REG))])
16619    (parallel
16620      [(set (match_dup 6)
16621            (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
16622       (clobber (reg:CC FLAGS_REG))])]
16624   if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
16625     {
16626       operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
16627       operands[2] = gen_lowpart (QImode, operands[2]);
16628       emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
16629                                               operands[2]));
16630       DONE;
16631     }
16633   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
16635   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
16636   operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
16638   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
16639       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
16640     {
16641       rtx xops[3];
16642       xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
16643       xops[1] = operands[2];
16644       xops[2] = GEN_INT (INTVAL (operands[3])
16645                          & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
16646       ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
16647       operands[2] = xops[0];
16648     }
16650   operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
16651   operands[2] = gen_lowpart (QImode, operands[2]);
16653   if (!rtx_equal_p (operands[4], operands[5]))
16654     emit_move_insn (operands[4], operands[5]);
16657 (define_insn_and_split "*<insn><dwi>3_doubleword_mask_1"
16658   [(set (match_operand:<DWI> 0 "register_operand")
16659         (any_shiftrt:<DWI>
16660           (match_operand:<DWI> 1 "register_operand")
16661           (and:QI
16662             (match_operand:QI 2 "register_operand" "c")
16663             (match_operand:QI 3 "const_int_operand"))))
16664    (clobber (reg:CC FLAGS_REG))]
16665   "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
16666     || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
16667          == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
16668    && ix86_pre_reload_split ()"
16669   "#"
16670   "&& 1"
16671   [(parallel
16672      [(set (match_dup 4)
16673            (ior:DWIH (lshiftrt:DWIH (match_dup 4)
16674                        (and:QI (match_dup 2) (match_dup 8)))
16675                      (subreg:DWIH
16676                        (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
16677                          (minus:QI (match_dup 9)
16678                                    (and:QI (match_dup 2) (match_dup 8)))) 0)))
16679       (clobber (reg:CC FLAGS_REG))])
16680    (parallel
16681      [(set (match_dup 6)
16682            (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
16683       (clobber (reg:CC FLAGS_REG))])]
16685   if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
16686     {
16687       emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
16688                                               operands[2]));
16689       DONE;
16690     }
16692   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
16694   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
16695   operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
16697   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
16698       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
16699     {
16700       rtx tem = gen_reg_rtx (QImode);
16701       emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
16702       operands[2] = tem;
16703     }
16705   if (!rtx_equal_p (operands[4], operands[5]))
16706     emit_move_insn (operands[4], operands[5]);
16709 (define_insn_and_split "<insn><mode>3_doubleword"
16710   [(set (match_operand:DWI 0 "register_operand" "=&r,&r")
16711         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0,r")
16712                          (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
16713    (clobber (reg:CC FLAGS_REG))]
16714   ""
16715   "#"
16716   "epilogue_completed"
16717   [(const_int 0)]
16719   if (TARGET_APX_NDD
16720       && !rtx_equal_p (operands[0], operands[1]))
16721     ix86_split_rshift_ndd (<CODE>, operands, NULL_RTX);
16722   else
16723     ix86_split_<insn> (operands, NULL_RTX, <MODE>mode);
16724   DONE;
16726   [(set_attr "type" "multi")
16727    (set_attr "isa" "*,apx_ndd")])
16729 ;; By default we don't ask for a scratch register, because when DWImode
16730 ;; values are manipulated, registers are already at a premium.  But if
16731 ;; we have one handy, we won't turn it away.
16733 (define_peephole2
16734   [(match_scratch:DWIH 3 "r")
16735    (parallel [(set (match_operand:<DWI> 0 "register_operand")
16736                    (any_shiftrt:<DWI>
16737                      (match_operand:<DWI> 1 "register_operand")
16738                      (match_operand:QI 2 "nonmemory_operand")))
16739               (clobber (reg:CC FLAGS_REG))])
16740    (match_dup 3)]
16741   "TARGET_CMOVE"
16742   [(const_int 0)]
16744   if (TARGET_APX_NDD
16745       && !rtx_equal_p (operands[0], operands[1]))
16746     ix86_split_rshift_ndd (<CODE>, operands, operands[3]);
16747   else
16748     ix86_split_<insn> (operands, operands[3], <DWI>mode);
16749   DONE;
16752 ;; Split truncations of double word right shifts into x86_shrd_1.
16753 (define_insn_and_split "<insn><dwi>3_doubleword_lowpart_nf"
16754   [(set (match_operand:DWIH 0 "register_operand" "=&r")
16755         (subreg:DWIH
16756           (any_shiftrt:<DWI> (match_operand:<DWI> 1 "register_operand" "r")
16757                              (match_operand:QI 2 "const_int_operand")) 0))]
16758   "TARGET_APX_NF && UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
16759   "#"
16760   "&& reload_completed"
16761   [(set (match_dup 0)
16762         (ior:DWIH (lshiftrt:DWIH (match_dup 0) (match_dup 2))
16763                   (subreg:DWIH
16764                     (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
16765                                   (match_dup 4)) 0)))]
16767   split_double_mode (<DWI>mode, &operands[1], 1, &operands[1], &operands[3]);
16768   operands[4] = GEN_INT ((<MODE_SIZE> * BITS_PER_UNIT) - INTVAL (operands[2]));
16769   if (!rtx_equal_p (operands[0], operands[1]))
16770     emit_move_insn (operands[0], operands[1]);
16773 (define_insn_and_split "<insn><dwi>3_doubleword_lowpart"
16774   [(set (match_operand:DWIH 0 "register_operand" "=&r")
16775         (subreg:DWIH
16776           (any_shiftrt:<DWI> (match_operand:<DWI> 1 "register_operand" "r")
16777                              (match_operand:QI 2 "const_int_operand")) 0))
16778    (clobber (reg:CC FLAGS_REG))]
16779   "UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
16780   "#"
16781   "&& reload_completed"
16782   [(parallel
16783       [(set (match_dup 0)
16784             (ior:DWIH (lshiftrt:DWIH (match_dup 0) (match_dup 2))
16785                       (subreg:DWIH
16786                         (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
16787                                       (match_dup 4)) 0)))
16788        (clobber (reg:CC FLAGS_REG))])]
16790   split_double_mode (<DWI>mode, &operands[1], 1, &operands[1], &operands[3]);
16791   operands[4] = GEN_INT ((<MODE_SIZE> * BITS_PER_UNIT) - INTVAL (operands[2]));
16792   if (!rtx_equal_p (operands[0], operands[1]))
16793     emit_move_insn (operands[0], operands[1]);
16795   [(set_attr "has_nf" "1")])
16797 (define_insn "x86_64_shrd<nf_name>"
16798   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
16799         (ior:DI (lshiftrt:DI (match_dup 0)
16800                   (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
16801                           (const_int 63)))
16802                 (subreg:DI
16803                   (ashift:TI
16804                     (zero_extend:TI
16805                       (match_operand:DI 1 "register_operand" "r"))
16806                     (minus:QI (const_int 64)
16807                               (and:QI (match_dup 2) (const_int 63)))) 0)))]
16808   "TARGET_64BIT && <nf_condition>"
16809   "<nf_prefix>shrd{q}\t{%2, %1, %0|%0, %1, %2}"
16810   [(set_attr "type" "ishift")
16811    (set_attr "prefix_0f" "1")
16812    (set_attr "has_nf" "1")
16813    (set_attr "mode" "DI")
16814    (set_attr "athlon_decode" "vector")
16815    (set_attr "amdfam10_decode" "vector")
16816    (set_attr "bdver1_decode" "vector")])
16818 (define_insn "x86_64_shrd_ndd<nf_name>"
16819   [(set (match_operand:DI 0 "register_operand" "=r")
16820         (ior:DI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "rm")
16821                   (and:QI (match_operand:QI 3 "nonmemory_operand" "Jc")
16822                           (const_int 63)))
16823                 (subreg:DI
16824                   (ashift:TI
16825                     (zero_extend:TI
16826                       (match_operand:DI 2 "register_operand" "r"))
16827                     (minus:QI (const_int 64)
16828                               (and:QI (match_dup 3) (const_int 63)))) 0)))]
16829   "TARGET_APX_NDD && <nf_condition>"
16830   "<nf_prefix>shrd{q}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
16831   [(set_attr "type" "ishift")
16832    (set_attr "has_nf" "1")
16833    (set_attr "mode" "DI")])
16835 (define_insn "x86_64_shrd_1<nf_name>"
16836   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
16837         (ior:DI (lshiftrt:DI (match_dup 0)
16838                              (match_operand:QI 2 "const_0_to_63_operand"))
16839                 (subreg:DI
16840                   (ashift:TI
16841                     (zero_extend:TI
16842                       (match_operand:DI 1 "register_operand" "r"))
16843                     (match_operand:QI 3 "const_0_to_255_operand")) 0)))]
16844   "TARGET_64BIT
16845    && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
16846    && <nf_condition>"
16847   "<nf_prefix>shrd{q}\t{%2, %1, %0|%0, %1, %2}"
16848   [(set_attr "type" "ishift")
16849    (set_attr "prefix_0f" "1")
16850    (set_attr "length_immediate" "1")
16851    (set_attr "has_nf" "1")
16852    (set_attr "mode" "DI")
16853    (set_attr "athlon_decode" "vector")
16854    (set_attr "amdfam10_decode" "vector")
16855    (set_attr "bdver1_decode" "vector")])
16857 (define_insn "x86_64_shrd_ndd_1<nf_name>"
16858   [(set (match_operand:DI 0 "register_operand" "=r")
16859         (ior:DI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "rm")
16860                              (match_operand:QI 3 "const_0_to_63_operand"))
16861                 (subreg:DI
16862                   (ashift:TI
16863                     (zero_extend:TI
16864                       (match_operand:DI 2 "register_operand" "r"))
16865                     (match_operand:QI 4 "const_0_to_255_operand")) 0)))]
16866   "TARGET_APX_NDD
16867    && INTVAL (operands[4]) == 64 - INTVAL (operands[3])
16868    && <nf_condition>"
16869   "<nf_prefix>shrd{q}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
16870   [(set_attr "type" "ishift")
16871    (set_attr "length_immediate" "1")
16872    (set_attr "has_nf" "1")
16873    (set_attr "mode" "DI")])
16875 (define_insn_and_split "*x86_64_shrd_shld_1_nozext_nf"
16876   [(set (match_operand:DI 0 "nonimmediate_operand")
16877         (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
16878                              (match_operand:QI 2 "const_0_to_63_operand"))
16879                 (ashift:DI
16880                   (match_operand:DI 1 "nonimmediate_operand")
16881                   (match_operand:QI 3 "const_0_to_63_operand"))))]
16882   "TARGET_64BIT && TARGET_APX_NF
16883    && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
16884    && ix86_pre_reload_split ()"
16885   "#"
16886   "&& 1"
16887   [(const_int 0)]
16889   if (rtx_equal_p (operands[4], operands[0]))
16890     {
16891       operands[1] = force_reg (DImode, operands[1]);
16892       emit_insn (gen_x86_64_shrd_1_nf (operands[0], operands[1],
16893                                        operands[2], operands[3]));
16894     }
16895   else if (rtx_equal_p (operands[1], operands[0]))
16896     {
16897       operands[4] = force_reg (DImode, operands[4]);
16898       emit_insn (gen_x86_64_shld_1_nf (operands[0], operands[4],
16899                                        operands[3], operands[2]));
16900     }
16901   else if (TARGET_APX_NDD)
16902     {
16903       rtx tmp = gen_reg_rtx (DImode);
16904       if (MEM_P (operands[4]))
16905         {
16906           operands[1] = force_reg (DImode, operands[1]);
16907           emit_insn (gen_x86_64_shrd_ndd_1_nf (tmp, operands[4], operands[1],
16908                                                operands[2], operands[3]));
16909         }
16910        else if (MEM_P (operands[1]))
16911          emit_insn (gen_x86_64_shld_ndd_1_nf (tmp, operands[1], operands[4],
16912                                               operands[3], operands[2]));
16913        else
16914          emit_insn (gen_x86_64_shrd_ndd_1_nf (tmp, operands[4], operands[1],
16915                                               operands[2], operands[3]));
16916        emit_move_insn (operands[0], tmp);
16917     }
16918   else
16919    {
16920      operands[1] = force_reg (DImode, operands[1]);
16921      rtx tmp = gen_reg_rtx (DImode);
16922      emit_move_insn (tmp, operands[4]);
16923      emit_insn (gen_x86_64_shrd_1_nf (tmp, operands[1],
16924                                       operands[2], operands[3]));
16925      emit_move_insn (operands[0], tmp);
16926    }
16927    DONE;
16930 (define_insn_and_split "*x86_64_shrd_shld_1_nozext"
16931   [(set (match_operand:DI 0 "nonimmediate_operand")
16932         (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
16933                              (match_operand:QI 2 "const_0_to_63_operand"))
16934                 (ashift:DI
16935                   (match_operand:DI 1 "nonimmediate_operand")
16936                   (match_operand:QI 3 "const_0_to_63_operand"))))
16937    (clobber (reg:CC FLAGS_REG))]
16938   "TARGET_64BIT
16939    && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
16940    && ix86_pre_reload_split ()"
16941   "#"
16942   "&& 1"
16943   [(const_int 0)]
16945   if (rtx_equal_p (operands[4], operands[0]))
16946     {
16947       operands[1] = force_reg (DImode, operands[1]);
16948       emit_insn (gen_x86_64_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
16949     }
16950   else if (rtx_equal_p (operands[1], operands[0]))
16951     {
16952       operands[4] = force_reg (DImode, operands[4]);
16953       emit_insn (gen_x86_64_shld_1 (operands[0], operands[4], operands[3], operands[2]));
16954     }
16955   else if (TARGET_APX_NDD)
16956     {
16957       rtx tmp = gen_reg_rtx (DImode);
16958       if (MEM_P (operands[4]))
16959         {
16960           operands[1] = force_reg (DImode, operands[1]);
16961           emit_insn (gen_x86_64_shrd_ndd_1 (tmp, operands[4], operands[1],
16962                                             operands[2], operands[3]));
16963         }
16964        else if (MEM_P (operands[1]))
16965          emit_insn (gen_x86_64_shld_ndd_1 (tmp, operands[1], operands[4],
16966                                            operands[3], operands[2]));
16967        else
16968          emit_insn (gen_x86_64_shrd_ndd_1 (tmp, operands[4], operands[1],
16969                                            operands[2], operands[3]));
16970        emit_move_insn (operands[0], tmp);
16971     }
16972   else
16973    {
16974      operands[1] = force_reg (DImode, operands[1]);
16975      rtx tmp = gen_reg_rtx (DImode);
16976      emit_move_insn (tmp, operands[4]);
16977      emit_insn (gen_x86_64_shrd_1 (tmp, operands[1], operands[2], operands[3]));
16978      emit_move_insn (operands[0], tmp);
16979    }
16980    DONE;
16982   [(set_attr "has_nf" "1")])
16984 (define_insn_and_split "*x86_64_shrd_2"
16985   [(set (match_operand:DI 0 "nonimmediate_operand")
16986         (ior:DI (lshiftrt:DI (match_dup 0)
16987                              (match_operand:QI 2 "nonmemory_operand"))
16988                 (ashift:DI (match_operand:DI 1 "register_operand")
16989                            (minus:QI (const_int 64) (match_dup 2)))))
16990    (clobber (reg:CC FLAGS_REG))]
16991   "TARGET_64BIT && ix86_pre_reload_split ()"
16992   "#"
16993   "&& 1"
16994   [(parallel [(set (match_dup 0)
16995                    (ior:DI (lshiftrt:DI (match_dup 0)
16996                                         (and:QI (match_dup 2) (const_int 63)))
16997                            (subreg:DI
16998                              (ashift:TI
16999                                (zero_extend:TI (match_dup 1))
17000                                  (minus:QI (const_int 64)
17001                                            (and:QI (match_dup 2)
17002                                                    (const_int 63)))) 0)))
17003               (clobber (reg:CC FLAGS_REG))])])
17005 (define_insn_and_split "*x86_64_shrd_ndd_2"
17006   [(set (match_operand:DI 0 "nonimmediate_operand")
17007         (ior:DI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand")
17008                              (match_operand:QI 3 "nonmemory_operand"))
17009                 (ashift:DI (match_operand:DI 2 "register_operand")
17010                            (minus:QI (const_int 64) (match_dup 2)))))
17011    (clobber (reg:CC FLAGS_REG))]
17012   "TARGET_APX_NDD
17013   && ix86_pre_reload_split ()"
17014   "#"
17015   "&& 1"
17016   [(parallel [(set (match_dup 4)
17017                    (ior:DI (lshiftrt:DI (match_dup 1)
17018                                         (and:QI (match_dup 3) (const_int 63)))
17019                            (subreg:DI
17020                              (ashift:TI
17021                                (zero_extend:TI (match_dup 2))
17022                                  (minus:QI (const_int 64)
17023                                            (and:QI (match_dup 3)
17024                                                    (const_int 63)))) 0)))
17025               (clobber (reg:CC FLAGS_REG))
17026               (set (match_dup 0) (match_dup 4))])]
17028   operands[4] = gen_reg_rtx (DImode);
17029   emit_move_insn (operands[4], operands[0]);
17032 (define_insn "x86_shrd<nf_name>"
17033   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
17034         (ior:SI (lshiftrt:SI (match_dup 0)
17035                   (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
17036                           (const_int 31)))
17037                 (subreg:SI
17038                   (ashift:DI
17039                     (zero_extend:DI
17040                       (match_operand:SI 1 "register_operand" "r"))
17041                     (minus:QI (const_int 32)
17042                               (and:QI (match_dup 2) (const_int 31)))) 0)))]
17043   "<nf_condition>"
17044   "<nf_prefix>shrd{l}\t{%2, %1, %0|%0, %1, %2}"
17045   [(set_attr "type" "ishift")
17046    (set_attr "prefix_0f" "1")
17047    (set_attr "has_nf" "1")
17048    (set_attr "mode" "SI")
17049    (set_attr "pent_pair" "np")
17050    (set_attr "athlon_decode" "vector")
17051    (set_attr "amdfam10_decode" "vector")
17052    (set_attr "bdver1_decode" "vector")])
17054 (define_insn "x86_shrd_ndd<nf_name>"
17055   [(set (match_operand:SI 0 "register_operand" "=r")
17056         (ior:SI (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
17057                   (and:QI (match_operand:QI 3 "nonmemory_operand" "Ic")
17058                           (const_int 31)))
17059                 (subreg:SI
17060                   (ashift:DI
17061                     (zero_extend:DI
17062                       (match_operand:SI 2 "register_operand" "r"))
17063                     (minus:QI (const_int 32)
17064                               (and:QI (match_dup 3) (const_int 31)))) 0)))]
17065   "TARGET_APX_NDD && <nf_condition>"
17066   "<nf_prefix>shrd{l}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
17067   [(set_attr "type" "ishift")
17068    (set_attr "has_nf" "1")
17069    (set_attr "mode" "SI")])
17071 (define_insn "x86_shrd_1<nf_name>"
17072   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
17073         (ior:SI (lshiftrt:SI (match_dup 0)
17074                              (match_operand:QI 2 "const_0_to_31_operand"))
17075                 (subreg:SI
17076                   (ashift:DI
17077                     (zero_extend:DI
17078                       (match_operand:SI 1 "register_operand" "r"))
17079                     (match_operand:QI 3 "const_0_to_63_operand")) 0)))]
17080   "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
17081    && <nf_condition>"
17082   "<nf_prefix>shrd{l}\t{%2, %1, %0|%0, %1, %2}"
17083   [(set_attr "type" "ishift")
17084    (set_attr "prefix_0f" "1")
17085    (set_attr "length_immediate" "1")
17086    (set_attr "has_nf" "1")
17087    (set_attr "mode" "SI")
17088    (set_attr "pent_pair" "np")
17089    (set_attr "athlon_decode" "vector")
17090    (set_attr "amdfam10_decode" "vector")
17091    (set_attr "bdver1_decode" "vector")])
17093 (define_insn "x86_shrd_ndd_1<nf_name>"
17094   [(set (match_operand:SI 0 "register_operand" "=r")
17095         (ior:SI (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
17096                              (match_operand:QI 3 "const_0_to_31_operand"))
17097                 (subreg:SI
17098                   (ashift:DI
17099                     (zero_extend:DI
17100                       (match_operand:SI 2 "register_operand" "r"))
17101                     (match_operand:QI 4 "const_0_to_63_operand")) 0)))]
17102   "TARGET_APX_NDD
17103    && (INTVAL (operands[4]) == 32 - INTVAL (operands[3]))
17104    && <nf_condition>"
17105   "<nf_prefix>shrd{l}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
17106   [(set_attr "type" "ishift")
17107    (set_attr "length_immediate" "1")
17108    (set_attr "has_nf" "1")
17109    (set_attr "mode" "SI")])
17111 (define_insn_and_split "*x86_shrd_shld_1_nozext_nf"
17112   [(set (match_operand:SI 0 "nonimmediate_operand")
17113         (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
17114                              (match_operand:QI 2 "const_0_to_31_operand"))
17115                (ashift:SI
17116                    (match_operand:SI 1 "nonimmediate_operand")
17117                    (match_operand:QI 3 "const_0_to_31_operand"))))]
17118   "TARGET_APX_NF
17119    && INTVAL (operands[3]) == 32 - INTVAL (operands[2])
17120    && ix86_pre_reload_split ()"
17121   "#"
17122   "&& 1"
17123   [(const_int 0)]
17125   if (rtx_equal_p (operands[4], operands[0]))
17126     {
17127       operands[1] = force_reg (SImode, operands[1]);
17128       emit_insn (gen_x86_shrd_1_nf (operands[0], operands[1],
17129                                     operands[2], operands[3]));
17130     }
17131   else if (rtx_equal_p (operands[1], operands[0]))
17132     {
17133       operands[4] = force_reg (SImode, operands[4]);
17134       emit_insn (gen_x86_shld_1_nf (operands[0], operands[4],
17135                                     operands[3], operands[2]));
17136     }
17137   else if (TARGET_APX_NDD)
17138     {
17139       rtx tmp = gen_reg_rtx (SImode);
17140       if (MEM_P (operands[4]))
17141         {
17142           operands[1] = force_reg (SImode, operands[1]);
17143           emit_insn (gen_x86_shrd_ndd_1_nf (tmp, operands[4], operands[1],
17144                                             operands[2], operands[3]));
17145         }
17146       else if (MEM_P (operands[1]))
17147         emit_insn (gen_x86_shld_ndd_1_nf (tmp, operands[1], operands[4],
17148                                           operands[3], operands[2]));
17149       else
17150         emit_insn (gen_x86_shrd_ndd_1_nf (tmp, operands[4], operands[1],
17151                                           operands[2], operands[3]));
17152       emit_move_insn (operands[0], tmp);
17153      }
17154    else
17155    {
17156      operands[1] = force_reg (SImode, operands[1]);
17157      rtx tmp = gen_reg_rtx (SImode);
17158      emit_move_insn (tmp, operands[4]);
17159      emit_insn (gen_x86_shrd_1_nf (tmp, operands[1], operands[2],
17160                                    operands[3]));
17161      emit_move_insn (operands[0], tmp);
17162    }
17163    DONE;
17166 (define_insn_and_split "*x86_shrd_shld_1_nozext"
17167   [(set (match_operand:SI 0 "nonimmediate_operand")
17168         (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
17169                              (match_operand:QI 2 "const_0_to_31_operand"))
17170                (ashift:SI
17171                    (match_operand:SI 1 "nonimmediate_operand")
17172                    (match_operand:QI 3 "const_0_to_31_operand"))))
17173    (clobber (reg:CC FLAGS_REG))]
17174   "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
17175    && ix86_pre_reload_split ()"
17176   "#"
17177   "&& 1"
17178   [(const_int 0)]
17180   if (rtx_equal_p (operands[4], operands[0]))
17181     {
17182       operands[1] = force_reg (SImode, operands[1]);
17183       emit_insn (gen_x86_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
17184     }
17185   else if (rtx_equal_p (operands[1], operands[0]))
17186     {
17187       operands[4] = force_reg (SImode, operands[4]);
17188       emit_insn (gen_x86_shld_1 (operands[0], operands[4], operands[3], operands[2]));
17189     }
17190   else if (TARGET_APX_NDD)
17191     {
17192       rtx tmp = gen_reg_rtx (SImode);
17193       if (MEM_P (operands[4]))
17194         {
17195           operands[1] = force_reg (SImode, operands[1]);
17196           emit_insn (gen_x86_shrd_ndd_1 (tmp, operands[4], operands[1],
17197                                          operands[2], operands[3]));
17198         }
17199       else if (MEM_P (operands[1]))
17200         emit_insn (gen_x86_shld_ndd_1 (tmp, operands[1], operands[4],
17201                                        operands[3], operands[2]));
17202       else
17203         emit_insn (gen_x86_shrd_ndd_1 (tmp, operands[4], operands[1],
17204                                        operands[2], operands[3]));
17205       emit_move_insn (operands[0], tmp);
17206      }
17207    else
17208    {
17209      operands[1] = force_reg (SImode, operands[1]);
17210      rtx tmp = gen_reg_rtx (SImode);
17211      emit_move_insn (tmp, operands[4]);
17212      emit_insn (gen_x86_shrd_1 (tmp, operands[1], operands[2], operands[3]));
17213      emit_move_insn (operands[0], tmp);
17214    }
17215    DONE;
17217   [(set_attr "has_nf" "1")])
17219 (define_insn_and_split "*x86_shrd_2"
17220   [(set (match_operand:SI 0 "nonimmediate_operand")
17221         (ior:SI (lshiftrt:SI (match_dup 0)
17222                              (match_operand:QI 2 "nonmemory_operand"))
17223                 (ashift:SI (match_operand:SI 1 "register_operand")
17224                            (minus:QI (const_int 32) (match_dup 2)))))
17225    (clobber (reg:CC FLAGS_REG))]
17226   "TARGET_64BIT && ix86_pre_reload_split ()"
17227   "#"
17228   "&& 1"
17229   [(parallel [(set (match_dup 0)
17230                    (ior:SI (lshiftrt:SI (match_dup 0)
17231                                         (and:QI (match_dup 2) (const_int 31)))
17232                            (subreg:SI
17233                              (ashift:DI
17234                                (zero_extend:DI (match_dup 1))
17235                                  (minus:QI (const_int 32)
17236                                            (and:QI (match_dup 2)
17237                                                    (const_int 31)))) 0)))
17238               (clobber (reg:CC FLAGS_REG))])])
17240 (define_insn_and_split "*x86_shrd_ndd_2"
17241   [(set (match_operand:SI 0 "nonimmediate_operand")
17242         (ior:SI (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
17243                            (match_operand:QI 3 "nonmemory_operand"))
17244                 (ashift:SI (match_operand:SI 2 "register_operand")
17245                            (minus:QI (const_int 32) (match_dup 3)))))
17246    (clobber (reg:CC FLAGS_REG))]
17247   "TARGET_APX_NDD
17248    && ix86_pre_reload_split ()"
17249   "#"
17250   "&& 1"
17251   [(parallel [(set (match_dup 4)
17252                    (ior:SI (lshiftrt:SI (match_dup 1)
17253                                         (and:QI (match_dup 3) (const_int 31)))
17254                            (subreg:SI
17255                              (ashift:DI
17256                                (zero_extend:DI (match_dup 2))
17257                                  (minus:QI (const_int 32)
17258                                            (and:QI (match_dup 3)
17259                                                    (const_int 31)))) 0)))
17260               (clobber (reg:CC FLAGS_REG))
17261               (set (match_dup 0) (match_dup 4))])]
17263   operands[4] = gen_reg_rtx (SImode);
17264   emit_move_insn (operands[4], operands[0]);
17267 ;; Base name for insn mnemonic.
17268 (define_mode_attr cvt_mnemonic
17269   [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
17271 (define_insn "ashr<mode>3_cvt<nf_name>"
17272   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm,r")
17273         (ashiftrt:SWI48
17274           (match_operand:SWI48 1 "nonimmediate_operand" "*a,0,rm")
17275           (match_operand:QI 2 "const_int_operand")))]
17276   "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
17277    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
17278    && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands, TARGET_APX_NDD)
17279    && <nf_condition>"
17280   "@
17281    <cvt_mnemonic>
17282    <nf_prefix>sar{<imodesuffix>}\t{%2, %0|%0, %2}
17283    <nf_prefix>sar{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
17284   [(set_attr "isa" "*,*,apx_ndd")
17285    (set_attr "type" "imovx,ishift,ishift")
17286    (set_attr "prefix_0f" "0,*,*")
17287    (set_attr "length_immediate" "0,*,*")
17288    (set_attr "modrm" "0,1,1")
17289    (set_attr "has_nf" "1")
17290    (set_attr "mode" "<MODE>")])
17292 (define_insn "*ashrsi3_cvt_zext"
17293   [(set (match_operand:DI 0 "register_operand" "=*d,r,r")
17294         (zero_extend:DI
17295           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0,rm")
17296                        (match_operand:QI 2 "const_int_operand"))))
17297    (clobber (reg:CC FLAGS_REG))]
17298   "TARGET_64BIT && INTVAL (operands[2]) == 31
17299    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
17300    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands, TARGET_APX_NDD)"
17301   "@
17302    {cltd|cdq}
17303    sar{l}\t{%2, %k0|%k0, %2}
17304    sar{l}\t{%2, %1, %k0|%k0, %1, %2}"
17305   [(set_attr "isa" "*,*,apx_ndd")
17306    (set_attr "type" "imovx,ishift,ishift")
17307    (set_attr "prefix_0f" "0,*,*")
17308    (set_attr "length_immediate" "0,*,*")
17309    (set_attr "modrm" "0,1,1")
17310    (set_attr "mode" "SI")])
17312 (define_expand "@x86_shift<mode>_adj_3"
17313   [(use (match_operand:SWI48 0 "register_operand"))
17314    (use (match_operand:SWI48 1 "register_operand"))
17315    (use (match_operand:QI 2 "register_operand"))]
17316   ""
17318   rtx_code_label *label = gen_label_rtx ();
17319   rtx tmp;
17321   emit_insn (gen_testqi_ccz_1 (operands[2],
17322                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
17324   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
17325   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
17326   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
17327                               gen_rtx_LABEL_REF (VOIDmode, label),
17328                               pc_rtx);
17329   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
17330   JUMP_LABEL (tmp) = label;
17332   emit_move_insn (operands[0], operands[1]);
17333   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
17334                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
17335   emit_label (label);
17336   LABEL_NUSES (label) = 1;
17338   DONE;
17341 (define_insn "*bmi2_<insn><mode>3_1"
17342   [(set (match_operand:SWI48 0 "register_operand" "=r")
17343         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
17344                            (match_operand:SWI48 2 "register_operand" "r")))]
17345   "TARGET_BMI2"
17346   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
17347   [(set_attr "type" "ishiftx")
17348    (set_attr "mode" "<MODE>")])
17350 (define_insn "*ashr<mode>3_1<nf_name>"
17351   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
17352         (ashiftrt:SWI48
17353           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,rm")
17354           (match_operand:QI 2 "nonmemory_operand" "c<S>,r,c<S>")))]
17355   "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands, TARGET_APX_NDD)
17356    && <nf_condition>"
17358   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17359   switch (get_attr_type (insn))
17360     {
17361     case TYPE_ISHIFTX:
17362       return "#";
17364     default:
17365       if (operands[2] == const1_rtx
17366           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17367           && !use_ndd && !<nf_applied>)
17368         return "sar{<imodesuffix>}\t%0";
17369       else
17370         return use_ndd ? "<nf_prefix>sar{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
17371                        : "<nf_prefix>sar{<imodesuffix>}\t{%2, %0|%0, %2}";
17372     }
17374   [(set_attr "isa" "*,bmi2,apx_ndd")
17375    (set_attr "type" "ishift,ishiftx,ishift")
17376    (set (attr "length_immediate")
17377      (if_then_else
17378        (and (match_operand 2 "const1_operand")
17379             (ior (match_test "TARGET_SHIFT1")
17380                  (match_test "optimize_function_for_size_p (cfun)")))
17381        (const_string "0")
17382        (const_string "*")))
17383    (set_attr "has_nf" "1")
17384    (set_attr "mode" "<MODE>")])
17386 ;; Specialization of *lshr<mode>3_1 below, extracting the SImode
17387 ;; highpart of a DI to be extracted, but allowing it to be clobbered.
17388 (define_insn_and_split "*highpartdisi2"
17389   [(set (subreg:DI (match_operand:SI 0 "register_operand" "=r,x,?k,r") 0)
17390         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0,k,rm")
17391                      (const_int 32)))
17392    (clobber (reg:CC FLAGS_REG))]
17393   "TARGET_64BIT"
17394   "#"
17395   "&& reload_completed"
17396   [(parallel
17397     [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 32)))
17398      (clobber (reg:CC FLAGS_REG))])]
17400   if (SSE_REG_P (operands[0]))
17401     {
17402       rtx tmp = gen_rtx_REG (V4SImode, REGNO (operands[0]));
17403       emit_insn (gen_sse_shufps_v4si (tmp, tmp, tmp,
17404                                       const1_rtx, const1_rtx,
17405                                       GEN_INT (5), GEN_INT (5)));
17406       DONE;
17407     }
17408   operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
17410 [(set_attr "isa" "*,*,*,apx_ndd")])
17412 (define_insn "*lshr<mode>3_1<nf_name>"
17413   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,?k,r")
17414         (lshiftrt:SWI48
17415           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,k,rm")
17416           (match_operand:QI 2 "nonmemory_operand" "c<S>,r,<KS>,c<S>")))]
17417   "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands, TARGET_APX_NDD)
17418    && <nf_condition>"
17420   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17421   switch (get_attr_type (insn))
17422     {
17423     case TYPE_ISHIFTX:
17424     case TYPE_MSKLOG:
17425       return "#";
17427     default:
17428       if (operands[2] == const1_rtx
17429           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17430           && !use_ndd && !<nf_applied>)
17431         return "shr{<imodesuffix>}\t%0";
17432       else
17433         return use_ndd ? "<nf_prefix>shr{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
17434                        : "<nf_prefix>shr{<imodesuffix>}\t{%2, %0|%0, %2}";
17435     }
17437   [(set_attr "isa" "*,bmi2,avx512bw,apx_ndd")
17438    (set_attr "type" "ishift,ishiftx,msklog,ishift")
17439    (set (attr "length_immediate")
17440      (if_then_else
17441        (and (and (match_operand 2 "const1_operand")
17442                  (eq_attr "alternative" "0"))
17443             (ior (match_test "TARGET_SHIFT1")
17444                  (match_test "optimize_function_for_size_p (cfun)")))
17445        (const_string "0")
17446        (const_string "*")))
17447    (set_attr "has_nf" "1")
17448    (set_attr "mode" "<MODE>")])
17450 ;; Convert shift to the shiftx pattern to avoid flags dependency.
17451 ;; For NF/NDD doesn't support shift count as r, it just support c<S>,
17452 ;; and it has no flag.
17453 (define_split
17454   [(set (match_operand:SWI48 0 "register_operand")
17455         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17456                            (match_operand:QI 2 "register_operand")))]
17457   "TARGET_BMI2 && reload_completed"
17458   [(set (match_dup 0)
17459         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
17460   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
17462 (define_split
17463   [(set (match_operand:SWI48 0 "register_operand")
17464         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17465                            (match_operand:QI 2 "register_operand")))
17466    (clobber (reg:CC FLAGS_REG))]
17467   "TARGET_BMI2 && reload_completed"
17468   [(set (match_dup 0)
17469         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
17470   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
17472 (define_insn "*bmi2_<insn>si3_1_zext"
17473   [(set (match_operand:DI 0 "register_operand" "=r")
17474         (zero_extend:DI
17475           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
17476                           (match_operand:SI 2 "register_operand" "r"))))]
17477   "TARGET_64BIT && TARGET_BMI2"
17478   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
17479   [(set_attr "type" "ishiftx")
17480    (set_attr "mode" "SI")])
17482 (define_insn "*<insn>qi3_1_zext<mode><nf_name>"
17483   [(set (match_operand:SWI248x 0 "register_operand" "=r")
17484         (zero_extend:SWI248x
17485           (any_shiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "rm")
17486                           (match_operand:QI 2 "nonmemory_operand" "cI"))))]
17487   "TARGET_APX_NDD && <nf_condition>"
17488   "<nf_prefix><shift>{b}\t{%2, %1, %b0|%b0, %1, %2}"
17489   [(set_attr "type" "ishift")
17490    (set_attr "has_nf" "1")
17491    (set_attr "mode" "QI")])
17493 (define_insn "*<insn>hi3_1_zext<mode><nf_name>"
17494   [(set (match_operand:SWI48x 0 "register_operand" "=r")
17495         (zero_extend:SWI48x
17496           (any_shiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "rm")
17497                           (match_operand:QI 2 "nonmemory_operand" "cI"))))]
17498   "TARGET_APX_NDD && <nf_condition>"
17499   "<nf_prefix><shift>{w}\t{%2, %1, %w0|%w0, %1, %2}"
17500   [(set_attr "type" "ishift")
17501    (set_attr "has_nf" "1")
17502    (set_attr "mode" "HI")])
17504 (define_insn "*<insn>si3_1_zext"
17505   [(set (match_operand:DI 0 "register_operand" "=r,r,r,?k")
17506         (zero_extend:DI
17507           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm,rm,k")
17508                           (match_operand:QI 2 "nonmemory_operand" "cI,r,cI,I"))))
17509    (clobber (reg:CC FLAGS_REG))]
17510   "TARGET_64BIT
17511    && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
17513   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17514   switch (get_attr_type (insn))
17515     {
17516     case TYPE_ISHIFTX:
17517       return "#";
17519     case TYPE_MSKLOG:
17520       return "#";
17521     default:
17522       if (operands[2] == const1_rtx
17523           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17524           && !use_ndd)
17525         return "<shift>{l}\t%k0";
17526       else
17527         return use_ndd ? "<shift>{l}\t{%2, %1, %k0|%k0, %1, %2}"
17528                        : "<shift>{l}\t{%2, %k0|%k0, %2}";
17529     }
17531   [(set_attr "isa" "*,bmi2,apx_ndd,avx512bw")
17532    (set_attr "type" "ishift,ishiftx,ishift,msklog")
17533    (set (attr "length_immediate")
17534      (if_then_else
17535        (and (match_operand 2 "const1_operand")
17536             (ior (match_test "TARGET_SHIFT1")
17537                  (match_test "optimize_function_for_size_p (cfun)")))
17538        (const_string "0")
17539        (const_string "*")))
17540    (set_attr "mode" "SI")
17541    (set (attr "enabled")
17542         (if_then_else
17543           (eq_attr "alternative" "3")
17544           (symbol_ref "<CODE> == LSHIFTRT && TARGET_AVX512BW")
17545           (const_string "*")))])
17547 ;; Convert shift to the shiftx pattern to avoid flags dependency.
17548 (define_split
17549   [(set (match_operand:DI 0 "register_operand")
17550         (zero_extend:DI
17551           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
17552                           (match_operand:QI 2 "register_operand"))))
17553    (clobber (reg:CC FLAGS_REG))]
17554   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
17555   [(set (match_dup 0)
17556         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
17557   "operands[2] = gen_lowpart (SImode, operands[2]);")
17559 (define_insn "*ashr<mode>3_1<nf_name>"
17560   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m, r")
17561         (ashiftrt:SWI12
17562           (match_operand:SWI12 1 "nonimmediate_operand" "0, rm")
17563           (match_operand:QI 2 "nonmemory_operand" "c<S>, c<S>")))]
17564   "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands, TARGET_APX_NDD)
17565    && <nf_condition>"
17567   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17568   if (operands[2] == const1_rtx
17569       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17570       && !use_ndd && !<nf_applied>)
17571     return "sar{<imodesuffix>}\t%0";
17572   else
17573     return use_ndd ? "<nf_prefix>sar{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
17574                    : "<nf_prefix>sar{<imodesuffix>}\t{%2, %0|%0, %2}";
17576   [(set_attr "isa" "*, apx_ndd")
17577    (set_attr "type" "ishift")
17578    (set (attr "length_immediate")
17579      (if_then_else
17580        (and (match_operand 2 "const1_operand")
17581             (ior (match_test "TARGET_SHIFT1")
17582                  (match_test "optimize_function_for_size_p (cfun)")))
17583        (const_string "0")
17584        (const_string "*")))
17585    (set_attr "has_nf" "1")
17586    (set_attr "mode" "<MODE>")])
17588 (define_insn "*lshrqi3_1<nf_name>"
17589   [(set (match_operand:QI 0 "nonimmediate_operand"  "=qm,?k,r")
17590         (lshiftrt:QI
17591           (match_operand:QI 1 "nonimmediate_operand" "0, k, rm")
17592           (match_operand:QI 2 "nonmemory_operand"    "cI,Wb,cI")))]
17593   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands, TARGET_APX_NDD)
17594    && <nf_condition>"
17596   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17597   switch (get_attr_type (insn))
17598     {
17599     case TYPE_ISHIFT:
17600       if (operands[2] == const1_rtx
17601           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17602           && !use_ndd && !<nf_applied>)
17603         return "shr{b}\t%0";
17604       else
17605         return use_ndd ? "<nf_prefix>shr{b}\t{%2, %1, %0|%0, %1, %2}"
17606                        : "<nf_prefix>shr{b}\t{%2, %0|%0, %2}";
17607     case TYPE_MSKLOG:
17608       return "#";
17609     default:
17610       gcc_unreachable ();
17611     }
17613   [(set_attr "isa" "*,avx512dq,apx_ndd")
17614    (set_attr "type" "ishift,msklog,ishift")
17615    (set (attr "length_immediate")
17616      (if_then_else
17617        (and (and (match_operand 2 "const1_operand")
17618                  (eq_attr "alternative" "0"))
17619             (ior (match_test "TARGET_SHIFT1")
17620                  (match_test "optimize_function_for_size_p (cfun)")))
17621        (const_string "0")
17622        (const_string "*")))
17623    (set_attr "has_nf" "1")
17624    (set_attr "mode" "QI")])
17626 (define_insn "*lshrhi3_1<nf_name>"
17627   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm, ?k, r")
17628         (lshiftrt:HI
17629           (match_operand:HI 1 "nonimmediate_operand" "0, k, rm")
17630           (match_operand:QI 2 "nonmemory_operand" "cI, Ww, cI")))]
17631   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands, TARGET_APX_NDD)
17632    && <nf_condition>"
17634   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17635   switch (get_attr_type (insn))
17636     {
17637     case TYPE_ISHIFT:
17638       if (operands[2] == const1_rtx
17639           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17640           && !use_ndd && !<nf_applied>)
17641         return "shr{w}\t%0";
17642       else
17643         return use_ndd ? "<nf_prefix>shr{w}\t{%2, %1, %0|%0, %1, %2}"
17644                        : "<nf_prefix>shr{w}\t{%2, %0|%0, %2}";
17645     case TYPE_MSKLOG:
17646       return "#";
17647     default:
17648       gcc_unreachable ();
17649     }
17651   [(set_attr "isa" "*, avx512f, apx_ndd")
17652    (set_attr "type" "ishift,msklog,ishift")
17653    (set (attr "length_immediate")
17654      (if_then_else
17655        (and (and (match_operand 2 "const1_operand")
17656                  (eq_attr "alternative" "0"))
17657             (ior (match_test "TARGET_SHIFT1")
17658                  (match_test "optimize_function_for_size_p (cfun)")))
17659        (const_string "0")
17660        (const_string "*")))
17661    (set_attr "has_nf" "1")
17662    (set_attr "mode" "HI")])
17664 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
17665 (define_insn_and_split "*<insn><mode>3_1_slp"
17666   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
17667         (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
17668                            (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
17669    (clobber (reg:CC FLAGS_REG))]
17670   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
17672   if (which_alternative)
17673     return "#";
17675   if (operands[2] == const1_rtx
17676       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
17677     return "<shift>{<imodesuffix>}\t%0";
17678   else
17679     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
17681   "&& reload_completed
17682    && !(rtx_equal_p (operands[0], operands[1]))"
17683   [(set (strict_low_part (match_dup 0)) (match_dup 1))
17684    (parallel
17685      [(set (strict_low_part (match_dup 0))
17686            (any_shiftrt:SWI12 (match_dup 0) (match_dup 2)))
17687       (clobber (reg:CC FLAGS_REG))])]
17688   ""
17689   [(set_attr "type" "ishift")
17690    (set (attr "length_immediate")
17691      (if_then_else
17692        (and (match_operand 2 "const1_operand")
17693             (ior (match_test "TARGET_SHIFT1")
17694                  (match_test "optimize_function_for_size_p (cfun)")))
17695        (const_string "0")
17696        (const_string "*")))
17697    (set_attr "mode" "<MODE>")])
17699 ;; This pattern can't accept a variable shift count, since shifts by
17700 ;; zero don't affect the flags.  We assume that shifts by constant
17701 ;; zero are optimized away.
17702 (define_insn "*<insn><mode>3_cmp"
17703   [(set (reg FLAGS_REG)
17704         (compare
17705           (any_shiftrt:SWI
17706             (match_operand:SWI 1 "nonimmediate_operand" "0,rm")
17707             (match_operand:QI 2 "<shift_immediate_operand>" "<S>,<S>"))
17708           (const_int 0)))
17709    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
17710         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
17711   "(optimize_function_for_size_p (cfun)
17712     || !TARGET_PARTIAL_FLAG_REG_STALL
17713     || (operands[2] == const1_rtx
17714         && TARGET_SHIFT1))
17715    && ix86_match_ccmode (insn, CCGOCmode)
17716    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)"
17718   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17719   if (operands[2] == const1_rtx
17720       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17721       && !use_ndd)
17722     return "<shift>{<imodesuffix>}\t%0";
17723   else
17724     return use_ndd ? "<shift>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
17725                    : "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
17727   [(set_attr "isa" "*,apx_ndd")
17728    (set_attr "type" "ishift")
17729    (set (attr "length_immediate")
17730      (if_then_else
17731        (and (match_operand 2 "const1_operand")
17732             (ior (match_test "TARGET_SHIFT1")
17733                  (match_test "optimize_function_for_size_p (cfun)")))
17734        (const_string "0")
17735        (const_string "*")))
17736    (set_attr "mode" "<MODE>")])
17738 (define_insn "*<insn>si3_cmp_zext"
17739   [(set (reg FLAGS_REG)
17740         (compare
17741           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
17742                           (match_operand:QI 2 "const_1_to_31_operand"))
17743           (const_int 0)))
17744    (set (match_operand:DI 0 "register_operand" "=r,r")
17745         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
17746   "TARGET_64BIT
17747    && (optimize_function_for_size_p (cfun)
17748        || !TARGET_PARTIAL_FLAG_REG_STALL
17749        || (operands[2] == const1_rtx
17750            && TARGET_SHIFT1))
17751    && ix86_match_ccmode (insn, CCGOCmode)
17752    && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
17754   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17755   if (operands[2] == const1_rtx
17756       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17757       && !use_ndd)
17758     return "<shift>{l}\t%k0";
17759   else
17760     return use_ndd ? "<shift>{l}\t{%2, %1, %k0|%k0, %1, %2}"
17761                    : "<shift>{l}\t{%2, %k0|%k0, %2}";
17763   [(set_attr "isa" "*,apx_ndd")
17764    (set_attr "type" "ishift")
17765    (set (attr "length_immediate")
17766      (if_then_else
17767        (and (match_operand 2 "const1_operand")
17768             (ior (match_test "TARGET_SHIFT1")
17769                  (match_test "optimize_function_for_size_p (cfun)")))
17770        (const_string "0")
17771        (const_string "*")))
17772    (set_attr "mode" "SI")])
17774 (define_insn "*<insn><mode>3_cconly"
17775   [(set (reg FLAGS_REG)
17776         (compare
17777           (any_shiftrt:SWI
17778             (match_operand:SWI 1 "nonimmediate_operand" "0,rm")
17779             (match_operand:QI 2 "<shift_immediate_operand>" "<S>,<S>"))
17780           (const_int 0)))
17781    (clobber (match_scratch:SWI 0 "=<r>,r"))]
17782   "(optimize_function_for_size_p (cfun)
17783     || !TARGET_PARTIAL_FLAG_REG_STALL
17784     || (operands[2] == const1_rtx
17785         && TARGET_SHIFT1))
17786    && ix86_match_ccmode (insn, CCGOCmode)"
17788   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17789   if (operands[2] == const1_rtx
17790       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17791       && !use_ndd)
17792     return "<shift>{<imodesuffix>}\t%0";
17793   else
17794     return use_ndd
17795            ? "<shift>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
17796            : "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
17798   [(set_attr "isa" "*,apx_ndd")
17799    (set_attr "type" "ishift")
17800    (set (attr "length_immediate")
17801      (if_then_else
17802        (and (match_operand 2 "const1_operand")
17803             (ior (match_test "TARGET_SHIFT1")
17804                  (match_test "optimize_function_for_size_p (cfun)")))
17805        (const_string "0")
17806        (const_string "*")))
17807    (set_attr "mode" "<MODE>")])
17809 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
17810 (define_insn_and_split "*<insn>qi_ext<mode>_1"
17811   [(set (zero_extract:SWI248
17812           (match_operand 0 "int248_register_operand" "+Q,&Q")
17813           (const_int 8)
17814           (const_int 8))
17815         (subreg:SWI248
17816           (any_shiftrt:QI
17817             (subreg:QI
17818               (match_operator:SWI248 3 "extract_operator"
17819                 [(match_operand 1 "int248_register_operand" "0,!Q")
17820                  (const_int 8)
17821                  (const_int 8)]) 0)
17822             (match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
17823    (clobber (reg:CC FLAGS_REG))]
17824   ""
17826   if (which_alternative)
17827     return "#";
17829   if (operands[2] == const1_rtx
17830       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
17831     return "<shift>{b}\t%h0";
17832   else
17833     return "<shift>{b}\t{%2, %h0|%h0, %2}";
17835   "reload_completed
17836    && !(rtx_equal_p (operands[0], operands[1]))"
17837   [(set (zero_extract:SWI248
17838           (match_dup 0) (const_int 8) (const_int 8))
17839         (zero_extract:SWI248
17840           (match_dup 1) (const_int 8) (const_int 8)))
17841    (parallel
17842      [(set (zero_extract:SWI248
17843              (match_dup 0) (const_int 8) (const_int 8))
17844            (subreg:SWI248
17845              (any_shiftrt:QI
17846                (subreg:QI
17847                  (match_op_dup 3
17848                    [(match_dup 0) (const_int 8) (const_int 8)]) 0)
17849                (match_dup 2)) 0))
17850       (clobber (reg:CC FLAGS_REG))])]
17851   ""
17852   [(set_attr "type" "ishift")
17853    (set (attr "length_immediate")
17854      (if_then_else
17855        (and (match_operand 2 "const1_operand")
17856             (ior (match_test "TARGET_SHIFT1")
17857                  (match_test "optimize_function_for_size_p (cfun)")))
17858        (const_string "0")
17859        (const_string "*")))
17860    (set_attr "mode" "QI")])
17862 (define_insn_and_split "*extend<dwi>2_doubleword_highpart"
17863   [(set (match_operand:<DWI> 0 "register_operand" "=r")
17864         (ashiftrt:<DWI>
17865           (ashift:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")
17866                         (match_operand:QI 2 "const_int_operand"))
17867           (match_operand:QI 3 "const_int_operand")))
17868    (clobber (reg:CC FLAGS_REG))]
17869   "INTVAL (operands[2]) == INTVAL (operands[3])
17870    && UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
17871   "#"
17872   "&& reload_completed"
17873   [(parallel [(set (match_dup 4)
17874                    (ashift:DWIH (match_dup 4) (match_dup 2)))
17875               (clobber (reg:CC FLAGS_REG))])
17876    (parallel [(set (match_dup 4)
17877                    (ashiftrt:DWIH (match_dup 4) (match_dup 2)))
17878               (clobber (reg:CC FLAGS_REG))])]
17879   "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[4]);")
17881 (define_insn_and_split "*extendv2di2_highpart_stv"
17882   [(set (match_operand:V2DI 0 "register_operand" "=v")
17883         (ashiftrt:V2DI
17884           (ashift:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "vm")
17885                        (match_operand:QI 2 "const_int_operand"))
17886           (match_operand:QI 3 "const_int_operand")))]
17887   "!TARGET_64BIT && TARGET_STV && TARGET_AVX512VL
17888    && INTVAL (operands[2]) == INTVAL (operands[3])
17889    && UINTVAL (operands[2]) < 32"
17890   "#"
17891   "&& reload_completed"
17892   [(set (match_dup 0)
17893         (ashift:V2DI (match_dup 1) (match_dup 2)))
17894    (set (match_dup 0)
17895         (ashiftrt:V2DI (match_dup 0) (match_dup 2)))])
17897 ;; Without AVX512VL, split this instruction before reload.
17898 (define_insn_and_split "*extendv2di2_highpart_stv_noavx512vl"
17899   [(set (match_operand:V2DI 0 "register_operand" "=v")
17900         (ashiftrt:V2DI
17901           (ashift:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "vm")
17902                        (match_operand:QI 2 "const_int_operand"))
17903           (match_operand:QI 3 "const_int_operand")))]
17904   "!TARGET_AVX512VL
17905    && INTVAL (operands[2]) == INTVAL (operands[3])
17906    && UINTVAL (operands[2]) < 32
17907    && ix86_pre_reload_split ()"
17908   "#"
17909   "&& 1"
17910   [(set (match_dup 4)
17911         (ashift:V2DI (match_dup 1) (match_dup 2)))
17912    (set (match_dup 0)
17913         (ashiftrt:V2DI (match_dup 4) (match_dup 2)))]
17915   if (!TARGET_XOP)
17916     {
17917       rtx op0 = operands[0];
17918       rtx op2 = operands[2];
17919       rtx tmp1 = gen_reg_rtx (V4SImode);
17920       rtx tmp2 = gen_reg_rtx (V4SImode);
17921       rtx tmp3 = gen_reg_rtx (V4SImode);
17922       rtx tmp4 = gen_reg_rtx (V4SImode);
17923       emit_move_insn (tmp1, lowpart_subreg (V4SImode, operands[1], V2DImode));
17924       emit_insn (gen_ashlv4si3 (tmp2, tmp1, op2));
17925       emit_insn (gen_ashrv4si3 (tmp3, tmp2, op2));
17926       vec_perm_builder sel (4, 4, 1);
17927       sel.quick_grow (4);
17928       sel[0] = 0;
17929       sel[1] = 5;
17930       sel[2] = 2;
17931       sel[3] = 7;
17932       vec_perm_indices indices(sel, 2, 4);
17933       bool ok = targetm.vectorize.vec_perm_const (V4SImode, V4SImode, tmp4,
17934                                                   tmp1, tmp3, indices);
17935       gcc_assert (ok);
17936       emit_move_insn (op0, lowpart_subreg (V2DImode, tmp4, V4SImode));
17937       DONE;
17938     }
17939   else
17940     operands[4] = gen_reg_rtx (V2DImode);
17943 ;; Rotate instructions
17945 (define_expand "<insn>ti3"
17946   [(set (match_operand:TI 0 "register_operand")
17947         (any_rotate:TI (match_operand:TI 1 "register_operand")
17948                        (match_operand:QI 2 "nonmemory_operand")))]
17949   "TARGET_64BIT"
17951   if (const_1_to_63_operand (operands[2], VOIDmode))
17952     emit_insn (gen_ix86_<insn>ti3_doubleword
17953                 (operands[0], operands[1], operands[2]));
17954   else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 64)
17955     {
17956       operands[1] = force_reg (TImode, operands[1]);
17957       emit_insn (gen_<insn>64ti2_doubleword (operands[0], operands[1]));
17958     }
17959   else
17960     {
17961       rtx amount = force_reg (QImode, operands[2]);
17962       rtx src_lo = gen_lowpart (DImode, operands[1]);
17963       rtx src_hi = gen_highpart (DImode, operands[1]);
17964       rtx tmp_lo = gen_reg_rtx (DImode);
17965       rtx tmp_hi = gen_reg_rtx (DImode);
17966       emit_move_insn (tmp_lo, src_lo);
17967       emit_move_insn (tmp_hi, src_hi);
17968       rtx (*shiftd) (rtx, rtx, rtx)
17969             = (<CODE> == ROTATE) ? gen_x86_64_shld : gen_x86_64_shrd;
17970       emit_insn (shiftd (tmp_lo, src_hi, amount));
17971       emit_insn (shiftd (tmp_hi, src_lo, amount));
17972       rtx dst_lo = gen_lowpart (DImode, operands[0]);
17973       rtx dst_hi = gen_highpart (DImode, operands[0]);
17974       emit_move_insn (dst_lo, tmp_lo);
17975       emit_move_insn (dst_hi, tmp_hi);
17976       emit_insn (gen_x86_shiftdi_adj_1 (dst_lo, dst_hi, amount, tmp_lo));
17977     }
17978   DONE;
17981 (define_expand "<insn>di3"
17982   [(set (match_operand:DI 0 "shiftdi_operand")
17983         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
17984                        (match_operand:QI 2 "nonmemory_operand")))]
17985  ""
17987   if (TARGET_64BIT)
17988     ix86_expand_binary_operator (<CODE>, DImode, operands, TARGET_APX_NDD);
17989   else if (const_1_to_31_operand (operands[2], VOIDmode))
17990     emit_insn (gen_ix86_<insn>di3_doubleword
17991                 (operands[0], operands[1], operands[2]));
17992   else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 32)
17993     {
17994       operands[1] = force_reg (DImode, operands[1]);
17995       emit_insn (gen_<insn>32di2_doubleword (operands[0], operands[1]));
17996     }
17997   else
17998     FAIL;
18000   DONE;
18003 (define_expand "<insn><mode>3"
18004   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
18005         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
18006                             (match_operand:QI 2 "nonmemory_operand")))]
18007   ""
18009   ix86_expand_binary_operator (<CODE>, <MODE>mode, operands, TARGET_APX_NDD);
18010   DONE;
18013 ;; Avoid useless masking of count operand.
18014 (define_insn_and_split "*<insn><mode>3_mask"
18015   [(set (match_operand:SWI 0 "nonimmediate_operand")
18016         (any_rotate:SWI
18017           (match_operand:SWI 1 "nonimmediate_operand")
18018           (subreg:QI
18019             (and
18020               (match_operand 2 "int248_register_operand" "c")
18021               (match_operand 3 "const_int_operand")) 0)))
18022    (clobber (reg:CC FLAGS_REG))]
18023   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
18024    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
18025       == GET_MODE_BITSIZE (<MODE>mode)-1
18026    && ix86_pre_reload_split ()"
18027   "#"
18028   "&& 1"
18029   [(parallel
18030      [(set (match_dup 0)
18031            (any_rotate:SWI (match_dup 1)
18032                            (match_dup 2)))
18033       (clobber (reg:CC FLAGS_REG))])]
18035   operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
18036   operands[2] = gen_lowpart (QImode, operands[2]);
18039 (define_split
18040   [(set (match_operand:SWI 0 "register_operand")
18041         (any_rotate:SWI
18042           (match_operand:SWI 1 "const_int_operand")
18043           (subreg:QI
18044             (and
18045               (match_operand 2 "int248_register_operand")
18046               (match_operand 3 "const_int_operand")) 0)))]
18047  "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
18048    == GET_MODE_BITSIZE (<MODE>mode) - 1"
18049  [(set (match_dup 4) (match_dup 1))
18050   (set (match_dup 0)
18051        (any_rotate:SWI (match_dup 4)
18052                        (subreg:QI (match_dup 2) 0)))]
18053  "operands[4] = gen_reg_rtx (<MODE>mode);")
18055 (define_insn_and_split "*<insn><mode>3_mask_1"
18056   [(set (match_operand:SWI 0 "nonimmediate_operand")
18057         (any_rotate:SWI
18058           (match_operand:SWI 1 "nonimmediate_operand")
18059           (and:QI
18060             (match_operand:QI 2 "register_operand" "c")
18061             (match_operand:QI 3 "const_int_operand"))))
18062    (clobber (reg:CC FLAGS_REG))]
18063   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
18064    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
18065       == GET_MODE_BITSIZE (<MODE>mode)-1
18066    && ix86_pre_reload_split ()"
18067   "#"
18068   "&& 1"
18069   [(parallel
18070      [(set (match_dup 0)
18071            (any_rotate:SWI (match_dup 1)
18072                            (match_dup 2)))
18073       (clobber (reg:CC FLAGS_REG))])])
18075 (define_split
18076   [(set (match_operand:SWI 0 "register_operand")
18077         (any_rotate:SWI
18078           (match_operand:SWI 1 "const_int_operand")
18079           (and:QI
18080             (match_operand:QI 2 "register_operand")
18081             (match_operand:QI 3 "const_int_operand"))))]
18082  "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
18083   == GET_MODE_BITSIZE (<MODE>mode) - 1"
18084  [(set (match_dup 4) (match_dup 1))
18085   (set (match_dup 0)
18086        (any_rotate:SWI (match_dup 4) (match_dup 2)))]
18087  "operands[4] = gen_reg_rtx (<MODE>mode);")
18089 ;; Implement rotation using two double-precision
18090 ;; shift instructions and a scratch register.
18092 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
18093  [(set (match_operand:<DWI> 0 "register_operand" "=r")
18094        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
18095                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
18096   (clobber (reg:CC FLAGS_REG))
18097   (clobber (match_scratch:DWIH 3 "=&r"))]
18098  ""
18099  "#"
18100  "reload_completed"
18101  [(set (match_dup 3) (match_dup 4))
18102   (parallel
18103    [(set (match_dup 4)
18104          (ior:DWIH (ashift:DWIH (match_dup 4)
18105                                 (and:QI (match_dup 2) (match_dup 6)))
18106                    (subreg:DWIH
18107                      (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
18108                                      (minus:QI (match_dup 7)
18109                                                (and:QI (match_dup 2)
18110                                                        (match_dup 6)))) 0)))
18111     (clobber (reg:CC FLAGS_REG))])
18112   (parallel
18113    [(set (match_dup 5)
18114          (ior:DWIH (ashift:DWIH (match_dup 5)
18115                                 (and:QI (match_dup 2) (match_dup 6)))
18116                    (subreg:DWIH
18117                      (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 3))
18118                                      (minus:QI (match_dup 7)
18119                                                (and:QI (match_dup 2)
18120                                                        (match_dup 6)))) 0)))
18121     (clobber (reg:CC FLAGS_REG))])]
18123   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
18124   operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
18126   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
18129 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
18130  [(set (match_operand:<DWI> 0 "register_operand" "=r")
18131        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
18132                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
18133   (clobber (reg:CC FLAGS_REG))
18134   (clobber (match_scratch:DWIH 3 "=&r"))]
18135  ""
18136  "#"
18137  "reload_completed"
18138  [(set (match_dup 3) (match_dup 4))
18139   (parallel
18140    [(set (match_dup 4)
18141          (ior:DWIH (lshiftrt:DWIH (match_dup 4)
18142                                   (and:QI (match_dup 2) (match_dup 6)))
18143                    (subreg:DWIH
18144                      (ashift:<DWI> (zero_extend:<DWI> (match_dup 5))
18145                                    (minus:QI (match_dup 7)
18146                                              (and:QI (match_dup 2)
18147                                                      (match_dup 6)))) 0)))
18148     (clobber (reg:CC FLAGS_REG))])
18149   (parallel
18150    [(set (match_dup 5)
18151          (ior:DWIH (lshiftrt:DWIH (match_dup 5)
18152                                   (and:QI (match_dup 2) (match_dup 6)))
18153                    (subreg:DWIH
18154                      (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
18155                                    (minus:QI (match_dup 7)
18156                                              (and:QI (match_dup 2)
18157                                                      (match_dup 6)))) 0)))
18158     (clobber (reg:CC FLAGS_REG))])]
18160   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
18161   operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
18163   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
18166 (define_insn_and_split "<insn>32di2_doubleword"
18167  [(set (match_operand:DI 0 "register_operand" "=r,r")
18168        (any_rotate:DI (match_operand:DI 1 "register_operand" "0,r")
18169                       (const_int 32)))]
18170  "!TARGET_64BIT"
18171  "#"
18172  "&& reload_completed"
18173  [(set (match_dup 0) (match_dup 3))
18174   (set (match_dup 2) (match_dup 1))]
18176   split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
18177   if (rtx_equal_p (operands[0], operands[1]))
18178     {
18179       emit_insn (gen_swapsi (operands[0], operands[2]));
18180       DONE;
18181     }
18184 (define_insn_and_split "<insn>64ti2_doubleword"
18185  [(set (match_operand:TI 0 "register_operand" "=r,r")
18186        (any_rotate:TI (match_operand:TI 1 "register_operand" "0,r")
18187                       (const_int 64)))]
18188  "TARGET_64BIT"
18189  "#"
18190  "&& reload_completed"
18191  [(set (match_dup 0) (match_dup 3))
18192   (set (match_dup 2) (match_dup 1))]
18194   split_double_mode (TImode, &operands[0], 2, &operands[0], &operands[2]);
18195   if (rtx_equal_p (operands[0], operands[1]))
18196     {
18197       emit_insn (gen_swapdi (operands[0], operands[2]));
18198       DONE;
18199     }
18202 (define_mode_attr rorx_immediate_operand
18203         [(SI "const_0_to_31_operand")
18204          (DI "const_0_to_63_operand")])
18206 (define_insn "*bmi2_rorx<mode>3_1"
18207   [(set (match_operand:SWI48 0 "register_operand" "=r")
18208         (rotatert:SWI48
18209           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18210           (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
18211   "TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
18212   "rorx\t{%2, %1, %0|%0, %1, %2}"
18213   [(set_attr "type" "rotatex")
18214    (set_attr "mode" "<MODE>")])
18216 (define_insn "*<insn><mode>3_1<nf_name>"
18217   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
18218         (any_rotate:SWI48
18219           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,rm")
18220           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>,c<S>")))]
18221   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)
18222    && <nf_condition>"
18224   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
18225   switch (get_attr_type (insn))
18226     {
18227     case TYPE_ROTATEX:
18228       if (TARGET_APX_NDD && <nf_applied>)
18229         return "%{nf%} <rotate>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}";
18230       else
18231         return "#";
18233     default:
18234       if (operands[2] == const1_rtx
18235           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
18236           && !use_ndd && !<nf_applied>)
18237         return "<rotate>{<imodesuffix>}\t%0";
18238       else
18239         return use_ndd ? "<nf_prefix><rotate>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
18240                        : "<nf_prefix><rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
18241     }
18243   [(set_attr "isa" "*,bmi2,apx_ndd")
18244    (set_attr "type" "rotate,rotatex,rotate")
18245    (set (attr "preferred_for_size")
18246      (cond [(eq_attr "alternative" "0")
18247               (symbol_ref "true")]
18248            (symbol_ref "false")))
18249    (set (attr "length_immediate")
18250      (if_then_else
18251        (and (eq_attr "type" "rotate")
18252             (and (match_operand 2 "const1_operand")
18253                  (ior (match_test "TARGET_SHIFT1")
18254                       (match_test "optimize_function_for_size_p (cfun)"))))
18255        (const_string "0")
18256        (const_string "*")))
18257    (set_attr "has_nf" "1")
18258    (set_attr "mode" "<MODE>")])
18260 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
18261 (define_split
18262   [(set (match_operand:SWI48 0 "register_operand")
18263         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18264                       (match_operand:QI 2 "const_int_operand")))
18265    (clobber (reg:CC FLAGS_REG))]
18266   "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
18267   [(set (match_dup 0)
18268         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
18270   int bitsize = GET_MODE_BITSIZE (<MODE>mode);
18272   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
18275 (define_split
18276   [(set (match_operand:SWI48 0 "register_operand")
18277         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18278                       (match_operand:QI 2 "const_int_operand")))]
18279   "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)
18280    && !TARGET_APX_NDD"
18281   [(set (match_dup 0)
18282         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
18284   int bitsize = GET_MODE_BITSIZE (<MODE>mode);
18286   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
18289 (define_split
18290   [(set (match_operand:SWI48 0 "register_operand")
18291         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18292                         (match_operand:QI 2 "const_int_operand")))
18293    (clobber (reg:CC FLAGS_REG))]
18294   "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
18295   [(set (match_dup 0)
18296         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
18298 (define_insn "*bmi2_rorxsi3_1_zext"
18299   [(set (match_operand:DI 0 "register_operand" "=r")
18300         (zero_extend:DI
18301           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
18302                        (match_operand:QI 2 "const_0_to_31_operand"))))]
18303   "TARGET_64BIT && TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
18304   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
18305   [(set_attr "type" "rotatex")
18306    (set_attr "mode" "SI")])
18308 (define_insn "*<insn>qi3_1_zext<mode><nf_name>"
18309   [(set (match_operand:SWI248x 0 "register_operand" "=r")
18310         (zero_extend:SWI248x
18311           (any_rotate:QI (match_operand:QI 1 "nonimmediate_operand" "rm")
18312                          (match_operand:QI 2 "nonmemory_operand" "cI"))))]
18313   "TARGET_APX_NDD && <nf_condition>"
18314   "<nf_prefix><rotate>{b}\t{%2, %1, %b0|%b0, %1, %2}"
18315   [(set_attr "type" "rotate")
18316    (set_attr "has_nf" "1")
18317    (set_attr "mode" "QI")])
18319 (define_insn "*<insn>hi3_1_zext<mode><nf_name>"
18320   [(set (match_operand:SWI48x 0 "register_operand" "=r")
18321         (zero_extend:SWI48x
18322           (any_rotate:HI (match_operand:HI 1 "nonimmediate_operand" "rm")
18323                          (match_operand:QI 2 "nonmemory_operand" "cI"))))]
18324   "TARGET_APX_NDD && <nf_condition>"
18325   "<nf_prefix><rotate>{w}\t{%2, %1, %w0|%w0, %1, %2}"
18326   [(set_attr "type" "rotate")
18327    (set_attr "has_nf" "1")
18328    (set_attr "mode" "HI")])
18330 (define_insn "*<insn>si3_1_zext"
18331   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
18332         (zero_extend:DI
18333           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm,rm")
18334                          (match_operand:QI 2 "nonmemory_operand" "cI,I,cI"))))
18335    (clobber (reg:CC FLAGS_REG))]
18336   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
18338   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
18339   switch (get_attr_type (insn))
18340     {
18341     case TYPE_ROTATEX:
18342       return "#";
18344     default:
18345       if (operands[2] == const1_rtx
18346           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
18347           && !use_ndd)
18348         return "<rotate>{l}\t%k0";
18349       else
18350         return use_ndd ? "<rotate>{l}\t{%2, %1, %k0|%k0, %1, %2}"
18351                        : "<rotate>{l}\t{%2, %k0|%k0, %2}";
18352     }
18354   [(set_attr "isa" "*,bmi2,apx_ndd")
18355    (set_attr "type" "rotate,rotatex,rotate")
18356    (set (attr "preferred_for_size")
18357      (cond [(eq_attr "alternative" "0")
18358               (symbol_ref "true")]
18359            (symbol_ref "false")))
18360    (set (attr "length_immediate")
18361      (if_then_else
18362        (and (eq_attr "type" "rotate")
18363             (and (match_operand 2 "const1_operand")
18364                  (ior (match_test "TARGET_SHIFT1")
18365                       (match_test "optimize_function_for_size_p (cfun)"))))
18366        (const_string "0")
18367        (const_string "*")))
18368    (set_attr "mode" "SI")])
18370 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
18371 (define_split
18372   [(set (match_operand:DI 0 "register_operand")
18373         (zero_extend:DI
18374           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
18375                      (match_operand:QI 2 "const_int_operand"))))
18376    (clobber (reg:CC FLAGS_REG))]
18377   "TARGET_64BIT && TARGET_BMI2 && reload_completed
18378    && !optimize_function_for_size_p (cfun)"
18379   [(set (match_dup 0)
18380         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
18382   int bitsize = GET_MODE_BITSIZE (SImode);
18384   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
18387 (define_split
18388   [(set (match_operand:DI 0 "register_operand")
18389         (zero_extend:DI
18390           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
18391                        (match_operand:QI 2 "const_int_operand"))))
18392    (clobber (reg:CC FLAGS_REG))]
18393   "TARGET_64BIT && TARGET_BMI2 && reload_completed
18394    && !optimize_function_for_size_p (cfun)"
18395   [(set (match_dup 0)
18396         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
18398 (define_insn "*<insn><mode>3_1<nf_name>"
18399   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m,r")
18400         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0,rm")
18401                           (match_operand:QI 2 "nonmemory_operand" "c<S>,c<S>")))]
18402   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)
18403    && <nf_condition>"
18405   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
18406   if (operands[2] == const1_rtx
18407       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
18408       && !use_ndd && !<nf_applied>)
18409     return "<rotate>{<imodesuffix>}\t%0";
18410   else
18411     return use_ndd
18412            ? "<nf_prefix><rotate>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
18413            : "<nf_prefix><rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
18415   [(set_attr "isa" "*,apx_ndd")
18416    (set_attr "type" "rotate")
18417    (set (attr "length_immediate")
18418      (if_then_else
18419        (and (match_operand 2 "const1_operand")
18420             (ior (match_test "TARGET_SHIFT1")
18421                  (match_test "optimize_function_for_size_p (cfun)")))
18422        (const_string "0")
18423        (const_string "*")))
18424    (set_attr "has_nf" "1")
18425    (set_attr "mode" "<MODE>")])
18427 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
18428 (define_insn_and_split "*<insn><mode>3_1_slp"
18429   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
18430         (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
18431                           (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
18432    (clobber (reg:CC FLAGS_REG))]
18433   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
18435   if (which_alternative)
18436     return "#";
18438   if (operands[2] == const1_rtx
18439       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
18440     return "<rotate>{<imodesuffix>}\t%0";
18441   else
18442     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
18444   "&& reload_completed
18445    && !(rtx_equal_p (operands[0], operands[1]))"
18446   [(set (strict_low_part (match_dup 0)) (match_dup 1))
18447    (parallel
18448      [(set (strict_low_part (match_dup 0))
18449            (any_rotate:SWI12 (match_dup 0) (match_dup 2)))
18450       (clobber (reg:CC FLAGS_REG))])]
18451   ""
18452   [(set_attr "type" "rotate")
18453    (set (attr "length_immediate")
18454      (if_then_else
18455        (and (match_operand 2 "const1_operand")
18456             (ior (match_test "TARGET_SHIFT1")
18457                  (match_test "optimize_function_for_size_p (cfun)")))
18458        (const_string "0")
18459        (const_string "*")))
18460    (set_attr "mode" "<MODE>")])
18462 (define_split
18463  [(set (match_operand:HI 0 "QIreg_operand")
18464        (any_rotate:HI (match_dup 0) (const_int 8)))
18465   (clobber (reg:CC FLAGS_REG))]
18466  "reload_completed
18467   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
18468  [(set (match_dup 0) (bswap:HI (match_dup 0)))])
18470 ;; Rotations through carry flag
18471 (define_insn "rcrsi2"
18472   [(set (match_operand:SI 0 "register_operand" "=r,r")
18473         (plus:SI
18474           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
18475                        (const_int 1))
18476           (ashift:SI (ltu:SI (reg:CCC FLAGS_REG) (const_int 0))
18477                      (const_int 31))))
18478    (clobber (reg:CC FLAGS_REG))]
18479   ""
18480   "@
18481    rcr{l}\t%0
18482    rcr{l}\t{%1, %0|%0, %1}"
18483   [(set_attr "isa" "*,apx_ndd")
18484    (set_attr "type" "ishift1")
18485    (set_attr "memory" "none")
18486    (set_attr "length_immediate" "0")
18487    (set_attr "mode" "SI")])
18489 (define_insn "rcrdi2"
18490   [(set (match_operand:DI 0 "register_operand" "=r,r")
18491         (plus:DI
18492           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,rm")
18493                        (const_int 1))
18494           (ashift:DI (ltu:DI (reg:CCC FLAGS_REG) (const_int 0))
18495                      (const_int 63))))
18496    (clobber (reg:CC FLAGS_REG))]
18497   "TARGET_64BIT"
18498   "@
18499    rcr{q}\t%0
18500    rcr{q}\t{%1, %0|%0, %1}"
18501   [(set_attr "isa" "*,apx_ndd")
18502    (set_attr "type" "ishift1")
18503    (set_attr "length_immediate" "0")
18504    (set_attr "mode" "DI")])
18506 ;; Versions of sar and shr that set the carry flag.
18507 (define_insn "<insn><mode>3_carry"
18508   [(set (reg:CCC FLAGS_REG)
18509         (unspec:CCC [(and:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
18510                                 (const_int 1))
18511                      (const_int 0)] UNSPEC_CC_NE))
18512    (set (match_operand:SWI48 0 "register_operand" "=r,r")
18513         (any_shiftrt:SWI48 (match_dup 1) (const_int 1)))]
18514   ""
18516   bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
18517   if ((TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
18518       && !use_ndd)
18519     return "<shift>{<imodesuffix>}\t%0";
18520   return use_ndd ? "<shift>{<imodesuffix>}\t{$1, %1, %0|%0, %1, 1}"
18521                  : "<shift>{<imodesuffix>}\t{$1, %0|%0, 1}";
18523   [(set_attr "isa" "*, apx_ndd")
18524    (set_attr "type" "ishift1")
18525    (set (attr "length_immediate")
18526      (if_then_else
18527        (ior (match_test "TARGET_SHIFT1")
18528             (match_test "optimize_function_for_size_p (cfun)"))
18529        (const_string "0")
18530        (const_string "*")))
18531    (set_attr "mode" "<MODE>")])
18533 ;; Bit set / bit test instructions
18535 ;; %%% bts, btr, btc
18537 ;; These instructions are *slow* when applied to memory.
18539 (define_code_attr btsc [(ior "bts") (xor "btc")])
18541 (define_insn "*<btsc><mode>"
18542   [(set (match_operand:SWI48 0 "register_operand" "=r")
18543         (any_or:SWI48
18544           (ashift:SWI48 (const_int 1)
18545                         (match_operand:QI 2 "register_operand" "r"))
18546           (match_operand:SWI48 1 "register_operand" "0")))
18547    (clobber (reg:CC FLAGS_REG))]
18548   "TARGET_USE_BT"
18549   "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
18550   [(set_attr "type" "alu1")
18551    (set_attr "prefix_0f" "1")
18552    (set_attr "znver1_decode" "double")
18553    (set_attr "mode" "<MODE>")])
18555 ;; Avoid useless masking of count operand.
18556 (define_insn_and_split "*<btsc><mode>_mask"
18557   [(set (match_operand:SWI48 0 "register_operand")
18558         (any_or:SWI48
18559           (ashift:SWI48
18560             (const_int 1)
18561             (subreg:QI
18562               (and
18563                 (match_operand 1 "int248_register_operand")
18564                 (match_operand 2 "const_int_operand")) 0))
18565           (match_operand:SWI48 3 "register_operand")))
18566    (clobber (reg:CC FLAGS_REG))]
18567   "TARGET_USE_BT
18568    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
18569       == GET_MODE_BITSIZE (<MODE>mode)-1
18570    && ix86_pre_reload_split ()"
18571   "#"
18572   "&& 1"
18573   [(parallel
18574      [(set (match_dup 0)
18575            (any_or:SWI48
18576              (ashift:SWI48 (const_int 1)
18577                            (match_dup 1))
18578              (match_dup 3)))
18579       (clobber (reg:CC FLAGS_REG))])]
18581   operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
18582   operands[1] = gen_lowpart (QImode, operands[1]);
18585 (define_insn_and_split "*<btsc><mode>_mask_1"
18586   [(set (match_operand:SWI48 0 "register_operand")
18587         (any_or:SWI48
18588           (ashift:SWI48
18589             (const_int 1)
18590             (and:QI
18591               (match_operand:QI 1 "register_operand")
18592               (match_operand:QI 2 "const_int_operand")))
18593           (match_operand:SWI48 3 "register_operand")))
18594    (clobber (reg:CC FLAGS_REG))]
18595   "TARGET_USE_BT
18596    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
18597       == GET_MODE_BITSIZE (<MODE>mode)-1
18598    && ix86_pre_reload_split ()"
18599   "#"
18600   "&& 1"
18601   [(parallel
18602      [(set (match_dup 0)
18603            (any_or:SWI48
18604              (ashift:SWI48 (const_int 1)
18605                            (match_dup 1))
18606              (match_dup 3)))
18607       (clobber (reg:CC FLAGS_REG))])])
18609 (define_insn "*btr<mode>"
18610   [(set (match_operand:SWI48 0 "register_operand" "=r")
18611         (and:SWI48
18612           (rotate:SWI48 (const_int -2)
18613                         (match_operand:QI 2 "register_operand" "r"))
18614         (match_operand:SWI48 1 "register_operand" "0")))
18615    (clobber (reg:CC FLAGS_REG))]
18616   "TARGET_USE_BT"
18617   "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
18618   [(set_attr "type" "alu1")
18619    (set_attr "prefix_0f" "1")
18620    (set_attr "znver1_decode" "double")
18621    (set_attr "mode" "<MODE>")])
18623 ;; Avoid useless masking of count operand.
18624 (define_insn_and_split "*btr<mode>_mask"
18625   [(set (match_operand:SWI48 0 "register_operand")
18626         (and:SWI48
18627           (rotate:SWI48
18628             (const_int -2)
18629             (subreg:QI
18630               (and
18631                 (match_operand 1 "int248_register_operand")
18632                 (match_operand 2 "const_int_operand")) 0))
18633           (match_operand:SWI48 3 "register_operand")))
18634    (clobber (reg:CC FLAGS_REG))]
18635   "TARGET_USE_BT
18636    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
18637       == GET_MODE_BITSIZE (<MODE>mode)-1
18638    && ix86_pre_reload_split ()"
18639   "#"
18640   "&& 1"
18641   [(parallel
18642      [(set (match_dup 0)
18643            (and:SWI48
18644              (rotate:SWI48 (const_int -2)
18645                            (match_dup 1))
18646              (match_dup 3)))
18647       (clobber (reg:CC FLAGS_REG))])]
18649   operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
18650   operands[1] = gen_lowpart (QImode, operands[1]);
18653 (define_insn_and_split "*btr<mode>_mask_1"
18654   [(set (match_operand:SWI48 0 "register_operand")
18655         (and:SWI48
18656           (rotate:SWI48
18657             (const_int -2)
18658             (and:QI
18659               (match_operand:QI 1 "register_operand")
18660               (match_operand:QI 2 "const_int_operand")))
18661           (match_operand:SWI48 3 "register_operand")))
18662    (clobber (reg:CC FLAGS_REG))]
18663   "TARGET_USE_BT
18664    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
18665       == GET_MODE_BITSIZE (<MODE>mode)-1
18666    && ix86_pre_reload_split ()"
18667   "#"
18668   "&& 1"
18669   [(parallel
18670      [(set (match_dup 0)
18671            (and:SWI48
18672              (rotate:SWI48 (const_int -2)
18673                            (match_dup 1))
18674              (match_dup 3)))
18675       (clobber (reg:CC FLAGS_REG))])])
18677 (define_insn_and_split "*btr<mode>_1"
18678   [(set (match_operand:SWI12 0 "register_operand")
18679         (and:SWI12
18680           (subreg:SWI12
18681             (rotate:SI (const_int -2)
18682                        (match_operand:QI 2 "register_operand")) 0)
18683           (match_operand:SWI12 1 "nonimmediate_operand")))
18684    (clobber (reg:CC FLAGS_REG))]
18685   "TARGET_USE_BT && ix86_pre_reload_split ()"
18686   "#"
18687   "&& 1"
18688   [(parallel
18689      [(set (match_dup 0)
18690            (and:SI (rotate:SI (const_int -2) (match_dup 2))
18691                    (match_dup 1)))
18692       (clobber (reg:CC FLAGS_REG))])]
18694   operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
18695   operands[1] = force_reg (<MODE>mode, operands[1]);
18696   operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
18699 (define_insn_and_split "*btr<mode>_2"
18700   [(set (zero_extract:HI
18701           (match_operand:SWI12 0 "nonimmediate_operand")
18702           (const_int 1)
18703           (match_operand:QI 1 "register_operand"))
18704         (const_int 0))
18705    (clobber (reg:CC FLAGS_REG))]
18706   "TARGET_USE_BT && ix86_pre_reload_split ()"
18707   "#"
18708   "&& MEM_P (operands[0])"
18709   [(set (match_dup 2) (match_dup 0))
18710    (parallel
18711      [(set (match_dup 3)
18712            (and:SI (rotate:SI (const_int -2) (match_dup 1))
18713                    (match_dup 4)))
18714       (clobber (reg:CC FLAGS_REG))])
18715    (set (match_dup 0) (match_dup 5))]
18717   operands[2] = gen_reg_rtx (<MODE>mode);
18718   operands[5] = gen_reg_rtx (<MODE>mode);
18719   operands[3] = lowpart_subreg (SImode, operands[5], <MODE>mode);
18720   operands[4] = lowpart_subreg (SImode, operands[2], <MODE>mode);
18723 (define_split
18724   [(set (zero_extract:HI
18725           (match_operand:SWI12 0 "register_operand")
18726           (const_int 1)
18727           (match_operand:QI 1 "register_operand"))
18728         (const_int 0))
18729    (clobber (reg:CC FLAGS_REG))]
18730   "TARGET_USE_BT && ix86_pre_reload_split ()"
18731   [(parallel
18732      [(set (match_dup 0)
18733            (and:SI (rotate:SI (const_int -2) (match_dup 1))
18734                    (match_dup 2)))
18735       (clobber (reg:CC FLAGS_REG))])]
18737   operands[2] = lowpart_subreg (SImode, operands[0], <MODE>mode);
18738   operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
18741 ;; These instructions are never faster than the corresponding
18742 ;; and/ior/xor operations when using immediate operand, so with
18743 ;; 32-bit there's no point.  But in 64-bit, we can't hold the
18744 ;; relevant immediates within the instruction itself, so operating
18745 ;; on bits in the high 32-bits of a register becomes easier.
18747 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
18748 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
18749 ;; negdf respectively, so they can never be disabled entirely.
18751 (define_insn "*btsq_imm"
18752   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
18753                          (const_int 1)
18754                          (match_operand:QI 1 "const_0_to_63_operand"))
18755         (const_int 1))
18756    (clobber (reg:CC FLAGS_REG))]
18757   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
18758   "bts{q}\t{%1, %0|%0, %1}"
18759   [(set_attr "type" "alu1")
18760    (set_attr "prefix_0f" "1")
18761    (set_attr "znver1_decode" "double")
18762    (set_attr "mode" "DI")])
18764 (define_insn "*btrq_imm"
18765   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
18766                          (const_int 1)
18767                          (match_operand:QI 1 "const_0_to_63_operand"))
18768         (const_int 0))
18769    (clobber (reg:CC FLAGS_REG))]
18770   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
18771   "btr{q}\t{%1, %0|%0, %1}"
18772   [(set_attr "type" "alu1")
18773    (set_attr "prefix_0f" "1")
18774    (set_attr "znver1_decode" "double")
18775    (set_attr "mode" "DI")])
18777 (define_insn "*btcq_imm"
18778   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
18779                          (const_int 1)
18780                          (match_operand:QI 1 "const_0_to_63_operand"))
18781         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
18782    (clobber (reg:CC FLAGS_REG))]
18783   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
18784   "btc{q}\t{%1, %0|%0, %1}"
18785   [(set_attr "type" "alu1")
18786    (set_attr "prefix_0f" "1")
18787    (set_attr "znver1_decode" "double")
18788    (set_attr "mode" "DI")])
18790 ;; Allow Nocona to avoid these instructions if a register is available.
18792 (define_peephole2
18793   [(match_scratch:DI 2 "r")
18794    (parallel [(set (zero_extract:DI
18795                      (match_operand:DI 0 "nonimmediate_operand")
18796                      (const_int 1)
18797                      (match_operand:QI 1 "const_0_to_63_operand"))
18798                    (const_int 1))
18799               (clobber (reg:CC FLAGS_REG))])]
18800   "TARGET_64BIT && !TARGET_USE_BT"
18801   [(parallel [(set (match_dup 0)
18802                    (ior:DI (match_dup 0) (match_dup 3)))
18803               (clobber (reg:CC FLAGS_REG))])]
18805   int i = INTVAL (operands[1]);
18807   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
18809   if (!x86_64_immediate_operand (operands[3], DImode))
18810     {
18811       emit_move_insn (operands[2], operands[3]);
18812       operands[3] = operands[2];
18813     }
18816 (define_peephole2
18817   [(match_scratch:DI 2 "r")
18818    (parallel [(set (zero_extract:DI
18819                      (match_operand:DI 0 "nonimmediate_operand")
18820                      (const_int 1)
18821                      (match_operand:QI 1 "const_0_to_63_operand"))
18822                    (const_int 0))
18823               (clobber (reg:CC FLAGS_REG))])]
18824   "TARGET_64BIT && !TARGET_USE_BT"
18825   [(parallel [(set (match_dup 0)
18826                    (and:DI (match_dup 0) (match_dup 3)))
18827               (clobber (reg:CC FLAGS_REG))])]
18829   int i = INTVAL (operands[1]);
18831   operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
18833   if (!x86_64_immediate_operand (operands[3], DImode))
18834     {
18835       emit_move_insn (operands[2], operands[3]);
18836       operands[3] = operands[2];
18837     }
18840 (define_peephole2
18841   [(match_scratch:DI 2 "r")
18842    (parallel [(set (zero_extract:DI
18843                      (match_operand:DI 0 "nonimmediate_operand")
18844                      (const_int 1)
18845                      (match_operand:QI 1 "const_0_to_63_operand"))
18846               (not:DI (zero_extract:DI
18847                         (match_dup 0) (const_int 1) (match_dup 1))))
18848               (clobber (reg:CC FLAGS_REG))])]
18849   "TARGET_64BIT && !TARGET_USE_BT"
18850   [(parallel [(set (match_dup 0)
18851                    (xor:DI (match_dup 0) (match_dup 3)))
18852               (clobber (reg:CC FLAGS_REG))])]
18854   int i = INTVAL (operands[1]);
18856   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
18858   if (!x86_64_immediate_operand (operands[3], DImode))
18859     {
18860       emit_move_insn (operands[2], operands[3]);
18861       operands[3] = operands[2];
18862     }
18865 ;; %%% bt
18867 (define_insn "*bt<mode>"
18868   [(set (reg:CCC FLAGS_REG)
18869         (compare:CCC
18870           (zero_extract:SWI48
18871             (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
18872             (const_int 1)
18873             (match_operand:QI 1 "nonmemory_operand" "q<S>,<S>"))
18874           (const_int 0)))]
18875   ""
18877   switch (get_attr_mode (insn))
18878     {
18879     case MODE_SI:
18880       return "bt{l}\t{%k1, %k0|%k0, %k1}";
18882     case MODE_DI:
18883       return "bt{q}\t{%q1, %0|%0, %q1}";
18885     default:
18886       gcc_unreachable ();
18887     }
18889   [(set_attr "type" "alu1")
18890    (set_attr "prefix_0f" "1")
18891    (set (attr "mode")
18892         (if_then_else
18893           (and (match_test "CONST_INT_P (operands[1])")
18894                (match_test "INTVAL (operands[1]) < 32"))
18895           (const_string "SI")
18896           (const_string "<MODE>")))])
18898 (define_insn_and_split "*bt<SWI48:mode>_mask"
18899   [(set (reg:CCC FLAGS_REG)
18900         (compare:CCC
18901           (zero_extract:SWI48
18902             (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
18903             (const_int 1)
18904             (subreg:QI
18905               (and:SWI248
18906                 (match_operand:SWI248 1 "register_operand")
18907                 (match_operand 2 "const_int_operand")) 0))
18908           (const_int 0)))]
18909   "TARGET_USE_BT
18910    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
18911       == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
18912    && ix86_pre_reload_split ()"
18913   "#"
18914   "&& 1"
18915   [(set (reg:CCC FLAGS_REG)
18916         (compare:CCC
18917          (zero_extract:SWI48 (match_dup 0) (const_int 1) (match_dup 1))
18918          (const_int 0)))]
18919   "operands[1] = gen_lowpart (QImode, operands[1]);")
18921 (define_insn_and_split "*jcc_bt<mode>"
18922   [(set (pc)
18923         (if_then_else (match_operator 0 "bt_comparison_operator"
18924                         [(zero_extract:SWI48
18925                            (match_operand:SWI48 1 "nonimmediate_operand")
18926                            (const_int 1)
18927                            (match_operand:QI 2 "nonmemory_operand"))
18928                          (const_int 0)])
18929                       (label_ref (match_operand 3))
18930                       (pc)))
18931    (clobber (reg:CC FLAGS_REG))]
18932   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
18933    && (CONST_INT_P (operands[2])
18934        ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
18935           && INTVAL (operands[2])
18936                >= (optimize_function_for_size_p (cfun) ? 8 : 32))
18937        : !memory_operand (operands[1], <MODE>mode))
18938    && ix86_pre_reload_split ()"
18939   "#"
18940   "&& 1"
18941   [(set (reg:CCC FLAGS_REG)
18942         (compare:CCC
18943           (zero_extract:SWI48
18944             (match_dup 1)
18945             (const_int 1)
18946             (match_dup 2))
18947           (const_int 0)))
18948    (set (pc)
18949         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
18950                       (label_ref (match_dup 3))
18951                       (pc)))]
18953   operands[0] = shallow_copy_rtx (operands[0]);
18954   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
18957 ;; Avoid useless masking of bit offset operand.
18958 (define_insn_and_split "*jcc_bt<mode>_mask"
18959   [(set (pc)
18960         (if_then_else (match_operator 0 "bt_comparison_operator"
18961                         [(zero_extract:SWI48
18962                            (match_operand:SWI48 1 "register_operand")
18963                            (const_int 1)
18964                            (and:QI
18965                              (match_operand:QI 2 "register_operand")
18966                              (match_operand 3 "const_int_operand")))
18967                          (const_int 0)])
18968                       (label_ref (match_operand 4))
18969                       (pc)))
18970    (clobber (reg:CC FLAGS_REG))]
18971   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
18972    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
18973       == GET_MODE_BITSIZE (<MODE>mode)-1
18974    && ix86_pre_reload_split ()"
18975   "#"
18976   "&& 1"
18977   [(set (reg:CCC FLAGS_REG)
18978         (compare:CCC
18979           (zero_extract:SWI48
18980             (match_dup 1)
18981             (const_int 1)
18982             (match_dup 2))
18983           (const_int 0)))
18984    (set (pc)
18985         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
18986                       (label_ref (match_dup 4))
18987                       (pc)))]
18989   operands[0] = shallow_copy_rtx (operands[0]);
18990   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
18993 ;; Avoid useless masking of bit offset operand.
18994 (define_insn_and_split "*jcc_bt<SWI48:mode>_mask_1"
18995   [(set (pc)
18996         (if_then_else (match_operator 0 "bt_comparison_operator"
18997                         [(zero_extract:SWI48
18998                            (match_operand:SWI48 1 "register_operand")
18999                            (const_int 1)
19000                            (subreg:QI
19001                              (and:SWI248
19002                                (match_operand:SWI248 2 "register_operand")
19003                                (match_operand 3 "const_int_operand")) 0))
19004                          (const_int 0)])
19005                       (label_ref (match_operand 4))
19006                       (pc)))
19007    (clobber (reg:CC FLAGS_REG))]
19008   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
19009    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
19010       == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
19011    && ix86_pre_reload_split ()"
19012   "#"
19013   "&& 1"
19014   [(set (reg:CCC FLAGS_REG)
19015         (compare:CCC
19016           (zero_extract:SWI48
19017             (match_dup 1)
19018             (const_int 1)
19019             (match_dup 2))
19020           (const_int 0)))
19021    (set (pc)
19022         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
19023                       (label_ref (match_dup 4))
19024                       (pc)))]
19026   operands[0] = shallow_copy_rtx (operands[0]);
19027   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
19028   operands[2] = gen_lowpart (QImode, operands[2]);
19031 ;; Help combine recognize bt followed by cmov
19032 (define_split
19033   [(set (match_operand:SWI248 0 "register_operand")
19034         (if_then_else:SWI248
19035          (match_operator 5 "bt_comparison_operator"
19036           [(zero_extract:SWI48
19037             (match_operand:SWI48 1 "register_operand")
19038             (const_int 1)
19039             (match_operand:QI 2 "register_operand"))
19040            (const_int 0)])
19041          (match_operand:SWI248 3 "nonimmediate_operand")
19042          (match_operand:SWI248 4 "nonimmediate_operand")))]
19043   "TARGET_USE_BT && TARGET_CMOVE
19044    && !(MEM_P (operands[3]) && MEM_P (operands[4]))
19045    && ix86_pre_reload_split ()"
19046   [(set (reg:CCC FLAGS_REG)
19047         (compare:CCC
19048          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
19049          (const_int 0)))
19050    (set (match_dup 0)
19051         (if_then_else:SWI248 (eq (reg:CCC FLAGS_REG) (const_int 0))
19052                              (match_dup 3)
19053                              (match_dup 4)))]
19055   if (GET_CODE (operands[5]) == EQ)
19056     std::swap (operands[3], operands[4]);
19059 ;; Help combine recognize bt followed by setc
19060 (define_insn_and_split "*bt<mode>_setcqi"
19061   [(set (subreg:SWI48 (match_operand:QI 0 "register_operand") 0)
19062         (zero_extract:SWI48
19063          (match_operand:SWI48 1 "register_operand")
19064          (const_int 1)
19065          (match_operand:QI 2 "register_operand")))
19066    (clobber (reg:CC FLAGS_REG))]
19067   "TARGET_USE_BT && ix86_pre_reload_split ()"
19068   "#"
19069   "&& 1"
19070   [(set (reg:CCC FLAGS_REG)
19071         (compare:CCC
19072          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
19073          (const_int 0)))
19074    (set (match_dup 0)
19075         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))])
19077 ;; Help combine recognize bt followed by setnc
19078 (define_insn_and_split "*bt<mode>_setncqi"
19079   [(set (match_operand:QI 0 "register_operand")
19080         (and:QI
19081          (not:QI
19082           (subreg:QI
19083            (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
19084                            (match_operand:QI 2 "register_operand")) 0))
19085          (const_int 1)))
19086    (clobber (reg:CC FLAGS_REG))]
19087   "TARGET_USE_BT && ix86_pre_reload_split ()"
19088   "#"
19089   "&& 1"
19090   [(set (reg:CCC FLAGS_REG)
19091         (compare:CCC
19092          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
19093          (const_int 0)))
19094    (set (match_dup 0)
19095         (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
19097 (define_insn_and_split "*bt<mode>_setnc<mode>"
19098   [(set (match_operand:SWI48 0 "register_operand")
19099         (and:SWI48
19100          (not:SWI48
19101           (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
19102                           (match_operand:QI 2 "register_operand")))
19103          (const_int 1)))
19104    (clobber (reg:CC FLAGS_REG))]
19105   "TARGET_USE_BT && ix86_pre_reload_split ()"
19106   "#"
19107   "&& 1"
19108   [(set (reg:CCC FLAGS_REG)
19109         (compare:CCC
19110          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
19111          (const_int 0)))
19112    (set (match_dup 3)
19113         (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
19114    (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
19115   "operands[3] = gen_reg_rtx (QImode);")
19117 ;; Help combine recognize bt followed by setnc (PR target/110588)
19118 (define_insn_and_split "*bt<mode>_setncqi_2"
19119   [(set (match_operand:QI 0 "register_operand")
19120         (eq:QI
19121           (zero_extract:SWI48
19122             (match_operand:SWI48 1 "register_operand")
19123             (const_int 1)
19124             (match_operand:QI 2 "register_operand"))
19125           (const_int 0)))
19126    (clobber (reg:CC FLAGS_REG))]
19127   "TARGET_USE_BT && ix86_pre_reload_split ()"
19128   "#"
19129   "&& 1"
19130   [(set (reg:CCC FLAGS_REG)
19131         (compare:CCC
19132          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
19133          (const_int 0)))
19134    (set (match_dup 0)
19135         (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
19137 ;; Help combine recognize bt followed by setc
19138 (define_insn_and_split "*bt<mode>_setc<mode>_mask"
19139   [(set (match_operand:SWI48 0 "register_operand")
19140         (zero_extract:SWI48
19141           (match_operand:SWI48 1 "register_operand")
19142           (const_int 1)
19143           (subreg:QI
19144             (and:SWI48
19145               (match_operand:SWI48 2 "register_operand")
19146               (match_operand 3 "const_int_operand")) 0)))
19147    (clobber (reg:CC FLAGS_REG))]
19148   "TARGET_USE_BT
19149    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
19150       == GET_MODE_BITSIZE (<MODE>mode)-1
19151    && ix86_pre_reload_split ()"
19152   "#"
19153   "&& 1"
19154   [(set (reg:CCC FLAGS_REG)
19155         (compare:CCC
19156          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
19157          (const_int 0)))
19158    (set (match_dup 3)
19159         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))
19160    (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
19162   operands[2] = gen_lowpart (QImode, operands[2]);
19163   operands[3] = gen_reg_rtx (QImode);
19166 ;; Store-flag instructions.
19168 (define_split
19169   [(set (match_operand:QI 0 "nonimmediate_operand")
19170         (match_operator:QI 1 "add_comparison_operator"
19171           [(not:SWI (match_operand:SWI 2 "register_operand"))
19172            (match_operand:SWI 3 "nonimmediate_operand")]))]
19173   ""
19174   [(set (reg:CCC FLAGS_REG)
19175         (compare:CCC
19176           (plus:SWI (match_dup 2) (match_dup 3))
19177           (match_dup 2)))
19178    (set (match_dup 0)
19179         (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))])
19181 (define_split
19182   [(set (match_operand:QI 0 "nonimmediate_operand")
19183         (match_operator:QI 1 "shr_comparison_operator"
19184           [(match_operand:DI 2 "register_operand")
19185            (match_operand 3 "const_int_operand")]))]
19186   "TARGET_64BIT
19187    && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
19188   [(set (reg:CCZ FLAGS_REG)
19189         (compare:CCZ
19190           (lshiftrt:DI (match_dup 2) (match_dup 4))
19191           (const_int 0)))
19192    (set (match_dup 0)
19193         (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))]
19195   enum rtx_code new_code;
19197   operands[1] = shallow_copy_rtx (operands[1]);
19198   switch (GET_CODE (operands[1]))
19199     {
19200     case GTU: new_code = NE; break;
19201     case LEU: new_code = EQ; break;
19202     default: gcc_unreachable ();
19203     }
19204   PUT_CODE (operands[1], new_code);
19206   operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
19209 ;; For all sCOND expanders, also expand the compare or test insn that
19210 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
19212 (define_insn "*setcc_<mode>_zu"
19213   [(set (match_operand:SWI248 0 "register_operand" "=r")
19214         (match_operator:SWI248 1 "ix86_comparison_operator"
19215           [(reg FLAGS_REG) (const_int 0)]))]
19216   "TARGET_APX_ZU"
19217   "setzu%C1\t%b0"
19218   [(set_attr "type" "setcc")])
19220 (define_insn_and_split "*setcc_di_1"
19221   [(set (match_operand:DI 0 "register_operand" "=q")
19222         (match_operator:DI 1 "ix86_comparison_operator"
19223           [(reg FLAGS_REG) (const_int 0)]))]
19224   "!TARGET_APX_ZU && TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
19225   "#"
19226   "&& reload_completed"
19227   [(set (match_dup 2) (match_dup 1))
19228    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
19230   operands[1] = shallow_copy_rtx (operands[1]);
19231   PUT_MODE (operands[1], QImode);
19232   operands[2] = gen_lowpart (QImode, operands[0]);
19235 (define_insn_and_split "*setcc_<mode>_1_and"
19236   [(set (match_operand:SWI24 0 "register_operand" "=q")
19237         (match_operator:SWI24 1 "ix86_comparison_operator"
19238           [(reg FLAGS_REG) (const_int 0)]))
19239    (clobber (reg:CC FLAGS_REG))]
19240   "!TARGET_PARTIAL_REG_STALL
19241    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
19242   "#"
19243   "&& reload_completed"
19244   [(set (match_dup 2) (match_dup 1))
19245    (parallel [(set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))
19246               (clobber (reg:CC FLAGS_REG))])]
19248   operands[1] = shallow_copy_rtx (operands[1]);
19249   PUT_MODE (operands[1], QImode);
19250   operands[2] = gen_lowpart (QImode, operands[0]);
19253 (define_insn_and_split "*setcc_<mode>_1_movzbl"
19254   [(set (match_operand:SWI24 0 "register_operand" "=q")
19255         (match_operator:SWI24 1 "ix86_comparison_operator"
19256           [(reg FLAGS_REG) (const_int 0)]))]
19257   "!TARGET_APX_ZU && !TARGET_PARTIAL_REG_STALL
19258    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
19259   "#"
19260   "&& reload_completed"
19261   [(set (match_dup 2) (match_dup 1))
19262    (set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))]
19264   operands[1] = shallow_copy_rtx (operands[1]);
19265   PUT_MODE (operands[1], QImode);
19266   operands[2] = gen_lowpart (QImode, operands[0]);
19269 (define_insn "*setcc_qi"
19270   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
19271         (match_operator:QI 1 "ix86_comparison_operator"
19272           [(reg FLAGS_REG) (const_int 0)]))]
19273   ""
19274   "set%C1\t%0"
19275   [(set_attr "type" "setcc")
19276    (set_attr "mode" "QI")])
19278 (define_insn "*setcc_qi_slp"
19279   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
19280         (match_operator:QI 1 "ix86_comparison_operator"
19281           [(reg FLAGS_REG) (const_int 0)]))]
19282   ""
19283   "set%C1\t%0"
19284   [(set_attr "type" "setcc")
19285    (set_attr "mode" "QI")])
19287 (define_expand "setcc_si_slp"
19288   [(set (match_operand:SI 0 "register_operand")
19289         (unspec:SI
19290           [(match_operand:QI 1)
19291            (match_operand:SI 2 "register_operand")] UNSPEC_SETCC_SI_SLP))])
19293 (define_insn_and_split "*setcc_si_slp"
19294   [(set (match_operand:SI 0 "register_operand" "=q")
19295         (unspec:SI
19296           [(match_operator:QI 1 "ix86_comparison_operator"
19297              [(reg FLAGS_REG) (const_int 0)])
19298            (match_operand:SI 2 "register_operand" "0")] UNSPEC_SETCC_SI_SLP))]
19299   "ix86_pre_reload_split ()"
19300   "#"
19301   "&& 1"
19302   [(set (match_dup 0) (match_dup 2))
19303    (set (strict_low_part (match_dup 3)) (match_dup 1))]
19305   operands[3] = gen_lowpart (QImode, operands[0]);
19308 ;; In general it is not safe to assume too much about CCmode registers,
19309 ;; so simplify-rtx stops when it sees a second one.  Under certain
19310 ;; conditions this is safe on x86, so help combine not create
19312 ;;      seta    %al
19313 ;;      testb   %al, %al
19314 ;;      sete    %al
19316 (define_split
19317   [(set (match_operand:QI 0 "nonimmediate_operand")
19318         (ne:QI (match_operator 1 "ix86_comparison_operator"
19319                  [(reg FLAGS_REG) (const_int 0)])
19320             (const_int 0)))]
19321   ""
19322   [(set (match_dup 0) (match_dup 1))]
19324   operands[1] = shallow_copy_rtx (operands[1]);
19325   PUT_MODE (operands[1], QImode);
19328 (define_split
19329   [(set (strict_low_part (match_operand:QI 0 "register_operand"))
19330         (ne:QI (match_operator 1 "ix86_comparison_operator"
19331                  [(reg FLAGS_REG) (const_int 0)])
19332             (const_int 0)))]
19333   ""
19334   [(set (match_dup 0) (match_dup 1))]
19336   operands[1] = shallow_copy_rtx (operands[1]);
19337   PUT_MODE (operands[1], QImode);
19340 (define_split
19341   [(set (match_operand:QI 0 "nonimmediate_operand")
19342         (eq:QI (match_operator 1 "ix86_comparison_operator"
19343                  [(reg FLAGS_REG) (const_int 0)])
19344             (const_int 0)))]
19345   ""
19346   [(set (match_dup 0) (match_dup 1))]
19348   operands[1] = shallow_copy_rtx (operands[1]);
19349   PUT_MODE (operands[1], QImode);
19350   PUT_CODE (operands[1],
19351             ix86_reverse_condition (GET_CODE (operands[1]),
19352                                     GET_MODE (XEXP (operands[1], 0))));
19354   /* Make sure that (a) the CCmode we have for the flags is strong
19355      enough for the reversed compare or (b) we have a valid FP compare.  */
19356   if (! ix86_comparison_operator (operands[1], VOIDmode))
19357     FAIL;
19360 (define_split
19361   [(set (strict_low_part (match_operand:QI 0 "register_operand"))
19362         (eq:QI (match_operator 1 "ix86_comparison_operator"
19363                  [(reg FLAGS_REG) (const_int 0)])
19364             (const_int 0)))]
19365   ""
19366   [(set (match_dup 0) (match_dup 1))]
19368   operands[1] = shallow_copy_rtx (operands[1]);
19369   PUT_MODE (operands[1], QImode);
19370   PUT_CODE (operands[1],
19371             ix86_reverse_condition (GET_CODE (operands[1]),
19372                                     GET_MODE (XEXP (operands[1], 0))));
19374   /* Make sure that (a) the CCmode we have for the flags is strong
19375      enough for the reversed compare or (b) we have a valid FP compare.  */
19376   if (! ix86_comparison_operator (operands[1], VOIDmode))
19377     FAIL;
19380 ;; Eliminate redundant compare between set{z,nz} and j{z,nz}:
19381 ;; setz %al; test %al,%al; jz <...> -> setz %al; jnz <...> and
19382 ;; setnz %al, test %al,%al; jz <...> -> setnz %al; jz <...>.
19383 (define_peephole2
19384   [(set (match_operand:QI 0 "nonimmediate_operand")
19385         (match_operator:QI 1 "bt_comparison_operator"
19386           [(reg:CCZ FLAGS_REG) (const_int 0)]))
19387    (set (reg:CCZ FLAGS_REG)
19388         (compare:CCZ (match_dup 0) (const_int 0)))
19389    (set (pc)
19390         (if_then_else (match_operator 2 "bt_comparison_operator"
19391                         [(reg:CCZ FLAGS_REG) (const_int 0)])
19392                       (match_operand 3)
19393                       (pc)))]
19394   "peep2_regno_dead_p (3, FLAGS_REG)"
19395   [(set (match_dup 0)
19396         (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))
19397    (set (pc)
19398         (if_then_else (match_dup 2)
19399                       (match_dup 3)
19400                       (pc)))]
19402   if (GET_CODE (operands[1]) == EQ)
19403     {
19404       operands[2] = shallow_copy_rtx (operands[2]);
19405       PUT_CODE (operands[2], reverse_condition (GET_CODE (operands[2])));
19406     }
19409 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
19410 ;; subsequent logical operations are used to imitate conditional moves.
19411 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
19412 ;; it directly.
19414 (define_insn "setcc_<mode>_sse"
19415   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19416         (match_operator:MODEF 3 "sse_comparison_operator"
19417           [(match_operand:MODEF 1 "register_operand" "0,x")
19418            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xjm")]))]
19419   "SSE_FLOAT_MODE_P (<MODE>mode)"
19420   "@
19421    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
19422    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
19423   [(set_attr "isa" "noavx,avx")
19424    (set_attr "addr" "*,gpr16")
19425    (set_attr "type" "ssecmp")
19426    (set_attr "length_immediate" "1")
19427    (set_attr "prefix" "orig,vex")
19428    (set_attr "mode" "<MODE>")])
19430 (define_insn "setcc_hf_mask"
19431   [(set (match_operand:QI 0 "register_operand" "=k")
19432         (unspec:QI
19433           [(match_operand:HF 1 "register_operand" "v")
19434            (match_operand:HF 2 "nonimmediate_operand" "vm")
19435            (match_operand:SI 3 "const_0_to_31_operand")]
19436           UNSPEC_PCMP))]
19437   "TARGET_AVX512FP16"
19438   "vcmpsh\t{%3, %2, %1, %0|%0, %1, %2, %3}"
19439   [(set_attr "type" "ssecmp")
19440    (set_attr "prefix" "evex")
19441    (set_attr "mode" "HF")])
19444 ;; Basic conditional jump instructions.
19446 (define_split
19447   [(set (pc)
19448         (if_then_else
19449           (match_operator 1 "add_comparison_operator"
19450             [(not:SWI (match_operand:SWI 2 "register_operand"))
19451              (match_operand:SWI 3 "nonimmediate_operand")])
19452           (label_ref (match_operand 0))
19453           (pc)))]
19454   ""
19455   [(set (reg:CCC FLAGS_REG)
19456         (compare:CCC
19457           (plus:SWI (match_dup 2) (match_dup 3))
19458           (match_dup 2)))
19459    (set (pc)
19460         (if_then_else (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)])
19461                       (label_ref (match_operand 0))
19462                       (pc)))])
19464 (define_split
19465   [(set (pc)
19466         (if_then_else
19467           (match_operator 1 "shr_comparison_operator"
19468             [(match_operand:DI 2 "register_operand")
19469              (match_operand 3 "const_int_operand")])
19470           (label_ref (match_operand 0))
19471           (pc)))]
19472   "TARGET_64BIT
19473    && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
19474   [(set (reg:CCZ FLAGS_REG)
19475         (compare:CCZ
19476           (lshiftrt:DI (match_dup 2) (match_dup 4))
19477           (const_int 0)))
19478    (set (pc)
19479         (if_then_else (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)])
19480                       (label_ref (match_operand 0))
19481                       (pc)))]
19483   enum rtx_code new_code;
19485   operands[1] = shallow_copy_rtx (operands[1]);
19486   switch (GET_CODE (operands[1]))
19487     {
19488     case GTU: new_code = NE; break;
19489     case LEU: new_code = EQ; break;
19490     default: gcc_unreachable ();
19491     }
19492   PUT_CODE (operands[1], new_code);
19494   operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
19497 ;; We ignore the overflow flag for signed branch instructions.
19499 (define_insn "*jcc"
19500   [(set (pc)
19501         (if_then_else (match_operator 1 "ix86_comparison_operator"
19502                                       [(reg FLAGS_REG) (const_int 0)])
19503                       (label_ref (match_operand 0))
19504                       (pc)))]
19505   ""
19506   "%!%+j%C1\t%l0"
19507   [(set_attr "type" "ibr")
19508    (set_attr "modrm" "0")
19509    (set (attr "length")
19510         (if_then_else
19511           (and (ge (minus (match_dup 0) (pc))
19512                    (const_int -126))
19513                (lt (minus (match_dup 0) (pc))
19514                    (const_int 128)))
19515           (const_int 2)
19516           (const_int 6)))])
19518 ;; In general it is not safe to assume too much about CCmode registers,
19519 ;; so simplify-rtx stops when it sees a second one.  Under certain
19520 ;; conditions this is safe on x86, so help combine not create
19522 ;;      seta    %al
19523 ;;      testb   %al, %al
19524 ;;      je      Lfoo
19526 (define_split
19527   [(set (pc)
19528         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
19529                                       [(reg FLAGS_REG) (const_int 0)])
19530                           (const_int 0))
19531                       (label_ref (match_operand 1))
19532                       (pc)))]
19533   ""
19534   [(set (pc)
19535         (if_then_else (match_dup 0)
19536                       (label_ref (match_dup 1))
19537                       (pc)))]
19539   operands[0] = shallow_copy_rtx (operands[0]);
19540   PUT_MODE (operands[0], VOIDmode);
19543 (define_split
19544   [(set (pc)
19545         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
19546                                       [(reg FLAGS_REG) (const_int 0)])
19547                           (const_int 0))
19548                       (label_ref (match_operand 1))
19549                       (pc)))]
19550   ""
19551   [(set (pc)
19552         (if_then_else (match_dup 0)
19553                       (label_ref (match_dup 1))
19554                       (pc)))]
19556   operands[0] = shallow_copy_rtx (operands[0]);
19557   PUT_MODE (operands[0], VOIDmode);
19558   PUT_CODE (operands[0],
19559             ix86_reverse_condition (GET_CODE (operands[0]),
19560                                     GET_MODE (XEXP (operands[0], 0))));
19562   /* Make sure that (a) the CCmode we have for the flags is strong
19563      enough for the reversed compare or (b) we have a valid FP compare.  */
19564   if (! ix86_comparison_operator (operands[0], VOIDmode))
19565     FAIL;
19568 ;; Unconditional and other jump instructions
19570 (define_insn "jump"
19571   [(set (pc)
19572         (label_ref (match_operand 0)))]
19573   ""
19574   "%!jmp\t%l0"
19575   [(set_attr "type" "ibr")
19576    (set_attr "modrm" "0")
19577    (set (attr "length")
19578         (if_then_else
19579           (and (ge (minus (match_dup 0) (pc))
19580                    (const_int -126))
19581                (lt (minus (match_dup 0) (pc))
19582                    (const_int 128)))
19583           (const_int 2)
19584           (const_int 5)))])
19586 (define_expand "indirect_jump"
19587   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
19588   ""
19590   if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
19591     operands[0] = convert_memory_address (word_mode, operands[0]);
19592   cfun->machine->has_local_indirect_jump = true;
19595 (define_insn "*indirect_jump"
19596   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
19597   ""
19598   "* return ix86_output_indirect_jmp (operands[0]);"
19599   [(set (attr "type")
19600      (if_then_else (match_test "(cfun->machine->indirect_branch_type
19601                                  != indirect_branch_keep)")
19602         (const_string "multi")
19603         (const_string "ibr")))
19604    (set_attr "length_immediate" "0")])
19606 (define_expand "tablejump"
19607   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
19608               (use (label_ref (match_operand 1)))])]
19609   ""
19611   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
19612      relative.  Convert the relative address to an absolute address.  */
19613   if (flag_pic)
19614     {
19615       rtx op0, op1;
19616       enum rtx_code code;
19618       /* We can't use @GOTOFF for text labels on VxWorks;
19619          see gotoff_operand.  */
19620       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
19621         {
19622           code = PLUS;
19623           op0 = operands[0];
19624           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
19625         }
19626       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
19627         {
19628           code = PLUS;
19629           op0 = operands[0];
19630           op1 = pic_offset_table_rtx;
19631         }
19632       else
19633         {
19634           code = MINUS;
19635           op0 = pic_offset_table_rtx;
19636           op1 = operands[0];
19637         }
19639       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
19640                                          OPTAB_DIRECT);
19641     }
19643   if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
19644     operands[0] = convert_memory_address (word_mode, operands[0]);
19645   cfun->machine->has_local_indirect_jump = true;
19648 (define_insn "*tablejump_1"
19649   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
19650    (use (label_ref (match_operand 1)))]
19651   ""
19652   "* return ix86_output_indirect_jmp (operands[0]);"
19653   [(set (attr "type")
19654      (if_then_else (match_test "(cfun->machine->indirect_branch_type
19655                                  != indirect_branch_keep)")
19656         (const_string "multi")
19657         (const_string "ibr")))
19658    (set_attr "length_immediate" "0")])
19660 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
19662 (define_peephole2
19663   [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
19664    (set (match_operand:QI 1 "register_operand")
19665         (match_operator:QI 2 "ix86_comparison_operator"
19666           [(reg FLAGS_REG) (const_int 0)]))
19667    (set (match_operand 3 "any_QIreg_operand")
19668         (zero_extend (match_dup 1)))]
19669   "(peep2_reg_dead_p (3, operands[1])
19670     || operands_match_p (operands[1], operands[3]))
19671    && ! reg_overlap_mentioned_p (operands[3], operands[0])
19672    && peep2_regno_dead_p (0, FLAGS_REG)"
19673   [(set (match_dup 4) (match_dup 0))
19674    (set (strict_low_part (match_dup 5))
19675         (match_dup 2))]
19677   operands[5] = gen_lowpart (QImode, operands[3]);
19678   ix86_expand_clear (operands[3]);
19681 (define_peephole2
19682   [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
19683               (match_operand 4)])
19684    (set (match_operand:QI 1 "register_operand")
19685         (match_operator:QI 2 "ix86_comparison_operator"
19686           [(reg FLAGS_REG) (const_int 0)]))
19687    (set (match_operand 3 "any_QIreg_operand")
19688         (zero_extend (match_dup 1)))]
19689   "(peep2_reg_dead_p (3, operands[1])
19690     || operands_match_p (operands[1], operands[3]))
19691    && ! reg_overlap_mentioned_p (operands[3], operands[0])
19692    && ! reg_overlap_mentioned_p (operands[3], operands[4])
19693    && ! reg_set_p (operands[3], operands[4])
19694    && peep2_regno_dead_p (0, FLAGS_REG)"
19695   [(parallel [(set (match_dup 5) (match_dup 0))
19696               (match_dup 4)])
19697    (set (strict_low_part (match_dup 6))
19698         (match_dup 2))]
19700   operands[6] = gen_lowpart (QImode, operands[3]);
19701   ix86_expand_clear (operands[3]);
19704 (define_peephole2
19705   [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
19706    (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
19707               (match_operand 5)])
19708    (set (match_operand:QI 2 "register_operand")
19709         (match_operator:QI 3 "ix86_comparison_operator"
19710           [(reg FLAGS_REG) (const_int 0)]))
19711    (set (match_operand 4 "any_QIreg_operand")
19712         (zero_extend (match_dup 2)))]
19713   "(peep2_reg_dead_p (4, operands[2])
19714     || operands_match_p (operands[2], operands[4]))
19715    && ! reg_overlap_mentioned_p (operands[4], operands[0])
19716    && ! reg_overlap_mentioned_p (operands[4], operands[1])
19717    && ! reg_overlap_mentioned_p (operands[4], operands[5])
19718    && ! reg_set_p (operands[4], operands[5])
19719    && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
19720    && peep2_regno_dead_p (0, FLAGS_REG)"
19721   [(set (match_dup 6) (match_dup 0))
19722    (parallel [(set (match_dup 7) (match_dup 1))
19723               (match_dup 5)])
19724    (set (strict_low_part (match_dup 8))
19725         (match_dup 3))]
19727   operands[8] = gen_lowpart (QImode, operands[4]);
19728   ix86_expand_clear (operands[4]);
19731 ;; Similar, but match zero extend with andsi3.
19733 (define_peephole2
19734   [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
19735    (set (match_operand:QI 1 "register_operand")
19736         (match_operator:QI 2 "ix86_comparison_operator"
19737           [(reg FLAGS_REG) (const_int 0)]))
19738    (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
19739                    (and:SI (match_dup 3) (const_int 255)))
19740               (clobber (reg:CC FLAGS_REG))])]
19741   "REGNO (operands[1]) == REGNO (operands[3])
19742    && ! reg_overlap_mentioned_p (operands[3], operands[0])
19743    && peep2_regno_dead_p (0, FLAGS_REG)"
19744   [(set (match_dup 4) (match_dup 0))
19745    (set (strict_low_part (match_dup 5))
19746         (match_dup 2))]
19748   operands[5] = gen_lowpart (QImode, operands[3]);
19749   ix86_expand_clear (operands[3]);
19752 (define_peephole2
19753   [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
19754               (match_operand 4)])
19755    (set (match_operand:QI 1 "register_operand")
19756         (match_operator:QI 2 "ix86_comparison_operator"
19757           [(reg FLAGS_REG) (const_int 0)]))
19758    (parallel [(set (match_operand 3 "any_QIreg_operand")
19759                    (zero_extend (match_dup 1)))
19760               (clobber (reg:CC FLAGS_REG))])]
19761   "(peep2_reg_dead_p (3, operands[1])
19762     || operands_match_p (operands[1], operands[3]))
19763    && ! reg_overlap_mentioned_p (operands[3], operands[0])
19764    && ! reg_overlap_mentioned_p (operands[3], operands[4])
19765    && ! reg_set_p (operands[3], operands[4])
19766    && peep2_regno_dead_p (0, FLAGS_REG)"
19767   [(parallel [(set (match_dup 5) (match_dup 0))
19768               (match_dup 4)])
19769    (set (strict_low_part (match_dup 6))
19770         (match_dup 2))]
19772   operands[6] = gen_lowpart (QImode, operands[3]);
19773   ix86_expand_clear (operands[3]);
19776 (define_peephole2
19777   [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
19778    (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
19779               (match_operand 5)])
19780    (set (match_operand:QI 2 "register_operand")
19781         (match_operator:QI 3 "ix86_comparison_operator"
19782           [(reg FLAGS_REG) (const_int 0)]))
19783    (parallel [(set (match_operand 4 "any_QIreg_operand")
19784                    (zero_extend (match_dup 2)))
19785               (clobber (reg:CC FLAGS_REG))])]
19786   "(peep2_reg_dead_p (4, operands[2])
19787     || operands_match_p (operands[2], operands[4]))
19788    && ! reg_overlap_mentioned_p (operands[4], operands[0])
19789    && ! reg_overlap_mentioned_p (operands[4], operands[1])
19790    && ! reg_overlap_mentioned_p (operands[4], operands[5])
19791    && ! reg_set_p (operands[4], operands[5])
19792    && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
19793    && peep2_regno_dead_p (0, FLAGS_REG)"
19794   [(set (match_dup 6) (match_dup 0))
19795    (parallel [(set (match_dup 7) (match_dup 1))
19796               (match_dup 5)])
19797    (set (strict_low_part (match_dup 8))
19798         (match_dup 3))]
19800   operands[8] = gen_lowpart (QImode, operands[4]);
19801   ix86_expand_clear (operands[4]);
19804 (define_peephole2
19805   [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
19806    (set (strict_low_part (match_operand:QI 5 "register_operand"))
19807         (match_operator:QI 6 "ix86_comparison_operator"
19808           [(reg FLAGS_REG) (const_int 0)]))
19809    (set (match_operand:QI 1 "register_operand")
19810         (match_operator:QI 2 "ix86_comparison_operator"
19811           [(reg FLAGS_REG) (const_int 0)]))
19812    (set (match_operand 3 "any_QIreg_operand")
19813         (zero_extend (match_dup 1)))]
19814   "(peep2_reg_dead_p (4, operands[1])
19815     || operands_match_p (operands[1], operands[3]))
19816    && ! reg_overlap_mentioned_p (operands[3], operands[0])
19817    && ! reg_overlap_mentioned_p (operands[3], operands[5])
19818    && ! reg_overlap_mentioned_p (operands[1], operands[5])
19819    && peep2_regno_dead_p (0, FLAGS_REG)"
19820   [(set (match_dup 4) (match_dup 0))
19821    (set (strict_low_part (match_dup 5))
19822         (match_dup 6))
19823    (set (strict_low_part (match_dup 7))
19824         (match_dup 2))]
19826   operands[7] = gen_lowpart (QImode, operands[3]);
19827   ix86_expand_clear (operands[3]);
19830 ;; Call instructions.
19832 ;; The predicates normally associated with named expanders are not properly
19833 ;; checked for calls.  This is a bug in the generic code, but it isn't that
19834 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
19836 ;; P6 processors will jump to the address after the decrement when %esp
19837 ;; is used as a call operand, so they will execute return address as a code.
19838 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
19840 ;; Register constraint for call instruction.
19841 (define_mode_attr c [(SI "l") (DI "r")])
19843 ;; Call subroutine returning no value.
19845 (define_expand "call"
19846   [(call (match_operand:QI 0)
19847          (match_operand 1))
19848    (use (match_operand 2))]
19849   ""
19851   ix86_expand_call (NULL, operands[0], operands[1],
19852                     operands[2], NULL, false);
19853   DONE;
19856 (define_expand "sibcall"
19857   [(call (match_operand:QI 0)
19858          (match_operand 1))
19859    (use (match_operand 2))]
19860   ""
19862   ix86_expand_call (NULL, operands[0], operands[1],
19863                     operands[2], NULL, true);
19864   DONE;
19867 (define_insn "*call"
19868   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
19869          (match_operand 1))]
19870   "!SIBLING_CALL_P (insn)"
19871   "* return ix86_output_call_insn (insn, operands[0]);"
19872   [(set_attr "type" "call")])
19874 ;; This covers both call and sibcall since only GOT slot is allowed.
19875 (define_insn "*call_got_x32"
19876   [(call (mem:QI (zero_extend:DI
19877                    (match_operand:SI 0 "GOT_memory_operand" "Bg")))
19878          (match_operand 1))]
19879   "TARGET_X32"
19881   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
19882   return ix86_output_call_insn (insn, fnaddr);
19884   [(set_attr "type" "call")])
19886 ;; Since sibcall never returns, we can only use call-clobbered register
19887 ;; as GOT base.
19888 (define_insn "*sibcall_GOT_32"
19889   [(call (mem:QI
19890            (mem:SI (plus:SI
19891                      (match_operand:SI 0 "register_no_elim_operand" "U")
19892                      (match_operand:SI 1 "GOT32_symbol_operand"))))
19893          (match_operand 2))]
19894   "!TARGET_MACHO
19895   && !TARGET_64BIT
19896   && !TARGET_INDIRECT_BRANCH_REGISTER
19897   && SIBLING_CALL_P (insn)"
19899   rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
19900   fnaddr = gen_const_mem (SImode, fnaddr);
19901   return ix86_output_call_insn (insn, fnaddr);
19903   [(set_attr "type" "call")])
19905 (define_insn "*sibcall"
19906   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
19907          (match_operand 1))]
19908   "SIBLING_CALL_P (insn)"
19909   "* return ix86_output_call_insn (insn, operands[0]);"
19910   [(set_attr "type" "call")])
19912 (define_insn "*sibcall_memory"
19913   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
19914          (match_operand 1))
19915    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
19916   "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
19917   "* return ix86_output_call_insn (insn, operands[0]);"
19918   [(set_attr "type" "call")])
19920 (define_peephole2
19921   [(set (match_operand:W 0 "register_operand")
19922         (match_operand:W 1 "memory_operand"))
19923    (call (mem:QI (match_dup 0))
19924          (match_operand 3))]
19925   "!TARGET_X32
19926    && !TARGET_INDIRECT_BRANCH_REGISTER
19927    && SIBLING_CALL_P (peep2_next_insn (1))
19928    && !reg_mentioned_p (operands[0],
19929                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
19930   [(parallel [(call (mem:QI (match_dup 1))
19931                     (match_dup 3))
19932               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
19934 (define_peephole2
19935   [(set (match_operand:W 0 "register_operand")
19936         (match_operand:W 1 "memory_operand"))
19937    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
19938    (call (mem:QI (match_dup 0))
19939          (match_operand 3))]
19940   "!TARGET_X32
19941    && !TARGET_INDIRECT_BRANCH_REGISTER
19942    && SIBLING_CALL_P (peep2_next_insn (2))
19943    && !reg_mentioned_p (operands[0],
19944                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
19945   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
19946    (parallel [(call (mem:QI (match_dup 1))
19947                     (match_dup 3))
19948               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
19950 (define_expand "call_pop"
19951   [(parallel [(call (match_operand:QI 0)
19952                     (match_operand:SI 1))
19953               (set (reg:SI SP_REG)
19954                    (plus:SI (reg:SI SP_REG)
19955                             (match_operand:SI 3)))])]
19956   "!TARGET_64BIT"
19958   ix86_expand_call (NULL, operands[0], operands[1],
19959                     operands[2], operands[3], false);
19960   DONE;
19963 (define_insn "*call_pop"
19964   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
19965          (match_operand 1))
19966    (set (reg:SI SP_REG)
19967         (plus:SI (reg:SI SP_REG)
19968                  (match_operand:SI 2 "immediate_operand" "i")))]
19969   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
19970   "* return ix86_output_call_insn (insn, operands[0]);"
19971   [(set_attr "type" "call")])
19973 (define_insn "*sibcall_pop"
19974   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
19975          (match_operand 1))
19976    (set (reg:SI SP_REG)
19977         (plus:SI (reg:SI SP_REG)
19978                  (match_operand:SI 2 "immediate_operand" "i")))]
19979   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
19980   "* return ix86_output_call_insn (insn, operands[0]);"
19981   [(set_attr "type" "call")])
19983 (define_insn "*sibcall_pop_memory"
19984   [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
19985          (match_operand 1))
19986    (set (reg:SI SP_REG)
19987         (plus:SI (reg:SI SP_REG)
19988                  (match_operand:SI 2 "immediate_operand" "i")))
19989    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
19990   "!TARGET_64BIT"
19991   "* return ix86_output_call_insn (insn, operands[0]);"
19992   [(set_attr "type" "call")])
19994 (define_peephole2
19995   [(set (match_operand:SI 0 "register_operand")
19996         (match_operand:SI 1 "memory_operand"))
19997    (parallel [(call (mem:QI (match_dup 0))
19998                     (match_operand 3))
19999               (set (reg:SI SP_REG)
20000                    (plus:SI (reg:SI SP_REG)
20001                             (match_operand:SI 4 "immediate_operand")))])]
20002   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
20003    && !reg_mentioned_p (operands[0],
20004                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
20005   [(parallel [(call (mem:QI (match_dup 1))
20006                     (match_dup 3))
20007               (set (reg:SI SP_REG)
20008                    (plus:SI (reg:SI SP_REG)
20009                             (match_dup 4)))
20010               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
20012 (define_peephole2
20013   [(set (match_operand:SI 0 "register_operand")
20014         (match_operand:SI 1 "memory_operand"))
20015    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
20016    (parallel [(call (mem:QI (match_dup 0))
20017                     (match_operand 3))
20018               (set (reg:SI SP_REG)
20019                    (plus:SI (reg:SI SP_REG)
20020                             (match_operand:SI 4 "immediate_operand")))])]
20021   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
20022    && !reg_mentioned_p (operands[0],
20023                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
20024   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
20025    (parallel [(call (mem:QI (match_dup 1))
20026                     (match_dup 3))
20027               (set (reg:SI SP_REG)
20028                    (plus:SI (reg:SI SP_REG)
20029                             (match_dup 4)))
20030               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
20032 ;; Combining simple memory jump instruction
20034 (define_peephole2
20035   [(set (match_operand:W 0 "register_operand")
20036         (match_operand:W 1 "memory_operand"))
20037    (set (pc) (match_dup 0))]
20038   "!TARGET_X32
20039    && !TARGET_INDIRECT_BRANCH_REGISTER
20040    && peep2_reg_dead_p (2, operands[0])"
20041   [(set (pc) (match_dup 1))])
20043 ;; Call subroutine, returning value in operand 0
20045 (define_expand "call_value"
20046   [(set (match_operand 0)
20047         (call (match_operand:QI 1)
20048               (match_operand 2)))
20049    (use (match_operand 3))]
20050   ""
20052   ix86_expand_call (operands[0], operands[1], operands[2],
20053                     operands[3], NULL, false);
20054   DONE;
20057 (define_expand "sibcall_value"
20058   [(set (match_operand 0)
20059         (call (match_operand:QI 1)
20060               (match_operand 2)))
20061    (use (match_operand 3))]
20062   ""
20064   ix86_expand_call (operands[0], operands[1], operands[2],
20065                     operands[3], NULL, true);
20066   DONE;
20069 (define_insn "*call_value"
20070   [(set (match_operand 0)
20071         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
20072               (match_operand 2)))]
20073   "!SIBLING_CALL_P (insn)"
20074   "* return ix86_output_call_insn (insn, operands[1]);"
20075   [(set_attr "type" "callv")])
20077 ;; This covers both call and sibcall since only GOT slot is allowed.
20078 (define_insn "*call_value_got_x32"
20079   [(set (match_operand 0)
20080         (call (mem:QI
20081                 (zero_extend:DI
20082                   (match_operand:SI 1 "GOT_memory_operand" "Bg")))
20083               (match_operand 2)))]
20084   "TARGET_X32"
20086   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
20087   return ix86_output_call_insn (insn, fnaddr);
20089   [(set_attr "type" "callv")])
20091 ;; Since sibcall never returns, we can only use call-clobbered register
20092 ;; as GOT base.
20093 (define_insn "*sibcall_value_GOT_32"
20094   [(set (match_operand 0)
20095         (call (mem:QI
20096                 (mem:SI (plus:SI
20097                           (match_operand:SI 1 "register_no_elim_operand" "U")
20098                           (match_operand:SI 2 "GOT32_symbol_operand"))))
20099          (match_operand 3)))]
20100   "!TARGET_MACHO
20101    && !TARGET_64BIT
20102    && !TARGET_INDIRECT_BRANCH_REGISTER
20103    && SIBLING_CALL_P (insn)"
20105   rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
20106   fnaddr = gen_const_mem (SImode, fnaddr);
20107   return ix86_output_call_insn (insn, fnaddr);
20109   [(set_attr "type" "callv")])
20111 (define_insn "*sibcall_value"
20112   [(set (match_operand 0)
20113         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
20114               (match_operand 2)))]
20115   "SIBLING_CALL_P (insn)"
20116   "* return ix86_output_call_insn (insn, operands[1]);"
20117   [(set_attr "type" "callv")])
20119 (define_insn "*sibcall_value_memory"
20120   [(set (match_operand 0)
20121         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
20122               (match_operand 2)))
20123    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
20124   "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
20125   "* return ix86_output_call_insn (insn, operands[1]);"
20126   [(set_attr "type" "callv")])
20128 (define_peephole2
20129   [(set (match_operand:W 0 "register_operand")
20130         (match_operand:W 1 "memory_operand"))
20131    (set (match_operand 2)
20132    (call (mem:QI (match_dup 0))
20133                  (match_operand 3)))]
20134   "!TARGET_X32
20135    && !TARGET_INDIRECT_BRANCH_REGISTER
20136    && SIBLING_CALL_P (peep2_next_insn (1))
20137    && !reg_mentioned_p (operands[0],
20138                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
20139   [(parallel [(set (match_dup 2)
20140                    (call (mem:QI (match_dup 1))
20141                          (match_dup 3)))
20142               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
20144 (define_peephole2
20145   [(set (match_operand:W 0 "register_operand")
20146         (match_operand:W 1 "memory_operand"))
20147    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
20148    (set (match_operand 2)
20149         (call (mem:QI (match_dup 0))
20150               (match_operand 3)))]
20151   "!TARGET_X32
20152    && !TARGET_INDIRECT_BRANCH_REGISTER
20153    && SIBLING_CALL_P (peep2_next_insn (2))
20154    && !reg_mentioned_p (operands[0],
20155                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
20156   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
20157    (parallel [(set (match_dup 2)
20158                    (call (mem:QI (match_dup 1))
20159                          (match_dup 3)))
20160               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
20162 (define_expand "call_value_pop"
20163   [(parallel [(set (match_operand 0)
20164                    (call (match_operand:QI 1)
20165                          (match_operand:SI 2)))
20166               (set (reg:SI SP_REG)
20167                    (plus:SI (reg:SI SP_REG)
20168                             (match_operand:SI 4)))])]
20169   "!TARGET_64BIT"
20171   ix86_expand_call (operands[0], operands[1], operands[2],
20172                     operands[3], operands[4], false);
20173   DONE;
20176 (define_insn "*call_value_pop"
20177   [(set (match_operand 0)
20178         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
20179               (match_operand 2)))
20180    (set (reg:SI SP_REG)
20181         (plus:SI (reg:SI SP_REG)
20182                  (match_operand:SI 3 "immediate_operand" "i")))]
20183   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20184   "* return ix86_output_call_insn (insn, operands[1]);"
20185   [(set_attr "type" "callv")])
20187 (define_insn "*sibcall_value_pop"
20188   [(set (match_operand 0)
20189         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
20190               (match_operand 2)))
20191    (set (reg:SI SP_REG)
20192         (plus:SI (reg:SI SP_REG)
20193                  (match_operand:SI 3 "immediate_operand" "i")))]
20194   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20195   "* return ix86_output_call_insn (insn, operands[1]);"
20196   [(set_attr "type" "callv")])
20198 (define_insn "*sibcall_value_pop_memory"
20199   [(set (match_operand 0)
20200         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
20201               (match_operand 2)))
20202    (set (reg:SI SP_REG)
20203         (plus:SI (reg:SI SP_REG)
20204                  (match_operand:SI 3 "immediate_operand" "i")))
20205    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
20206   "!TARGET_64BIT"
20207   "* return ix86_output_call_insn (insn, operands[1]);"
20208   [(set_attr "type" "callv")])
20210 (define_peephole2
20211   [(set (match_operand:SI 0 "register_operand")
20212         (match_operand:SI 1 "memory_operand"))
20213    (parallel [(set (match_operand 2)
20214                    (call (mem:QI (match_dup 0))
20215                          (match_operand 3)))
20216               (set (reg:SI SP_REG)
20217                    (plus:SI (reg:SI SP_REG)
20218                             (match_operand:SI 4 "immediate_operand")))])]
20219   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
20220    && !reg_mentioned_p (operands[0],
20221                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
20222   [(parallel [(set (match_dup 2)
20223                    (call (mem:QI (match_dup 1))
20224                          (match_dup 3)))
20225               (set (reg:SI SP_REG)
20226                    (plus:SI (reg:SI SP_REG)
20227                             (match_dup 4)))
20228               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
20230 (define_peephole2
20231   [(set (match_operand:SI 0 "register_operand")
20232         (match_operand:SI 1 "memory_operand"))
20233    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
20234    (parallel [(set (match_operand 2)
20235                    (call (mem:QI (match_dup 0))
20236                          (match_operand 3)))
20237               (set (reg:SI SP_REG)
20238                    (plus:SI (reg:SI SP_REG)
20239                             (match_operand:SI 4 "immediate_operand")))])]
20240   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
20241    && !reg_mentioned_p (operands[0],
20242                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
20243   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
20244    (parallel [(set (match_dup 2)
20245                    (call (mem:QI (match_dup 1))
20246                          (match_dup 3)))
20247               (set (reg:SI SP_REG)
20248                    (plus:SI (reg:SI SP_REG)
20249                             (match_dup 4)))
20250               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
20252 ;; Call subroutine returning any type.
20254 (define_expand "untyped_call"
20255   [(parallel [(call (match_operand 0)
20256                     (const_int 0))
20257               (match_operand 1)
20258               (match_operand 2)])]
20259   ""
20261   int i;
20263   /* In order to give reg-stack an easier job in validating two
20264      coprocessor registers as containing a possible return value,
20265      simply pretend the untyped call returns a complex long double
20266      value. 
20268      We can't use SSE_REGPARM_MAX here since callee is unprototyped
20269      and should have the default ABI.  */
20271   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
20272                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
20273                     operands[0], const0_rtx,
20274                     GEN_INT ((TARGET_64BIT
20275                               ? (ix86_abi == SYSV_ABI
20276                                  ? X86_64_SSE_REGPARM_MAX
20277                                  : X86_64_MS_SSE_REGPARM_MAX)
20278                               : X86_32_SSE_REGPARM_MAX)
20279                              - 1),
20280                     NULL, false);
20282   for (i = 0; i < XVECLEN (operands[2], 0); i++)
20283     {
20284       rtx set = XVECEXP (operands[2], 0, i);
20285       emit_move_insn (SET_DEST (set), SET_SRC (set));
20286     }
20288   /* The optimizer does not know that the call sets the function value
20289      registers we stored in the result block.  We avoid problems by
20290      claiming that all hard registers are used and clobbered at this
20291      point.  */
20292   emit_insn (gen_blockage ());
20294   DONE;
20297 ;; Prologue and epilogue instructions
20299 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
20300 ;; all of memory.  This blocks insns from being moved across this point.
20302 (define_insn "blockage"
20303   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
20304   ""
20305   ""
20306   [(set_attr "length" "0")])
20308 ;; Do not schedule instructions accessing memory across this point.
20310 (define_expand "memory_blockage"
20311   [(set (match_dup 0)
20312         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
20313   ""
20315   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20316   MEM_VOLATILE_P (operands[0]) = 1;
20319 (define_insn "*memory_blockage"
20320   [(set (match_operand:BLK 0)
20321         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
20322   ""
20323   ""
20324   [(set_attr "length" "0")])
20326 ;; As USE insns aren't meaningful after reload, this is used instead
20327 ;; to prevent deleting instructions setting registers for PIC code
20328 (define_insn "prologue_use"
20329   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
20330   ""
20331   ""
20332   [(set_attr "length" "0")])
20334 ;; Insn emitted into the body of a function to return from a function.
20335 ;; This is only done if the function's epilogue is known to be simple.
20336 ;; See comments for ix86_can_use_return_insn_p in i386.cc.
20338 (define_expand "return"
20339   [(simple_return)]
20340   "ix86_can_use_return_insn_p ()"
20342   if (crtl->args.pops_args)
20343     {
20344       rtx popc = GEN_INT (crtl->args.pops_args);
20345       emit_jump_insn (gen_simple_return_pop_internal (popc));
20346       DONE;
20347     }
20350 ;; We need to disable this for TARGET_SEH, as otherwise
20351 ;; shrink-wrapped prologue gets enabled too.  This might exceed
20352 ;; the maximum size of prologue in unwind information.
20353 ;; Also disallow shrink-wrapping if using stack slot to pass the
20354 ;; static chain pointer - the first instruction has to be pushl %esi
20355 ;; and it can't be moved around, as we use alternate entry points
20356 ;; in that case.
20357 ;; Also disallow for ms_hook_prologue functions which have frame
20358 ;; pointer set up in function label which is correctly handled in
20359 ;; ix86_expand_{prologue|epligoue}() only.
20361 (define_expand "simple_return"
20362   [(simple_return)]
20363   "!TARGET_SEH && !ix86_static_chain_on_stack && !ix86_function_ms_hook_prologue (cfun->decl)"
20365   if (crtl->args.pops_args)
20366     {
20367       rtx popc = GEN_INT (crtl->args.pops_args);
20368       emit_jump_insn (gen_simple_return_pop_internal (popc));
20369       DONE;
20370     }
20373 (define_insn "simple_return_internal"
20374   [(simple_return)]
20375   "reload_completed"
20376   "* return ix86_output_function_return (false);"
20377   [(set_attr "length" "1")
20378    (set_attr "atom_unit" "jeu")
20379    (set_attr "length_immediate" "0")
20380    (set_attr "modrm" "0")])
20382 (define_insn "interrupt_return"
20383   [(simple_return)
20384    (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
20385   "reload_completed"
20387   return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret";
20390 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
20391 ;; instruction Athlon and K8 have.
20393 (define_insn "simple_return_internal_long"
20394   [(simple_return)
20395    (unspec [(const_int 0)] UNSPEC_REP)]
20396   "reload_completed"
20397   "* return ix86_output_function_return (true);"
20398   [(set_attr "length" "2")
20399    (set_attr "atom_unit" "jeu")
20400    (set_attr "length_immediate" "0")
20401    (set_attr "prefix_rep" "1")
20402    (set_attr "modrm" "0")])
20404 (define_insn_and_split "simple_return_pop_internal"
20405   [(simple_return)
20406    (use (match_operand:SI 0 "const_int_operand"))]
20407   "reload_completed"
20408   "ret\t%0"
20409   "&& cfun->machine->function_return_type != indirect_branch_keep"
20410   [(const_int 0)]
20411   "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
20412   [(set_attr "length" "3")
20413    (set_attr "atom_unit" "jeu")
20414    (set_attr "length_immediate" "2")
20415    (set_attr "modrm" "0")])
20417 (define_expand "simple_return_indirect_internal"
20418   [(parallel
20419      [(simple_return)
20420       (use (match_operand 0 "register_operand"))])])
20422 (define_insn "*simple_return_indirect_internal<mode>"
20423   [(simple_return)
20424    (use (match_operand:W 0 "register_operand" "r"))]
20425   "reload_completed"
20426   "* return ix86_output_indirect_function_return (operands[0]);"
20427   [(set (attr "type")
20428      (if_then_else (match_test "(cfun->machine->indirect_branch_type
20429                                  != indirect_branch_keep)")
20430         (const_string "multi")
20431         (const_string "ibr")))
20432    (set_attr "length_immediate" "0")])
20434 (define_insn "nop"
20435   [(const_int 0)]
20436   ""
20437   "nop"
20438   [(set_attr "length" "1")
20439    (set_attr "length_immediate" "0")
20440    (set_attr "modrm" "0")])
20442 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
20443 (define_insn "nops"
20444   [(unspec_volatile [(match_operand 0 "const_int_operand")]
20445                     UNSPECV_NOPS)]
20446   "reload_completed"
20448   int num = INTVAL (operands[0]);
20450   gcc_assert (IN_RANGE (num, 1, 8));
20452   while (num--)
20453     fputs ("\tnop\n", asm_out_file);
20455   return "";
20457   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
20458    (set_attr "length_immediate" "0")
20459    (set_attr "modrm" "0")])
20461 ;; Pad to 1 << op0 byte boundary, max skip in op1.  Used to avoid
20462 ;; branch prediction penalty for the third jump in a 16-byte
20463 ;; block on K8.
20464 ;; Also it's used to align tight loops which can be fix into 1 cacheline.
20465 ;; It can help code prefetch and reduce DSB miss.
20467 (define_insn "max_skip_align"
20468   [(unspec_volatile [(match_operand 0) (match_operand 1)] UNSPECV_ALIGN)]
20469   ""
20471 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
20472   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, (int)INTVAL (operands[0]), (int)INTVAL (operands[1]));
20473 #else
20474   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
20475      The align insn is used to avoid 3 jump instructions in the row to improve
20476      branch prediction and the benefits hardly outweigh the cost of extra 8
20477      nops on the average inserted by full alignment pseudo operation.  */
20478 #endif
20479   return "";
20481   [(set_attr "length" "16")])
20483 (define_expand "prologue"
20484   [(const_int 0)]
20485   ""
20486   "ix86_expand_prologue (); DONE;")
20488 (define_expand "set_got"
20489   [(parallel
20490      [(set (match_operand:SI 0 "register_operand")
20491            (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
20492       (clobber (reg:CC FLAGS_REG))])]
20493   "!TARGET_64BIT"
20495   if (flag_pic && !TARGET_VXWORKS_RTP)
20496     ix86_pc_thunk_call_expanded = true;
20499 (define_insn "*set_got"
20500   [(set (match_operand:SI 0 "register_operand" "=r")
20501         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
20502    (clobber (reg:CC FLAGS_REG))]
20503   "!TARGET_64BIT"
20504   "* return output_set_got (operands[0], NULL_RTX);"
20505   [(set_attr "type" "multi")
20506    (set_attr "length" "12")])
20508 (define_expand "set_got_labelled"
20509   [(parallel
20510      [(set (match_operand:SI 0 "register_operand")
20511            (unspec:SI [(label_ref (match_operand 1))]
20512                       UNSPEC_SET_GOT))
20513       (clobber (reg:CC FLAGS_REG))])]
20514   "!TARGET_64BIT"
20516   if (flag_pic && !TARGET_VXWORKS_RTP)
20517     ix86_pc_thunk_call_expanded = true;
20520 (define_insn "*set_got_labelled"
20521   [(set (match_operand:SI 0 "register_operand" "=r")
20522         (unspec:SI [(label_ref (match_operand 1))]
20523          UNSPEC_SET_GOT))
20524    (clobber (reg:CC FLAGS_REG))]
20525   "!TARGET_64BIT"
20526   "* return output_set_got (operands[0], operands[1]);"
20527   [(set_attr "type" "multi")
20528    (set_attr "length" "12")])
20530 (define_insn "set_got_rex64"
20531   [(set (match_operand:DI 0 "register_operand" "=r")
20532         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
20533   "TARGET_64BIT"
20534   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
20535   [(set_attr "type" "lea")
20536    (set_attr "length_address" "4")
20537    (set_attr "mode" "DI")])
20539 (define_insn "set_rip_rex64"
20540   [(set (match_operand:DI 0 "register_operand" "=r")
20541         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
20542   "TARGET_64BIT"
20543   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
20544   [(set_attr "type" "lea")
20545    (set_attr "length_address" "4")
20546    (set_attr "mode" "DI")])
20548 (define_insn "set_got_offset_rex64"
20549   [(set (match_operand:DI 0 "register_operand" "=r")
20550         (unspec:DI
20551           [(label_ref (match_operand 1))]
20552           UNSPEC_SET_GOT_OFFSET))]
20553   "TARGET_LP64"
20554   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
20555   [(set_attr "type" "imov")
20556    (set_attr "length_immediate" "0")
20557    (set_attr "length_address" "8")
20558    (set_attr "mode" "DI")])
20560 (define_expand "epilogue"
20561   [(const_int 0)]
20562   ""
20563   "ix86_expand_epilogue (1); DONE;")
20565 (define_expand "sibcall_epilogue"
20566   [(const_int 0)]
20567   ""
20568   "ix86_expand_epilogue (0); DONE;")
20570 (define_expand "eh_return"
20571   [(use (match_operand 0 "register_operand"))]
20572   ""
20574   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
20576   /* Tricky bit: we write the address of the handler to which we will
20577      be returning into someone else's stack frame, one word below the
20578      stack address we wish to restore.  */
20579   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
20580   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
20581   /* Return address is always in word_mode.  */
20582   tmp = gen_rtx_MEM (word_mode, tmp);
20583   if (GET_MODE (ra) != word_mode)
20584     ra = convert_to_mode (word_mode, ra, 1);
20585   emit_move_insn (tmp, ra);
20587   emit_jump_insn (gen_eh_return_internal ());
20588   emit_barrier ();
20589   DONE;
20592 (define_insn_and_split "eh_return_internal"
20593   [(eh_return)]
20594   ""
20595   "#"
20596   "epilogue_completed"
20597   [(const_int 0)]
20598   "ix86_expand_epilogue (2); DONE;")
20600 (define_expand "@leave_<mode>"
20601   [(parallel
20602     [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
20603      (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
20604      (clobber (mem:BLK (scratch)))])]
20605   ""
20606   "operands[0] = GEN_INT (<MODE_SIZE>);")
20608 (define_insn "*leave"
20609   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
20610    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
20611    (clobber (mem:BLK (scratch)))]
20612   "!TARGET_64BIT"
20613   "leave"
20614   [(set_attr "type" "leave")])
20616 (define_insn "*leave_rex64"
20617   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
20618    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
20619    (clobber (mem:BLK (scratch)))]
20620   "TARGET_64BIT"
20621   "leave"
20622   [(set_attr "type" "leave")])
20624 ;; Handle -fsplit-stack.
20626 (define_expand "split_stack_prologue"
20627   [(const_int 0)]
20628   ""
20630   ix86_expand_split_stack_prologue ();
20631   DONE;
20634 ;; In order to support the call/return predictor, we use a return
20635 ;; instruction which the middle-end doesn't see.
20636 (define_insn "split_stack_return"
20637   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
20638                      UNSPECV_SPLIT_STACK_RETURN)]
20639   ""
20641   if (operands[0] == const0_rtx)
20642     return "ret";
20643   else
20644     return "ret\t%0";
20646   [(set_attr "atom_unit" "jeu")
20647    (set_attr "modrm" "0")
20648    (set (attr "length")
20649         (if_then_else (match_operand:SI 0 "const0_operand")
20650                       (const_int 1)
20651                       (const_int 3)))
20652    (set (attr "length_immediate")
20653         (if_then_else (match_operand:SI 0 "const0_operand")
20654                       (const_int 0)
20655                       (const_int 2)))])
20657 ;; If there are operand 0 bytes available on the stack, jump to
20658 ;; operand 1.
20660 (define_expand "split_stack_space_check"
20661   [(set (pc) (if_then_else
20662               (ltu (minus (reg SP_REG)
20663                           (match_operand 0 "register_operand"))
20664                    (match_dup 2))
20665               (label_ref (match_operand 1))
20666               (pc)))]
20667   ""
20669   rtx reg = gen_reg_rtx (Pmode);
20671   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
20673   operands[2] = ix86_split_stack_guard ();
20674   ix86_expand_branch (GEU, reg, operands[2], operands[1]);
20676   DONE;
20679 ;; Bit manipulation instructions.
20681 (define_expand "ffs<mode>2"
20682   [(set (match_dup 2) (const_int -1))
20683    (parallel [(set (match_dup 3) (match_dup 4))
20684               (set (match_operand:SWI48 0 "register_operand")
20685                    (ctz:SWI48
20686                      (match_operand:SWI48 1 "nonimmediate_operand")))])
20687    (set (match_dup 0) (if_then_else:SWI48
20688                         (eq (match_dup 3) (const_int 0))
20689                         (match_dup 2)
20690                         (match_dup 0)))
20691    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
20692               (clobber (reg:CC FLAGS_REG))])]
20693   ""
20695   machine_mode flags_mode;
20697   if (<MODE>mode == SImode && !TARGET_CMOVE)
20698     {
20699       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
20700       DONE;
20701     }
20703   flags_mode = TARGET_BMI ? CCCmode : CCZmode;
20705   operands[2] = gen_reg_rtx (<MODE>mode);
20706   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
20707   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
20710 (define_insn_and_split "ffssi2_no_cmove"
20711   [(set (match_operand:SI 0 "register_operand" "=r")
20712         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
20713    (clobber (match_scratch:SI 2 "=&q"))
20714    (clobber (reg:CC FLAGS_REG))]
20715   "!TARGET_CMOVE"
20716   "#"
20717   "&& reload_completed"
20718   [(parallel [(set (match_dup 4) (match_dup 5))
20719               (set (match_dup 0) (ctz:SI (match_dup 1)))])
20720    (set (strict_low_part (match_dup 3))
20721         (eq:QI (match_dup 4) (const_int 0)))
20722    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
20723               (clobber (reg:CC FLAGS_REG))])
20724    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
20725               (clobber (reg:CC FLAGS_REG))])
20726    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
20727               (clobber (reg:CC FLAGS_REG))])]
20729   machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
20731   operands[3] = gen_lowpart (QImode, operands[2]);
20732   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
20733   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
20735   ix86_expand_clear (operands[2]);
20738 (define_insn_and_split "*tzcnt<mode>_1"
20739   [(set (reg:CCC FLAGS_REG)
20740         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20741                      (const_int 0)))
20742    (set (match_operand:SWI48 0 "register_operand" "=r")
20743         (ctz:SWI48 (match_dup 1)))]
20744   "TARGET_BMI"
20745   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
20746   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
20747    && optimize_function_for_speed_p (cfun)
20748    && !reg_mentioned_p (operands[0], operands[1])"
20749   [(parallel
20750     [(set (reg:CCC FLAGS_REG)
20751           (compare:CCC (match_dup 1) (const_int 0)))
20752      (set (match_dup 0)
20753           (ctz:SWI48 (match_dup 1)))
20754      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
20755   "ix86_expand_clear (operands[0]);"
20756   [(set_attr "type" "alu1")
20757    (set_attr "prefix_0f" "1")
20758    (set_attr "prefix_rep" "1")
20759    (set_attr "btver2_decode" "double")
20760    (set_attr "mode" "<MODE>")])
20762 ; False dependency happens when destination is only updated by tzcnt,
20763 ; lzcnt or popcnt.  There is no false dependency when destination is
20764 ; also used in source.
20765 (define_insn "*tzcnt<mode>_1_falsedep"
20766   [(set (reg:CCC FLAGS_REG)
20767         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20768                      (const_int 0)))
20769    (set (match_operand:SWI48 0 "register_operand" "=r")
20770         (ctz:SWI48 (match_dup 1)))
20771    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
20772            UNSPEC_INSN_FALSE_DEP)]
20773   "TARGET_BMI"
20774   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
20775   [(set_attr "type" "alu1")
20776    (set_attr "prefix_0f" "1")
20777    (set_attr "prefix_rep" "1")
20778    (set_attr "btver2_decode" "double")
20779    (set_attr "mode" "<MODE>")])
20781 (define_insn "*bsf<mode>_1"
20782   [(set (reg:CCZ FLAGS_REG)
20783         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20784                      (const_int 0)))
20785    (set (match_operand:SWI48 0 "register_operand" "=r")
20786         (ctz:SWI48 (match_dup 1)))]
20787   ""
20788   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
20789   [(set_attr "type" "alu1")
20790    (set_attr "prefix_0f" "1")
20791    (set_attr "btver2_decode" "double")
20792    (set_attr "znver1_decode" "vector")
20793    (set_attr "mode" "<MODE>")])
20795 (define_insn_and_split "ctz<mode>2"
20796   [(set (match_operand:SWI48 0 "register_operand" "=r")
20797         (ctz:SWI48
20798           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
20799    (clobber (reg:CC FLAGS_REG))]
20800   ""
20802   if (TARGET_BMI)
20803     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
20804   else if (optimize_function_for_size_p (cfun))
20805     ;
20806   else if (TARGET_CPU_P (GENERIC))
20807     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
20808     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
20810   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
20812   "(TARGET_BMI || TARGET_CPU_P (GENERIC))
20813    && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
20814    && optimize_function_for_speed_p (cfun)
20815    && !reg_mentioned_p (operands[0], operands[1])"
20816   [(parallel
20817     [(set (match_dup 0)
20818           (ctz:SWI48 (match_dup 1)))
20819      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
20820      (clobber (reg:CC FLAGS_REG))])]
20821   "ix86_expand_clear (operands[0]);"
20822   [(set_attr "type" "alu1")
20823    (set_attr "prefix_0f" "1")
20824    (set (attr "prefix_rep")
20825      (if_then_else
20826        (ior (match_test "TARGET_BMI")
20827             (and (not (match_test "optimize_function_for_size_p (cfun)"))
20828                  (match_test "TARGET_CPU_P (GENERIC)")))
20829        (const_string "1")
20830        (const_string "0")))
20831    (set_attr "mode" "<MODE>")])
20833 ; False dependency happens when destination is only updated by tzcnt,
20834 ; lzcnt or popcnt.  There is no false dependency when destination is
20835 ; also used in source.
20836 (define_insn "*ctz<mode>2_falsedep"
20837   [(set (match_operand:SWI48 0 "register_operand" "=r")
20838         (ctz:SWI48
20839           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
20840    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
20841            UNSPEC_INSN_FALSE_DEP)
20842    (clobber (reg:CC FLAGS_REG))]
20843   ""
20845   if (TARGET_BMI)
20846     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
20847   else if (TARGET_CPU_P (GENERIC))
20848     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
20849     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
20850   else
20851     gcc_unreachable ();
20853   [(set_attr "type" "alu1")
20854    (set_attr "prefix_0f" "1")
20855    (set_attr "prefix_rep" "1")
20856    (set_attr "mode" "<MODE>")])
20858 (define_insn_and_split "*ctzsi2_zext"
20859   [(set (match_operand:DI 0 "register_operand" "=r")
20860         (and:DI
20861           (subreg:DI
20862             (ctz:SI
20863               (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
20864           (const_int 63)))
20865    (clobber (reg:CC FLAGS_REG))]
20866   "TARGET_BMI && TARGET_64BIT"
20867   "tzcnt{l}\t{%1, %k0|%k0, %1}"
20868   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
20869    && optimize_function_for_speed_p (cfun)
20870    && !reg_mentioned_p (operands[0], operands[1])"
20871   [(parallel
20872     [(set (match_dup 0)
20873           (and:DI (subreg:DI (ctz:SI (match_dup 1)) 0) (const_int 63)))
20874      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
20875      (clobber (reg:CC FLAGS_REG))])]
20876   "ix86_expand_clear (operands[0]);"
20877   [(set_attr "type" "alu1")
20878    (set_attr "prefix_0f" "1")
20879    (set_attr "prefix_rep" "1")
20880    (set_attr "mode" "SI")])
20882 ; False dependency happens when destination is only updated by tzcnt,
20883 ; lzcnt or popcnt.  There is no false dependency when destination is
20884 ; also used in source.
20885 (define_insn "*ctzsi2_zext_falsedep"
20886   [(set (match_operand:DI 0 "register_operand" "=r")
20887         (and:DI
20888           (subreg:DI
20889             (ctz:SI
20890               (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
20891           (const_int 63)))
20892    (unspec [(match_operand:DI 2 "register_operand" "0")]
20893            UNSPEC_INSN_FALSE_DEP)
20894    (clobber (reg:CC FLAGS_REG))]
20895   "TARGET_BMI && TARGET_64BIT"
20896   "tzcnt{l}\t{%1, %k0|%k0, %1}"
20897   [(set_attr "type" "alu1")
20898    (set_attr "prefix_0f" "1")
20899    (set_attr "prefix_rep" "1")
20900    (set_attr "mode" "SI")])
20902 (define_insn_and_split "*ctzsidi2_<s>ext"
20903   [(set (match_operand:DI 0 "register_operand" "=r")
20904         (any_extend:DI
20905           (ctz:SI
20906             (match_operand:SI 1 "nonimmediate_operand" "rm"))))
20907    (clobber (reg:CC FLAGS_REG))]
20908   "TARGET_64BIT"
20910   if (TARGET_BMI)
20911     return "tzcnt{l}\t{%1, %k0|%k0, %1}";
20912   else if (TARGET_CPU_P (GENERIC)
20913            && !optimize_function_for_size_p (cfun))
20914     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
20915     return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
20916   return "bsf{l}\t{%1, %k0|%k0, %1}";
20918   "(TARGET_BMI || TARGET_CPU_P (GENERIC))
20919    && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
20920    && optimize_function_for_speed_p (cfun)
20921    && !reg_mentioned_p (operands[0], operands[1])"
20922   [(parallel
20923     [(set (match_dup 0)
20924           (any_extend:DI (ctz:SI (match_dup 1))))
20925      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
20926      (clobber (reg:CC FLAGS_REG))])]
20927   "ix86_expand_clear (operands[0]);"
20928   [(set_attr "type" "alu1")
20929    (set_attr "prefix_0f" "1")
20930    (set (attr "prefix_rep")
20931      (if_then_else
20932        (ior (match_test "TARGET_BMI")
20933             (and (not (match_test "optimize_function_for_size_p (cfun)"))
20934                  (match_test "TARGET_CPU_P (GENERIC)")))
20935        (const_string "1")
20936        (const_string "0")))
20937    (set_attr "mode" "SI")])
20939 (define_insn "*ctzsidi2_<s>ext_falsedep"
20940   [(set (match_operand:DI 0 "register_operand" "=r")
20941         (any_extend:DI
20942           (ctz:SI
20943             (match_operand:SI 1 "nonimmediate_operand" "rm"))))
20944    (unspec [(match_operand:DI 2 "register_operand" "0")]
20945            UNSPEC_INSN_FALSE_DEP)
20946    (clobber (reg:CC FLAGS_REG))]
20947   "TARGET_64BIT"
20949   if (TARGET_BMI)
20950     return "tzcnt{l}\t{%1, %k0|%k0, %1}";
20951   else if (TARGET_CPU_P (GENERIC))
20952     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
20953     return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
20954   else
20955     gcc_unreachable ();
20957   [(set_attr "type" "alu1")
20958    (set_attr "prefix_0f" "1")
20959    (set_attr "prefix_rep" "1")
20960    (set_attr "mode" "SI")])
20962 (define_insn "bsr_rex64"
20963   [(set (reg:CCZ FLAGS_REG)
20964         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
20965                      (const_int 0)))
20966    (set (match_operand:DI 0 "register_operand" "=r")
20967         (minus:DI (const_int 63)
20968                   (clz:DI (match_dup 1))))]
20969   "TARGET_64BIT"
20970   "bsr{q}\t{%1, %0|%0, %1}"
20971   [(set_attr "type" "alu1")
20972    (set_attr "prefix_0f" "1")
20973    (set_attr "znver1_decode" "vector")
20974    (set_attr "mode" "DI")])
20976 (define_insn "bsr_rex64_1"
20977   [(set (match_operand:DI 0 "register_operand" "=r")
20978         (minus:DI (const_int 63)
20979                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
20980    (clobber (reg:CC FLAGS_REG))]
20981   "!TARGET_LZCNT && TARGET_64BIT"
20982   "bsr{q}\t{%1, %0|%0, %1}"
20983   [(set_attr "type" "alu1")
20984    (set_attr "prefix_0f" "1")
20985    (set_attr "znver1_decode" "vector")
20986    (set_attr "mode" "DI")])
20988 (define_insn "bsr_rex64_1_zext"
20989   [(set (match_operand:DI 0 "register_operand" "=r")
20990         (zero_extend:DI
20991           (minus:SI (const_int 63)
20992                     (subreg:SI
20993                       (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
20994                       0))))
20995    (clobber (reg:CC FLAGS_REG))]
20996   "!TARGET_LZCNT && TARGET_64BIT"
20997   "bsr{q}\t{%1, %0|%0, %1}"
20998   [(set_attr "type" "alu1")
20999    (set_attr "prefix_0f" "1")
21000    (set_attr "znver1_decode" "vector")
21001    (set_attr "mode" "DI")])
21003 (define_insn "bsr"
21004   [(set (reg:CCZ FLAGS_REG)
21005         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
21006                      (const_int 0)))
21007    (set (match_operand:SI 0 "register_operand" "=r")
21008         (minus:SI (const_int 31)
21009                   (clz:SI (match_dup 1))))]
21010   ""
21011   "bsr{l}\t{%1, %0|%0, %1}"
21012   [(set_attr "type" "alu1")
21013    (set_attr "prefix_0f" "1")
21014    (set_attr "znver1_decode" "vector")
21015    (set_attr "mode" "SI")])
21017 (define_insn "bsr_1"
21018   [(set (match_operand:SI 0 "register_operand" "=r")
21019         (minus:SI (const_int 31)
21020                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
21021    (clobber (reg:CC FLAGS_REG))]
21022   "!TARGET_LZCNT"
21023   "bsr{l}\t{%1, %0|%0, %1}"
21024   [(set_attr "type" "alu1")
21025    (set_attr "prefix_0f" "1")
21026    (set_attr "znver1_decode" "vector")
21027    (set_attr "mode" "SI")])
21029 (define_insn "bsr_zext_1"
21030   [(set (match_operand:DI 0 "register_operand" "=r")
21031         (zero_extend:DI
21032           (minus:SI
21033             (const_int 31)
21034             (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))))
21035    (clobber (reg:CC FLAGS_REG))]
21036   "!TARGET_LZCNT && TARGET_64BIT"
21037   "bsr{l}\t{%1, %k0|%k0, %1}"
21038   [(set_attr "type" "alu1")
21039    (set_attr "prefix_0f" "1")
21040    (set_attr "znver1_decode" "vector")
21041    (set_attr "mode" "SI")])
21043 ; As bsr is undefined behavior on zero and for other input
21044 ; values it is in range 0 to 63, we can optimize away sign-extends.
21045 (define_insn_and_split "*bsr_rex64_2"
21046   [(set (match_operand:DI 0 "register_operand")
21047         (xor:DI
21048           (sign_extend:DI
21049             (minus:SI
21050               (const_int 63)
21051               (subreg:SI (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
21052                          0)))
21053           (const_int 63)))
21054     (clobber (reg:CC FLAGS_REG))]
21055   "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
21056   "#"
21057   "&& 1"
21058   [(parallel [(set (reg:CCZ FLAGS_REG)
21059                    (compare:CCZ (match_dup 1) (const_int 0)))
21060               (set (match_dup 2)
21061                    (minus:DI (const_int 63) (clz:DI (match_dup 1))))])
21062    (parallel [(set (match_dup 0)
21063                    (zero_extend:DI (xor:SI (match_dup 3) (const_int 63))))
21064               (clobber (reg:CC FLAGS_REG))])]
21066   operands[2] = gen_reg_rtx (DImode);
21067   operands[3] = lowpart_subreg (SImode, operands[2], DImode);
21070 (define_insn_and_split "*bsr_2"
21071   [(set (match_operand:DI 0 "register_operand")
21072         (sign_extend:DI
21073           (xor:SI
21074             (minus:SI
21075               (const_int 31)
21076               (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
21077             (const_int 31))))
21078    (clobber (reg:CC FLAGS_REG))]
21079   "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
21080   "#"
21081   "&& 1"
21082   [(parallel [(set (reg:CCZ FLAGS_REG)
21083                    (compare:CCZ (match_dup 1) (const_int 0)))
21084               (set (match_dup 2)
21085                    (minus:SI (const_int 31) (clz:SI (match_dup 1))))])
21086    (parallel [(set (match_dup 0)
21087                    (zero_extend:DI (xor:SI (match_dup 2) (const_int 31))))
21088               (clobber (reg:CC FLAGS_REG))])]
21089   "operands[2] = gen_reg_rtx (SImode);")
21091 ; Splitters to optimize 64 - __builtin_clzl (x) or 32 - __builtin_clz (x).
21092 ; Again, as for !TARGET_LZCNT CLZ is UB at zero, CLZ is guaranteed to be
21093 ; in [0, 63] or [0, 31] range.
21094 (define_split
21095   [(set (match_operand:SI 0 "register_operand")
21096         (minus:SI
21097           (match_operand:SI 2 "const_int_operand")
21098           (xor:SI
21099             (minus:SI (const_int 63)
21100                       (subreg:SI
21101                         (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
21102                         0))
21103             (const_int 63))))]
21104   "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
21105   [(set (match_dup 3)
21106         (minus:DI (const_int 63) (clz:DI (match_dup 1))))
21107    (set (match_dup 0)
21108         (plus:SI (match_dup 5) (match_dup 4)))]
21110   operands[3] = gen_reg_rtx (DImode);
21111   operands[5] = lowpart_subreg (SImode, operands[3], DImode);
21112   if (INTVAL (operands[2]) == 63)
21113     {
21114       emit_insn (gen_bsr_rex64_1_zext (operands[3], operands[1]));
21115       emit_move_insn (operands[0], operands[5]);
21116       DONE;
21117     }
21118   operands[4] = gen_int_mode (UINTVAL (operands[2]) - 63, SImode);
21121 (define_split
21122   [(set (match_operand:SI 0 "register_operand")
21123         (minus:SI
21124           (match_operand:SI 2 "const_int_operand")
21125           (xor:SI
21126             (minus:SI (const_int 31)
21127                       (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
21128             (const_int 31))))]
21129   "!TARGET_LZCNT && ix86_pre_reload_split ()"
21130   [(set (match_dup 3)
21131         (minus:SI (const_int 31) (clz:SI (match_dup 1))))
21132    (set (match_dup 0)
21133         (plus:SI (match_dup 3) (match_dup 4)))]
21135   if (INTVAL (operands[2]) == 31)
21136     {
21137       emit_insn (gen_bsr_1 (operands[0], operands[1]));
21138       DONE;
21139     }
21140   operands[3] = gen_reg_rtx (SImode);
21141   operands[4] = gen_int_mode (UINTVAL (operands[2]) - 31, SImode);
21144 (define_split
21145   [(set (match_operand:DI 0 "register_operand")
21146         (minus:DI
21147           (match_operand:DI 2 "const_int_operand")
21148           (xor:DI
21149             (sign_extend:DI
21150               (minus:SI (const_int 63)
21151                         (subreg:SI
21152                           (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
21153                           0)))
21154             (const_int 63))))]
21155   "!TARGET_LZCNT
21156    && TARGET_64BIT
21157    && ix86_pre_reload_split ()
21158    && ((unsigned HOST_WIDE_INT)
21159        trunc_int_for_mode (UINTVAL (operands[2]) - 63, SImode)
21160        == UINTVAL (operands[2]) - 63)"
21161   [(set (match_dup 3)
21162         (minus:DI (const_int 63) (clz:DI (match_dup 1))))
21163    (set (match_dup 0)
21164         (plus:DI (match_dup 3) (match_dup 4)))]
21166   if (INTVAL (operands[2]) == 63)
21167     {
21168       emit_insn (gen_bsr_rex64_1 (operands[0], operands[1]));
21169       DONE;
21170     }
21171   operands[3] = gen_reg_rtx (DImode);
21172   operands[4] = GEN_INT (UINTVAL (operands[2]) - 63);
21175 (define_split
21176   [(set (match_operand:DI 0 "register_operand")
21177         (minus:DI
21178           (match_operand:DI 2 "const_int_operand")
21179           (sign_extend:DI
21180             (xor:SI
21181               (minus:SI (const_int 31)
21182                         (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
21183               (const_int 31)))))]
21184   "!TARGET_LZCNT
21185    && TARGET_64BIT
21186    && ix86_pre_reload_split ()
21187    && ((unsigned HOST_WIDE_INT)
21188        trunc_int_for_mode (UINTVAL (operands[2]) - 31, SImode)
21189        == UINTVAL (operands[2]) - 31)"
21190   [(set (match_dup 3)
21191         (zero_extend:DI (minus:SI (const_int 31) (clz:SI (match_dup 1)))))
21192    (set (match_dup 0)
21193         (plus:DI (match_dup 3) (match_dup 4)))]
21195   if (INTVAL (operands[2]) == 31)
21196     {
21197       emit_insn (gen_bsr_zext_1 (operands[0], operands[1]));
21198       DONE;
21199     }
21200   operands[3] = gen_reg_rtx (DImode);
21201   operands[4] = GEN_INT (UINTVAL (operands[2]) - 31);
21204 (define_expand "clz<mode>2"
21205   [(parallel
21206      [(set (reg:CCZ FLAGS_REG)
21207         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21208                      (const_int 0)))
21209       (set (match_dup 3) (minus:SWI48
21210                            (match_dup 2)
21211                            (clz:SWI48 (match_dup 1))))])
21212    (parallel
21213      [(set (match_operand:SWI48 0 "register_operand")
21214            (xor:SWI48 (match_dup 3) (match_dup 2)))
21215       (clobber (reg:CC FLAGS_REG))])]
21216   ""
21218   if (TARGET_LZCNT)
21219     {
21220       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
21221       DONE;
21222     }
21223   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
21224   operands[3] = gen_reg_rtx (<MODE>mode);
21227 (define_insn_and_split "clz<mode>2_lzcnt_nf"
21228   [(set (match_operand:SWI48 0 "register_operand" "=r")
21229         (clz:SWI48
21230           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
21231   "TARGET_APX_NF && TARGET_LZCNT"
21232   "%{nf%} lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
21233   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
21234    && optimize_function_for_speed_p (cfun)
21235    && !reg_mentioned_p (operands[0], operands[1])"
21236   [(parallel
21237     [(set (match_dup 0)
21238           (clz:SWI48 (match_dup 1)))
21239      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
21240   "ix86_expand_clear (operands[0]);"
21241   [(set_attr "prefix_rep" "1")
21242    (set_attr "type" "bitmanip")
21243    (set_attr "mode" "<MODE>")])
21245 (define_insn_and_split "clz<mode>2_lzcnt"
21246   [(set (match_operand:SWI48 0 "register_operand" "=r")
21247         (clz:SWI48
21248           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
21249    (clobber (reg:CC FLAGS_REG))]
21250   "TARGET_LZCNT"
21251   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
21252   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
21253    && optimize_function_for_speed_p (cfun)
21254    && !reg_mentioned_p (operands[0], operands[1])"
21255   [(parallel
21256     [(set (match_dup 0)
21257           (clz:SWI48 (match_dup 1)))
21258      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
21259      (clobber (reg:CC FLAGS_REG))])]
21260   "ix86_expand_clear (operands[0]);"
21261   [(set_attr "prefix_rep" "1")
21262    (set_attr "type" "bitmanip")
21263    (set_attr "has_nf" "1")
21264    (set_attr "mode" "<MODE>")])
21266 ; False dependency happens when destination is only updated by tzcnt,
21267 ; lzcnt or popcnt.  There is no false dependency when destination is
21268 ; also used in source.
21269 (define_insn "*clz<mode>2_lzcnt_falsedep_nf"
21270   [(set (match_operand:SWI48 0 "register_operand" "=r")
21271         (clz:SWI48
21272           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
21273    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
21274            UNSPEC_INSN_FALSE_DEP)]
21275   "TARGET_APX_NF && TARGET_LZCNT"
21276   "%{nf%} lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
21277   [(set_attr "prefix_rep" "1")
21278    (set_attr "type" "bitmanip")
21279    (set_attr "mode" "<MODE>")])
21281 (define_insn "*clz<mode>2_lzcnt_falsedep"
21282   [(set (match_operand:SWI48 0 "register_operand" "=r")
21283         (clz:SWI48
21284           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
21285    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
21286            UNSPEC_INSN_FALSE_DEP)
21287    (clobber (reg:CC FLAGS_REG))]
21288   "TARGET_LZCNT"
21289   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
21290   [(set_attr "prefix_rep" "1")
21291    (set_attr "type" "bitmanip")
21292    (set_attr "has_nf" "1")
21293    (set_attr "mode" "<MODE>")])
21295 (define_insn_and_split "*clzsi2_lzcnt_zext"
21296   [(set (match_operand:DI 0 "register_operand" "=r")
21297         (and:DI
21298           (subreg:DI
21299             (clz:SI
21300               (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
21301           (const_int 63)))
21302    (clobber (reg:CC FLAGS_REG))]
21303   "TARGET_LZCNT && TARGET_64BIT"
21304   "lzcnt{l}\t{%1, %k0|%k0, %1}"
21305   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
21306    && optimize_function_for_speed_p (cfun)
21307    && !reg_mentioned_p (operands[0], operands[1])"
21308   [(parallel
21309     [(set (match_dup 0)
21310           (and:DI (subreg:DI (clz:SI (match_dup 1)) 0) (const_int 63)))
21311      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
21312      (clobber (reg:CC FLAGS_REG))])]
21313   "ix86_expand_clear (operands[0]);"
21314   [(set_attr "prefix_rep" "1")
21315    (set_attr "type" "bitmanip")
21316    (set_attr "mode" "SI")])
21318 ; False dependency happens when destination is only updated by tzcnt,
21319 ; lzcnt or popcnt.  There is no false dependency when destination is
21320 ; also used in source.
21321 (define_insn "*clzsi2_lzcnt_zext_falsedep"
21322   [(set (match_operand:DI 0 "register_operand" "=r")
21323         (and:DI
21324           (subreg:DI
21325             (clz:SI
21326               (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 0)
21327           (const_int 63)))
21328    (unspec [(match_operand:DI 2 "register_operand" "0")]
21329            UNSPEC_INSN_FALSE_DEP)
21330    (clobber (reg:CC FLAGS_REG))]
21331   "TARGET_LZCNT"
21332   "lzcnt{l}\t{%1, %k0|%k0, %1}"
21333   [(set_attr "prefix_rep" "1")
21334    (set_attr "type" "bitmanip")
21335    (set_attr "mode" "SI")])
21337 (define_insn_and_split "*clzsi2_lzcnt_zext_2"
21338   [(set (match_operand:DI 0 "register_operand" "=r")
21339         (zero_extend:DI
21340           (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
21341    (clobber (reg:CC FLAGS_REG))]
21342   "TARGET_LZCNT && TARGET_64BIT"
21343   "lzcnt{l}\t{%1, %k0|%k0, %1}"
21344   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
21345    && optimize_function_for_speed_p (cfun)
21346    && !reg_mentioned_p (operands[0], operands[1])"
21347   [(parallel
21348     [(set (match_dup 0)
21349           (zero_extend:DI (clz:SI (match_dup 1))))
21350      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
21351      (clobber (reg:CC FLAGS_REG))])]
21352   "ix86_expand_clear (operands[0]);"
21353   [(set_attr "prefix_rep" "1")
21354    (set_attr "type" "bitmanip")
21355    (set_attr "mode" "SI")])
21357 ; False dependency happens when destination is only updated by tzcnt,
21358 ; lzcnt or popcnt.  There is no false dependency when destination is
21359 ; also used in source.
21360 (define_insn "*clzsi2_lzcnt_zext_2_falsedep"
21361   [(set (match_operand:DI 0 "register_operand" "=r")
21362         (zero_extend:DI
21363           (clz:SI (match_operand:SWI48 1 "nonimmediate_operand" "rm"))))
21364    (unspec [(match_operand:DI 2 "register_operand" "0")]
21365            UNSPEC_INSN_FALSE_DEP)
21366    (clobber (reg:CC FLAGS_REG))]
21367   "TARGET_LZCNT"
21368   "lzcnt{l}\t{%1, %k0|%k0, %1}"
21369   [(set_attr "prefix_rep" "1")
21370    (set_attr "type" "bitmanip")
21371    (set_attr "mode" "SI")])
21373 (define_int_iterator LT_ZCNT
21374         [(UNSPEC_TZCNT "TARGET_BMI")
21375          (UNSPEC_LZCNT "TARGET_LZCNT")])
21377 (define_int_attr lt_zcnt
21378         [(UNSPEC_TZCNT "tzcnt")
21379          (UNSPEC_LZCNT "lzcnt")])
21381 (define_int_attr lt_zcnt_type
21382         [(UNSPEC_TZCNT "alu1")
21383          (UNSPEC_LZCNT "bitmanip")])
21385 ;; Version of lzcnt/tzcnt that is expanded from intrinsics.  This version
21386 ;; provides operand size as output when source operand is zero. 
21388 (define_insn_and_split "<lt_zcnt>_<mode>_nf"
21389   [(set (match_operand:SWI48 0 "register_operand" "=r")
21390         (unspec:SWI48
21391           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))]
21392   "TARGET_APX_NF"
21393   "%{nf%} <lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
21394   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
21395    && optimize_function_for_speed_p (cfun)
21396    && !reg_mentioned_p (operands[0], operands[1])"
21397   [(parallel
21398     [(set (match_dup 0)
21399           (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
21400      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
21401   "ix86_expand_clear (operands[0]);"
21402   [(set_attr "type" "<lt_zcnt_type>")
21403    (set_attr "prefix_0f" "1")
21404    (set_attr "prefix_rep" "1")
21405    (set_attr "mode" "<MODE>")])
21407 (define_insn_and_split "<lt_zcnt>_<mode>"
21408   [(set (match_operand:SWI48 0 "register_operand" "=r")
21409         (unspec:SWI48
21410           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
21411    (clobber (reg:CC FLAGS_REG))]
21412   ""
21413   "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
21414   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
21415    && optimize_function_for_speed_p (cfun)
21416    && !reg_mentioned_p (operands[0], operands[1])"
21417   [(parallel
21418     [(set (match_dup 0)
21419           (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
21420      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
21421      (clobber (reg:CC FLAGS_REG))])]
21422   "ix86_expand_clear (operands[0]);"
21423   [(set_attr "type" "<lt_zcnt_type>")
21424    (set_attr "prefix_0f" "1")
21425    (set_attr "prefix_rep" "1")
21426    (set_attr "has_nf" "1")
21427    (set_attr "mode" "<MODE>")])
21429 ; False dependency happens when destination is only updated by tzcnt,
21430 ; lzcnt or popcnt.  There is no false dependency when destination is
21431 ; also used in source.
21432 (define_insn "*<lt_zcnt>_<mode>_falsedep_nf"
21433   [(set (match_operand:SWI48 0 "register_operand" "=r")
21434         (unspec:SWI48
21435           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
21436    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
21437            UNSPEC_INSN_FALSE_DEP)]
21438   "TARGET_APX_NF"
21439   "%{nf%} <lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
21440   [(set_attr "type" "<lt_zcnt_type>")
21441    (set_attr "prefix_0f" "1")
21442    (set_attr "prefix_rep" "1")
21443    (set_attr "mode" "<MODE>")])
21445 (define_insn "*<lt_zcnt>_<mode>_falsedep"
21446   [(set (match_operand:SWI48 0 "register_operand" "=r")
21447         (unspec:SWI48
21448           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
21449    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
21450            UNSPEC_INSN_FALSE_DEP)
21451    (clobber (reg:CC FLAGS_REG))]
21452   ""
21453   "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
21454   [(set_attr "type" "<lt_zcnt_type>")
21455    (set_attr "prefix_0f" "1")
21456    (set_attr "prefix_rep" "1")
21457    (set_attr "has_nf" "1")
21458    (set_attr "mode" "<MODE>")])
21460 (define_insn "<lt_zcnt>_hi<nf_name>"
21461   [(set (match_operand:HI 0 "register_operand" "=r")
21462         (unspec:HI
21463           [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))]
21464   "<nf_condition>"
21465   "<nf_prefix><lt_zcnt>{w}\t{%1, %0|%0, %1}"
21466   [(set_attr "type" "<lt_zcnt_type>")
21467    (set_attr "prefix_0f" "1")
21468    (set_attr "prefix_rep" "1")
21469    (set_attr "has_nf" "1")
21470    (set_attr "mode" "HI")])
21472 ;; BMI instructions.
21474 (define_insn "bmi_bextr_<mode>"
21475   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
21476         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
21477                        (match_operand:SWI48 2 "register_operand" "r,r")]
21478                       UNSPEC_BEXTR))
21479    (clobber (reg:CC FLAGS_REG))]
21480   "TARGET_BMI"
21481   "bextr\t{%2, %1, %0|%0, %1, %2}"
21482   [(set_attr "type" "bitmanip")
21483    (set_attr "btver2_decode" "direct, double")
21484    (set_attr "mode" "<MODE>")])
21486 (define_insn "*bmi_bextr_<mode>_ccz"
21487   [(set (reg:CCZ FLAGS_REG)
21488         (compare:CCZ
21489           (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
21490                          (match_operand:SWI48 2 "register_operand" "r,r")]
21491                         UNSPEC_BEXTR)
21492           (const_int 0)))
21493    (clobber (match_scratch:SWI48 0 "=r,r"))]
21494   "TARGET_BMI"
21495   "bextr\t{%2, %1, %0|%0, %1, %2}"
21496   [(set_attr "type" "bitmanip")
21497    (set_attr "btver2_decode" "direct, double")
21498    (set_attr "mode" "<MODE>")])
21500 (define_insn "*bmi_blsi_<mode>"
21501   [(set (match_operand:SWI48 0 "register_operand" "=r")
21502         (and:SWI48
21503           (neg:SWI48
21504             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
21505           (match_dup 1)))
21506    (clobber (reg:CC FLAGS_REG))]
21507   "TARGET_BMI"
21508   "blsi\t{%1, %0|%0, %1}"
21509   [(set_attr "type" "bitmanip")
21510    (set_attr "btver2_decode" "double")
21511    (set_attr "mode" "<MODE>")])
21513 (define_insn "*bmi_blsi_<mode>_cmp"
21514   [(set (reg FLAGS_REG)
21515         (compare
21516           (and:SWI48
21517             (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
21518             (match_dup 1))
21519           (const_int 0)))
21520    (set (match_operand:SWI48 0 "register_operand" "=r")
21521         (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))]
21522    "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
21523    "blsi\t{%1, %0|%0, %1}"
21524   [(set_attr "type" "bitmanip")
21525    (set_attr "btver2_decode" "double")
21526    (set_attr "mode" "<MODE>")])
21528 (define_insn "*bmi_blsi_<mode>_ccno"
21529   [(set (reg FLAGS_REG)
21530         (compare
21531           (and:SWI48
21532             (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
21533             (match_dup 1))
21534           (const_int 0)))
21535    (clobber (match_scratch:SWI48 0 "=r"))]
21536    "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
21537    "blsi\t{%1, %0|%0, %1}"
21538   [(set_attr "type" "bitmanip")
21539    (set_attr "btver2_decode" "double")
21540    (set_attr "mode" "<MODE>")])
21542 (define_insn "*bmi_blsmsk_<mode>"
21543   [(set (match_operand:SWI48 0 "register_operand" "=r")
21544         (xor:SWI48
21545           (plus:SWI48
21546             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21547             (const_int -1))
21548           (match_dup 1)))
21549    (clobber (reg:CC FLAGS_REG))]
21550   "TARGET_BMI"
21551   "blsmsk\t{%1, %0|%0, %1}"
21552   [(set_attr "type" "bitmanip")
21553    (set_attr "btver2_decode" "double")
21554    (set_attr "mode" "<MODE>")])
21556 (define_insn "*bmi_blsr_<mode>"
21557   [(set (match_operand:SWI48 0 "register_operand" "=r")
21558         (and:SWI48
21559           (plus:SWI48
21560             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21561             (const_int -1))
21562           (match_dup 1)))
21563    (clobber (reg:CC FLAGS_REG))]
21564    "TARGET_BMI"
21565    "blsr\t{%1, %0|%0, %1}"
21566   [(set_attr "type" "bitmanip")
21567    (set_attr "btver2_decode" "double")
21568    (set_attr "mode" "<MODE>")])
21570 (define_insn "*bmi_blsr_<mode>_cmp"
21571   [(set (reg:CCZ FLAGS_REG)
21572         (compare:CCZ
21573           (and:SWI48
21574             (plus:SWI48
21575               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21576               (const_int -1))
21577             (match_dup 1))
21578           (const_int 0)))
21579    (set (match_operand:SWI48 0 "register_operand" "=r")
21580         (and:SWI48
21581           (plus:SWI48
21582             (match_dup 1)
21583             (const_int -1))
21584           (match_dup 1)))]
21585    "TARGET_BMI"
21586    "blsr\t{%1, %0|%0, %1}"
21587   [(set_attr "type" "bitmanip")
21588    (set_attr "btver2_decode" "double")
21589    (set_attr "mode" "<MODE>")])
21591 (define_insn "*bmi_blsr_<mode>_ccz"
21592   [(set (reg:CCZ FLAGS_REG)
21593         (compare:CCZ
21594           (and:SWI48
21595             (plus:SWI48
21596               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21597               (const_int -1))
21598             (match_dup 1))
21599           (const_int 0)))
21600    (clobber (match_scratch:SWI48 0 "=r"))]
21601    "TARGET_BMI"
21602    "blsr\t{%1, %0|%0, %1}"
21603   [(set_attr "type" "bitmanip")
21604    (set_attr "btver2_decode" "double")
21605    (set_attr "mode" "<MODE>")])
21607 ;; BMI2 instructions.
21608 (define_expand "bmi2_bzhi_<mode>3"
21609   [(parallel
21610     [(set (match_operand:SWI48 0 "register_operand")
21611           (if_then_else:SWI48
21612             (ne:QI (match_operand:QI 2 "register_operand")
21613                    (const_int 0))
21614             (zero_extract:SWI48
21615               (match_operand:SWI48 1 "nonimmediate_operand")
21616               (umin:QI (match_dup 2) (match_dup 3))
21617               (const_int 0))
21618             (const_int 0)))
21619      (clobber (reg:CC FLAGS_REG))])]
21620   "TARGET_BMI2"
21622   operands[2] = gen_lowpart (QImode, operands[2]);
21623   operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
21626 (define_insn "*bmi2_bzhi_<mode>3"
21627   [(set (match_operand:SWI48 0 "register_operand" "=r")
21628         (if_then_else:SWI48
21629           (ne:QI (match_operand:QI 2 "register_operand" "q")
21630                  (const_int 0))
21631           (zero_extract:SWI48
21632             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21633             (umin:QI (match_dup 2)
21634                      (match_operand:QI 3 "const_int_operand"))
21635             (const_int 0))
21636           (const_int 0)))
21637    (clobber (reg:CC FLAGS_REG))]
21638   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
21639   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
21640   [(set_attr "type" "bitmanip")
21641    (set_attr "prefix" "vex")
21642    (set_attr "mode" "<MODE>")])
21644 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
21645   [(set (reg:CCZ FLAGS_REG)
21646         (compare:CCZ
21647           (if_then_else:SWI48
21648             (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
21649             (zero_extract:SWI48
21650               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21651               (umin:QI (match_dup 2)
21652                        (match_operand:QI 3 "const_int_operand"))
21653               (const_int 0))
21654             (const_int 0))
21655         (const_int 0)))
21656    (clobber (match_scratch:SWI48 0 "=r"))]
21657   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
21658   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
21659   [(set_attr "type" "bitmanip")
21660    (set_attr "prefix" "vex")
21661    (set_attr "mode" "<MODE>")])
21663 (define_insn "*bmi2_bzhi_<mode>3_2"
21664   [(set (match_operand:SWI48 0 "register_operand" "=r")
21665         (and:SWI48
21666           (plus:SWI48
21667             (ashift:SWI48 (const_int 1)
21668                           (match_operand:QI 2 "register_operand" "r"))
21669             (const_int -1))
21670           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
21671    (clobber (reg:CC FLAGS_REG))]
21672   "TARGET_BMI2"
21673   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
21674   [(set_attr "type" "bitmanip")
21675    (set_attr "prefix" "vex")
21676    (set_attr "mode" "<MODE>")])
21678 (define_insn "*bmi2_bzhi_<mode>3_3"
21679   [(set (match_operand:SWI48 0 "register_operand" "=r")
21680         (and:SWI48
21681           (not:SWI48
21682             (ashift:SWI48 (const_int -1)
21683                           (match_operand:QI 2 "register_operand" "r")))
21684           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
21685    (clobber (reg:CC FLAGS_REG))]
21686   "TARGET_BMI2"
21687   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
21688   [(set_attr "type" "bitmanip")
21689    (set_attr "prefix" "vex")
21690    (set_attr "mode" "<MODE>")])
21692 (define_insn "*bmi2_bzhi_zero_extendsidi_4"
21693   [(set (match_operand:DI 0 "register_operand" "=r")
21694         (zero_extend:DI
21695           (and:SI
21696             (plus:SI
21697               (ashift:SI (const_int 1)
21698                          (match_operand:QI 2 "register_operand" "r"))
21699               (const_int -1))
21700             (match_operand:SI 1 "nonimmediate_operand" "rm"))))
21701    (clobber (reg:CC FLAGS_REG))]
21702   "TARGET_64BIT && TARGET_BMI2"
21703   "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
21704   [(set_attr "type" "bitmanip")
21705    (set_attr "prefix" "vex")
21706    (set_attr "mode" "DI")])
21708 (define_insn "*bmi2_bzhi_zero_extendsidi_5"
21709   [(set (match_operand:DI 0 "register_operand" "=r")
21710         (and:DI
21711           (zero_extend:DI
21712             (plus:SI
21713               (ashift:SI (const_int 1)
21714                          (match_operand:QI 2 "register_operand" "r"))
21715               (const_int -1)))
21716           (match_operand:DI 1 "nonimmediate_operand" "rm")))
21717    (clobber (reg:CC FLAGS_REG))]
21718   "TARGET_64BIT && TARGET_BMI2"
21719   "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
21720   [(set_attr "type" "bitmanip")
21721    (set_attr "prefix" "vex")
21722    (set_attr "mode" "DI")])
21724 (define_insn "bmi2_pdep_<mode>3"
21725   [(set (match_operand:SWI48 0 "register_operand" "=r")
21726         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
21727                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
21728                        UNSPEC_PDEP))]
21729   "TARGET_BMI2"
21730   "pdep\t{%2, %1, %0|%0, %1, %2}"
21731   [(set_attr "type" "bitmanip")
21732    (set_attr "prefix" "vex")
21733    (set_attr "mode" "<MODE>")])
21735 (define_insn "bmi2_pext_<mode>3"
21736   [(set (match_operand:SWI48 0 "register_operand" "=r")
21737         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
21738                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
21739                        UNSPEC_PEXT))]
21740   "TARGET_BMI2"
21741   "pext\t{%2, %1, %0|%0, %1, %2}"
21742   [(set_attr "type" "bitmanip")
21743    (set_attr "prefix" "vex")
21744    (set_attr "mode" "<MODE>")])
21746 ;; TBM instructions.
21747 (define_insn "@tbm_bextri_<mode>"
21748   [(set (match_operand:SWI48 0 "register_operand" "=r")
21749         (zero_extract:SWI48
21750           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21751           (match_operand:QI 2 "const_0_to_255_operand")
21752           (match_operand:QI 3 "const_0_to_255_operand")))
21753    (clobber (reg:CC FLAGS_REG))]
21754    "TARGET_TBM"
21756   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
21757   return "bextr\t{%2, %1, %0|%0, %1, %2}";
21759   [(set_attr "type" "bitmanip")
21760    (set_attr "mode" "<MODE>")])
21762 (define_insn "*tbm_blcfill_<mode>"
21763   [(set (match_operand:SWI48 0 "register_operand" "=r")
21764         (and:SWI48
21765           (plus:SWI48
21766             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21767             (const_int 1))
21768           (match_dup 1)))
21769    (clobber (reg:CC FLAGS_REG))]
21770    "TARGET_TBM"
21771    "blcfill\t{%1, %0|%0, %1}"
21772   [(set_attr "type" "bitmanip")
21773    (set_attr "mode" "<MODE>")])
21775 (define_insn "*tbm_blci_<mode>"
21776   [(set (match_operand:SWI48 0 "register_operand" "=r")
21777         (ior:SWI48
21778           (not:SWI48
21779             (plus:SWI48
21780               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21781               (const_int 1)))
21782           (match_dup 1)))
21783    (clobber (reg:CC FLAGS_REG))]
21784    "TARGET_TBM"
21785    "blci\t{%1, %0|%0, %1}"
21786   [(set_attr "type" "bitmanip")
21787    (set_attr "mode" "<MODE>")])
21789 (define_insn "*tbm_blcic_<mode>"
21790   [(set (match_operand:SWI48 0 "register_operand" "=r")
21791         (and:SWI48
21792           (plus:SWI48
21793             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21794             (const_int 1))
21795           (not:SWI48
21796             (match_dup 1))))
21797    (clobber (reg:CC FLAGS_REG))]
21798    "TARGET_TBM"
21799    "blcic\t{%1, %0|%0, %1}"
21800   [(set_attr "type" "bitmanip")
21801    (set_attr "mode" "<MODE>")])
21803 (define_insn "*tbm_blcmsk_<mode>"
21804   [(set (match_operand:SWI48 0 "register_operand" "=r")
21805         (xor:SWI48
21806           (plus:SWI48
21807             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21808             (const_int 1))
21809           (match_dup 1)))
21810    (clobber (reg:CC FLAGS_REG))]
21811    "TARGET_TBM"
21812    "blcmsk\t{%1, %0|%0, %1}"
21813   [(set_attr "type" "bitmanip")
21814    (set_attr "mode" "<MODE>")])
21816 (define_insn "*tbm_blcs_<mode>"
21817   [(set (match_operand:SWI48 0 "register_operand" "=r")
21818         (ior:SWI48
21819           (plus:SWI48
21820             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21821             (const_int 1))
21822           (match_dup 1)))
21823    (clobber (reg:CC FLAGS_REG))]
21824    "TARGET_TBM"
21825    "blcs\t{%1, %0|%0, %1}"
21826   [(set_attr "type" "bitmanip")
21827    (set_attr "mode" "<MODE>")])
21829 (define_insn "*tbm_blsfill_<mode>"
21830   [(set (match_operand:SWI48 0 "register_operand" "=r")
21831         (ior:SWI48
21832           (plus:SWI48
21833             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21834             (const_int -1))
21835           (match_dup 1)))
21836    (clobber (reg:CC FLAGS_REG))]
21837    "TARGET_TBM"
21838    "blsfill\t{%1, %0|%0, %1}"
21839   [(set_attr "type" "bitmanip")
21840    (set_attr "mode" "<MODE>")])
21842 (define_insn "*tbm_blsic_<mode>"
21843   [(set (match_operand:SWI48 0 "register_operand" "=r")
21844         (ior:SWI48
21845           (plus:SWI48
21846             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21847             (const_int -1))
21848           (not:SWI48
21849             (match_dup 1))))
21850    (clobber (reg:CC FLAGS_REG))]
21851    "TARGET_TBM"
21852    "blsic\t{%1, %0|%0, %1}"
21853   [(set_attr "type" "bitmanip")
21854    (set_attr "mode" "<MODE>")])
21856 (define_insn "*tbm_t1mskc_<mode>"
21857   [(set (match_operand:SWI48 0 "register_operand" "=r")
21858         (ior:SWI48
21859           (plus:SWI48
21860             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21861             (const_int 1))
21862           (not:SWI48
21863             (match_dup 1))))
21864    (clobber (reg:CC FLAGS_REG))]
21865    "TARGET_TBM"
21866    "t1mskc\t{%1, %0|%0, %1}"
21867   [(set_attr "type" "bitmanip")
21868    (set_attr "mode" "<MODE>")])
21870 (define_insn "*tbm_tzmsk_<mode>"
21871   [(set (match_operand:SWI48 0 "register_operand" "=r")
21872         (and:SWI48
21873           (plus:SWI48
21874             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21875             (const_int -1))
21876           (not:SWI48
21877             (match_dup 1))))
21878    (clobber (reg:CC FLAGS_REG))]
21879    "TARGET_TBM"
21880    "tzmsk\t{%1, %0|%0, %1}"
21881   [(set_attr "type" "bitmanip")
21882    (set_attr "mode" "<MODE>")])
21884 (define_insn_and_split "popcount<mode>2_nf"
21885   [(set (match_operand:SWI48 0 "register_operand" "=r")
21886         (popcount:SWI48
21887           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
21888   "TARGET_APX_NF && TARGET_POPCNT"
21890 #if TARGET_MACHO
21891   return "%{nf%} popcnt\t{%1, %0|%0, %1}";
21892 #else
21893   return "%{nf%} popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
21894 #endif
21896   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
21897    && optimize_function_for_speed_p (cfun)
21898    && !reg_mentioned_p (operands[0], operands[1])"
21899   [(parallel
21900     [(set (match_dup 0)
21901           (popcount:SWI48 (match_dup 1)))
21902      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
21903   "ix86_expand_clear (operands[0]);"
21904   [(set_attr "prefix_rep" "1")
21905    (set_attr "type" "bitmanip")
21906    (set_attr "mode" "<MODE>")])
21908 (define_insn_and_split "popcount<mode>2"
21909   [(set (match_operand:SWI48 0 "register_operand" "=r")
21910         (popcount:SWI48
21911           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
21912    (clobber (reg:CC FLAGS_REG))]
21913   "TARGET_POPCNT"
21915 #if TARGET_MACHO
21916   return "popcnt\t{%1, %0|%0, %1}";
21917 #else
21918   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
21919 #endif
21921   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
21922    && optimize_function_for_speed_p (cfun)
21923    && !reg_mentioned_p (operands[0], operands[1])"
21924   [(parallel
21925     [(set (match_dup 0)
21926           (popcount:SWI48 (match_dup 1)))
21927      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
21928      (clobber (reg:CC FLAGS_REG))])]
21929   "ix86_expand_clear (operands[0]);"
21930   [(set_attr "prefix_rep" "1")
21931    (set_attr "type" "bitmanip")
21932    (set_attr "has_nf" "1")
21933    (set_attr "mode" "<MODE>")])
21935 ; False dependency happens when destination is only updated by tzcnt,
21936 ; lzcnt or popcnt.  There is no false dependency when destination is
21937 ; also used in source.
21938 (define_insn "*popcount<mode>2_falsedep_nf"
21939   [(set (match_operand:SWI48 0 "register_operand" "=r")
21940         (popcount:SWI48
21941           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
21942    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
21943            UNSPEC_INSN_FALSE_DEP)]
21944   "TARGET_APX_NF && TARGET_POPCNT"
21946 #if TARGET_MACHO
21947   return "%{nf%} popcnt\t{%1, %0|%0, %1}";
21948 #else
21949   return "%{nf%} popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
21950 #endif
21952   [(set_attr "prefix_rep" "1")
21953    (set_attr "type" "bitmanip")
21954    (set_attr "mode" "<MODE>")])
21956 (define_insn "*popcount<mode>2_falsedep"
21957   [(set (match_operand:SWI48 0 "register_operand" "=r")
21958         (popcount:SWI48
21959           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
21960    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
21961            UNSPEC_INSN_FALSE_DEP)
21962    (clobber (reg:CC FLAGS_REG))]
21963   "TARGET_POPCNT"
21965 #if TARGET_MACHO
21966   return "popcnt\t{%1, %0|%0, %1}";
21967 #else
21968   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
21969 #endif
21971   [(set_attr "prefix_rep" "1")
21972    (set_attr "type" "bitmanip")
21973    (set_attr "has_nf" "1")
21974    (set_attr "mode" "<MODE>")])
21976 (define_insn_and_split "*popcountsi2_zext"
21977   [(set (match_operand:DI 0 "register_operand" "=r")
21978         (and:DI
21979           (subreg:DI
21980             (popcount:SI
21981               (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
21982           (const_int 63)))
21983    (clobber (reg:CC FLAGS_REG))]
21984   "TARGET_POPCNT && TARGET_64BIT"
21986 #if TARGET_MACHO
21987   return "popcnt\t{%1, %k0|%k0, %1}";
21988 #else
21989   return "popcnt{l}\t{%1, %k0|%k0, %1}";
21990 #endif
21992   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
21993    && optimize_function_for_speed_p (cfun)
21994    && !reg_mentioned_p (operands[0], operands[1])"
21995   [(parallel
21996     [(set (match_dup 0)
21997           (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63)))
21998      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
21999      (clobber (reg:CC FLAGS_REG))])]
22000   "ix86_expand_clear (operands[0]);"
22001   [(set_attr "prefix_rep" "1")
22002    (set_attr "type" "bitmanip")
22003    (set_attr "mode" "SI")])
22005 ; False dependency happens when destination is only updated by tzcnt,
22006 ; lzcnt or popcnt.  There is no false dependency when destination is
22007 ; also used in source.
22008 (define_insn "*popcountsi2_zext_falsedep"
22009   [(set (match_operand:DI 0 "register_operand" "=r")
22010         (and:DI
22011           (subreg:DI
22012             (popcount:SI
22013               (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
22014           (const_int 63)))
22015    (unspec [(match_operand:DI 2 "register_operand" "0")]
22016            UNSPEC_INSN_FALSE_DEP)
22017    (clobber (reg:CC FLAGS_REG))]
22018   "TARGET_POPCNT && TARGET_64BIT"
22020 #if TARGET_MACHO
22021   return "popcnt\t{%1, %k0|%k0, %1}";
22022 #else
22023   return "popcnt{l}\t{%1, %k0|%k0, %1}";
22024 #endif
22026   [(set_attr "prefix_rep" "1")
22027    (set_attr "type" "bitmanip")
22028    (set_attr "mode" "SI")])
22030 (define_insn_and_split "*popcountsi2_zext_2"
22031   [(set (match_operand:DI 0 "register_operand" "=r")
22032         (zero_extend:DI
22033           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
22034    (clobber (reg:CC FLAGS_REG))]
22035   "TARGET_POPCNT && TARGET_64BIT"
22037 #if TARGET_MACHO
22038   return "popcnt\t{%1, %k0|%k0, %1}";
22039 #else
22040   return "popcnt{l}\t{%1, %k0|%k0, %1}";
22041 #endif
22043   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
22044    && optimize_function_for_speed_p (cfun)
22045    && !reg_mentioned_p (operands[0], operands[1])"
22046   [(parallel
22047     [(set (match_dup 0)
22048           (zero_extend:DI (popcount:SI (match_dup 1))))
22049      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
22050      (clobber (reg:CC FLAGS_REG))])]
22051   "ix86_expand_clear (operands[0]);"
22052   [(set_attr "prefix_rep" "1")
22053    (set_attr "type" "bitmanip")
22054    (set_attr "mode" "SI")])
22056 ; False dependency happens when destination is only updated by tzcnt,
22057 ; lzcnt or popcnt.  There is no false dependency when destination is
22058 ; also used in source.
22059 (define_insn "*popcountsi2_zext_2_falsedep"
22060   [(set (match_operand:DI 0 "register_operand" "=r")
22061         (zero_extend:DI
22062           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
22063    (unspec [(match_operand:DI 2 "register_operand" "0")]
22064            UNSPEC_INSN_FALSE_DEP)
22065    (clobber (reg:CC FLAGS_REG))]
22066   "TARGET_POPCNT && TARGET_64BIT"
22068 #if TARGET_MACHO
22069   return "popcnt\t{%1, %k0|%k0, %1}";
22070 #else
22071   return "popcnt{l}\t{%1, %k0|%k0, %1}";
22072 #endif
22074   [(set_attr "prefix_rep" "1")
22075    (set_attr "type" "bitmanip")
22076    (set_attr "mode" "SI")])
22078 (define_insn_and_split "*popcounthi2_1"
22079   [(set (match_operand:SI 0 "register_operand")
22080         (popcount:SI
22081           (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
22082    (clobber (reg:CC FLAGS_REG))]
22083   "TARGET_POPCNT
22084    && ix86_pre_reload_split ()"
22085   "#"
22086   "&& 1"
22087   [(const_int 0)]
22089   rtx tmp = gen_reg_rtx (HImode);
22091   emit_insn (gen_popcounthi2 (tmp, operands[1]));
22092   emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
22093   DONE;
22096 (define_insn_and_split "*popcounthi2_2"
22097   [(set (match_operand:SI 0 "register_operand")
22098         (zero_extend:SI
22099           (popcount:HI (match_operand:HI 1 "nonimmediate_operand"))))
22100    (clobber (reg:CC FLAGS_REG))]
22101   "TARGET_POPCNT
22102    && ix86_pre_reload_split ()"
22103   "#"
22104   "&& 1"
22105   [(const_int 0)]
22107   rtx tmp = gen_reg_rtx (HImode);
22109   emit_insn (gen_popcounthi2 (tmp, operands[1]));
22110   emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
22111   DONE;
22114 (define_insn "popcounthi2<nf_name>"
22115   [(set (match_operand:HI 0 "register_operand" "=r")
22116         (popcount:HI
22117           (match_operand:HI 1 "nonimmediate_operand" "rm")))]
22118   "TARGET_POPCNT && <nf_condition>"
22120 #if TARGET_MACHO
22121   return "<nf_prefix>popcnt\t{%1, %0|%0, %1}";
22122 #else
22123   return "<nf_prefix>popcnt{w}\t{%1, %0|%0, %1}";
22124 #endif
22126   [(set_attr "prefix_rep" "1")
22127    (set_attr "type" "bitmanip")
22128    (set_attr "has_nf" "1")
22129    (set_attr "mode" "HI")])
22131 (define_expand "bswapdi2"
22132   [(set (match_operand:DI 0 "register_operand")
22133         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
22134   "TARGET_64BIT"
22136   if (!TARGET_MOVBE)
22137     operands[1] = force_reg (DImode, operands[1]);
22140 (define_expand "bswapsi2"
22141   [(set (match_operand:SI 0 "register_operand")
22142         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
22143   ""
22145   if (!TARGET_MOVBE)
22146     {
22147       operands[1] = force_reg (SImode, operands[1]);
22149       if (!TARGET_BSWAP)
22150         {
22151           rtx x = gen_reg_rtx (SImode);
22153           emit_insn (gen_bswaphisi2_lowpart (x, operands[1]));
22154           emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
22155           emit_insn (gen_bswaphisi2_lowpart (operands[0], x));
22156           DONE;
22157         }
22158     }
22161 (define_insn "*bswap<mode>2_movbe"
22162   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
22163         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
22164   "TARGET_MOVBE
22165    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
22166   "@
22167     bswap\t%0
22168     movbe{<imodesuffix>}\t{%1, %0|%0, %1}
22169     movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
22170   [(set_attr "type" "bitmanip,imov,imov")
22171    (set_attr "modrm" "0,1,1")
22172    (set_attr "prefix_0f" "*,1,1")
22173    (set_attr "prefix_extra" "*,1,1")
22174    (set_attr "mode" "<MODE>")])
22176 (define_insn "*bswap<mode>2"
22177   [(set (match_operand:SWI48 0 "register_operand" "=r")
22178         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
22179   "TARGET_BSWAP"
22180   "bswap\t%0"
22181   [(set_attr "type" "bitmanip")
22182    (set_attr "modrm" "0")
22183    (set_attr "mode" "<MODE>")])
22185 (define_expand "bswaphi2"
22186   [(set (match_operand:HI 0 "register_operand")
22187         (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
22188   ""
22190   if (!TARGET_MOVBE)
22191     operands[1] = force_reg (HImode, operands[1]);
22194 (define_insn "*bswaphi2_movbe"
22195   [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
22196         (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
22197   "TARGET_MOVBE
22198    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
22199   "@
22200     xchg{b}\t{%h0, %b0|%b0, %h0}
22201     movbe{w}\t{%1, %0|%0, %1}
22202     movbe{w}\t{%1, %0|%0, %1}"
22203   [(set_attr "type" "imov")
22204    (set_attr "modrm" "*,1,1")
22205    (set_attr "prefix_0f" "*,1,1")
22206    (set_attr "prefix_extra" "*,1,1")
22207    (set_attr "pent_pair" "np,*,*")
22208    (set_attr "athlon_decode" "vector,*,*")
22209    (set_attr "amdfam10_decode" "double,*,*")
22210    (set_attr "bdver1_decode" "double,*,*")
22211    (set_attr "mode" "QI,HI,HI")])
22213 (define_insn "*bswaphi2"
22214   [(set (match_operand:HI 0 "register_operand" "=Q")
22215         (bswap:HI (match_operand:HI 1 "register_operand" "0")))]
22216   "!TARGET_MOVBE"
22217   "xchg{b}\t{%h0, %b0|%b0, %h0}"
22218   [(set_attr "type" "imov")
22219    (set_attr "pent_pair" "np")
22220    (set_attr "athlon_decode" "vector")
22221    (set_attr "amdfam10_decode" "double")
22222    (set_attr "bdver1_decode" "double")
22223    (set_attr "mode" "QI")])
22225 (define_peephole2
22226   [(set (match_operand:HI 0 "general_reg_operand")
22227         (bswap:HI (match_dup 0)))]
22228   "!(TARGET_USE_XCHGB ||
22229      TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
22230    && peep2_regno_dead_p (0, FLAGS_REG)"
22231   [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
22232               (clobber (reg:CC FLAGS_REG))])])
22234 (define_insn "bswaphisi2_lowpart"
22235   [(set (match_operand:SI 0 "register_operand" "=Q")
22236         (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
22237                         (const_int -65536))
22238                 (lshiftrt:SI (bswap:SI (match_dup 1))
22239                              (const_int 16))))]
22240   ""
22241   "xchg{b}\t{%h0, %b0|%b0, %h0}"
22242   [(set_attr "type" "imov")
22243    (set_attr "pent_pair" "np")
22244    (set_attr "athlon_decode" "vector")
22245    (set_attr "amdfam10_decode" "double")
22246    (set_attr "bdver1_decode" "double")
22247    (set_attr "mode" "QI")])
22249 (define_peephole2
22250   [(set (match_operand:SI 0 "general_reg_operand")
22251         (ior:SI (and:SI (match_dup 0)
22252                         (const_int -65536))
22253                 (lshiftrt:SI (bswap:SI (match_dup 0))
22254                              (const_int 16))))]
22255   "!(TARGET_USE_XCHGB ||
22256      TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
22257    && peep2_regno_dead_p (0, FLAGS_REG)"
22258   [(parallel [(set (strict_low_part (match_dup 0))
22259                                     (rotate:HI (match_dup 0) (const_int 8)))
22260               (clobber (reg:CC FLAGS_REG))])]
22261   "operands[0] = gen_lowpart (HImode, operands[0]);")
22263 ;; Variant of above peephole2 to improve register allocation.
22264 (define_peephole2
22265   [(set (match_operand:SI 0 "general_reg_operand")
22266         (match_operand:SI 1 "register_operand"))
22267    (set (match_dup 0)
22268         (ior:SI (and:SI (match_dup 0)
22269                         (const_int -65536))
22270                 (lshiftrt:SI (bswap:SI (match_dup 0))
22271                              (const_int 16))))
22272    (set (match_operand:SI 2 "general_reg_operand") (match_dup 0))]
22273   "!(TARGET_USE_XCHGB ||
22274      TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
22275    && peep2_regno_dead_p (0, FLAGS_REG)
22276    && peep2_reg_dead_p(3, operands[0])"
22277   [(parallel
22278     [(set (strict_low_part (match_dup 3))
22279           (rotate:HI (match_dup 3) (const_int 8)))
22280      (clobber (reg:CC FLAGS_REG))])]
22282   if (!rtx_equal_p (operands[1], operands[2]))
22283     emit_move_insn (operands[2], operands[1]);
22284   operands[3] = gen_lowpart (HImode, operands[2]);
22287 (define_expand "paritydi2"
22288   [(set (match_operand:DI 0 "register_operand")
22289         (parity:DI (match_operand:DI 1 "register_operand")))]
22290   "! TARGET_POPCNT"
22292   rtx scratch = gen_reg_rtx (QImode);
22293   rtx hipart1 = gen_reg_rtx (SImode);
22294   rtx lopart1 = gen_reg_rtx (SImode);
22295   rtx xor1 = gen_reg_rtx (SImode);
22296   rtx shift2 = gen_reg_rtx (SImode);
22297   rtx hipart2 = gen_reg_rtx (HImode);
22298   rtx lopart2 = gen_reg_rtx (HImode);
22299   rtx xor2 = gen_reg_rtx (HImode);
22301   if (TARGET_64BIT)
22302     {
22303       rtx shift1 = gen_reg_rtx (DImode);
22304       emit_insn (gen_lshrdi3 (shift1, operands[1], GEN_INT (32)));
22305       emit_move_insn (hipart1, gen_lowpart (SImode, shift1));
22306     }
22307   else
22308     emit_move_insn (hipart1, gen_highpart (SImode, operands[1]));
22310   emit_move_insn (lopart1, gen_lowpart (SImode, operands[1]));
22311   emit_insn (gen_xorsi3 (xor1, hipart1, lopart1));
22313   emit_insn (gen_lshrsi3 (shift2, xor1, GEN_INT (16)));
22314   emit_move_insn (hipart2, gen_lowpart (HImode, shift2));
22315   emit_move_insn (lopart2, gen_lowpart (HImode, xor1));
22316   emit_insn (gen_xorhi3 (xor2, hipart2, lopart2));
22318   emit_insn (gen_parityhi2_cmp (xor2));
22320   ix86_expand_setcc (scratch, ORDERED,
22321                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
22323   if (TARGET_64BIT)
22324     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
22325   else
22326     {
22327       rtx tmp = gen_reg_rtx (SImode);
22329       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
22330       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
22331     }
22332   DONE;
22335 (define_expand "paritysi2"
22336   [(set (match_operand:SI 0 "register_operand")
22337         (parity:SI (match_operand:SI 1 "register_operand")))]
22338   "! TARGET_POPCNT"
22340   rtx scratch = gen_reg_rtx (QImode);
22341   rtx shift = gen_reg_rtx (SImode);
22342   rtx hipart = gen_reg_rtx (HImode);
22343   rtx lopart = gen_reg_rtx (HImode);
22344   rtx tmp = gen_reg_rtx (HImode);
22346   emit_insn (gen_lshrsi3 (shift, operands[1], GEN_INT (16)));
22347   emit_move_insn (hipart, gen_lowpart (HImode, shift));
22348   emit_move_insn (lopart, gen_lowpart (HImode, operands[1]));
22349   emit_insn (gen_xorhi3 (tmp, hipart, lopart));
22351   emit_insn (gen_parityhi2_cmp (tmp));
22353   ix86_expand_setcc (scratch, ORDERED,
22354                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
22356   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
22357   DONE;
22360 (define_expand "parityhi2"
22361   [(set (match_operand:HI 0 "register_operand")
22362         (parity:HI (match_operand:HI 1 "register_operand")))]
22363   "! TARGET_POPCNT"
22365   rtx scratch = gen_reg_rtx (QImode);
22366   rtx tmp = gen_reg_rtx (HImode);
22368   emit_move_insn (tmp, operands[1]);
22369   emit_insn (gen_parityhi2_cmp (tmp));
22371   ix86_expand_setcc (scratch, ORDERED,
22372                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
22374   emit_insn (gen_zero_extendqihi2 (operands[0], scratch));
22375   DONE;
22378 (define_expand "parityqi2"
22379   [(set (match_operand:QI 0 "register_operand")
22380         (parity:QI (match_operand:QI 1 "register_operand")))]
22381   "! TARGET_POPCNT"
22383   emit_insn (gen_parityqi2_cmp (operands[1]));
22385   ix86_expand_setcc (operands[0], ORDERED,
22386                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
22387   DONE;
22390 (define_insn "parityhi2_cmp"
22391   [(set (reg:CC FLAGS_REG)
22392         (unspec:CC [(match_operand:HI 0 "register_operand" "+Q")]
22393                    UNSPEC_PARITY))
22394    (clobber (match_dup 0))]
22395   ""
22396   "xor{b}\t{%h0, %b0|%b0, %h0}"
22397   [(set_attr "length" "2")
22398    (set_attr "mode" "QI")])
22400 (define_insn "parityqi2_cmp"
22401   [(set (reg:CC FLAGS_REG)
22402         (unspec:CC [(match_operand:QI 0 "register_operand" "q")]
22403                    UNSPEC_PARITY))]
22404   ""
22405   "test{b}\t%0, %0"
22406   [(set_attr "mode" "QI")])
22408 ;; Replace zero_extend:HI followed by parityhi2_cmp with parityqi2_cmp
22409 (define_peephole2
22410   [(set (match_operand:HI 0 "register_operand")
22411         (zero_extend:HI (match_operand:QI 1 "general_reg_operand")))
22412    (parallel [(set (reg:CC FLAGS_REG)
22413                    (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
22414               (clobber (match_dup 0))])]
22415   ""
22416   [(set (reg:CC FLAGS_REG)
22417         (unspec:CC [(match_dup 1)] UNSPEC_PARITY))])
22419 ;; Eliminate QImode popcount&1 using parity flag
22420 (define_peephole2
22421   [(set (match_operand:SI 0 "register_operand")
22422         (zero_extend:SI (match_operand:QI 1 "general_reg_operand")))
22423    (parallel [(set (match_operand:SI 2 "register_operand")
22424                    (popcount:SI (match_dup 0)))
22425               (clobber (reg:CC FLAGS_REG))])
22426    (set (reg:CCZ FLAGS_REG)
22427         (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
22428                              (const_int 1))
22429                      (const_int 0)))
22430    (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
22431                             [(reg:CCZ FLAGS_REG)
22432                              (const_int 0)])
22433                            (label_ref (match_operand 5))
22434                            (pc)))]
22435   "REGNO (operands[2]) == REGNO (operands[3])
22436    && peep2_reg_dead_p (3, operands[0])
22437    && peep2_reg_dead_p (3, operands[2])
22438    && peep2_regno_dead_p (4, FLAGS_REG)"
22439   [(set (reg:CC FLAGS_REG)
22440         (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
22441    (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
22442                                             (const_int 0)])
22443                            (label_ref (match_dup 5))
22444                            (pc)))]
22446   operands[4] = shallow_copy_rtx (operands[4]);
22447   PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
22450 ;; Eliminate HImode popcount&1 using parity flag
22451 (define_peephole2
22452   [(match_scratch:HI 0 "Q")
22453    (parallel [(set (match_operand:HI 1 "register_operand")
22454                    (popcount:HI
22455                     (match_operand:HI 2 "nonimmediate_operand")))
22456               (clobber (reg:CC FLAGS_REG))])
22457    (set (match_operand 3 "register_operand")
22458         (zero_extend (match_dup 1)))
22459    (set (reg:CCZ FLAGS_REG)
22460         (compare:CCZ (and:QI (match_operand:QI 4 "register_operand")
22461                              (const_int 1))
22462                      (const_int 0)))
22463    (set (pc) (if_then_else (match_operator 5 "bt_comparison_operator"
22464                             [(reg:CCZ FLAGS_REG)
22465                              (const_int 0)])
22466                            (label_ref (match_operand 6))
22467                            (pc)))]
22468   "REGNO (operands[3]) == REGNO (operands[4])
22469    && peep2_reg_dead_p (3, operands[1])
22470    && peep2_reg_dead_p (3, operands[3])
22471    && peep2_regno_dead_p (4, FLAGS_REG)"
22472   [(set (match_dup 0) (match_dup 2))
22473    (parallel [(set (reg:CC FLAGS_REG)
22474                    (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
22475               (clobber (match_dup 0))])
22476    (set (pc) (if_then_else (match_op_dup 5 [(reg:CC FLAGS_REG)
22477                                             (const_int 0)])
22478                            (label_ref (match_dup 6))
22479                            (pc)))]
22481   operands[5] = shallow_copy_rtx (operands[5]);
22482   PUT_CODE (operands[5], GET_CODE (operands[5]) == EQ ? UNORDERED : ORDERED);
22485 ;; Eliminate HImode popcount&1 using parity flag (variant 2)
22486 (define_peephole2
22487   [(match_scratch:HI 0 "Q")
22488    (parallel [(set (match_operand:HI 1 "register_operand")
22489                    (popcount:HI
22490                     (match_operand:HI 2 "nonimmediate_operand")))
22491               (clobber (reg:CC FLAGS_REG))])
22492    (set (reg:CCZ FLAGS_REG)
22493         (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
22494                              (const_int 1))
22495                      (const_int 0)))
22496    (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
22497                             [(reg:CCZ FLAGS_REG)
22498                              (const_int 0)])
22499                            (label_ref (match_operand 5))
22500                            (pc)))]
22501   "REGNO (operands[1]) == REGNO (operands[3])
22502    && peep2_reg_dead_p (2, operands[1])
22503    && peep2_reg_dead_p (2, operands[3])
22504    && peep2_regno_dead_p (3, FLAGS_REG)"
22505   [(set (match_dup 0) (match_dup 2))
22506    (parallel [(set (reg:CC FLAGS_REG)
22507                    (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
22508               (clobber (match_dup 0))])
22509    (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
22510                                             (const_int 0)])
22511                            (label_ref (match_dup 5))
22512                            (pc)))]
22514   operands[4] = shallow_copy_rtx (operands[4]);
22515   PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
22519 ;; Thread-local storage patterns for ELF.
22521 ;; Note that these code sequences must appear exactly as shown
22522 ;; in order to allow linker relaxation.
22524 (define_insn "*tls_global_dynamic_32_gnu"
22525   [(set (match_operand:SI 0 "register_operand" "=a")
22526         (unspec:SI
22527          [(match_operand:SI 1 "register_operand" "Yb")
22528           (match_operand 2 "tls_symbolic_operand")
22529           (match_operand 3 "constant_call_address_operand" "Bz")
22530           (reg:SI SP_REG)]
22531          UNSPEC_TLS_GD))
22532    (clobber (match_scratch:SI 4 "=d"))
22533    (clobber (match_scratch:SI 5 "=c"))
22534    (clobber (reg:CC FLAGS_REG))]
22535   "!TARGET_64BIT && TARGET_GNU_TLS"
22537   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
22538     output_asm_insn
22539       ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
22540   else
22541     output_asm_insn
22542       ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
22543   if (TARGET_SUN_TLS)
22544 #ifdef HAVE_AS_IX86_TLSGDPLT
22545     return "call\t%a2@tlsgdplt";
22546 #else
22547     return "call\t%p3@plt";
22548 #endif
22549   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
22550     return "call\t%P3";
22551   return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
22553   [(set_attr "type" "multi")
22554    (set_attr "length" "12")])
22556 (define_expand "tls_global_dynamic_32"
22557   [(parallel
22558     [(set (match_operand:SI 0 "register_operand")
22559           (unspec:SI [(match_operand:SI 2 "register_operand")
22560                       (match_operand 1 "tls_symbolic_operand")
22561                       (match_operand 3 "constant_call_address_operand")
22562                       (reg:SI SP_REG)]
22563                      UNSPEC_TLS_GD))
22564      (clobber (scratch:SI))
22565      (clobber (scratch:SI))
22566      (clobber (reg:CC FLAGS_REG))])]
22567   ""
22568   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
22570 (define_insn "*tls_global_dynamic_64_<mode>"
22571   [(set (match_operand:P 0 "register_operand" "=a")
22572         (call:P
22573          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
22574          (match_operand 3)))
22575    (unspec:P [(match_operand 1 "tls_symbolic_operand")
22576               (reg:P SP_REG)]
22577              UNSPEC_TLS_GD)]
22578   "TARGET_64BIT"
22580   if (!TARGET_X32)
22581     /* The .loc directive has effect for 'the immediately following assembly
22582        instruction'.  So for a sequence:
22583          .loc f l
22584          .byte x
22585          insn1
22586        the 'immediately following assembly instruction' is insn1.
22587        We want to emit an insn prefix here, but if we use .byte (as shown in
22588        'ELF Handling For Thread-Local Storage'), a preceding .loc will point
22589        inside the insn sequence, rather than to the start.  After relaxation
22590        of the sequence by the linker, the .loc might point inside an insn.
22591        Use data16 prefix instead, which doesn't have this problem.  */
22592     fputs ("\tdata16", asm_out_file);
22593   output_asm_insn
22594     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
22595   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
22596     fputs (ASM_SHORT "0x6666\n", asm_out_file);
22597   else
22598     fputs (ASM_BYTE "0x66\n", asm_out_file);
22599   fputs ("\trex64\n", asm_out_file);
22600   if (TARGET_SUN_TLS)
22601     return "call\t%p2@plt";
22602   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
22603     return "call\t%P2";
22604   return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
22606   [(set_attr "type" "multi")
22607    (set (attr "length")
22608         (symbol_ref "TARGET_X32 ? 15 : 16"))])
22610 (define_insn "*tls_global_dynamic_64_largepic"
22611   [(set (match_operand:DI 0 "register_operand" "=a")
22612         (call:DI
22613          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
22614                           (match_operand:DI 3 "immediate_operand" "i")))
22615          (match_operand 4)))
22616    (unspec:DI [(match_operand 1 "tls_symbolic_operand")
22617                (reg:DI SP_REG)]
22618               UNSPEC_TLS_GD)]
22619   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
22620    && GET_CODE (operands[3]) == CONST
22621    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
22622    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
22624   output_asm_insn
22625     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
22626   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
22627   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
22628   return "call\t{*%%rax|rax}";
22630   [(set_attr "type" "multi")
22631    (set_attr "length" "22")])
22633 (define_expand "@tls_global_dynamic_64_<mode>"
22634   [(parallel
22635     [(set (match_operand:P 0 "register_operand")
22636           (call:P
22637            (mem:QI (match_operand 2))
22638            (const_int 0)))
22639      (unspec:P [(match_operand 1 "tls_symbolic_operand")
22640                 (reg:P SP_REG)]
22641                UNSPEC_TLS_GD)])]
22642   "TARGET_64BIT"
22643   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
22645 (define_insn "*tls_local_dynamic_base_32_gnu"
22646   [(set (match_operand:SI 0 "register_operand" "=a")
22647         (unspec:SI
22648          [(match_operand:SI 1 "register_operand" "Yb")
22649           (match_operand 2 "constant_call_address_operand" "Bz")
22650           (reg:SI SP_REG)]
22651          UNSPEC_TLS_LD_BASE))
22652    (clobber (match_scratch:SI 3 "=d"))
22653    (clobber (match_scratch:SI 4 "=c"))
22654    (clobber (reg:CC FLAGS_REG))]
22655   "!TARGET_64BIT && TARGET_GNU_TLS"
22657   output_asm_insn
22658     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
22659   if (TARGET_SUN_TLS)
22660     {
22661       if (HAVE_AS_IX86_TLSLDMPLT)
22662         return "call\t%&@tlsldmplt";
22663       else
22664         return "call\t%p2@plt";
22665     }
22666   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
22667     return "call\t%P2";
22668   return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
22670   [(set_attr "type" "multi")
22671    (set_attr "length" "11")])
22673 (define_expand "tls_local_dynamic_base_32"
22674   [(parallel
22675      [(set (match_operand:SI 0 "register_operand")
22676            (unspec:SI
22677             [(match_operand:SI 1 "register_operand")
22678              (match_operand 2 "constant_call_address_operand")
22679              (reg:SI SP_REG)]
22680             UNSPEC_TLS_LD_BASE))
22681       (clobber (scratch:SI))
22682       (clobber (scratch:SI))
22683       (clobber (reg:CC FLAGS_REG))])]
22684   ""
22685   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
22687 (define_insn "*tls_local_dynamic_base_64_<mode>"
22688   [(set (match_operand:P 0 "register_operand" "=a")
22689         (call:P
22690          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
22691          (match_operand 2)))
22692    (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
22693   "TARGET_64BIT"
22695   output_asm_insn
22696     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
22697   if (TARGET_SUN_TLS)
22698     return "call\t%p1@plt";
22699   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
22700     return "call\t%P1";
22701   return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
22703   [(set_attr "type" "multi")
22704    (set_attr "length" "12")])
22706 (define_insn "*tls_local_dynamic_base_64_largepic"
22707   [(set (match_operand:DI 0 "register_operand" "=a")
22708         (call:DI
22709          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
22710                           (match_operand:DI 2 "immediate_operand" "i")))
22711          (match_operand 3)))
22712    (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
22713   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
22714    && GET_CODE (operands[2]) == CONST
22715    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
22716    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
22718   output_asm_insn
22719     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
22720   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
22721   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
22722   return "call\t{*%%rax|rax}";
22724   [(set_attr "type" "multi")
22725    (set_attr "length" "22")])
22727 (define_expand "@tls_local_dynamic_base_64_<mode>"
22728   [(parallel
22729      [(set (match_operand:P 0 "register_operand")
22730            (call:P
22731             (mem:QI (match_operand 1))
22732             (const_int 0)))
22733       (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
22734   "TARGET_64BIT"
22735   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
22737 ;; Local dynamic of a single variable is a lose.  Show combine how
22738 ;; to convert that back to global dynamic.
22740 (define_insn_and_split "*tls_local_dynamic_32_once"
22741   [(set (match_operand:SI 0 "register_operand" "=a")
22742         (plus:SI
22743          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
22744                      (match_operand 2 "constant_call_address_operand" "Bz")
22745                      (reg:SI SP_REG)]
22746                     UNSPEC_TLS_LD_BASE)
22747          (const:SI (unspec:SI
22748                     [(match_operand 3 "tls_symbolic_operand")]
22749                     UNSPEC_DTPOFF))))
22750    (clobber (match_scratch:SI 4 "=d"))
22751    (clobber (match_scratch:SI 5 "=c"))
22752    (clobber (reg:CC FLAGS_REG))]
22753   ""
22754   "#"
22755   ""
22756   [(parallel
22757      [(set (match_dup 0)
22758            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
22759                        (reg:SI SP_REG)]
22760                       UNSPEC_TLS_GD))
22761       (clobber (match_dup 4))
22762       (clobber (match_dup 5))
22763       (clobber (reg:CC FLAGS_REG))])])
22765 ;; Load and add the thread base pointer from %<tp_seg>:0.
22766 (define_expand "get_thread_pointer<mode>"
22767   [(set (match_operand:PTR 0 "register_operand")
22768         (unspec:PTR [(const_int 0)] UNSPEC_TP))]
22769   ""
22771   /* targetm is not visible in the scope of the condition.  */
22772   if (!targetm.have_tls)
22773     error ("%<__builtin_thread_pointer%> is not supported on this target");
22776 (define_insn_and_split "*load_tp_<mode>"
22777   [(set (match_operand:PTR 0 "register_operand" "=r")
22778         (unspec:PTR [(const_int 0)] UNSPEC_TP))]
22779   ""
22780   "#"
22781   ""
22782   [(set (match_dup 0)
22783         (match_dup 1))]
22785   addr_space_t as = DEFAULT_TLS_SEG_REG;
22787   operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
22788   set_mem_addr_space (operands[1], as);
22791 (define_insn_and_split "*load_tp_x32_zext"
22792   [(set (match_operand:DI 0 "register_operand" "=r")
22793         (zero_extend:DI
22794           (unspec:SI [(const_int 0)] UNSPEC_TP)))]
22795   "TARGET_X32"
22796   "#"
22797   "&& 1"
22798   [(set (match_dup 0)
22799         (zero_extend:DI (match_dup 1)))]
22801   addr_space_t as = DEFAULT_TLS_SEG_REG;
22803   operands[1] = gen_const_mem (SImode, const0_rtx);
22804   set_mem_addr_space (operands[1], as);
22807 (define_insn_and_split "*add_tp_<mode>"
22808   [(set (match_operand:PTR 0 "register_operand" "=r")
22809         (plus:PTR
22810           (unspec:PTR [(const_int 0)] UNSPEC_TP)
22811           (match_operand:PTR 1 "register_operand" "0")))
22812    (clobber (reg:CC FLAGS_REG))]
22813   ""
22814   "#"
22815   ""
22816   [(parallel
22817      [(set (match_dup 0)
22818            (plus:PTR (match_dup 1) (match_dup 2)))
22819       (clobber (reg:CC FLAGS_REG))])]
22821   addr_space_t as = DEFAULT_TLS_SEG_REG;
22823   operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
22824   set_mem_addr_space (operands[2], as);
22827 (define_insn_and_split "*add_tp_x32_zext"
22828   [(set (match_operand:DI 0 "register_operand" "=r")
22829         (zero_extend:DI
22830           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
22831                    (match_operand:SI 1 "register_operand" "0"))))
22832    (clobber (reg:CC FLAGS_REG))]
22833   "TARGET_X32"
22834   "#"
22835   "&& 1"
22836   [(parallel
22837      [(set (match_dup 0)
22838            (zero_extend:DI
22839              (plus:SI (match_dup 1) (match_dup 2))))
22840       (clobber (reg:CC FLAGS_REG))])]
22842   addr_space_t as = DEFAULT_TLS_SEG_REG;
22844   operands[2] = gen_const_mem (SImode, const0_rtx);
22845   set_mem_addr_space (operands[2], as);
22848 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
22849 ;; %rax as destination of the initial executable code sequence.
22850 (define_insn "tls_initial_exec_64_sun"
22851   [(set (match_operand:DI 0 "register_operand" "=a")
22852         (unspec:DI
22853          [(match_operand 1 "tls_symbolic_operand")]
22854          UNSPEC_TLS_IE_SUN))
22855    (clobber (reg:CC FLAGS_REG))]
22856   "TARGET_64BIT && TARGET_SUN_TLS"
22858   output_asm_insn
22859     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
22860   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
22862   [(set_attr "type" "multi")])
22864 ;; GNU2 TLS patterns can be split.
22866 (define_expand "tls_dynamic_gnu2_32"
22867   [(set (match_dup 3)
22868         (plus:SI (match_operand:SI 2 "register_operand")
22869                  (const:SI
22870                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
22871                              UNSPEC_TLSDESC))))
22872    (parallel
22873     [(set (match_operand:SI 0 "register_operand")
22874           (unspec:SI [(match_dup 1) (match_dup 3)
22875                       (match_dup 2) (reg:SI SP_REG)]
22876                       UNSPEC_TLSDESC))
22877      (clobber (reg:CC FLAGS_REG))])]
22878   "!TARGET_64BIT && TARGET_GNU2_TLS"
22880   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
22881   ix86_tls_descriptor_calls_expanded_in_cfun = true;
22884 (define_insn "*tls_dynamic_gnu2_lea_32"
22885   [(set (match_operand:SI 0 "register_operand" "=r")
22886         (plus:SI (match_operand:SI 1 "register_operand" "b")
22887                  (const:SI
22888                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
22889                               UNSPEC_TLSDESC))))]
22890   "!TARGET_64BIT && TARGET_GNU2_TLS"
22891   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
22892   [(set_attr "type" "lea")
22893    (set_attr "mode" "SI")
22894    (set_attr "length" "6")
22895    (set_attr "length_address" "4")])
22897 (define_insn "*tls_dynamic_gnu2_call_32"
22898   [(set (match_operand:SI 0 "register_operand" "=a")
22899         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
22900                     (match_operand:SI 2 "register_operand" "0")
22901                     ;; we have to make sure %ebx still points to the GOT
22902                     (match_operand:SI 3 "register_operand" "b")
22903                     (reg:SI SP_REG)]
22904                    UNSPEC_TLSDESC))
22905    (clobber (reg:CC FLAGS_REG))]
22906   "!TARGET_64BIT && TARGET_GNU2_TLS"
22907   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
22908   [(set_attr "type" "call")
22909    (set_attr "length" "2")
22910    (set_attr "length_address" "0")])
22912 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
22913   [(set (match_operand:SI 0 "register_operand" "=&a")
22914         (plus:SI
22915          (unspec:SI [(match_operand 3 "tls_modbase_operand")
22916                      (match_operand:SI 4)
22917                      (match_operand:SI 2 "register_operand" "b")
22918                      (reg:SI SP_REG)]
22919                     UNSPEC_TLSDESC)
22920          (const:SI (unspec:SI
22921                     [(match_operand 1 "tls_symbolic_operand")]
22922                     UNSPEC_DTPOFF))))
22923    (clobber (reg:CC FLAGS_REG))]
22924   "!TARGET_64BIT && TARGET_GNU2_TLS"
22925   "#"
22926   "&& 1"
22927   [(set (match_dup 0) (match_dup 5))]
22929   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
22930   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
22933 (define_expand "@tls_dynamic_gnu2_64_<mode>"
22934   [(set (match_dup 2)
22935         (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
22936                     UNSPEC_TLSDESC))
22937    (parallel
22938     [(set (match_operand:PTR 0 "register_operand")
22939           (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)]
22940                       UNSPEC_TLSDESC))
22941      (clobber (reg:CC FLAGS_REG))])]
22942   "TARGET_64BIT && TARGET_GNU2_TLS"
22944   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
22945   ix86_tls_descriptor_calls_expanded_in_cfun = true;
22948 (define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
22949   [(set (match_operand:PTR 0 "register_operand" "=r")
22950         (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
22951                     UNSPEC_TLSDESC))]
22952   "TARGET_64BIT && TARGET_GNU2_TLS"
22953   "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
22954   [(set_attr "type" "lea")
22955    (set_attr "mode" "<MODE>")
22956    (set_attr "length" "7")
22957    (set_attr "length_address" "4")])
22959 (define_insn "*tls_dynamic_gnu2_call_64_<mode>"
22960   [(set (match_operand:PTR 0 "register_operand" "=a")
22961         (unspec:PTR [(match_operand 1 "tls_symbolic_operand")
22962                    (match_operand:PTR 2 "register_operand" "0")
22963                    (reg:PTR SP_REG)]
22964                   UNSPEC_TLSDESC))
22965    (clobber (reg:CC FLAGS_REG))]
22966   "TARGET_64BIT && TARGET_GNU2_TLS"
22967   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
22968   [(set_attr "type" "call")
22969    (set_attr "length" "2")
22970    (set_attr "length_address" "0")])
22972 (define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
22973   [(set (match_operand:PTR 0 "register_operand" "=&a")
22974         (plus:PTR
22975          (unspec:PTR [(match_operand 2 "tls_modbase_operand")
22976                       (match_operand:PTR 3)
22977                       (reg:PTR SP_REG)]
22978                      UNSPEC_TLSDESC)
22979          (const:PTR (unspec:PTR
22980                      [(match_operand 1 "tls_symbolic_operand")]
22981                      UNSPEC_DTPOFF))))
22982    (clobber (reg:CC FLAGS_REG))]
22983   "TARGET_64BIT && TARGET_GNU2_TLS"
22984   "#"
22985   "&& 1"
22986   [(set (match_dup 0) (match_dup 4))]
22988   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
22989   emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1]));
22992 (define_split
22993   [(match_operand 0 "tls_address_pattern")]
22994   "TARGET_TLS_DIRECT_SEG_REFS"
22995   [(match_dup 0)]
22996   "operands[0] = ix86_rewrite_tls_address (operands[0]);")
22999 ;; These patterns match the binary 387 instructions for addM3, subM3,
23000 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
23001 ;; SFmode.  The first is the normal insn, the second the same insn but
23002 ;; with one operand a conversion, and the third the same insn but with
23003 ;; the other operand a conversion.  The conversion may be SFmode or
23004 ;; SImode if the target mode DFmode, but only SImode if the target mode
23005 ;; is SFmode.
23007 ;; Gcc is slightly more smart about handling normal two address instructions
23008 ;; so use special patterns for add and mull.
23010 (define_insn "*fop_xf_comm_i387"
23011   [(set (match_operand:XF 0 "register_operand" "=f")
23012         (match_operator:XF 3 "binary_fp_operator"
23013                         [(match_operand:XF 1 "register_operand" "%0")
23014                          (match_operand:XF 2 "register_operand" "f")]))]
23015   "TARGET_80387
23016    && COMMUTATIVE_ARITH_P (operands[3])"
23017   "* return output_387_binary_op (insn, operands);"
23018   [(set (attr "type")
23019         (if_then_else (match_operand:XF 3 "mult_operator")
23020            (const_string "fmul")
23021            (const_string "fop")))
23022    (set_attr "mode" "XF")])
23024 (define_insn "*fop_<mode>_comm"
23025   [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
23026         (match_operator:MODEF 3 "binary_fp_operator"
23027           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
23028            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
23029   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23030     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
23031    && COMMUTATIVE_ARITH_P (operands[3])
23032    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
23033   "* return output_387_binary_op (insn, operands);"
23034   [(set (attr "type")
23035         (if_then_else (eq_attr "alternative" "1,2")
23036            (if_then_else (match_operand:MODEF 3 "mult_operator")
23037               (const_string "ssemul")
23038               (const_string "sseadd"))
23039            (if_then_else (match_operand:MODEF 3 "mult_operator")
23040               (const_string "fmul")
23041               (const_string "fop"))))
23042    (set_attr "isa" "*,noavx,avx")
23043    (set_attr "prefix" "orig,orig,vex")
23044    (set_attr "mode" "<MODE>")
23045    (set (attr "enabled")
23046      (if_then_else
23047        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
23048        (if_then_else
23049          (eq_attr "alternative" "0")
23050          (symbol_ref "TARGET_MIX_SSE_I387
23051                       && X87_ENABLE_ARITH (<MODE>mode)")
23052          (const_string "*"))
23053        (if_then_else
23054          (eq_attr "alternative" "0")
23055          (symbol_ref "true")
23056          (symbol_ref "false"))))])
23058 (define_insn "*<insn>hf"
23059   [(set (match_operand:HF 0 "register_operand" "=v")
23060         (plusminusmultdiv:HF
23061           (match_operand:HF 1 "nonimmediate_operand" "<comm>v")
23062           (match_operand:HF 2 "nonimmediate_operand" "vm")))]
23063   "TARGET_AVX512FP16
23064    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
23065   "v<insn>sh\t{%2, %1, %0|%0, %1, %2}"
23066   [(set_attr "prefix" "evex")
23067    (set_attr "mode" "HF")])
23069 (define_insn "*rcpsf2_sse"
23070   [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
23071         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
23072                    UNSPEC_RCP))]
23073   "TARGET_SSE && TARGET_SSE_MATH"
23074   "@
23075    %vrcpss\t{%d1, %0|%0, %d1}
23076    %vrcpss\t{%d1, %0|%0, %d1}
23077    rcpss\t{%1, %d0|%d0, %1}
23078    vrcpss\t{%1, %d0|%d0, %1}"
23079   [(set_attr "isa" "*,*,noavx,avx")
23080    (set_attr "addr" "*,*,*,gpr16")
23081    (set_attr "type" "sse")
23082    (set_attr "atom_sse_attr" "rcp")
23083    (set_attr "btver2_sse_attr" "rcp")
23084    (set_attr "prefix" "maybe_vex")
23085    (set_attr "mode" "SF")
23086    (set_attr "avx_partial_xmm_update" "false,false,true,true")
23087    (set (attr "preferred_for_speed")
23088       (cond [(match_test "TARGET_AVX")
23089                (symbol_ref "true")
23090              (eq_attr "alternative" "1,2,3")
23091                (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
23092             ]
23093             (symbol_ref "true")))])
23095 (define_insn "rcphf2"
23096   [(set (match_operand:HF 0 "register_operand" "=v,v")
23097         (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
23098                    UNSPEC_RCP))]
23099   "TARGET_AVX512FP16"
23100   "@
23101    vrcpsh\t{%d1, %0|%0, %d1}
23102    vrcpsh\t{%1, %d0|%d0, %1}"
23103   [(set_attr "type" "sse")
23104    (set_attr "prefix" "evex")
23105    (set_attr "mode" "HF")
23106    (set_attr "avx_partial_xmm_update" "false,true")])
23108 (define_insn "*fop_xf_1_i387"
23109   [(set (match_operand:XF 0 "register_operand" "=f,f")
23110         (match_operator:XF 3 "binary_fp_operator"
23111                         [(match_operand:XF 1 "register_operand" "0,f")
23112                          (match_operand:XF 2 "register_operand" "f,0")]))]
23113   "TARGET_80387
23114    && !COMMUTATIVE_ARITH_P (operands[3])"
23115   "* return output_387_binary_op (insn, operands);"
23116   [(set (attr "type")
23117         (if_then_else (match_operand:XF 3 "div_operator")
23118            (const_string "fdiv")
23119            (const_string "fop")))
23120    (set_attr "mode" "XF")])
23122 (define_insn "*fop_<mode>_1"
23123   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
23124         (match_operator:MODEF 3 "binary_fp_operator"
23125           [(match_operand:MODEF 1
23126              "x87nonimm_ssenomem_operand" "0,fm,0,v")
23127            (match_operand:MODEF 2
23128              "nonimmediate_operand"       "fm,0,xm,vm")]))]
23129   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23130     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
23131    && !COMMUTATIVE_ARITH_P (operands[3])
23132    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
23133   "* return output_387_binary_op (insn, operands);"
23134   [(set (attr "type")
23135         (if_then_else (eq_attr "alternative" "2,3")
23136            (if_then_else (match_operand:MODEF 3 "div_operator")
23137               (const_string "ssediv")
23138               (const_string "sseadd"))
23139            (if_then_else (match_operand:MODEF 3 "div_operator")
23140               (const_string "fdiv")
23141               (const_string "fop"))))
23142    (set_attr "isa" "*,*,noavx,avx")
23143    (set_attr "prefix" "orig,orig,orig,vex")
23144    (set_attr "mode" "<MODE>")
23145    (set (attr "enabled")
23146      (if_then_else
23147        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
23148        (if_then_else
23149          (eq_attr "alternative" "0,1")
23150          (symbol_ref "TARGET_MIX_SSE_I387
23151                       && X87_ENABLE_ARITH (<MODE>mode)")
23152          (const_string "*"))
23153        (if_then_else
23154          (eq_attr "alternative" "0,1")
23155          (symbol_ref "true")
23156          (symbol_ref "false"))))])
23158 (define_insn "*fop_<X87MODEF:mode>_2_i387"
23159   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
23160         (match_operator:X87MODEF 3 "binary_fp_operator"
23161           [(float:X87MODEF
23162              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
23163            (match_operand:X87MODEF 2 "register_operand" "0")]))]
23164   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
23165    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
23166    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
23167        || optimize_function_for_size_p (cfun))"
23168   "* return output_387_binary_op (insn, operands);"
23169   [(set (attr "type")
23170         (cond [(match_operand:X87MODEF 3 "mult_operator")
23171                  (const_string "fmul")
23172                (match_operand:X87MODEF 3 "div_operator")
23173                  (const_string "fdiv")
23174               ]
23175               (const_string "fop")))
23176    (set_attr "fp_int_src" "true")
23177    (set_attr "mode" "<SWI24:MODE>")])
23179 (define_insn "*fop_<X87MODEF:mode>_3_i387"
23180   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
23181         (match_operator:X87MODEF 3 "binary_fp_operator"
23182           [(match_operand:X87MODEF 1 "register_operand" "0")
23183            (float:X87MODEF
23184              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
23185   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
23186    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
23187    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
23188        || optimize_function_for_size_p (cfun))"
23189   "* return output_387_binary_op (insn, operands);"
23190   [(set (attr "type")
23191         (cond [(match_operand:X87MODEF 3 "mult_operator")
23192                  (const_string "fmul")
23193                (match_operand:X87MODEF 3 "div_operator")
23194                  (const_string "fdiv")
23195               ]
23196               (const_string "fop")))
23197    (set_attr "fp_int_src" "true")
23198    (set_attr "mode" "<SWI24:MODE>")])
23200 (define_insn "*fop_xf_4_i387"
23201   [(set (match_operand:XF 0 "register_operand" "=f,f")
23202         (match_operator:XF 3 "binary_fp_operator"
23203            [(float_extend:XF
23204               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
23205             (match_operand:XF 2 "register_operand" "0,f")]))]
23206   "TARGET_80387"
23207   "* return output_387_binary_op (insn, operands);"
23208   [(set (attr "type")
23209         (cond [(match_operand:XF 3 "mult_operator")
23210                  (const_string "fmul")
23211                (match_operand:XF 3 "div_operator")
23212                  (const_string "fdiv")
23213               ]
23214               (const_string "fop")))
23215    (set_attr "mode" "<MODE>")])
23217 (define_insn "*fop_df_4_i387"
23218   [(set (match_operand:DF 0 "register_operand" "=f,f")
23219         (match_operator:DF 3 "binary_fp_operator"
23220            [(float_extend:DF
23221              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
23222             (match_operand:DF 2 "register_operand" "0,f")]))]
23223   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
23224    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
23225   "* return output_387_binary_op (insn, operands);"
23226   [(set (attr "type")
23227         (cond [(match_operand:DF 3 "mult_operator")
23228                  (const_string "fmul")
23229                (match_operand:DF 3 "div_operator")
23230                  (const_string "fdiv")
23231               ]
23232               (const_string "fop")))
23233    (set_attr "mode" "SF")])
23235 (define_insn "*fop_xf_5_i387"
23236   [(set (match_operand:XF 0 "register_operand" "=f,f")
23237         (match_operator:XF 3 "binary_fp_operator"
23238           [(match_operand:XF 1 "register_operand" "0,f")
23239            (float_extend:XF
23240              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
23241   "TARGET_80387"
23242   "* return output_387_binary_op (insn, operands);"
23243   [(set (attr "type")
23244         (cond [(match_operand:XF 3 "mult_operator")
23245                  (const_string "fmul")
23246                (match_operand:XF 3 "div_operator")
23247                  (const_string "fdiv")
23248               ]
23249               (const_string "fop")))
23250    (set_attr "mode" "<MODE>")])
23252 (define_insn "*fop_df_5_i387"
23253   [(set (match_operand:DF 0 "register_operand" "=f,f")
23254         (match_operator:DF 3 "binary_fp_operator"
23255           [(match_operand:DF 1 "register_operand" "0,f")
23256            (float_extend:DF
23257             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
23258   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
23259    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
23260   "* return output_387_binary_op (insn, operands);"
23261   [(set (attr "type")
23262         (cond [(match_operand:DF 3 "mult_operator")
23263                  (const_string "fmul")
23264                (match_operand:DF 3 "div_operator")
23265                  (const_string "fdiv")
23266               ]
23267               (const_string "fop")))
23268    (set_attr "mode" "SF")])
23270 (define_insn "*fop_xf_6_i387"
23271   [(set (match_operand:XF 0 "register_operand" "=f,f")
23272         (match_operator:XF 3 "binary_fp_operator"
23273           [(float_extend:XF
23274              (match_operand:MODEF 1 "register_operand" "0,f"))
23275            (float_extend:XF
23276              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
23277   "TARGET_80387"
23278   "* return output_387_binary_op (insn, operands);"
23279   [(set (attr "type")
23280         (cond [(match_operand:XF 3 "mult_operator")
23281                  (const_string "fmul")
23282                (match_operand:XF 3 "div_operator")
23283                  (const_string "fdiv")
23284               ]
23285               (const_string "fop")))
23286    (set_attr "mode" "<MODE>")])
23288 (define_insn "*fop_df_6_i387"
23289   [(set (match_operand:DF 0 "register_operand" "=f,f")
23290         (match_operator:DF 3 "binary_fp_operator"
23291           [(float_extend:DF
23292             (match_operand:SF 1 "register_operand" "0,f"))
23293            (float_extend:DF
23294             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
23295   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
23296    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
23297   "* return output_387_binary_op (insn, operands);"
23298   [(set (attr "type")
23299         (cond [(match_operand:DF 3 "mult_operator")
23300                  (const_string "fmul")
23301                (match_operand:DF 3 "div_operator")
23302                  (const_string "fdiv")
23303               ]
23304               (const_string "fop")))
23305    (set_attr "mode" "SF")])
23307 ;; FPU special functions.
23309 ;; This pattern implements a no-op XFmode truncation for
23310 ;; all fancy i386 XFmode math functions.
23312 (define_insn "truncxf<mode>2_i387_noop_unspec"
23313   [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
23314         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
23315         UNSPEC_TRUNC_NOOP))]
23316   "TARGET_USE_FANCY_MATH_387"
23317   "* return output_387_reg_move (insn, operands);"
23318   [(set_attr "type" "fmov")
23319    (set_attr "mode" "<MODE>")])
23321 (define_insn "sqrtxf2"
23322   [(set (match_operand:XF 0 "register_operand" "=f")
23323         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
23324   "TARGET_USE_FANCY_MATH_387"
23325   "fsqrt"
23326   [(set_attr "type" "fpspc")
23327    (set_attr "mode" "XF")
23328    (set_attr "athlon_decode" "direct")
23329    (set_attr "amdfam10_decode" "direct")
23330    (set_attr "bdver1_decode" "direct")])
23332 (define_insn "*rsqrtsf2_sse"
23333   [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
23334         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
23335                    UNSPEC_RSQRT))]
23336   "TARGET_SSE && TARGET_SSE_MATH"
23337   "@
23338    %vrsqrtss\t{%d1, %0|%0, %d1}
23339    %vrsqrtss\t{%d1, %0|%0, %d1}
23340    rsqrtss\t{%1, %d0|%d0, %1}
23341    vrsqrtss\t{%1, %d0|%d0, %1}"
23342   [(set_attr "isa" "*,*,noavx,avx")
23343    (set_attr "addr" "*,*,*,gpr16")
23344    (set_attr "type" "sse")
23345    (set_attr "atom_sse_attr" "rcp")
23346    (set_attr "btver2_sse_attr" "rcp")
23347    (set_attr "prefix" "maybe_vex")
23348    (set_attr "mode" "SF")
23349    (set_attr "avx_partial_xmm_update" "false,false,true,true")
23350    (set (attr "preferred_for_speed")
23351       (cond [(match_test "TARGET_AVX")
23352                (symbol_ref "true")
23353              (eq_attr "alternative" "1,2,3")
23354                (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
23355             ]
23356             (symbol_ref "true")))])
23358 (define_expand "rsqrtsf2"
23359   [(set (match_operand:SF 0 "register_operand")
23360         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
23361                    UNSPEC_RSQRT))]
23362   "TARGET_SSE && TARGET_SSE_MATH"
23364   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
23365   DONE;
23368 (define_insn "rsqrthf2"
23369   [(set (match_operand:HF 0 "register_operand" "=v,v")
23370         (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
23371                    UNSPEC_RSQRT))]
23372   "TARGET_AVX512FP16"
23373   "@
23374    vrsqrtsh\t{%d1, %0|%0, %d1}
23375    vrsqrtsh\t{%1, %d0|%d0, %1}"
23376   [(set_attr "type" "sse")
23377    (set_attr "prefix" "evex")
23378    (set_attr "avx_partial_xmm_update" "false,true")
23379    (set_attr "mode" "HF")])
23381 (define_insn "sqrthf2"
23382   [(set (match_operand:HF 0 "register_operand" "=v,v")
23383         (sqrt:HF
23384           (match_operand:HF 1 "nonimmediate_operand" "v,m")))]
23385   "TARGET_AVX512FP16"
23386   "@
23387    vsqrtsh\t{%d1, %0|%0, %d1}
23388    vsqrtsh\t{%1, %d0|%d0, %1}"
23389   [(set_attr "type" "sse")
23390    (set_attr "prefix" "evex")
23391    (set_attr "avx_partial_xmm_update" "false,true")
23392    (set_attr "mode" "HF")])
23394 (define_insn "*sqrt<mode>2_sse"
23395   [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
23396         (sqrt:MODEF
23397           (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
23398   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23399   "@
23400    %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
23401    %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
23402    %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
23403   [(set_attr "type" "sse")
23404    (set_attr "atom_sse_attr" "sqrt")
23405    (set_attr "btver2_sse_attr" "sqrt")
23406    (set_attr "prefix" "maybe_vex")
23407    (set_attr "avx_partial_xmm_update" "false,false,true")
23408    (set_attr "mode" "<MODE>")
23409    (set (attr "preferred_for_speed")
23410       (cond [(match_test "TARGET_AVX")
23411                (symbol_ref "true")
23412              (eq_attr "alternative" "1,2")
23413                (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
23414             ]
23415             (symbol_ref "true")))])
23417 (define_expand "sqrt<mode>2"
23418   [(set (match_operand:MODEF 0 "register_operand")
23419         (sqrt:MODEF
23420           (match_operand:MODEF 1 "nonimmediate_operand")))]
23421   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
23422    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
23424   if (<MODE>mode == SFmode
23425       && TARGET_SSE && TARGET_SSE_MATH
23426       && TARGET_RECIP_SQRT
23427       && !optimize_function_for_size_p (cfun)
23428       && flag_finite_math_only && !flag_trapping_math
23429       && flag_unsafe_math_optimizations)
23430     {
23431       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
23432       DONE;
23433     }
23435   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
23436     {
23437       rtx op0 = gen_reg_rtx (XFmode);
23438       rtx op1 = gen_reg_rtx (XFmode);
23440       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23441       emit_insn (gen_sqrtxf2 (op0, op1));
23442       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
23443       DONE;
23444    }
23447 (define_expand "hypot<mode>3"
23448   [(use (match_operand:MODEF 0 "register_operand"))
23449    (use (match_operand:MODEF 1 "general_operand"))
23450    (use (match_operand:MODEF 2 "general_operand"))]
23451   "TARGET_USE_FANCY_MATH_387
23452    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23453        || TARGET_MIX_SSE_I387)
23454    && flag_finite_math_only
23455    && flag_unsafe_math_optimizations"
23457   rtx op0 = gen_reg_rtx (XFmode);
23458   rtx op1 = gen_reg_rtx (XFmode);
23459   rtx op2 = gen_reg_rtx (XFmode);
23461   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
23462   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23464   emit_insn (gen_mulxf3 (op1, op1, op1));
23465   emit_insn (gen_mulxf3 (op2, op2, op2));
23466   emit_insn (gen_addxf3 (op0, op2, op1));
23467   emit_insn (gen_sqrtxf2 (op0, op0));
23469   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23470   DONE;
23473 (define_insn "x86_fnstsw_1"
23474   [(set (match_operand:HI 0 "register_operand" "=a")
23475         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
23476   "TARGET_80387"
23477   "fnstsw\t%0"
23478   [(set_attr "length" "2")
23479    (set_attr "mode" "SI")
23480    (set_attr "unit" "i387")])
23482 (define_insn "fpremxf4_i387"
23483   [(set (match_operand:XF 0 "register_operand" "=f")
23484         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
23485                     (match_operand:XF 3 "register_operand" "1")]
23486                    UNSPEC_FPREM_F))
23487    (set (match_operand:XF 1 "register_operand" "=f")
23488         (unspec:XF [(match_dup 2) (match_dup 3)]
23489                    UNSPEC_FPREM_U))
23490    (set (reg:CCFP FPSR_REG)
23491         (unspec:CCFP [(match_dup 2) (match_dup 3)]
23492                      UNSPEC_C2_FLAG))]
23493   "TARGET_USE_FANCY_MATH_387"
23494   "fprem"
23495   [(set_attr "type" "fpspc")
23496    (set_attr "znver1_decode" "vector")
23497    (set_attr "mode" "XF")])
23499 (define_expand "fmodxf3"
23500   [(use (match_operand:XF 0 "register_operand"))
23501    (use (match_operand:XF 1 "general_operand"))
23502    (use (match_operand:XF 2 "general_operand"))]
23503   "TARGET_USE_FANCY_MATH_387"
23505   rtx_code_label *label = gen_label_rtx ();
23507   rtx op1 = gen_reg_rtx (XFmode);
23508   rtx op2 = gen_reg_rtx (XFmode);
23510   emit_move_insn (op2, operands[2]);
23511   emit_move_insn (op1, operands[1]);
23513   emit_label (label);
23514   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
23515   ix86_emit_fp_unordered_jump (label);
23516   LABEL_NUSES (label) = 1;
23518   emit_move_insn (operands[0], op1);
23519   DONE;
23522 (define_expand "fmod<mode>3"
23523   [(use (match_operand:MODEF 0 "register_operand"))
23524    (use (match_operand:MODEF 1 "general_operand"))
23525    (use (match_operand:MODEF 2 "general_operand"))]
23526   "TARGET_USE_FANCY_MATH_387"
23528   rtx (*gen_truncxf) (rtx, rtx);
23530   rtx_code_label *label = gen_label_rtx ();
23532   rtx op1 = gen_reg_rtx (XFmode);
23533   rtx op2 = gen_reg_rtx (XFmode);
23535   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
23536   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23538   emit_label (label);
23539   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
23540   ix86_emit_fp_unordered_jump (label);
23541   LABEL_NUSES (label) = 1;
23543   /* Truncate the result properly for strict SSE math.  */
23544   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23545       && !TARGET_MIX_SSE_I387)
23546     gen_truncxf = gen_truncxf<mode>2;
23547   else
23548     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
23550   emit_insn (gen_truncxf (operands[0], op1));
23551   DONE;
23554 (define_insn "fprem1xf4_i387"
23555   [(set (match_operand:XF 0 "register_operand" "=f")
23556         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
23557                     (match_operand:XF 3 "register_operand" "1")]
23558                    UNSPEC_FPREM1_F))
23559    (set (match_operand:XF 1 "register_operand" "=f")
23560         (unspec:XF [(match_dup 2) (match_dup 3)]
23561                    UNSPEC_FPREM1_U))
23562    (set (reg:CCFP FPSR_REG)
23563         (unspec:CCFP [(match_dup 2) (match_dup 3)]
23564                      UNSPEC_C2_FLAG))]
23565   "TARGET_USE_FANCY_MATH_387"
23566   "fprem1"
23567   [(set_attr "type" "fpspc")
23568    (set_attr "znver1_decode" "vector")
23569    (set_attr "mode" "XF")])
23571 (define_expand "remainderxf3"
23572   [(use (match_operand:XF 0 "register_operand"))
23573    (use (match_operand:XF 1 "general_operand"))
23574    (use (match_operand:XF 2 "general_operand"))]
23575   "TARGET_USE_FANCY_MATH_387"
23577   rtx_code_label *label = gen_label_rtx ();
23579   rtx op1 = gen_reg_rtx (XFmode);
23580   rtx op2 = gen_reg_rtx (XFmode);
23582   emit_move_insn (op2, operands[2]);
23583   emit_move_insn (op1, operands[1]);
23585   emit_label (label);
23586   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
23587   ix86_emit_fp_unordered_jump (label);
23588   LABEL_NUSES (label) = 1;
23590   emit_move_insn (operands[0], op1);
23591   DONE;
23594 (define_expand "remainder<mode>3"
23595   [(use (match_operand:MODEF 0 "register_operand"))
23596    (use (match_operand:MODEF 1 "general_operand"))
23597    (use (match_operand:MODEF 2 "general_operand"))]
23598   "TARGET_USE_FANCY_MATH_387"
23600   rtx (*gen_truncxf) (rtx, rtx);
23602   rtx_code_label *label = gen_label_rtx ();
23604   rtx op1 = gen_reg_rtx (XFmode);
23605   rtx op2 = gen_reg_rtx (XFmode);
23607   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
23608   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23610   emit_label (label);
23612   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
23613   ix86_emit_fp_unordered_jump (label);
23614   LABEL_NUSES (label) = 1;
23616   /* Truncate the result properly for strict SSE math.  */
23617   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23618       && !TARGET_MIX_SSE_I387)
23619     gen_truncxf = gen_truncxf<mode>2;
23620   else
23621     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
23623   emit_insn (gen_truncxf (operands[0], op1));
23624   DONE;
23627 (define_int_iterator SINCOS
23628         [UNSPEC_SIN
23629          UNSPEC_COS])
23631 (define_int_attr sincos
23632         [(UNSPEC_SIN "sin")
23633          (UNSPEC_COS "cos")])
23635 (define_insn "<sincos>xf2"
23636   [(set (match_operand:XF 0 "register_operand" "=f")
23637         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
23638                    SINCOS))]
23639   "TARGET_USE_FANCY_MATH_387
23640    && flag_unsafe_math_optimizations"
23641   "f<sincos>"
23642   [(set_attr "type" "fpspc")
23643    (set_attr "znver1_decode" "vector")
23644    (set_attr "mode" "XF")])
23646 (define_expand "<sincos><mode>2"
23647   [(set (match_operand:MODEF 0 "register_operand")
23648         (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
23649                       SINCOS))]
23650   "TARGET_USE_FANCY_MATH_387
23651    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23652        || TARGET_MIX_SSE_I387)
23653    && flag_unsafe_math_optimizations"
23655   rtx op0 = gen_reg_rtx (XFmode);
23656   rtx op1 = gen_reg_rtx (XFmode);
23658   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23659   emit_insn (gen_<sincos>xf2 (op0, op1));
23660   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23661   DONE;
23664 (define_insn "sincosxf3"
23665   [(set (match_operand:XF 0 "register_operand" "=f")
23666         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
23667                    UNSPEC_SINCOS_COS))
23668    (set (match_operand:XF 1 "register_operand" "=f")
23669         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
23670   "TARGET_USE_FANCY_MATH_387
23671    && flag_unsafe_math_optimizations"
23672   "fsincos"
23673   [(set_attr "type" "fpspc")
23674    (set_attr "znver1_decode" "vector")
23675    (set_attr "mode" "XF")])
23677 (define_expand "sincos<mode>3"
23678   [(use (match_operand:MODEF 0 "register_operand"))
23679    (use (match_operand:MODEF 1 "register_operand"))
23680    (use (match_operand:MODEF 2 "general_operand"))]
23681   "TARGET_USE_FANCY_MATH_387
23682    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23683        || TARGET_MIX_SSE_I387)
23684    && flag_unsafe_math_optimizations"
23686   rtx op0 = gen_reg_rtx (XFmode);
23687   rtx op1 = gen_reg_rtx (XFmode);
23688   rtx op2 = gen_reg_rtx (XFmode);
23690   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
23691   emit_insn (gen_sincosxf3 (op0, op1, op2));
23692   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23693   emit_insn (gen_truncxf<mode>2 (operands[1], op1));
23694   DONE;
23697 (define_insn "fptanxf4_i387"
23698   [(set (match_operand:SF 0 "register_operand" "=f")
23699         (match_operand:SF 3 "const1_operand"))
23700    (set (match_operand:XF 1 "register_operand" "=f")
23701         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
23702                    UNSPEC_TAN))]
23703   "TARGET_USE_FANCY_MATH_387
23704    && flag_unsafe_math_optimizations"
23705   "fptan"
23706   [(set_attr "type" "fpspc")
23707    (set_attr "znver1_decode" "vector")
23708    (set_attr "mode" "XF")])
23710 (define_expand "tanxf2"
23711   [(use (match_operand:XF 0 "register_operand"))
23712    (use (match_operand:XF 1 "register_operand"))]
23713   "TARGET_USE_FANCY_MATH_387
23714    && flag_unsafe_math_optimizations"
23716   rtx one = gen_reg_rtx (SFmode);
23717   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
23718                                 CONST1_RTX (SFmode)));
23719   DONE;
23722 (define_expand "tan<mode>2"
23723   [(use (match_operand:MODEF 0 "register_operand"))
23724    (use (match_operand:MODEF 1 "general_operand"))]
23725   "TARGET_USE_FANCY_MATH_387
23726    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23727        || TARGET_MIX_SSE_I387)
23728    && flag_unsafe_math_optimizations"
23730   rtx op0 = gen_reg_rtx (XFmode);
23731   rtx op1 = gen_reg_rtx (XFmode);
23733   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23734   emit_insn (gen_tanxf2 (op0, op1));
23735   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23736   DONE;
23739 (define_insn "atan2xf3"
23740   [(set (match_operand:XF 0 "register_operand" "=f")
23741         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
23742                     (match_operand:XF 1 "register_operand" "f")]
23743                    UNSPEC_FPATAN))
23744    (clobber (match_scratch:XF 3 "=1"))]
23745   "TARGET_USE_FANCY_MATH_387
23746    && flag_unsafe_math_optimizations"
23747   "fpatan"
23748   [(set_attr "type" "fpspc")
23749    (set_attr "znver1_decode" "vector")
23750    (set_attr "mode" "XF")])
23752 (define_expand "atan2<mode>3"
23753   [(use (match_operand:MODEF 0 "register_operand"))
23754    (use (match_operand:MODEF 1 "general_operand"))
23755    (use (match_operand:MODEF 2 "general_operand"))]
23756   "TARGET_USE_FANCY_MATH_387
23757    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23758        || TARGET_MIX_SSE_I387)
23759    && flag_unsafe_math_optimizations"
23761   rtx op0 = gen_reg_rtx (XFmode);
23762   rtx op1 = gen_reg_rtx (XFmode);
23763   rtx op2 = gen_reg_rtx (XFmode);
23765   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
23766   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23768   emit_insn (gen_atan2xf3 (op0, op1, op2));
23769   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23770   DONE;
23773 (define_expand "atanxf2"
23774   [(parallel [(set (match_operand:XF 0 "register_operand")
23775                    (unspec:XF [(match_dup 2)
23776                                (match_operand:XF 1 "register_operand")]
23777                               UNSPEC_FPATAN))
23778               (clobber (scratch:XF))])]
23779   "TARGET_USE_FANCY_MATH_387
23780    && flag_unsafe_math_optimizations"
23781   "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
23783 (define_expand "atan<mode>2"
23784   [(use (match_operand:MODEF 0 "register_operand"))
23785    (use (match_operand:MODEF 1 "general_operand"))]
23786   "TARGET_USE_FANCY_MATH_387
23787    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23788        || TARGET_MIX_SSE_I387)
23789    && flag_unsafe_math_optimizations"
23791   rtx op0 = gen_reg_rtx (XFmode);
23792   rtx op1 = gen_reg_rtx (XFmode);
23794   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23795   emit_insn (gen_atanxf2 (op0, op1));
23796   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23797   DONE;
23800 (define_expand "asinxf2"
23801   [(set (match_dup 2)
23802         (mult:XF (match_operand:XF 1 "register_operand")
23803                  (match_dup 1)))
23804    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
23805    (set (match_dup 5) (sqrt:XF (match_dup 4)))
23806    (parallel [(set (match_operand:XF 0 "register_operand")
23807                    (unspec:XF [(match_dup 5) (match_dup 1)]
23808                               UNSPEC_FPATAN))
23809               (clobber (scratch:XF))])]
23810   "TARGET_USE_FANCY_MATH_387
23811    && flag_unsafe_math_optimizations"
23813   int i;
23815   for (i = 2; i < 6; i++)
23816     operands[i] = gen_reg_rtx (XFmode);
23818   emit_move_insn (operands[3], CONST1_RTX (XFmode));
23821 (define_expand "asin<mode>2"
23822   [(use (match_operand:MODEF 0 "register_operand"))
23823    (use (match_operand:MODEF 1 "general_operand"))]
23824   "TARGET_USE_FANCY_MATH_387
23825    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23826        || TARGET_MIX_SSE_I387)
23827    && flag_unsafe_math_optimizations"
23829   rtx op0 = gen_reg_rtx (XFmode);
23830   rtx op1 = gen_reg_rtx (XFmode);
23832   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23833   emit_insn (gen_asinxf2 (op0, op1));
23834   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23835   DONE;
23838 (define_expand "acosxf2"
23839   [(set (match_dup 2)
23840         (mult:XF (match_operand:XF 1 "register_operand")
23841                  (match_dup 1)))
23842    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
23843    (set (match_dup 5) (sqrt:XF (match_dup 4)))
23844    (parallel [(set (match_operand:XF 0 "register_operand")
23845                    (unspec:XF [(match_dup 1) (match_dup 5)]
23846                               UNSPEC_FPATAN))
23847               (clobber (scratch:XF))])]
23848   "TARGET_USE_FANCY_MATH_387
23849    && flag_unsafe_math_optimizations"
23851   int i;
23853   for (i = 2; i < 6; i++)
23854     operands[i] = gen_reg_rtx (XFmode);
23856   emit_move_insn (operands[3], CONST1_RTX (XFmode));
23859 (define_expand "acos<mode>2"
23860   [(use (match_operand:MODEF 0 "register_operand"))
23861    (use (match_operand:MODEF 1 "general_operand"))]
23862   "TARGET_USE_FANCY_MATH_387
23863    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23864        || TARGET_MIX_SSE_I387)
23865    && flag_unsafe_math_optimizations"
23867   rtx op0 = gen_reg_rtx (XFmode);
23868   rtx op1 = gen_reg_rtx (XFmode);
23870   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23871   emit_insn (gen_acosxf2 (op0, op1));
23872   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23873   DONE;
23876 (define_expand "sinhxf2"
23877   [(use (match_operand:XF 0 "register_operand"))
23878    (use (match_operand:XF 1 "register_operand"))]
23879   "TARGET_USE_FANCY_MATH_387
23880    && flag_finite_math_only
23881    && flag_unsafe_math_optimizations"
23883   ix86_emit_i387_sinh (operands[0], operands[1]);
23884   DONE;
23887 (define_expand "sinh<mode>2"
23888   [(use (match_operand:MODEF 0 "register_operand"))
23889    (use (match_operand:MODEF 1 "general_operand"))]
23890   "TARGET_USE_FANCY_MATH_387
23891    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23892        || TARGET_MIX_SSE_I387)
23893    && flag_finite_math_only
23894    && flag_unsafe_math_optimizations"
23896   rtx op0 = gen_reg_rtx (XFmode);
23897   rtx op1 = gen_reg_rtx (XFmode);
23899   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23900   emit_insn (gen_sinhxf2 (op0, op1));
23901   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23902   DONE;
23905 (define_expand "coshxf2"
23906   [(use (match_operand:XF 0 "register_operand"))
23907    (use (match_operand:XF 1 "register_operand"))]
23908   "TARGET_USE_FANCY_MATH_387
23909    && flag_unsafe_math_optimizations"
23911   ix86_emit_i387_cosh (operands[0], operands[1]);
23912   DONE;
23915 (define_expand "cosh<mode>2"
23916   [(use (match_operand:MODEF 0 "register_operand"))
23917    (use (match_operand:MODEF 1 "general_operand"))]
23918   "TARGET_USE_FANCY_MATH_387
23919    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23920        || TARGET_MIX_SSE_I387)
23921    && flag_unsafe_math_optimizations"
23923   rtx op0 = gen_reg_rtx (XFmode);
23924   rtx op1 = gen_reg_rtx (XFmode);
23926   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23927   emit_insn (gen_coshxf2 (op0, op1));
23928   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23929   DONE;
23932 (define_expand "tanhxf2"
23933   [(use (match_operand:XF 0 "register_operand"))
23934    (use (match_operand:XF 1 "register_operand"))]
23935   "TARGET_USE_FANCY_MATH_387
23936    && flag_unsafe_math_optimizations"
23938   ix86_emit_i387_tanh (operands[0], operands[1]);
23939   DONE;
23942 (define_expand "tanh<mode>2"
23943   [(use (match_operand:MODEF 0 "register_operand"))
23944    (use (match_operand:MODEF 1 "general_operand"))]
23945   "TARGET_USE_FANCY_MATH_387
23946    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23947        || TARGET_MIX_SSE_I387)
23948    && flag_unsafe_math_optimizations"
23950   rtx op0 = gen_reg_rtx (XFmode);
23951   rtx op1 = gen_reg_rtx (XFmode);
23953   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23954   emit_insn (gen_tanhxf2 (op0, op1));
23955   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23956   DONE;
23959 (define_expand "asinhxf2"
23960   [(use (match_operand:XF 0 "register_operand"))
23961    (use (match_operand:XF 1 "register_operand"))]
23962   "TARGET_USE_FANCY_MATH_387
23963    && flag_finite_math_only
23964    && flag_unsafe_math_optimizations"
23966   ix86_emit_i387_asinh (operands[0], operands[1]);
23967   DONE;
23970 (define_expand "asinh<mode>2"
23971   [(use (match_operand:MODEF 0 "register_operand"))
23972    (use (match_operand:MODEF 1 "general_operand"))]
23973   "TARGET_USE_FANCY_MATH_387
23974    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23975        || TARGET_MIX_SSE_I387)
23976    && flag_finite_math_only
23977    && flag_unsafe_math_optimizations"
23979   rtx op0 = gen_reg_rtx (XFmode);
23980   rtx op1 = gen_reg_rtx (XFmode);
23982   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23983   emit_insn (gen_asinhxf2 (op0, op1));
23984   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23985   DONE;
23988 (define_expand "acoshxf2"
23989   [(use (match_operand:XF 0 "register_operand"))
23990    (use (match_operand:XF 1 "register_operand"))]
23991   "TARGET_USE_FANCY_MATH_387
23992    && flag_unsafe_math_optimizations"
23994   ix86_emit_i387_acosh (operands[0], operands[1]);
23995   DONE;
23998 (define_expand "acosh<mode>2"
23999   [(use (match_operand:MODEF 0 "register_operand"))
24000    (use (match_operand:MODEF 1 "general_operand"))]
24001   "TARGET_USE_FANCY_MATH_387
24002    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24003        || TARGET_MIX_SSE_I387)
24004    && flag_unsafe_math_optimizations"
24006   rtx op0 = gen_reg_rtx (XFmode);
24007   rtx op1 = gen_reg_rtx (XFmode);
24009   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24010   emit_insn (gen_acoshxf2 (op0, op1));
24011   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24012   DONE;
24015 (define_expand "atanhxf2"
24016   [(use (match_operand:XF 0 "register_operand"))
24017    (use (match_operand:XF 1 "register_operand"))]
24018   "TARGET_USE_FANCY_MATH_387
24019    && flag_unsafe_math_optimizations"
24021   ix86_emit_i387_atanh (operands[0], operands[1]);
24022   DONE;
24025 (define_expand "atanh<mode>2"
24026   [(use (match_operand:MODEF 0 "register_operand"))
24027    (use (match_operand:MODEF 1 "general_operand"))]
24028   "TARGET_USE_FANCY_MATH_387
24029    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24030        || TARGET_MIX_SSE_I387)
24031    && flag_unsafe_math_optimizations"
24033   rtx op0 = gen_reg_rtx (XFmode);
24034   rtx op1 = gen_reg_rtx (XFmode);
24036   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24037   emit_insn (gen_atanhxf2 (op0, op1));
24038   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24039   DONE;
24042 (define_insn "fyl2xxf3_i387"
24043   [(set (match_operand:XF 0 "register_operand" "=f")
24044         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
24045                     (match_operand:XF 2 "register_operand" "f")]
24046                    UNSPEC_FYL2X))
24047    (clobber (match_scratch:XF 3 "=2"))]
24048   "TARGET_USE_FANCY_MATH_387
24049    && flag_unsafe_math_optimizations"
24050   "fyl2x"
24051   [(set_attr "type" "fpspc")
24052    (set_attr "znver1_decode" "vector")
24053    (set_attr "mode" "XF")])
24055 (define_expand "logxf2"
24056   [(parallel [(set (match_operand:XF 0 "register_operand")
24057                    (unspec:XF [(match_operand:XF 1 "register_operand")
24058                                (match_dup 2)] UNSPEC_FYL2X))
24059               (clobber (scratch:XF))])]
24060   "TARGET_USE_FANCY_MATH_387
24061    && flag_unsafe_math_optimizations"
24063   operands[2]
24064     = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
24067 (define_expand "log<mode>2"
24068   [(use (match_operand:MODEF 0 "register_operand"))
24069    (use (match_operand:MODEF 1 "general_operand"))]
24070   "TARGET_USE_FANCY_MATH_387
24071    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24072        || TARGET_MIX_SSE_I387)
24073    && flag_unsafe_math_optimizations"
24075   rtx op0 = gen_reg_rtx (XFmode);
24076   rtx op1 = gen_reg_rtx (XFmode);
24078   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24079   emit_insn (gen_logxf2 (op0, op1));
24080   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24081   DONE;
24084 (define_expand "log10xf2"
24085   [(parallel [(set (match_operand:XF 0 "register_operand")
24086                    (unspec:XF [(match_operand:XF 1 "register_operand")
24087                                (match_dup 2)] UNSPEC_FYL2X))
24088               (clobber (scratch:XF))])]
24089   "TARGET_USE_FANCY_MATH_387
24090    && flag_unsafe_math_optimizations"
24092   operands[2]
24093     = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
24096 (define_expand "log10<mode>2"
24097   [(use (match_operand:MODEF 0 "register_operand"))
24098    (use (match_operand:MODEF 1 "general_operand"))]
24099   "TARGET_USE_FANCY_MATH_387
24100    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24101        || TARGET_MIX_SSE_I387)
24102    && flag_unsafe_math_optimizations"
24104   rtx op0 = gen_reg_rtx (XFmode);
24105   rtx op1 = gen_reg_rtx (XFmode);
24107   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24108   emit_insn (gen_log10xf2 (op0, op1));
24109   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24110   DONE;
24113 (define_expand "log2xf2"
24114   [(parallel [(set (match_operand:XF 0 "register_operand")
24115                    (unspec:XF [(match_operand:XF 1 "register_operand")
24116                                (match_dup 2)] UNSPEC_FYL2X))
24117               (clobber (scratch:XF))])]
24118   "TARGET_USE_FANCY_MATH_387
24119    && flag_unsafe_math_optimizations"
24120   "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
24122 (define_expand "log2<mode>2"
24123   [(use (match_operand:MODEF 0 "register_operand"))
24124    (use (match_operand:MODEF 1 "general_operand"))]
24125   "TARGET_USE_FANCY_MATH_387
24126    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24127        || TARGET_MIX_SSE_I387)
24128    && flag_unsafe_math_optimizations"
24130   rtx op0 = gen_reg_rtx (XFmode);
24131   rtx op1 = gen_reg_rtx (XFmode);
24133   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24134   emit_insn (gen_log2xf2 (op0, op1));
24135   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24136   DONE;
24139 (define_insn "fyl2xp1xf3_i387"
24140   [(set (match_operand:XF 0 "register_operand" "=f")
24141         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
24142                     (match_operand:XF 2 "register_operand" "f")]
24143                    UNSPEC_FYL2XP1))
24144    (clobber (match_scratch:XF 3 "=2"))]
24145   "TARGET_USE_FANCY_MATH_387
24146    && flag_unsafe_math_optimizations"
24147   "fyl2xp1"
24148   [(set_attr "type" "fpspc")
24149    (set_attr "znver1_decode" "vector")
24150    (set_attr "mode" "XF")])
24152 (define_expand "log1pxf2"
24153   [(use (match_operand:XF 0 "register_operand"))
24154    (use (match_operand:XF 1 "register_operand"))]
24155   "TARGET_USE_FANCY_MATH_387
24156    && flag_unsafe_math_optimizations"
24158   ix86_emit_i387_log1p (operands[0], operands[1]);
24159   DONE;
24162 (define_expand "log1p<mode>2"
24163   [(use (match_operand:MODEF 0 "register_operand"))
24164    (use (match_operand:MODEF 1 "general_operand"))]
24165   "TARGET_USE_FANCY_MATH_387
24166    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24167        || TARGET_MIX_SSE_I387)
24168    && flag_unsafe_math_optimizations"
24170   rtx op0 = gen_reg_rtx (XFmode);
24171   rtx op1 = gen_reg_rtx (XFmode);
24173   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24174   emit_insn (gen_log1pxf2 (op0, op1));
24175   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24176   DONE;
24179 (define_insn "fxtractxf3_i387"
24180   [(set (match_operand:XF 0 "register_operand" "=f")
24181         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
24182                    UNSPEC_XTRACT_FRACT))
24183    (set (match_operand:XF 1 "register_operand" "=f")
24184         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
24185   "TARGET_USE_FANCY_MATH_387
24186    && flag_unsafe_math_optimizations"
24187   "fxtract"
24188   [(set_attr "type" "fpspc")
24189    (set_attr "znver1_decode" "vector")
24190    (set_attr "mode" "XF")])
24192 (define_expand "logbxf2"
24193   [(parallel [(set (match_dup 2)
24194                    (unspec:XF [(match_operand:XF 1 "register_operand")]
24195                               UNSPEC_XTRACT_FRACT))
24196               (set (match_operand:XF 0 "register_operand")
24197                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
24198   "TARGET_USE_FANCY_MATH_387
24199    && flag_unsafe_math_optimizations"
24200   "operands[2] = gen_reg_rtx (XFmode);")
24202 (define_expand "logb<mode>2"
24203   [(use (match_operand:MODEF 0 "register_operand"))
24204    (use (match_operand:MODEF 1 "general_operand"))]
24205   "TARGET_USE_FANCY_MATH_387
24206    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24207        || TARGET_MIX_SSE_I387)
24208    && flag_unsafe_math_optimizations"
24210   rtx op0 = gen_reg_rtx (XFmode);
24211   rtx op1 = gen_reg_rtx (XFmode);
24213   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24214   emit_insn (gen_logbxf2 (op0, op1));
24215   emit_insn (gen_truncxf<mode>2 (operands[0], op1));
24216   DONE;
24219 (define_expand "ilogbxf2"
24220   [(use (match_operand:SI 0 "register_operand"))
24221    (use (match_operand:XF 1 "register_operand"))]
24222   "TARGET_USE_FANCY_MATH_387
24223    && flag_unsafe_math_optimizations"
24225   rtx op0, op1;
24227   if (optimize_insn_for_size_p ())
24228     FAIL;
24230   op0 = gen_reg_rtx (XFmode);
24231   op1 = gen_reg_rtx (XFmode);
24233   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
24234   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
24235   DONE;
24238 (define_expand "ilogb<mode>2"
24239   [(use (match_operand:SI 0 "register_operand"))
24240    (use (match_operand:MODEF 1 "general_operand"))]
24241   "TARGET_USE_FANCY_MATH_387
24242    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24243        || TARGET_MIX_SSE_I387)
24244    && flag_unsafe_math_optimizations"
24246   rtx op0, op1, op2;
24248   if (optimize_insn_for_size_p ())
24249     FAIL;
24251   op0 = gen_reg_rtx (XFmode);
24252   op1 = gen_reg_rtx (XFmode);
24253   op2 = gen_reg_rtx (XFmode);
24255   emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
24256   emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
24257   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
24258   DONE;
24261 (define_insn "*f2xm1xf2_i387"
24262   [(set (match_operand:XF 0 "register_operand" "=f")
24263         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
24264                    UNSPEC_F2XM1))]
24265   "TARGET_USE_FANCY_MATH_387
24266    && flag_unsafe_math_optimizations"
24267   "f2xm1"
24268   [(set_attr "type" "fpspc")
24269    (set_attr "znver1_decode" "vector")
24270    (set_attr "mode" "XF")])
24272 (define_insn "fscalexf4_i387"
24273   [(set (match_operand:XF 0 "register_operand" "=f")
24274         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
24275                     (match_operand:XF 3 "register_operand" "1")]
24276                    UNSPEC_FSCALE_FRACT))
24277    (set (match_operand:XF 1 "register_operand" "=f")
24278         (unspec:XF [(match_dup 2) (match_dup 3)]
24279                    UNSPEC_FSCALE_EXP))]
24280   "TARGET_USE_FANCY_MATH_387
24281    && flag_unsafe_math_optimizations"
24282   "fscale"
24283   [(set_attr "type" "fpspc")
24284    (set_attr "znver1_decode" "vector")
24285    (set_attr "mode" "XF")])
24287 (define_expand "expNcorexf3"
24288   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
24289                                (match_operand:XF 2 "register_operand")))
24290    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
24291    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
24292    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
24293    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
24294    (parallel [(set (match_operand:XF 0 "register_operand")
24295                    (unspec:XF [(match_dup 8) (match_dup 4)]
24296                               UNSPEC_FSCALE_FRACT))
24297               (set (match_dup 9)
24298                    (unspec:XF [(match_dup 8) (match_dup 4)]
24299                               UNSPEC_FSCALE_EXP))])]
24300   "TARGET_USE_FANCY_MATH_387
24301    && flag_unsafe_math_optimizations"
24303   int i;
24305   for (i = 3; i < 10; i++)
24306     operands[i] = gen_reg_rtx (XFmode);
24308   emit_move_insn (operands[7], CONST1_RTX (XFmode));
24311 (define_expand "expxf2"
24312   [(use (match_operand:XF 0 "register_operand"))
24313    (use (match_operand:XF 1 "register_operand"))]
24314   "TARGET_USE_FANCY_MATH_387
24315    && flag_unsafe_math_optimizations"
24317   rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
24319   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
24320   DONE;
24323 (define_expand "exp<mode>2"
24324   [(use (match_operand:MODEF 0 "register_operand"))
24325    (use (match_operand:MODEF 1 "general_operand"))]
24326   "TARGET_USE_FANCY_MATH_387
24327    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24328        || TARGET_MIX_SSE_I387)
24329    && flag_unsafe_math_optimizations"
24331   rtx op0 = gen_reg_rtx (XFmode);
24332   rtx op1 = gen_reg_rtx (XFmode);
24334   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24335   emit_insn (gen_expxf2 (op0, op1));
24336   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24337   DONE;
24340 (define_expand "exp10xf2"
24341   [(use (match_operand:XF 0 "register_operand"))
24342    (use (match_operand:XF 1 "register_operand"))]
24343   "TARGET_USE_FANCY_MATH_387
24344    && flag_unsafe_math_optimizations"
24346   rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
24348   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
24349   DONE;
24352 (define_expand "exp10<mode>2"
24353   [(use (match_operand:MODEF 0 "register_operand"))
24354    (use (match_operand:MODEF 1 "general_operand"))]
24355   "TARGET_USE_FANCY_MATH_387
24356    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24357        || TARGET_MIX_SSE_I387)
24358    && flag_unsafe_math_optimizations"
24360   rtx op0 = gen_reg_rtx (XFmode);
24361   rtx op1 = gen_reg_rtx (XFmode);
24363   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24364   emit_insn (gen_exp10xf2 (op0, op1));
24365   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24366   DONE;
24369 (define_expand "exp2xf2"
24370   [(use (match_operand:XF 0 "register_operand"))
24371    (use (match_operand:XF 1 "register_operand"))]
24372   "TARGET_USE_FANCY_MATH_387
24373    && flag_unsafe_math_optimizations"
24375   rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
24377   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
24378   DONE;
24381 (define_expand "exp2<mode>2"
24382   [(use (match_operand:MODEF 0 "register_operand"))
24383    (use (match_operand:MODEF 1 "general_operand"))]
24384   "TARGET_USE_FANCY_MATH_387
24385    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24386        || TARGET_MIX_SSE_I387)
24387    && flag_unsafe_math_optimizations"
24389   rtx op0 = gen_reg_rtx (XFmode);
24390   rtx op1 = gen_reg_rtx (XFmode);
24392   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24393   emit_insn (gen_exp2xf2 (op0, op1));
24394   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24395   DONE;
24398 (define_expand "expm1xf2"
24399   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
24400                                (match_dup 2)))
24401    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
24402    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
24403    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
24404    (parallel [(set (match_dup 7)
24405                    (unspec:XF [(match_dup 6) (match_dup 4)]
24406                               UNSPEC_FSCALE_FRACT))
24407               (set (match_dup 8)
24408                    (unspec:XF [(match_dup 6) (match_dup 4)]
24409                               UNSPEC_FSCALE_EXP))])
24410    (parallel [(set (match_dup 10)
24411                    (unspec:XF [(match_dup 9) (match_dup 8)]
24412                               UNSPEC_FSCALE_FRACT))
24413               (set (match_dup 11)
24414                    (unspec:XF [(match_dup 9) (match_dup 8)]
24415                               UNSPEC_FSCALE_EXP))])
24416    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
24417    (set (match_operand:XF 0 "register_operand")
24418         (plus:XF (match_dup 12) (match_dup 7)))]
24419   "TARGET_USE_FANCY_MATH_387
24420    && flag_unsafe_math_optimizations"
24422   int i;
24424   for (i = 2; i < 13; i++)
24425     operands[i] = gen_reg_rtx (XFmode);
24427   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
24428   emit_move_insn (operands[9], CONST1_RTX (XFmode));
24431 (define_expand "expm1<mode>2"
24432   [(use (match_operand:MODEF 0 "register_operand"))
24433    (use (match_operand:MODEF 1 "general_operand"))]
24434   "TARGET_USE_FANCY_MATH_387
24435    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24436        || TARGET_MIX_SSE_I387)
24437    && flag_unsafe_math_optimizations"
24439   rtx op0 = gen_reg_rtx (XFmode);
24440   rtx op1 = gen_reg_rtx (XFmode);
24442   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24443   emit_insn (gen_expm1xf2 (op0, op1));
24444   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24445   DONE;
24448 (define_insn "avx512f_scalef<mode>2"
24449   [(set (match_operand:MODEF 0 "register_operand" "=v")
24450         (unspec:MODEF
24451           [(match_operand:MODEF 1 "register_operand" "v")
24452            (match_operand:MODEF 2 "nonimmediate_operand" "vm")]
24453           UNSPEC_SCALEF))]
24454   "TARGET_AVX512F"
24455   "vscalef<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
24456   [(set_attr "prefix" "evex")
24457    (set_attr "mode"  "<MODE>")])
24459 (define_expand "ldexpxf3"
24460   [(match_operand:XF 0 "register_operand")
24461    (match_operand:XF 1 "register_operand")
24462    (match_operand:SI 2 "register_operand")]
24463   "TARGET_USE_FANCY_MATH_387
24464    && flag_unsafe_math_optimizations"
24466   rtx tmp1 = gen_reg_rtx (XFmode);
24467   rtx tmp2 = gen_reg_rtx (XFmode);
24469   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
24470   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
24471                                  operands[1], tmp1));
24472   DONE;
24475 (define_expand "ldexp<mode>3"
24476   [(use (match_operand:MODEF 0 "register_operand"))
24477    (use (match_operand:MODEF 1 "general_operand"))
24478    (use (match_operand:SI 2 "register_operand"))]
24479   "((TARGET_USE_FANCY_MATH_387
24480      && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24481          || TARGET_MIX_SSE_I387))
24482     || (TARGET_AVX512F && TARGET_SSE_MATH))
24483    && flag_unsafe_math_optimizations"
24485   /* Prefer avx512f version.  */
24486   if (TARGET_AVX512F && TARGET_SSE_MATH)
24487    {
24488      rtx op2 = gen_reg_rtx (<MODE>mode);
24489      operands[1] = force_reg (<MODE>mode, operands[1]);
24491      emit_insn (gen_floatsi<mode>2 (op2, operands[2]));
24492      emit_insn (gen_avx512f_scalef<mode>2 (operands[0], operands[1], op2));
24493    }
24494   else
24495     {
24496       rtx op0 = gen_reg_rtx (XFmode);
24497       rtx op1 = gen_reg_rtx (XFmode);
24499       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24500       emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
24501       emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24502   }
24503   DONE;
24506 (define_expand "scalbxf3"
24507   [(parallel [(set (match_operand:XF 0 " register_operand")
24508                    (unspec:XF [(match_operand:XF 1 "register_operand")
24509                                (match_operand:XF 2 "register_operand")]
24510                               UNSPEC_FSCALE_FRACT))
24511               (set (match_dup 3)
24512                    (unspec:XF [(match_dup 1) (match_dup 2)]
24513                               UNSPEC_FSCALE_EXP))])]
24514   "TARGET_USE_FANCY_MATH_387
24515    && flag_unsafe_math_optimizations"
24516   "operands[3] = gen_reg_rtx (XFmode);")
24518 (define_expand "scalb<mode>3"
24519   [(use (match_operand:MODEF 0 "register_operand"))
24520    (use (match_operand:MODEF 1 "general_operand"))
24521    (use (match_operand:MODEF 2 "general_operand"))]
24522   "TARGET_USE_FANCY_MATH_387
24523    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24524        || TARGET_MIX_SSE_I387)
24525    && flag_unsafe_math_optimizations"
24527   rtx op0 = gen_reg_rtx (XFmode);
24528   rtx op1 = gen_reg_rtx (XFmode);
24529   rtx op2 = gen_reg_rtx (XFmode);
24531   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24532   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
24533   emit_insn (gen_scalbxf3 (op0, op1, op2));
24534   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24535   DONE;
24538 (define_expand "significandxf2"
24539   [(parallel [(set (match_operand:XF 0 "register_operand")
24540                    (unspec:XF [(match_operand:XF 1 "register_operand")]
24541                               UNSPEC_XTRACT_FRACT))
24542               (set (match_dup 2)
24543                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
24544   "TARGET_USE_FANCY_MATH_387
24545    && flag_unsafe_math_optimizations"
24546   "operands[2] = gen_reg_rtx (XFmode);")
24548 (define_expand "significand<mode>2"
24549   [(use (match_operand:MODEF 0 "register_operand"))
24550    (use (match_operand:MODEF 1 "general_operand"))]
24551   "TARGET_USE_FANCY_MATH_387
24552    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24553        || TARGET_MIX_SSE_I387)
24554    && flag_unsafe_math_optimizations"
24556   rtx op0 = gen_reg_rtx (XFmode);
24557   rtx op1 = gen_reg_rtx (XFmode);
24559   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24560   emit_insn (gen_significandxf2 (op0, op1));
24561   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24562   DONE;
24566 (define_insn "sse4_1_round<mode>2"
24567   [(set (match_operand:MODEFH 0 "register_operand" "=x,x,x,v,v")
24568         (unspec:MODEFH
24569           [(match_operand:MODEFH 1 "nonimmediate_operand" "0,x,jm,v,m")
24570            (match_operand:SI 2 "const_0_to_15_operand")]
24571           UNSPEC_ROUND))]
24572   "TARGET_SSE4_1"
24573   "@
24574    %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
24575    %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
24576    %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
24577    vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
24578    vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
24579   [(set_attr "type" "ssecvt")
24580    (set_attr "prefix_extra" "1,1,1,*,*")
24581    (set_attr "length_immediate" "1")
24582    (set_attr "addr" "*,*,gpr16,*,*")
24583    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
24584    (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
24585    (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
24586    (set_attr "mode" "<MODE>")
24587    (set (attr "preferred_for_speed")
24588       (cond [(match_test "TARGET_AVX")
24589                (symbol_ref "true")
24590              (eq_attr "alternative" "1,2")
24591                (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
24592             ]
24593             (symbol_ref "true")))])
24595 (define_insn "rintxf2"
24596   [(set (match_operand:XF 0 "register_operand" "=f")
24597         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
24598                    UNSPEC_FRNDINT))]
24599   "TARGET_USE_FANCY_MATH_387"
24600   "frndint"
24601   [(set_attr "type" "fpspc")
24602    (set_attr "znver1_decode" "vector")
24603    (set_attr "mode" "XF")])
24605 (define_expand "rinthf2"
24606   [(match_operand:HF 0 "register_operand")
24607    (match_operand:HF 1 "nonimmediate_operand")]
24608   "TARGET_AVX512FP16"
24610   emit_insn (gen_sse4_1_roundhf2 (operands[0],
24611                                   operands[1],
24612                                   GEN_INT (ROUND_MXCSR)));
24613   DONE;
24616 (define_expand "rint<mode>2"
24617   [(use (match_operand:MODEF 0 "register_operand"))
24618    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
24619   "TARGET_USE_FANCY_MATH_387
24620    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
24622   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24623     {
24624       if (TARGET_SSE4_1)
24625         emit_insn (gen_sse4_1_round<mode>2
24626                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
24627       else
24628         ix86_expand_rint (operands[0], operands[1]);
24629     }
24630   else
24631     {
24632       rtx op0 = gen_reg_rtx (XFmode);
24633       rtx op1 = gen_reg_rtx (XFmode);
24635       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24636       emit_insn (gen_rintxf2 (op0, op1));
24637       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
24638     }
24639   DONE;
24642 (define_expand "nearbyintxf2"
24643   [(set (match_operand:XF 0 "register_operand")
24644         (unspec:XF [(match_operand:XF 1 "register_operand")]
24645                    UNSPEC_FRNDINT))]
24646   "TARGET_USE_FANCY_MATH_387
24647    && !flag_trapping_math")
24649 (define_expand "nearbyinthf2"
24650   [(match_operand:HF 0 "register_operand")
24651    (match_operand:HF 1 "nonimmediate_operand")]
24652   "TARGET_AVX512FP16"
24654   emit_insn (gen_sse4_1_roundhf2 (operands[0],
24655                                   operands[1],
24656                                   GEN_INT (ROUND_MXCSR | ROUND_NO_EXC)));
24657   DONE;
24660 (define_expand "nearbyint<mode>2"
24661   [(use (match_operand:MODEF 0 "register_operand"))
24662    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
24663   "(TARGET_USE_FANCY_MATH_387
24664     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24665           || TARGET_MIX_SSE_I387)
24666     && !flag_trapping_math)
24667    || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
24669   if (TARGET_SSE4_1 && TARGET_SSE_MATH)
24670     emit_insn (gen_sse4_1_round<mode>2
24671                (operands[0], operands[1], GEN_INT (ROUND_MXCSR
24672                                                    | ROUND_NO_EXC)));
24673   else
24674     {
24675       rtx op0 = gen_reg_rtx (XFmode);
24676       rtx op1 = gen_reg_rtx (XFmode);
24678       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24679       emit_insn (gen_nearbyintxf2 (op0, op1));
24680       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
24681     }
24682   DONE;
24685 (define_expand "roundhf2"
24686   [(match_operand:HF 0 "register_operand")
24687    (match_operand:HF 1 "register_operand")]
24688   "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
24690   ix86_expand_round_sse4 (operands[0], operands[1]);
24691   DONE;
24694 (define_expand "round<mode>2"
24695   [(match_operand:X87MODEF 0 "register_operand")
24696    (match_operand:X87MODEF 1 "nonimmediate_operand")]
24697   "(TARGET_USE_FANCY_MATH_387
24698     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24699         || TARGET_MIX_SSE_I387)
24700     && flag_unsafe_math_optimizations
24701     && (flag_fp_int_builtin_inexact || !flag_trapping_math))
24702    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
24703        && !flag_trapping_math && !flag_rounding_math)"
24705   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
24706       && !flag_trapping_math && !flag_rounding_math)
24707     {
24708       if (TARGET_SSE4_1)
24709         {
24710           operands[1] = force_reg (<MODE>mode, operands[1]);
24711           ix86_expand_round_sse4 (operands[0], operands[1]);
24712         }
24713       else if (TARGET_64BIT || (<MODE>mode != DFmode))
24714         ix86_expand_round (operands[0], operands[1]);
24715       else
24716         ix86_expand_rounddf_32 (operands[0], operands[1]);
24717     }
24718   else
24719     {
24720       operands[1] = force_reg (<MODE>mode, operands[1]);
24721       ix86_emit_i387_round (operands[0], operands[1]);
24722     }
24723   DONE;
24726 (define_insn "lrintxfdi2"
24727   [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
24728         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
24729                    UNSPEC_FIST))
24730    (clobber (match_scratch:XF 2 "=&f"))]
24731   "TARGET_USE_FANCY_MATH_387"
24732   "* return output_fix_trunc (insn, operands, false);"
24733   [(set_attr "type" "fpspc")
24734    (set_attr "mode" "DI")])
24736 (define_insn "lrintxf<mode>2"
24737   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
24738         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
24739                       UNSPEC_FIST))]
24740   "TARGET_USE_FANCY_MATH_387"
24741   "* return output_fix_trunc (insn, operands, false);"
24742   [(set_attr "type" "fpspc")
24743    (set_attr "mode" "<MODE>")])
24745 (define_expand "lroundhf<mode>2"
24746   [(set (match_operand:SWI248 0 "register_operand")
24747      (unspec:SWI248 [(match_operand:HF 1 "nonimmediate_operand")]
24748                    UNSPEC_FIX_NOTRUNC))]
24749   "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
24751   ix86_expand_lround (operands[0], operands[1]);
24752   DONE;
24755 (define_expand "lrinthf<mode>2"
24756   [(set (match_operand:SWI48 0 "register_operand")
24757      (unspec:SWI48 [(match_operand:HF 1 "nonimmediate_operand")]
24758                    UNSPEC_FIX_NOTRUNC))]
24759   "TARGET_AVX512FP16")
24761 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
24762   [(set (match_operand:SWI48 0 "register_operand")
24763      (unspec:SWI48 [(match_operand:MODEF 1 "nonimmediate_operand")]
24764                    UNSPEC_FIX_NOTRUNC))]
24765   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
24767 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
24768   [(match_operand:SWI248x 0 "nonimmediate_operand")
24769    (match_operand:X87MODEF 1 "register_operand")]
24770   "(TARGET_USE_FANCY_MATH_387
24771     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
24772         || TARGET_MIX_SSE_I387)
24773     && flag_unsafe_math_optimizations)
24774    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
24775        && <SWI248x:MODE>mode != HImode 
24776        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
24777        && !flag_trapping_math && !flag_rounding_math)"
24779   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
24780       && <SWI248x:MODE>mode != HImode
24781       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
24782       && !flag_trapping_math && !flag_rounding_math)
24783     ix86_expand_lround (operands[0], operands[1]);
24784   else
24785     ix86_emit_i387_round (operands[0], operands[1]);
24786   DONE;
24789 (define_int_iterator FRNDINT_ROUNDING
24790         [UNSPEC_FRNDINT_ROUNDEVEN
24791          UNSPEC_FRNDINT_FLOOR
24792          UNSPEC_FRNDINT_CEIL
24793          UNSPEC_FRNDINT_TRUNC])
24795 (define_int_iterator FIST_ROUNDING
24796         [UNSPEC_FIST_FLOOR
24797          UNSPEC_FIST_CEIL])
24799 ;; Base name for define_insn
24800 (define_int_attr rounding_insn
24801         [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
24802          (UNSPEC_FRNDINT_FLOOR "floor")
24803          (UNSPEC_FRNDINT_CEIL "ceil")
24804          (UNSPEC_FRNDINT_TRUNC "btrunc")
24805          (UNSPEC_FIST_FLOOR "floor")
24806          (UNSPEC_FIST_CEIL "ceil")])
24808 (define_int_attr rounding
24809         [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
24810          (UNSPEC_FRNDINT_FLOOR "floor")
24811          (UNSPEC_FRNDINT_CEIL "ceil")
24812          (UNSPEC_FRNDINT_TRUNC "trunc")
24813          (UNSPEC_FIST_FLOOR "floor")
24814          (UNSPEC_FIST_CEIL "ceil")])
24816 (define_int_attr ROUNDING
24817         [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
24818          (UNSPEC_FRNDINT_FLOOR "FLOOR")
24819          (UNSPEC_FRNDINT_CEIL "CEIL")
24820          (UNSPEC_FRNDINT_TRUNC "TRUNC")
24821          (UNSPEC_FIST_FLOOR "FLOOR")
24822          (UNSPEC_FIST_CEIL "CEIL")])
24824 ;; Rounding mode control word calculation could clobber FLAGS_REG.
24825 (define_insn_and_split "frndintxf2_<rounding>"
24826   [(set (match_operand:XF 0 "register_operand")
24827         (unspec:XF [(match_operand:XF 1 "register_operand")]
24828                    FRNDINT_ROUNDING))
24829    (clobber (reg:CC FLAGS_REG))]
24830   "TARGET_USE_FANCY_MATH_387
24831    && (flag_fp_int_builtin_inexact || !flag_trapping_math)
24832    && ix86_pre_reload_split ()"
24833   "#"
24834   "&& 1"
24835   [(const_int 0)]
24837   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
24839   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
24840   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
24842   emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
24843                                              operands[2], operands[3]));
24844   DONE;
24846   [(set_attr "type" "frndint")
24847    (set_attr "i387_cw" "<rounding>")
24848    (set_attr "mode" "XF")])
24850 (define_insn "frndintxf2_<rounding>_i387"
24851   [(set (match_operand:XF 0 "register_operand" "=f")
24852         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
24853                    FRNDINT_ROUNDING))
24854    (use (match_operand:HI 2 "memory_operand" "m"))
24855    (use (match_operand:HI 3 "memory_operand" "m"))]
24856   "TARGET_USE_FANCY_MATH_387
24857    && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
24858   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
24859   [(set_attr "type" "frndint")
24860    (set_attr "i387_cw" "<rounding>")
24861    (set_attr "mode" "XF")])
24863 (define_expand "<rounding_insn>xf2"
24864   [(parallel [(set (match_operand:XF 0 "register_operand")
24865                    (unspec:XF [(match_operand:XF 1 "register_operand")]
24866                               FRNDINT_ROUNDING))
24867               (clobber (reg:CC FLAGS_REG))])]
24868   "TARGET_USE_FANCY_MATH_387
24869    && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
24871 (define_expand "<rounding_insn>hf2"
24872   [(parallel [(set (match_operand:HF 0 "register_operand")
24873                    (unspec:HF [(match_operand:HF 1 "register_operand")]
24874                      FRNDINT_ROUNDING))
24875               (clobber (reg:CC FLAGS_REG))])]
24876   "TARGET_AVX512FP16"
24878   emit_insn (gen_sse4_1_roundhf2 (operands[0], operands[1],
24879                                   GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
24880   DONE;
24883 (define_expand "<rounding_insn><mode>2"
24884   [(parallel [(set (match_operand:MODEF 0 "register_operand")
24885                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
24886                                  FRNDINT_ROUNDING))
24887               (clobber (reg:CC FLAGS_REG))])]
24888   "(TARGET_USE_FANCY_MATH_387
24889     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24890         || TARGET_MIX_SSE_I387)
24891     && (flag_fp_int_builtin_inexact || !flag_trapping_math))
24892    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
24893        && (TARGET_SSE4_1
24894            || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
24895                && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
24897   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
24898       && (TARGET_SSE4_1
24899           || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
24900               && (flag_fp_int_builtin_inexact || !flag_trapping_math))))
24901     {
24902       if (TARGET_SSE4_1)
24903         emit_insn (gen_sse4_1_round<mode>2
24904                    (operands[0], operands[1],
24905                     GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
24906       else if (TARGET_64BIT || (<MODE>mode != DFmode))
24907         {
24908           if (ROUND_<ROUNDING> == ROUND_FLOOR)
24909             ix86_expand_floorceil (operands[0], operands[1], true);
24910           else if (ROUND_<ROUNDING> == ROUND_CEIL)
24911             ix86_expand_floorceil (operands[0], operands[1], false);
24912           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
24913             ix86_expand_trunc (operands[0], operands[1]);
24914           else
24915             gcc_unreachable ();
24916         }
24917       else
24918         {
24919           if (ROUND_<ROUNDING> == ROUND_FLOOR)
24920             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
24921           else if (ROUND_<ROUNDING> == ROUND_CEIL)
24922             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
24923           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
24924             ix86_expand_truncdf_32 (operands[0], operands[1]);
24925           else
24926             gcc_unreachable ();
24927         }
24928     }
24929   else
24930     {
24931       rtx op0 = gen_reg_rtx (XFmode);
24932       rtx op1 = gen_reg_rtx (XFmode);
24934       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24935       emit_insn (gen_frndintxf2_<rounding> (op0, op1));
24936       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
24937     }
24938   DONE;
24941 ;; Rounding mode control word calculation could clobber FLAGS_REG.
24942 (define_insn_and_split "*fist<mode>2_<rounding>_1"
24943   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
24944         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
24945                         FIST_ROUNDING))
24946    (clobber (reg:CC FLAGS_REG))]
24947   "TARGET_USE_FANCY_MATH_387
24948    && flag_unsafe_math_optimizations
24949    && ix86_pre_reload_split ()"
24950   "#"
24951   "&& 1"
24952   [(const_int 0)]
24954   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
24956   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
24957   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
24959   emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
24960                                          operands[2], operands[3]));
24961   DONE;
24963   [(set_attr "type" "fistp")
24964    (set_attr "i387_cw" "<rounding>")
24965    (set_attr "mode" "<MODE>")])
24967 (define_insn "fistdi2_<rounding>"
24968   [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
24969         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
24970                    FIST_ROUNDING))
24971    (use (match_operand:HI 2 "memory_operand" "m"))
24972    (use (match_operand:HI 3 "memory_operand" "m"))
24973    (clobber (match_scratch:XF 4 "=&f"))]
24974   "TARGET_USE_FANCY_MATH_387
24975    && flag_unsafe_math_optimizations"
24976   "* return output_fix_trunc (insn, operands, false);"
24977   [(set_attr "type" "fistp")
24978    (set_attr "i387_cw" "<rounding>")
24979    (set_attr "mode" "DI")])
24981 (define_insn "fist<mode>2_<rounding>"
24982   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
24983         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
24984                       FIST_ROUNDING))
24985    (use (match_operand:HI 2 "memory_operand" "m"))
24986    (use (match_operand:HI 3 "memory_operand" "m"))]
24987   "TARGET_USE_FANCY_MATH_387
24988    && flag_unsafe_math_optimizations"
24989   "* return output_fix_trunc (insn, operands, false);"
24990   [(set_attr "type" "fistp")
24991    (set_attr "i387_cw" "<rounding>")
24992    (set_attr "mode" "<MODE>")])
24994 (define_expand "l<rounding_insn>xf<mode>2"
24995   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
24996                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
24997                                    FIST_ROUNDING))
24998               (clobber (reg:CC FLAGS_REG))])]
24999   "TARGET_USE_FANCY_MATH_387
25000    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
25001    && flag_unsafe_math_optimizations")
25003 (define_expand "l<rounding_insn>hf<mode>2"
25004   [(set (match_operand:SWI48 0 "nonimmediate_operand")
25005         (unspec:SWI48 [(match_operand:HF 1 "register_operand")]
25006                     FIST_ROUNDING))]
25007   "TARGET_AVX512FP16"
25009   rtx tmp = gen_reg_rtx (HFmode);
25010   emit_insn (gen_sse4_1_roundhf2 (tmp, operands[1],
25011                                  GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
25012   emit_insn (gen_fix_trunchf<mode>2 (operands[0], tmp));
25013   DONE;
25016 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
25017   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
25018                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
25019                                  FIST_ROUNDING))
25020               (clobber (reg:CC FLAGS_REG))])]
25021   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
25022    && (TARGET_SSE4_1 || !flag_trapping_math)"
25024   if (TARGET_SSE4_1)
25025     {
25026       rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
25028       emit_insn (gen_sse4_1_round<MODEF:mode>2
25029                  (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
25030                                              | ROUND_NO_EXC)));
25031       emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
25032                  (operands[0], tmp));
25033     }
25034   else if (ROUND_<ROUNDING> == ROUND_FLOOR)
25035     ix86_expand_lfloorceil (operands[0], operands[1], true);
25036   else if (ROUND_<ROUNDING> == ROUND_CEIL)
25037     ix86_expand_lfloorceil (operands[0], operands[1], false);
25038   else
25039     gcc_unreachable ();
25041   DONE;
25044 (define_insn "fxam<mode>2_i387"
25045   [(set (match_operand:HI 0 "register_operand" "=a")
25046         (unspec:HI
25047           [(match_operand:X87MODEF 1 "register_operand" "f")]
25048           UNSPEC_FXAM))]
25049   "TARGET_USE_FANCY_MATH_387"
25050   "fxam\n\tfnstsw\t%0"
25051   [(set_attr "type" "multi")
25052    (set_attr "length" "4")
25053    (set_attr "unit" "i387")
25054    (set_attr "mode" "<MODE>")])
25056 (define_expand "signbittf2"
25057   [(use (match_operand:SI 0 "register_operand"))
25058    (use (match_operand:TF 1 "register_operand"))]
25059   "TARGET_SSE"
25061   if (TARGET_SSE4_1)
25062     {
25063       rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
25064       rtx scratch = gen_reg_rtx (QImode);
25066       emit_insn (gen_ptesttf2 (operands[1], mask));
25067         ix86_expand_setcc (scratch, NE,
25068                            gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
25070       emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
25071     }
25072   else
25073     {
25074       emit_insn (gen_sse_movmskps (operands[0],
25075                                    gen_lowpart (V4SFmode, operands[1])));
25076       emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
25077     }
25078   DONE;
25081 (define_expand "signbitxf2"
25082   [(use (match_operand:SI 0 "register_operand"))
25083    (use (match_operand:XF 1 "register_operand"))]
25084   "TARGET_USE_FANCY_MATH_387"
25086   rtx scratch = gen_reg_rtx (HImode);
25088   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
25089   emit_insn (gen_andsi3 (operands[0],
25090              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
25091   DONE;
25094 (define_insn "movmsk_df"
25095   [(set (match_operand:SI 0 "register_operand" "=r,jr")
25096         (unspec:SI
25097           [(match_operand:DF 1 "register_operand" "x,x")]
25098           UNSPEC_MOVMSK))]
25099   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
25100   "%vmovmskpd\t{%1, %0|%0, %1}"
25101   [(set_attr "isa" "noavx,avx")
25102    (set_attr "type" "ssemov")
25103    (set_attr "prefix" "maybe_evex")
25104    (set_attr "mode" "DF")])
25106 ;; Use movmskpd in SSE mode to avoid store forwarding stall
25107 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
25108 (define_expand "signbitdf2"
25109   [(use (match_operand:SI 0 "register_operand"))
25110    (use (match_operand:DF 1 "register_operand"))]
25111   "TARGET_USE_FANCY_MATH_387
25112    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
25114   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
25115     {
25116       emit_insn (gen_movmsk_df (operands[0], operands[1]));
25117       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
25118     }
25119   else
25120     {
25121       rtx scratch = gen_reg_rtx (HImode);
25123       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
25124       emit_insn (gen_andsi3 (operands[0],
25125                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
25126     }
25127   DONE;
25130 (define_expand "signbitsf2"
25131   [(use (match_operand:SI 0 "register_operand"))
25132    (use (match_operand:SF 1 "register_operand"))]
25133   "TARGET_USE_FANCY_MATH_387
25134    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
25136   rtx scratch = gen_reg_rtx (HImode);
25138   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
25139   emit_insn (gen_andsi3 (operands[0],
25140              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
25141   DONE;
25144 ;; Block operation instructions
25146 (define_insn "cld"
25147   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
25148   ""
25149   "cld"
25150   [(set_attr "length" "1")
25151    (set_attr "length_immediate" "0")
25152    (set_attr "modrm" "0")])
25154 (define_expand "cpymem<mode>"
25155   [(use (match_operand:BLK 0 "memory_operand"))
25156    (use (match_operand:BLK 1 "memory_operand"))
25157    (use (match_operand:SWI48 2 "nonmemory_operand"))
25158    (use (match_operand:SWI48 3 "const_int_operand"))
25159    (use (match_operand:SI 4 "const_int_operand"))
25160    (use (match_operand:SI 5 "const_int_operand"))
25161    (use (match_operand:SI 6 ""))
25162    (use (match_operand:SI 7 ""))
25163    (use (match_operand:SI 8 ""))]
25164   ""
25166  if (ix86_expand_set_or_cpymem (operands[0], operands[1],
25167                                 operands[2], NULL, operands[3],
25168                                 operands[4], operands[5],
25169                                 operands[6], operands[7],
25170                                 operands[8], false))
25171    DONE;
25172  else
25173    FAIL;
25176 ;; Most CPUs don't like single string operations
25177 ;; Handle this case here to simplify previous expander.
25179 (define_expand "strmov"
25180   [(set (match_dup 4) (match_operand 3 "memory_operand"))
25181    (set (match_operand 1 "memory_operand") (match_dup 4))
25182    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
25183               (clobber (reg:CC FLAGS_REG))])
25184    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
25185               (clobber (reg:CC FLAGS_REG))])]
25186   ""
25188   /* Can't use this for non-default address spaces.  */
25189   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
25190     FAIL;
25192   int piece_size = GET_MODE_SIZE (GET_MODE (operands[1]));
25194   /* If .md ever supports :P for Pmode, these can be directly
25195      in the pattern above.  */
25196   operands[5] = plus_constant (Pmode, operands[0], piece_size);
25197   operands[6] = plus_constant (Pmode, operands[2], piece_size);
25199   /* Can't use this if the user has appropriated esi or edi.  */
25200   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
25201       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
25202     {
25203       emit_insn (gen_strmov_singleop (operands[0], operands[1],
25204                                       operands[2], operands[3],
25205                                       operands[5], operands[6]));
25206       DONE;
25207     }
25209   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
25212 (define_expand "strmov_singleop"
25213   [(parallel [(set (match_operand 1 "memory_operand")
25214                    (match_operand 3 "memory_operand"))
25215               (set (match_operand 0 "register_operand")
25216                    (match_operand 4))
25217               (set (match_operand 2 "register_operand")
25218                    (match_operand 5))])]
25219   ""
25221   if (TARGET_CLD)
25222     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
25225 (define_insn "*strmovdi_rex_1"
25226   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
25227         (mem:DI (match_operand:P 3 "register_operand" "1")))
25228    (set (match_operand:P 0 "register_operand" "=D")
25229         (plus:P (match_dup 2)
25230                 (const_int 8)))
25231    (set (match_operand:P 1 "register_operand" "=S")
25232         (plus:P (match_dup 3)
25233                 (const_int 8)))]
25234   "TARGET_64BIT
25235    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
25236    && ix86_check_no_addr_space (insn)"
25237   "%^movsq"
25238   [(set_attr "type" "str")
25239    (set_attr "memory" "both")
25240    (set_attr "mode" "DI")])
25242 (define_insn "*strmovsi_1"
25243   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
25244         (mem:SI (match_operand:P 3 "register_operand" "1")))
25245    (set (match_operand:P 0 "register_operand" "=D")
25246         (plus:P (match_dup 2)
25247                 (const_int 4)))
25248    (set (match_operand:P 1 "register_operand" "=S")
25249         (plus:P (match_dup 3)
25250                 (const_int 4)))]
25251   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
25252    && ix86_check_no_addr_space (insn)"
25253   "%^movs{l|d}"
25254   [(set_attr "type" "str")
25255    (set_attr "memory" "both")
25256    (set_attr "mode" "SI")])
25258 (define_insn "*strmovhi_1"
25259   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
25260         (mem:HI (match_operand:P 3 "register_operand" "1")))
25261    (set (match_operand:P 0 "register_operand" "=D")
25262         (plus:P (match_dup 2)
25263                 (const_int 2)))
25264    (set (match_operand:P 1 "register_operand" "=S")
25265         (plus:P (match_dup 3)
25266                 (const_int 2)))]
25267   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
25268    && ix86_check_no_addr_space (insn)"
25269   "%^movsw"
25270   [(set_attr "type" "str")
25271    (set_attr "memory" "both")
25272    (set_attr "mode" "HI")])
25274 (define_insn "*strmovqi_1"
25275   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
25276         (mem:QI (match_operand:P 3 "register_operand" "1")))
25277    (set (match_operand:P 0 "register_operand" "=D")
25278         (plus:P (match_dup 2)
25279                 (const_int 1)))
25280    (set (match_operand:P 1 "register_operand" "=S")
25281         (plus:P (match_dup 3)
25282                 (const_int 1)))]
25283   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
25284    && ix86_check_no_addr_space (insn)"
25285   "%^movsb"
25286   [(set_attr "type" "str")
25287    (set_attr "memory" "both")
25288    (set (attr "prefix_rex")
25289         (if_then_else
25290           (match_test "<P:MODE>mode == DImode")
25291           (const_string "0")
25292           (const_string "*")))
25293    (set_attr "mode" "QI")])
25295 (define_expand "rep_mov"
25296   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
25297               (set (match_operand 0 "register_operand")
25298                    (match_operand 5))
25299               (set (match_operand 2 "register_operand")
25300                    (match_operand 6))
25301               (set (match_operand 1 "memory_operand")
25302                    (match_operand 3 "memory_operand"))
25303               (use (match_dup 4))])]
25304   ""
25306   if (TARGET_CLD)
25307     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
25310 (define_insn "*rep_movdi_rex64"
25311   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
25312    (set (match_operand:P 0 "register_operand" "=D")
25313         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
25314                           (const_int 3))
25315                 (match_operand:P 3 "register_operand" "0")))
25316    (set (match_operand:P 1 "register_operand" "=S")
25317         (plus:P (ashift:P (match_dup 5) (const_int 3))
25318                 (match_operand:P 4 "register_operand" "1")))
25319    (set (mem:BLK (match_dup 3))
25320         (mem:BLK (match_dup 4)))
25321    (use (match_dup 5))]
25322   "TARGET_64BIT
25323    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
25324    && ix86_check_no_addr_space (insn)"
25325   "%^rep{%;} movsq"
25326   [(set_attr "type" "str")
25327    (set_attr "prefix_rep" "1")
25328    (set_attr "memory" "both")
25329    (set_attr "mode" "DI")])
25331 (define_insn "*rep_movsi"
25332   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
25333    (set (match_operand:P 0 "register_operand" "=D")
25334         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
25335                           (const_int 2))
25336                  (match_operand:P 3 "register_operand" "0")))
25337    (set (match_operand:P 1 "register_operand" "=S")
25338         (plus:P (ashift:P (match_dup 5) (const_int 2))
25339                 (match_operand:P 4 "register_operand" "1")))
25340    (set (mem:BLK (match_dup 3))
25341         (mem:BLK (match_dup 4)))
25342    (use (match_dup 5))]
25343   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
25344    && ix86_check_no_addr_space (insn)"
25345   "%^rep{%;} movs{l|d}"
25346   [(set_attr "type" "str")
25347    (set_attr "prefix_rep" "1")
25348    (set_attr "memory" "both")
25349    (set_attr "mode" "SI")])
25351 (define_insn "*rep_movqi"
25352   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
25353    (set (match_operand:P 0 "register_operand" "=D")
25354         (plus:P (match_operand:P 3 "register_operand" "0")
25355                 (match_operand:P 5 "register_operand" "2")))
25356    (set (match_operand:P 1 "register_operand" "=S")
25357         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
25358    (set (mem:BLK (match_dup 3))
25359         (mem:BLK (match_dup 4)))
25360    (use (match_dup 5))]
25361   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
25362    && ix86_check_no_addr_space (insn)"
25363   "%^rep{%;} movsb"
25364   [(set_attr "type" "str")
25365    (set_attr "prefix_rep" "1")
25366    (set_attr "memory" "both")
25367    (set_attr "mode" "QI")])
25369 (define_expand "setmem<mode>"
25370    [(use (match_operand:BLK 0 "memory_operand"))
25371     (use (match_operand:SWI48 1 "nonmemory_operand"))
25372     (use (match_operand:QI 2 "nonmemory_operand"))
25373     (use (match_operand 3 "const_int_operand"))
25374     (use (match_operand:SI 4 "const_int_operand"))
25375     (use (match_operand:SI 5 "const_int_operand"))
25376     (use (match_operand:SI 6 ""))
25377     (use (match_operand:SI 7 ""))
25378     (use (match_operand:SI 8 ""))]
25379   ""
25381  if (ix86_expand_set_or_cpymem (operands[0], NULL,
25382                                 operands[1], operands[2],
25383                                 operands[3], operands[4],
25384                                 operands[5], operands[6],
25385                                 operands[7], operands[8], true))
25386    DONE;
25387  else
25388    FAIL;
25391 ;; Most CPUs don't like single string operations
25392 ;; Handle this case here to simplify previous expander.
25394 (define_expand "strset"
25395   [(set (match_operand 1 "memory_operand")
25396         (match_operand 2 "register_operand"))
25397    (parallel [(set (match_operand 0 "register_operand")
25398                    (match_dup 3))
25399               (clobber (reg:CC FLAGS_REG))])]
25400   ""
25402   /* Can't use this for non-default address spaces.  */
25403   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
25404     FAIL;
25406   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
25407     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
25409   /* If .md ever supports :P for Pmode, this can be directly
25410      in the pattern above.  */
25411   operands[3] = plus_constant (Pmode, operands[0],
25412                                GET_MODE_SIZE (GET_MODE (operands[2])));
25414   /* Can't use this if the user has appropriated eax or edi.  */
25415   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
25416       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
25417     {
25418       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
25419                                       operands[3]));
25420       DONE;
25421     }
25424 (define_expand "strset_singleop"
25425   [(parallel [(set (match_operand 1 "memory_operand")
25426                    (match_operand 2 "register_operand"))
25427               (set (match_operand 0 "register_operand")
25428                    (match_operand 3))
25429               (unspec [(const_int 0)] UNSPEC_STOS)])]
25430   ""
25432   if (TARGET_CLD)
25433     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
25436 (define_insn "*strsetdi_rex_1"
25437   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
25438         (match_operand:DI 2 "register_operand" "a"))
25439    (set (match_operand:P 0 "register_operand" "=D")
25440         (plus:P (match_dup 1)
25441                 (const_int 8)))
25442    (unspec [(const_int 0)] UNSPEC_STOS)]
25443   "TARGET_64BIT
25444    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
25445    && ix86_check_no_addr_space (insn)"
25446   "%^stosq"
25447   [(set_attr "type" "str")
25448    (set_attr "memory" "store")
25449    (set_attr "mode" "DI")])
25451 (define_insn "*strsetsi_1"
25452   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
25453         (match_operand:SI 2 "register_operand" "a"))
25454    (set (match_operand:P 0 "register_operand" "=D")
25455         (plus:P (match_dup 1)
25456                 (const_int 4)))
25457    (unspec [(const_int 0)] UNSPEC_STOS)]
25458   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
25459    && ix86_check_no_addr_space (insn)"
25460   "%^stos{l|d}"
25461   [(set_attr "type" "str")
25462    (set_attr "memory" "store")
25463    (set_attr "mode" "SI")])
25465 (define_insn "*strsethi_1"
25466   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
25467         (match_operand:HI 2 "register_operand" "a"))
25468    (set (match_operand:P 0 "register_operand" "=D")
25469         (plus:P (match_dup 1)
25470                 (const_int 2)))
25471    (unspec [(const_int 0)] UNSPEC_STOS)]
25472   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
25473    && ix86_check_no_addr_space (insn)"
25474   "%^stosw"
25475   [(set_attr "type" "str")
25476    (set_attr "memory" "store")
25477    (set_attr "mode" "HI")])
25479 (define_insn "*strsetqi_1"
25480   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
25481         (match_operand:QI 2 "register_operand" "a"))
25482    (set (match_operand:P 0 "register_operand" "=D")
25483         (plus:P (match_dup 1)
25484                 (const_int 1)))
25485    (unspec [(const_int 0)] UNSPEC_STOS)]
25486   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
25487    && ix86_check_no_addr_space (insn)"
25488   "%^stosb"
25489   [(set_attr "type" "str")
25490    (set_attr "memory" "store")
25491    (set (attr "prefix_rex")
25492         (if_then_else
25493           (match_test "<P:MODE>mode == DImode")
25494           (const_string "0")
25495           (const_string "*")))
25496    (set_attr "mode" "QI")])
25498 (define_expand "rep_stos"
25499   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
25500               (set (match_operand 0 "register_operand")
25501                    (match_operand 4))
25502               (set (match_operand 2 "memory_operand") (const_int 0))
25503               (use (match_operand 3 "register_operand"))
25504               (use (match_dup 1))])]
25505   ""
25507   if (TARGET_CLD)
25508     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
25511 (define_insn "*rep_stosdi_rex64"
25512   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
25513    (set (match_operand:P 0 "register_operand" "=D")
25514         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
25515                           (const_int 3))
25516                  (match_operand:P 3 "register_operand" "0")))
25517    (set (mem:BLK (match_dup 3))
25518         (const_int 0))
25519    (use (match_operand:DI 2 "register_operand" "a"))
25520    (use (match_dup 4))]
25521   "TARGET_64BIT
25522    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
25523    && ix86_check_no_addr_space (insn)"
25524   "%^rep{%;} stosq"
25525   [(set_attr "type" "str")
25526    (set_attr "prefix_rep" "1")
25527    (set_attr "memory" "store")
25528    (set_attr "mode" "DI")])
25530 (define_insn "*rep_stossi"
25531   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
25532    (set (match_operand:P 0 "register_operand" "=D")
25533         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
25534                           (const_int 2))
25535                  (match_operand:P 3 "register_operand" "0")))
25536    (set (mem:BLK (match_dup 3))
25537         (const_int 0))
25538    (use (match_operand:SI 2 "register_operand" "a"))
25539    (use (match_dup 4))]
25540   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
25541    && ix86_check_no_addr_space (insn)"
25542   "%^rep{%;} stos{l|d}"
25543   [(set_attr "type" "str")
25544    (set_attr "prefix_rep" "1")
25545    (set_attr "memory" "store")
25546    (set_attr "mode" "SI")])
25548 (define_insn "*rep_stosqi"
25549   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
25550    (set (match_operand:P 0 "register_operand" "=D")
25551         (plus:P (match_operand:P 3 "register_operand" "0")
25552                 (match_operand:P 4 "register_operand" "1")))
25553    (set (mem:BLK (match_dup 3))
25554         (const_int 0))
25555    (use (match_operand:QI 2 "register_operand" "a"))
25556    (use (match_dup 4))]
25557   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
25558    && ix86_check_no_addr_space (insn)"
25559   "%^rep{%;} stosb"
25560   [(set_attr "type" "str")
25561    (set_attr "prefix_rep" "1")
25562    (set_attr "memory" "store")
25563    (set (attr "prefix_rex")
25564         (if_then_else
25565           (match_test "<P:MODE>mode == DImode")
25566           (const_string "0")
25567           (const_string "*")))
25568    (set_attr "mode" "QI")])
25570 (define_expand "cmpmemsi"
25571   [(set (match_operand:SI 0 "register_operand" "")
25572         (compare:SI (match_operand:BLK 1 "memory_operand" "")
25573                     (match_operand:BLK 2 "memory_operand" "") ) )
25574    (use (match_operand 3 "general_operand"))
25575    (use (match_operand 4 "immediate_operand"))]
25576   ""
25578   if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
25579                                      operands[2], operands[3],
25580                                      operands[4], false))
25581     DONE;
25582   else
25583     FAIL;
25586 (define_expand "cmpstrnsi"
25587   [(set (match_operand:SI 0 "register_operand")
25588         (compare:SI (match_operand:BLK 1 "general_operand")
25589                     (match_operand:BLK 2 "general_operand")))
25590    (use (match_operand 3 "general_operand"))
25591    (use (match_operand 4 "immediate_operand"))]
25592   ""
25594   if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
25595                                      operands[2], operands[3],
25596                                      operands[4], true))
25597     DONE;
25598   else
25599     FAIL;
25602 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
25604 (define_expand "cmpintqi"
25605   [(set (match_dup 1)
25606         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
25607    (set (match_dup 2)
25608         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
25609    (parallel [(set (match_operand:QI 0 "register_operand")
25610                    (minus:QI (match_dup 1)
25611                              (match_dup 2)))
25612               (clobber (reg:CC FLAGS_REG))])]
25613   ""
25615   operands[1] = gen_reg_rtx (QImode);
25616   operands[2] = gen_reg_rtx (QImode);
25619 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
25620 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
25622 (define_expand "cmpstrnqi_nz_1"
25623   [(parallel [(set (reg:CC FLAGS_REG)
25624                    (compare:CC (match_operand 4 "memory_operand")
25625                                (match_operand 5 "memory_operand")))
25626               (use (match_operand 2 "register_operand"))
25627               (use (match_operand:SI 3 "immediate_operand"))
25628               (clobber (match_operand 0 "register_operand"))
25629               (clobber (match_operand 1 "register_operand"))
25630               (clobber (match_dup 2))])]
25631   ""
25633   if (TARGET_CLD)
25634     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
25637 (define_insn "*cmpstrnqi_nz_1"
25638   [(set (reg:CC FLAGS_REG)
25639         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
25640                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
25641    (use (match_operand:P 6 "register_operand" "2"))
25642    (use (match_operand:SI 3 "immediate_operand" "i"))
25643    (clobber (match_operand:P 0 "register_operand" "=S"))
25644    (clobber (match_operand:P 1 "register_operand" "=D"))
25645    (clobber (match_operand:P 2 "register_operand" "=c"))]
25646   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
25647    && ix86_check_no_addr_space (insn)"
25648   "%^repz{%;} cmpsb"
25649   [(set_attr "type" "str")
25650    (set_attr "mode" "QI")
25651    (set (attr "prefix_rex")
25652         (if_then_else
25653           (match_test "<P:MODE>mode == DImode")
25654           (const_string "0")
25655           (const_string "*")))
25656    (set_attr "prefix_rep" "1")])
25658 ;; The same, but the count is not known to not be zero.
25660 (define_expand "cmpstrnqi_1"
25661   [(parallel [(set (reg:CC FLAGS_REG)
25662                 (if_then_else:CC (ne (match_operand 2 "register_operand")
25663                                      (const_int 0))
25664                   (compare:CC (match_operand 4 "memory_operand")
25665                               (match_operand 5 "memory_operand"))
25666                   (reg:CC FLAGS_REG)))
25667               (use (match_operand:SI 3 "immediate_operand"))
25668               (clobber (match_operand 0 "register_operand"))
25669               (clobber (match_operand 1 "register_operand"))
25670               (clobber (match_dup 2))])]
25671   ""
25673   if (TARGET_CLD)
25674     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
25677 (define_insn "*cmpstrnqi_1"
25678   [(set (reg:CC FLAGS_REG)
25679         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
25680                              (const_int 0))
25681           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
25682                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
25683           (reg:CC FLAGS_REG)))
25684    (use (match_operand:SI 3 "immediate_operand" "i"))
25685    (clobber (match_operand:P 0 "register_operand" "=S"))
25686    (clobber (match_operand:P 1 "register_operand" "=D"))
25687    (clobber (match_operand:P 2 "register_operand" "=c"))]
25688   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
25689    && ix86_check_no_addr_space (insn)"
25690   "%^repz{%;} cmpsb"
25691   [(set_attr "type" "str")
25692    (set_attr "mode" "QI")
25693    (set (attr "prefix_rex")
25694         (if_then_else
25695           (match_test "<P:MODE>mode == DImode")
25696           (const_string "0")
25697           (const_string "*")))
25698    (set_attr "prefix_rep" "1")])
25700 (define_expand "strlen<mode>"
25701   [(set (match_operand:P 0 "register_operand")
25702         (unspec:P [(match_operand:BLK 1 "general_operand")
25703                    (match_operand:QI 2 "immediate_operand")
25704                    (match_operand 3 "immediate_operand")]
25705                   UNSPEC_SCAS))]
25706   ""
25708  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
25709    DONE;
25710  else
25711    FAIL;
25714 (define_expand "strlenqi_1"
25715   [(parallel [(set (match_operand 0 "register_operand")
25716                    (match_operand 2))
25717               (clobber (match_operand 1 "register_operand"))
25718               (clobber (reg:CC FLAGS_REG))])]
25719   ""
25721   if (TARGET_CLD)
25722     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
25725 (define_insn "*strlenqi_1"
25726   [(set (match_operand:P 0 "register_operand" "=&c")
25727         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
25728                    (match_operand:QI 2 "register_operand" "a")
25729                    (match_operand:P 3 "immediate_operand" "i")
25730                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
25731    (clobber (match_operand:P 1 "register_operand" "=D"))
25732    (clobber (reg:CC FLAGS_REG))]
25733   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
25734    && ix86_check_no_addr_space (insn)"
25735   "%^repnz{%;} scasb"
25736   [(set_attr "type" "str")
25737    (set_attr "mode" "QI")
25738    (set (attr "prefix_rex")
25739         (if_then_else
25740           (match_test "<P:MODE>mode == DImode")
25741           (const_string "0")
25742           (const_string "*")))
25743    (set_attr "prefix_rep" "1")])
25745 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
25746 ;; handled in combine, but it is not currently up to the task.
25747 ;; When used for their truth value, the cmpstrn* expanders generate
25748 ;; code like this:
25750 ;;   repz cmpsb
25751 ;;   seta       %al
25752 ;;   setb       %dl
25753 ;;   cmpb       %al, %dl
25754 ;;   jcc        label
25756 ;; The intermediate three instructions are unnecessary.
25758 ;; This one handles cmpstrn*_nz_1...
25759 (define_peephole2
25760   [(parallel[
25761      (set (reg:CC FLAGS_REG)
25762           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
25763                       (mem:BLK (match_operand 5 "register_operand"))))
25764      (use (match_operand 6 "register_operand"))
25765      (use (match_operand:SI 3 "immediate_operand"))
25766      (clobber (match_operand 0 "register_operand"))
25767      (clobber (match_operand 1 "register_operand"))
25768      (clobber (match_operand 2 "register_operand"))])
25769    (set (match_operand:QI 7 "register_operand")
25770         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
25771    (set (match_operand:QI 8 "register_operand")
25772         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
25773    (set (reg FLAGS_REG)
25774         (compare (match_dup 7) (match_dup 8)))
25775   ]
25776   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
25777   [(parallel[
25778      (set (reg:CC FLAGS_REG)
25779           (compare:CC (mem:BLK (match_dup 4))
25780                       (mem:BLK (match_dup 5))))
25781      (use (match_dup 6))
25782      (use (match_dup 3))
25783      (clobber (match_dup 0))
25784      (clobber (match_dup 1))
25785      (clobber (match_dup 2))])])
25787 ;; ...and this one handles cmpstrn*_1.
25788 (define_peephole2
25789   [(parallel[
25790      (set (reg:CC FLAGS_REG)
25791           (if_then_else:CC (ne (match_operand 6 "register_operand")
25792                                (const_int 0))
25793             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
25794                         (mem:BLK (match_operand 5 "register_operand")))
25795             (reg:CC FLAGS_REG)))
25796      (use (match_operand:SI 3 "immediate_operand"))
25797      (clobber (match_operand 0 "register_operand"))
25798      (clobber (match_operand 1 "register_operand"))
25799      (clobber (match_operand 2 "register_operand"))])
25800    (set (match_operand:QI 7 "register_operand")
25801         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
25802    (set (match_operand:QI 8 "register_operand")
25803         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
25804    (set (reg FLAGS_REG)
25805         (compare (match_dup 7) (match_dup 8)))
25806   ]
25807   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
25808   [(parallel[
25809      (set (reg:CC FLAGS_REG)
25810           (if_then_else:CC (ne (match_dup 6)
25811                                (const_int 0))
25812             (compare:CC (mem:BLK (match_dup 4))
25813                         (mem:BLK (match_dup 5)))
25814             (reg:CC FLAGS_REG)))
25815      (use (match_dup 3))
25816      (clobber (match_dup 0))
25817      (clobber (match_dup 1))
25818      (clobber (match_dup 2))])])
25820 ;; Conditional move instructions.
25822 (define_expand "mov<mode>cc"
25823   [(set (match_operand:SWIM 0 "register_operand")
25824         (if_then_else:SWIM (match_operand 1 "comparison_operator")
25825                            (match_operand:SWIM 2 "<general_operand>")
25826                            (match_operand:SWIM 3 "<general_operand>")))]
25827   ""
25828   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
25830 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
25831 ;; the register first winds up with `sbbl $0,reg', which is also weird.
25832 ;; So just document what we're doing explicitly.
25834 (define_expand "x86_mov<mode>cc_0_m1"
25835   [(parallel
25836     [(set (match_operand:SWI48 0 "register_operand")
25837           (if_then_else:SWI48
25838             (match_operator:SWI48 2 "ix86_carry_flag_operator"
25839              [(match_operand 1 "flags_reg_operand")
25840               (const_int 0)])
25841             (const_int -1)
25842             (const_int 0)))
25843      (clobber (reg:CC FLAGS_REG))])])
25845 (define_insn "*x86_mov<mode>cc_0_m1"
25846   [(set (match_operand:SWI48 0 "register_operand" "=r")
25847         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
25848                              [(reg FLAGS_REG) (const_int 0)])
25849           (const_int -1)
25850           (const_int 0)))
25851    (clobber (reg:CC FLAGS_REG))]
25852   ""
25853   "sbb{<imodesuffix>}\t%0, %0"
25854   [(set_attr "type" "alu1")
25855    (set_attr "use_carry" "1")
25856    (set_attr "pent_pair" "pu")
25857    (set_attr "mode" "<MODE>")
25858    (set_attr "length_immediate" "0")])
25860 (define_insn "*x86_mov<mode>cc_0_m1_se"
25861   [(set (match_operand:SWI48 0 "register_operand" "=r")
25862         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
25863                              [(reg FLAGS_REG) (const_int 0)])
25864                             (const_int 1)
25865                             (const_int 0)))
25866    (clobber (reg:CC FLAGS_REG))]
25867   ""
25868   "sbb{<imodesuffix>}\t%0, %0"
25869   [(set_attr "type" "alu1")
25870    (set_attr "use_carry" "1")
25871    (set_attr "pent_pair" "pu")
25872    (set_attr "mode" "<MODE>")
25873    (set_attr "length_immediate" "0")])
25875 (define_insn "*x86_mov<mode>cc_0_m1_neg"
25876   [(set (match_operand:SWI 0 "register_operand" "=<r>")
25877         (neg:SWI (match_operator 1 "ix86_carry_flag_operator"
25878                   [(reg FLAGS_REG) (const_int 0)])))
25879    (clobber (reg:CC FLAGS_REG))]
25880   ""
25881   "sbb{<imodesuffix>}\t%0, %0"
25882   [(set_attr "type" "alu1")
25883    (set_attr "use_carry" "1")
25884    (set_attr "pent_pair" "pu")
25885    (set_attr "mode" "<MODE>")
25886    (set_attr "length_immediate" "0")])
25888 (define_expand "x86_mov<mode>cc_0_m1_neg"
25889   [(parallel
25890     [(set (match_operand:SWI 0 "register_operand")
25891           (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))
25892      (clobber (reg:CC FLAGS_REG))])])
25894 (define_split
25895   [(set (match_operand:SWI48 0 "register_operand")
25896         (neg:SWI48
25897           (leu:SWI48
25898             (match_operand 1 "int_nonimmediate_operand")
25899             (match_operand 2 "const_int_operand"))))]
25900   "x86_64_immediate_operand (operands[2], VOIDmode)
25901    && INTVAL (operands[2]) != -1
25902    && INTVAL (operands[2]) != 2147483647"
25903   [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
25904    (set (match_dup 0)
25905         (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))]
25906   "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
25908 (define_split
25909   [(set (match_operand:SWI 0 "register_operand")
25910         (neg:SWI
25911           (eq:SWI
25912             (match_operand 1 "int_nonimmediate_operand")
25913             (const_int 0))))]
25914   ""
25915   [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (const_int 1)))
25916    (set (match_dup 0)
25917         (neg:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))])
25919 (define_split
25920   [(set (match_operand:SWI 0 "register_operand")
25921         (neg:SWI
25922           (ne:SWI
25923             (match_operand 1 "int_nonimmediate_operand")
25924             (const_int 0))))]
25925   ""
25926   [(set (reg:CCC FLAGS_REG)
25927         (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
25928    (set (match_dup 0)
25929         (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))])
25931 (define_insn "*mov<mode>cc_noc"
25932   [(set (match_operand:SWI248 0 "register_operand" "=r,r,r,r")
25933         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
25934                                [(reg FLAGS_REG) (const_int 0)])
25935           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0,rm,r")
25936           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm,r,rm")))]
25937   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
25938   "@
25939    cmov%O2%C1\t{%2, %0|%0, %2}
25940    cmov%O2%c1\t{%3, %0|%0, %3}
25941    cmov%O2%C1\t{%2, %3, %0|%0, %3, %2}
25942    cmov%O2%c1\t{%3, %2, %0|%0, %2, %3}"
25943   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
25944    (set_attr "type" "icmov")
25945    (set_attr "mode" "<MODE>")])
25947 (define_insn "*movsicc_noc_zext"
25948   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
25949         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
25950                            [(reg FLAGS_REG) (const_int 0)])
25951           (zero_extend:DI
25952             (match_operand:SI 2 "nonimmediate_operand" "rm,0,rm,r"))
25953           (zero_extend:DI
25954             (match_operand:SI 3 "nonimmediate_operand" "0,rm,r,rm"))))]
25955   "TARGET_64BIT
25956    && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
25957   "@
25958    cmov%O2%C1\t{%2, %k0|%k0, %2}
25959    cmov%O2%c1\t{%3, %k0|%k0, %3}
25960    cmov%O2%C1\t{%2, %3, %k0|%k0, %3, %2}
25961    cmov%O2%c1\t{%3, %2, %k0|%k0, %2, %3}"
25962   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
25963    (set_attr "type" "icmov")
25964    (set_attr "mode" "SI")])
25966 (define_insn "*movsicc_noc_zext_1"
25967   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r")
25968         (zero_extend:DI
25969           (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
25970                              [(reg FLAGS_REG) (const_int 0)])
25971              (match_operand:SI 2 "nonimmediate_operand" "rm,0,rm,r")
25972              (match_operand:SI 3 "nonimmediate_operand" "0,rm,r,rm"))))]
25973   "TARGET_64BIT
25974    && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
25975   "@
25976    cmov%O2%C1\t{%2, %k0|%k0, %2}
25977    cmov%O2%c1\t{%3, %k0|%k0, %3}
25978    cmov%O2%C1\t{%2, %3, %k0|%k0, %3, %2}
25979    cmov%O2%c1\t{%3, %2, %k0|%k0, %2, %3}"
25980   [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
25981    (set_attr "type" "icmov")
25982    (set_attr "mode" "SI")])
25985 ;; Don't do conditional moves with memory inputs.  This splitter helps
25986 ;; register starved x86_32 by forcing inputs into registers before reload.
25987 (define_split
25988   [(set (match_operand:SWI248 0 "register_operand")
25989         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
25990                                [(reg FLAGS_REG) (const_int 0)])
25991           (match_operand:SWI248 2 "nonimmediate_operand")
25992           (match_operand:SWI248 3 "nonimmediate_operand")))]
25993   "!TARGET_64BIT && TARGET_CMOVE
25994    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
25995    && (MEM_P (operands[2]) || MEM_P (operands[3]))
25996    && can_create_pseudo_p ()
25997    && optimize_insn_for_speed_p ()"
25998   [(set (match_dup 0)
25999         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
26001   operands[2] = force_reg (<MODE>mode, operands[2]);
26002   operands[3] = force_reg (<MODE>mode, operands[3]);
26005 (define_insn "*movqicc_noc"
26006   [(set (match_operand:QI 0 "register_operand" "=r,r,r")
26007         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
26008                            [(reg FLAGS_REG) (const_int 0)])
26009                       (match_operand:QI 2 "register_operand" "r,0,r")
26010                       (match_operand:QI 3 "register_operand" "0,r,r")))]
26011   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
26012   "#"
26013   [(set_attr "isa" "*,*,apx_ndd")
26014    (set_attr "type" "icmov")
26015    (set_attr "mode" "QI")])
26017 (define_split
26018   [(set (match_operand:SWI12 0 "register_operand")
26019         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
26020                               [(reg FLAGS_REG) (const_int 0)])
26021                       (match_operand:SWI12 2 "register_operand")
26022                       (match_operand:SWI12 3 "register_operand")))]
26023   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
26024    && reload_completed"
26025   [(set (match_dup 0)
26026         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
26028   operands[0] = gen_lowpart (SImode, operands[0]);
26029   operands[2] = gen_lowpart (SImode, operands[2]);
26030   operands[3] = gen_lowpart (SImode, operands[3]);
26033 ;; Don't do conditional moves with memory inputs
26034 (define_peephole2
26035   [(match_scratch:SWI248 4 "r")
26036    (set (match_operand:SWI248 0 "register_operand")
26037         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
26038                                [(reg FLAGS_REG) (const_int 0)])
26039           (match_operand:SWI248 2 "nonimmediate_operand")
26040           (match_operand:SWI248 3 "nonimmediate_operand")))]
26041   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
26042    && (MEM_P (operands[2]) || MEM_P (operands[3]))
26043    && optimize_insn_for_speed_p ()"
26044   [(set (match_dup 4) (match_dup 5))
26045    (set (match_dup 0)
26046         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
26048   if (MEM_P (operands[2]))
26049     {
26050       operands[5] = operands[2];
26051       operands[2] = operands[4];
26052     }
26053   else if (MEM_P (operands[3]))
26054     {
26055       operands[5] = operands[3];
26056       operands[3] = operands[4];
26057     }
26058   else
26059     gcc_unreachable ();
26062 (define_peephole2
26063   [(match_scratch:SI 4 "r")
26064    (set (match_operand:DI 0 "register_operand")
26065         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
26066                            [(reg FLAGS_REG) (const_int 0)])
26067           (zero_extend:DI
26068             (match_operand:SI 2 "nonimmediate_operand"))
26069           (zero_extend:DI
26070             (match_operand:SI 3 "nonimmediate_operand"))))]
26071   "TARGET_64BIT
26072    && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
26073    && (MEM_P (operands[2]) || MEM_P (operands[3]))
26074    && optimize_insn_for_speed_p ()"
26075   [(set (match_dup 4) (match_dup 5))
26076    (set (match_dup 0)
26077         (if_then_else:DI (match_dup 1)
26078           (zero_extend:DI (match_dup 2))
26079           (zero_extend:DI (match_dup 3))))]
26081   if (MEM_P (operands[2]))
26082     {
26083       operands[5] = operands[2];
26084       operands[2] = operands[4];
26085     }
26086   else if (MEM_P (operands[3]))
26087     {
26088       operands[5] = operands[3];
26089       operands[3] = operands[4];
26090     }
26091   else
26092     gcc_unreachable ();
26095 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#1).
26096 ;; mov r0,r1; dec r0; mov r2,r3; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
26097 (define_peephole2
26098  [(set (match_operand:SWI248 0 "general_reg_operand")
26099        (match_operand:SWI248 1 "general_reg_operand"))
26100   (parallel [(set (reg FLAGS_REG) (match_operand 5))
26101              (set (match_dup 0) (match_operand:SWI248 6))])
26102   (set (match_operand:SWI248 2 "general_reg_operand")
26103        (match_operand:SWI248 3 "general_gr_operand"))
26104   (set (match_dup 0)
26105        (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
26106                              [(reg FLAGS_REG) (const_int 0)])
26107         (match_dup 0)
26108         (match_dup 2)))]
26109  "TARGET_CMOVE
26110   && REGNO (operands[2]) != REGNO (operands[0])
26111   && REGNO (operands[2]) != REGNO (operands[1])
26112   && peep2_reg_dead_p (1, operands[1])
26113   && peep2_reg_dead_p (4, operands[2])
26114   && !reg_overlap_mentioned_p (operands[0], operands[3])"
26115  [(parallel [(set (match_dup 7) (match_dup 8))
26116              (set (match_dup 1) (match_dup 9))])
26117   (set (match_dup 0) (match_dup 3))
26118   (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
26119                                           (match_dup 1)
26120                                           (match_dup 0)))]
26122   operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
26123   operands[8]
26124     = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
26125   operands[9]
26126     = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
26129 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#2).
26130 ;; mov r2,r3; mov r0,r1; dec r0; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
26131 (define_peephole2
26132  [(set (match_operand:SWI248 2 "general_reg_operand")
26133        (match_operand:SWI248 3 "general_gr_operand"))
26134   (set (match_operand:SWI248 0 "general_reg_operand")
26135        (match_operand:SWI248 1 "general_reg_operand"))
26136   (parallel [(set (reg FLAGS_REG) (match_operand 5))
26137              (set (match_dup 0) (match_operand:SWI248 6))])
26138   (set (match_dup 0)
26139        (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
26140                              [(reg FLAGS_REG) (const_int 0)])
26141         (match_dup 0)
26142         (match_dup 2)))]
26143  "TARGET_CMOVE
26144   && REGNO (operands[2]) != REGNO (operands[0])
26145   && REGNO (operands[2]) != REGNO (operands[1])
26146   && peep2_reg_dead_p (2, operands[1])
26147   && peep2_reg_dead_p (4, operands[2])
26148   && !reg_overlap_mentioned_p (operands[0], operands[3])
26149   && !reg_mentioned_p (operands[2], operands[6])"
26150  [(parallel [(set (match_dup 7) (match_dup 8))
26151              (set (match_dup 1) (match_dup 9))])
26152   (set (match_dup 0) (match_dup 3))
26153   (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
26154                                           (match_dup 1)
26155                                           (match_dup 0)))]
26157   operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (2)), 0, 0));
26158   operands[8]
26159     = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
26160   operands[9]
26161     = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
26164 (define_insn "movhf_mask"
26165   [(set (match_operand:HF 0 "nonimmediate_operand" "=v,m,v")
26166         (unspec:HF
26167           [(match_operand:HF 1 "nonimmediate_operand" "m,v,v")
26168            (match_operand:HF 2 "nonimm_or_0_operand" "0C,0C,0C")
26169            (match_operand:QI 3 "register_operand" "Yk,Yk,Yk")]
26170           UNSPEC_MOVCC_MASK))]
26171   "TARGET_AVX512FP16"
26172   "@
26173    vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
26174    vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
26175    vmovsh\t{%d1, %0%{%3%}%N2|%0%{%3%}%N2, %d1}"
26176   [(set_attr "type" "ssemov")
26177    (set_attr "prefix" "evex")
26178    (set_attr "mode" "HF")])
26180 (define_expand "movhfcc"
26181   [(set (match_operand:HF 0 "register_operand")
26182         (if_then_else:HF
26183           (match_operand 1 "comparison_operator")
26184           (match_operand:HF 2 "register_operand")
26185           (match_operand:HF 3 "register_operand")))]
26186   "TARGET_AVX512FP16"
26187   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
26189 (define_expand "mov<mode>cc"
26190   [(set (match_operand:X87MODEF 0 "register_operand")
26191         (if_then_else:X87MODEF
26192           (match_operand 1 "comparison_operator")
26193           (match_operand:X87MODEF 2 "register_operand")
26194           (match_operand:X87MODEF 3 "register_operand")))]
26195   "(TARGET_80387 && TARGET_CMOVE)
26196    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
26197   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
26199 (define_insn "*movxfcc_1"
26200   [(set (match_operand:XF 0 "register_operand" "=f,f")
26201         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
26202                                 [(reg FLAGS_REG) (const_int 0)])
26203                       (match_operand:XF 2 "register_operand" "f,0")
26204                       (match_operand:XF 3 "register_operand" "0,f")))]
26205   "TARGET_80387 && TARGET_CMOVE"
26206   "@
26207    fcmov%F1\t{%2, %0|%0, %2}
26208    fcmov%f1\t{%3, %0|%0, %3}"
26209   [(set_attr "type" "fcmov")
26210    (set_attr "mode" "XF")])
26212 (define_insn "*movdfcc_1"
26213   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
26214         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
26215                                 [(reg FLAGS_REG) (const_int 0)])
26216                       (match_operand:DF 2 "nonimmediate_operand"
26217                                                "f ,0,rm,0 ,rm,0")
26218                       (match_operand:DF 3 "nonimmediate_operand"
26219                                                "0 ,f,0 ,rm,0, rm")))]
26220   "TARGET_80387 && TARGET_CMOVE
26221    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
26222   "@
26223    fcmov%F1\t{%2, %0|%0, %2}
26224    fcmov%f1\t{%3, %0|%0, %3}
26225    #
26226    #
26227    cmov%O2%C1\t{%2, %0|%0, %2}
26228    cmov%O2%c1\t{%3, %0|%0, %3}"
26229   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
26230    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
26231    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
26233 (define_split
26234   [(set (match_operand:DF 0 "general_reg_operand")
26235         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
26236                                 [(reg FLAGS_REG) (const_int 0)])
26237                       (match_operand:DF 2 "nonimmediate_operand")
26238                       (match_operand:DF 3 "nonimmediate_operand")))]
26239   "!TARGET_64BIT && reload_completed"
26240   [(set (match_dup 2)
26241         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
26242    (set (match_dup 3)
26243         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
26245   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
26246   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
26249 (define_insn "*movsfcc_1_387"
26250   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
26251         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
26252                                 [(reg FLAGS_REG) (const_int 0)])
26253                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
26254                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
26255   "TARGET_80387 && TARGET_CMOVE
26256    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
26257   "@
26258    fcmov%F1\t{%2, %0|%0, %2}
26259    fcmov%f1\t{%3, %0|%0, %3}
26260    cmov%O2%C1\t{%2, %0|%0, %2}
26261    cmov%O2%c1\t{%3, %0|%0, %3}"
26262   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
26263    (set_attr "mode" "SF,SF,SI,SI")])
26265 ;; Don't do conditional moves with memory inputs.  This splitter helps
26266 ;; register starved x86_32 by forcing inputs into registers before reload.
26267 (define_split
26268   [(set (match_operand:MODEF 0 "register_operand")
26269         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
26270                               [(reg FLAGS_REG) (const_int 0)])
26271           (match_operand:MODEF 2 "nonimmediate_operand")
26272           (match_operand:MODEF 3 "nonimmediate_operand")))]
26273   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
26274    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
26275    && (MEM_P (operands[2]) || MEM_P (operands[3]))
26276    && can_create_pseudo_p ()
26277    && optimize_insn_for_speed_p ()"
26278   [(set (match_dup 0)
26279         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
26281   operands[2] = force_reg (<MODE>mode, operands[2]);
26282   operands[3] = force_reg (<MODE>mode, operands[3]);
26285 ;; Don't do conditional moves with memory inputs
26286 (define_peephole2
26287   [(match_scratch:MODEF 4 "r")
26288    (set (match_operand:MODEF 0 "general_reg_operand")
26289         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
26290                               [(reg FLAGS_REG) (const_int 0)])
26291           (match_operand:MODEF 2 "nonimmediate_operand")
26292           (match_operand:MODEF 3 "nonimmediate_operand")))]
26293   "(<MODE>mode != DFmode || TARGET_64BIT)
26294    && TARGET_80387 && TARGET_CMOVE
26295    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
26296    && (MEM_P (operands[2]) || MEM_P (operands[3]))
26297    && optimize_insn_for_speed_p ()"
26298   [(set (match_dup 4) (match_dup 5))
26299    (set (match_dup 0)
26300         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
26302   if (MEM_P (operands[2]))
26303     {
26304       operands[5] = operands[2];
26305       operands[2] = operands[4];
26306     }
26307   else if (MEM_P (operands[3]))
26308     {
26309       operands[5] = operands[3];
26310       operands[3] = operands[4];
26311     }
26312   else
26313     gcc_unreachable ();
26316 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
26317 ;; the scalar versions to have only XMM registers as operands.
26319 ;; XOP conditional move
26320 (define_insn "*xop_pcmov_<mode>"
26321   [(set (match_operand:MODEF 0 "register_operand" "=x")
26322         (if_then_else:MODEF
26323           (match_operand:MODEF 1 "register_operand" "x")
26324           (match_operand:MODEF 2 "register_operand" "x")
26325           (match_operand:MODEF 3 "register_operand" "x")))]
26326   "TARGET_XOP"
26327   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
26328   [(set_attr "type" "sse4arg")
26329    (set_attr "mode" "TI")])
26331 ;; These versions of the min/max patterns are intentionally ignorant of
26332 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
26333 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
26334 ;; are undefined in this condition, we're certain this is correct.
26336 (define_insn "<code><mode>3"
26337   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
26338         (smaxmin:MODEF
26339           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
26340           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
26341   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
26342   "@
26343    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
26344    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
26345   [(set_attr "isa" "noavx,avx")
26346    (set_attr "prefix" "orig,vex")
26347    (set_attr "type" "sseadd")
26348    (set_attr "mode" "<MODE>")])
26350 (define_insn "<code>hf3"
26351   [(set (match_operand:HF 0 "register_operand" "=v")
26352         (smaxmin:HF
26353           (match_operand:HF 1 "nonimmediate_operand" "%v")
26354           (match_operand:HF 2 "nonimmediate_operand" "vm")))]
26355   "TARGET_AVX512FP16"
26356   "v<maxmin_float>sh\t{%2, %1, %0|%0, %1, %2}"
26357   [(set_attr "prefix" "evex")
26358    (set_attr "type" "sseadd")
26359    (set_attr "mode" "HF")])
26361 ;; These versions of the min/max patterns implement exactly the operations
26362 ;;   min = (op1 < op2 ? op1 : op2)
26363 ;;   max = (!(op1 < op2) ? op1 : op2)
26364 ;; Their operands are not commutative, and thus they may be used in the
26365 ;; presence of -0.0 and NaN.
26367 (define_insn "*ieee_s<ieee_maxmin>hf3"
26368   [(set (match_operand:HF 0 "register_operand" "=v")
26369         (unspec:HF
26370           [(match_operand:HF 1 "register_operand" "v")
26371            (match_operand:HF 2 "nonimmediate_operand" "vm")]
26372           IEEE_MAXMIN))]
26373   "TARGET_AVX512FP16"
26374   "v<ieee_maxmin>sh\t{%2, %1, %0|%0, %1, %2}"
26375   [(set_attr "prefix" "evex")
26376    (set_attr "type" "sseadd")
26377    (set_attr "mode" "HF")])
26379 (define_insn "*ieee_s<ieee_maxmin><mode>3"
26380   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
26381         (unspec:MODEF
26382           [(match_operand:MODEF 1 "register_operand" "0,v")
26383            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
26384           IEEE_MAXMIN))]
26385   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
26386   "@
26387    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
26388    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
26389   [(set_attr "isa" "noavx,avx")
26390    (set_attr "prefix" "orig,maybe_evex")
26391    (set_attr "type" "sseadd")
26392    (set_attr "mode" "<MODE>")])
26394 ;; Operands order in min/max instruction matters for signed zero and NANs.
26395 (define_insn_and_split "*ieee_max<mode>3_1"
26396   [(set (match_operand:MODEF 0 "register_operand")
26397         (unspec:MODEF
26398           [(match_operand:MODEF 1 "register_operand")
26399            (match_operand:MODEF 2 "register_operand")
26400            (lt:MODEF
26401              (match_operand:MODEF 3 "register_operand")
26402              (match_operand:MODEF 4 "register_operand"))]
26403           UNSPEC_BLENDV))]
26404   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
26405   && (rtx_equal_p (operands[1], operands[3])
26406       && rtx_equal_p (operands[2], operands[4]))
26407   && ix86_pre_reload_split ()"
26408   "#"
26409   "&& 1"
26410   [(set (match_dup 0)
26411         (unspec:MODEF
26412           [(match_dup 2)
26413            (match_dup 1)]
26414          UNSPEC_IEEE_MAX))])
26416 (define_insn_and_split "*ieee_min<mode>3_1"
26417   [(set (match_operand:MODEF 0 "register_operand")
26418         (unspec:MODEF
26419           [(match_operand:MODEF 1 "register_operand")
26420            (match_operand:MODEF 2 "register_operand")
26421            (lt:MODEF
26422              (match_operand:MODEF 3 "register_operand")
26423              (match_operand:MODEF 4 "register_operand"))]
26424           UNSPEC_BLENDV))]
26425   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
26426   && (rtx_equal_p (operands[1], operands[4])
26427       && rtx_equal_p (operands[2], operands[3]))
26428   && ix86_pre_reload_split ()"
26429   "#"
26430   "&& 1"
26431   [(set (match_dup 0)
26432         (unspec:MODEF
26433           [(match_dup 2)
26434            (match_dup 1)]
26435          UNSPEC_IEEE_MIN))])
26437 ;; Make two stack loads independent:
26438 ;;   fld aa              fld aa
26439 ;;   fld %st(0)     ->   fld bb
26440 ;;   fmul bb             fmul %st(1), %st
26442 ;; Actually we only match the last two instructions for simplicity.
26444 (define_peephole2
26445   [(set (match_operand 0 "fp_register_operand")
26446         (match_operand 1 "fp_register_operand"))
26447    (set (match_dup 0)
26448         (match_operator 2 "binary_fp_operator"
26449            [(match_dup 0)
26450             (match_operand 3 "memory_operand")]))]
26451   "REGNO (operands[0]) != REGNO (operands[1])"
26452   [(set (match_dup 0) (match_dup 3))
26453    (set (match_dup 0)
26454         (match_op_dup 2
26455           [(match_dup 5) (match_dup 4)]))]
26457   operands[4] = operands[0];
26458   operands[5] = operands[1];
26460   /* The % modifier is not operational anymore in peephole2's, so we have to
26461      swap the operands manually in the case of addition and multiplication. */
26462   if (COMMUTATIVE_ARITH_P (operands[2]))
26463     std::swap (operands[4], operands[5]);
26466 (define_peephole2
26467   [(set (match_operand 0 "fp_register_operand")
26468         (match_operand 1 "fp_register_operand"))
26469    (set (match_dup 0)
26470         (match_operator 2 "binary_fp_operator"
26471            [(match_operand 3 "memory_operand")
26472             (match_dup 0)]))]
26473   "REGNO (operands[0]) != REGNO (operands[1])"
26474   [(set (match_dup 0) (match_dup 3))
26475    (set (match_dup 0)
26476         (match_op_dup 2
26477           [(match_dup 4) (match_dup 5)]))]
26479   operands[4] = operands[0];
26480   operands[5] = operands[1];
26482   /* The % modifier is not operational anymore in peephole2's, so we have to
26483      swap the operands manually in the case of addition and multiplication. */
26484   if (COMMUTATIVE_ARITH_P (operands[2]))
26485     std::swap (operands[4], operands[5]);
26488 ;; Conditional addition patterns
26489 (define_expand "add<mode>cc"
26490   [(match_operand:SWI 0 "register_operand")
26491    (match_operand 1 "ordered_comparison_operator")
26492    (match_operand:SWI 2 "register_operand")
26493    (match_operand:SWI 3 "const_int_operand")]
26494   ""
26495   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
26497 ;; min/max patterns
26499 (define_code_attr maxmin_rel
26500   [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
26502 (define_expand "<code><mode>3"
26503   [(parallel
26504     [(set (match_operand:SDWIM 0 "register_operand")
26505           (maxmin:SDWIM
26506             (match_operand:SDWIM 1 "register_operand")
26507             (match_operand:SDWIM 2 "general_operand")))
26508      (clobber (reg:CC FLAGS_REG))])]
26509   "TARGET_CMOVE
26510    && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)")
26512 (define_insn_and_split "*<code><dwi>3_doubleword"
26513   [(set (match_operand:<DWI> 0 "register_operand")
26514         (maxmin:<DWI>
26515           (match_operand:<DWI> 1 "register_operand")
26516           (match_operand:<DWI> 2 "general_operand")))
26517    (clobber (reg:CC FLAGS_REG))]
26518   "TARGET_CMOVE
26519    && ix86_pre_reload_split ()"
26520   "#"
26521   "&& 1"
26522   [(set (match_dup 0)
26523         (if_then_else:DWIH (match_dup 6)
26524           (match_dup 1)
26525           (match_dup 2)))
26526    (set (match_dup 3)
26527         (if_then_else:DWIH (match_dup 6)
26528           (match_dup 4)
26529           (match_dup 5)))]
26531   operands[2] = force_reg (<DWI>mode, operands[2]);
26533   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
26535   rtx cmplo[2] = { operands[1], operands[2] };
26536   rtx cmphi[2] = { operands[4], operands[5] };
26538   enum rtx_code code = <maxmin_rel>;
26540   switch (code)
26541     {
26542     case LE: case LEU:
26543       std::swap (cmplo[0], cmplo[1]);
26544       std::swap (cmphi[0], cmphi[1]);
26545       code = swap_condition (code);
26546       /* FALLTHRU */
26548     case GE: case GEU:
26549       {
26550         bool uns = (code == GEU);
26551         rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
26552           = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
26554         emit_insn (gen_cmp_1 (<MODE>mode, cmplo[0], cmplo[1]));
26556         rtx tmp = gen_rtx_SCRATCH (<MODE>mode);
26557         emit_insn (sbb_insn (<MODE>mode, tmp, cmphi[0], cmphi[1]));
26559         rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
26560         operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
26562         break;
26563       }
26565     default:
26566       gcc_unreachable ();
26567     }
26570 (define_insn_and_split "*<code><mode>3_1"
26571   [(set (match_operand:SWI 0 "register_operand")
26572         (maxmin:SWI
26573           (match_operand:SWI 1 "register_operand")
26574           (match_operand:SWI 2 "general_operand")))
26575    (clobber (reg:CC FLAGS_REG))]
26576   "TARGET_CMOVE
26577    && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
26578    && ix86_pre_reload_split ()"
26579   "#"
26580   "&& 1"
26581   [(set (match_dup 0)
26582         (if_then_else:SWI (match_dup 3)
26583           (match_dup 1)
26584           (match_dup 2)))]
26586   machine_mode mode = <MODE>mode;
26587   rtx cmp_op = operands[2];
26589   operands[2] = force_reg (mode, cmp_op);
26591   enum rtx_code code = <maxmin_rel>;
26593   if (cmp_op == const1_rtx)
26594     {
26595       /* Convert smax (x, 1) into (x > 0 ? x : 1).
26596          Convert umax (x, 1) into (x != 0 ? x : 1).
26597          Convert ?min (x, 1) into (x <= 0 ? x : 1).  */
26598       cmp_op = const0_rtx;
26599       if (code == GE)
26600         code = GT;
26601       else if (code == GEU)
26602         code = NE;
26603     }
26604   /* Convert smin (x, -1) into (x < 0 ? x : -1).  */
26605   else if (cmp_op == constm1_rtx && code == LE)
26606     {
26607       cmp_op = const0_rtx;
26608       code = LT;
26609     }
26610   /* Convert smax (x, -1) into (x >= 0 ? x : -1).  */
26611   else if (cmp_op == constm1_rtx && code == GE)
26612     cmp_op = const0_rtx;
26613   else if (cmp_op != const0_rtx)
26614     cmp_op = operands[2];
26616   machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], cmp_op);
26617   rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
26619   rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], cmp_op);
26620   emit_insn (gen_rtx_SET (flags, tmp));
26622   operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
26625 ;; Avoid clearing a register between a flags setting comparison and its use,
26626 ;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
26627 (define_peephole2
26628   [(set (reg FLAGS_REG) (match_operand 0))
26629    (set (match_operand:SWI 1 "general_reg_operand") (const_int 0))]
26630   "peep2_regno_dead_p (0, FLAGS_REG)
26631    && !reg_overlap_mentioned_p (operands[1], operands[0])"
26632    [(set (match_dup 2) (match_dup 0))]
26634   operands[2] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
26635   ix86_expand_clear (operands[1]);
26638 ;; When optimizing for size, zeroing memory should use a register.
26639 (define_peephole2
26640   [(match_scratch:SWI48 0 "r")
26641    (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
26642    (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
26643    (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
26644    (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
26645   "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
26646   [(const_int 0)]
26648   ix86_expand_clear (operands[0]);
26649   emit_move_insn (operands[1], operands[0]);
26650   emit_move_insn (operands[2], operands[0]);
26651   emit_move_insn (operands[3], operands[0]);
26652   ix86_last_zero_store_uid
26653     = INSN_UID (emit_move_insn (operands[4], operands[0]));
26654   DONE;
26657 (define_peephole2
26658   [(match_scratch:SWI48 0 "r")
26659    (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
26660    (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
26661   "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
26662   [(const_int 0)]
26664   ix86_expand_clear (operands[0]);
26665   emit_move_insn (operands[1], operands[0]);
26666   ix86_last_zero_store_uid
26667     = INSN_UID (emit_move_insn (operands[2], operands[0]));
26668   DONE;
26671 (define_peephole2
26672   [(match_scratch:SWI48 0 "r")
26673    (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
26674   "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
26675   [(const_int 0)]
26677   ix86_expand_clear (operands[0]);
26678   ix86_last_zero_store_uid
26679     = INSN_UID (emit_move_insn (operands[1], operands[0]));
26680   DONE;
26683 (define_peephole2
26684   [(set (match_operand:SWI48 5 "memory_operand")
26685         (match_operand:SWI48 0 "general_reg_operand"))
26686    (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
26687    (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
26688    (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
26689    (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
26690   "optimize_insn_for_size_p ()
26691    && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
26692   [(const_int 0)]
26694   emit_move_insn (operands[5], operands[0]);
26695   emit_move_insn (operands[1], operands[0]);
26696   emit_move_insn (operands[2], operands[0]);
26697   emit_move_insn (operands[3], operands[0]);
26698   ix86_last_zero_store_uid
26699     = INSN_UID (emit_move_insn (operands[4], operands[0]));
26700   DONE;
26703 (define_peephole2
26704   [(set (match_operand:SWI48 3 "memory_operand")
26705         (match_operand:SWI48 0 "general_reg_operand"))
26706    (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
26707    (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
26708   "optimize_insn_for_size_p ()
26709    && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
26710   [(const_int 0)]
26712   emit_move_insn (operands[3], operands[0]);
26713   emit_move_insn (operands[1], operands[0]);
26714   ix86_last_zero_store_uid
26715     = INSN_UID (emit_move_insn (operands[2], operands[0]));
26716   DONE;
26719 (define_peephole2
26720   [(set (match_operand:SWI48 2 "memory_operand")
26721         (match_operand:SWI48 0 "general_reg_operand"))
26722    (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
26723   "optimize_insn_for_size_p ()
26724    && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
26725   [(const_int 0)]
26727   emit_move_insn (operands[2], operands[0]);
26728   ix86_last_zero_store_uid
26729     = INSN_UID (emit_move_insn (operands[1], operands[0]));
26730   DONE;
26733 ;; Reload dislikes loading constants directly into class_likely_spilled
26734 ;; hard registers.  Try to tidy things up here.
26735 (define_peephole2
26736   [(set (match_operand:SWI 0 "general_reg_operand")
26737         (match_operand:SWI 1 "x86_64_general_operand"))
26738    (set (match_operand:SWI 2 "general_reg_operand")
26739         (match_dup 0))]
26740   "peep2_reg_dead_p (2, operands[0])"
26741   [(set (match_dup 2) (match_dup 1))])
26743 ;; Misc patterns (?)
26745 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
26746 ;; Otherwise there will be nothing to keep
26748 ;; [(set (reg ebp) (reg esp))]
26749 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
26750 ;;  (clobber (eflags)]
26751 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
26753 ;; in proper program order.
26755 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
26756   [(set (match_operand:P 0 "register_operand" "=r,r")
26757         (plus:P (match_operand:P 1 "register_operand" "0,r")
26758                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
26759    (clobber (reg:CC FLAGS_REG))
26760    (clobber (mem:BLK (scratch)))]
26761   ""
26763   switch (get_attr_type (insn))
26764     {
26765     case TYPE_IMOV:
26766       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
26768     case TYPE_ALU:
26769       gcc_assert (rtx_equal_p (operands[0], operands[1]));
26770       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
26771         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
26773       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
26775     default:
26776       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
26777       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
26778     }
26780   [(set (attr "type")
26781         (cond [(and (eq_attr "alternative" "0")
26782                     (not (match_test "TARGET_OPT_AGU")))
26783                  (const_string "alu")
26784                (match_operand:<MODE> 2 "const0_operand")
26785                  (const_string "imov")
26786               ]
26787               (const_string "lea")))
26788    (set (attr "length_immediate")
26789         (cond [(eq_attr "type" "imov")
26790                  (const_string "0")
26791                (and (eq_attr "type" "alu")
26792                     (match_operand 2 "const128_operand"))
26793                  (const_string "1")
26794               ]
26795               (const_string "*")))
26796    (set_attr "mode" "<MODE>")])
26798 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
26799   [(set (match_operand:P 0 "register_operand" "=r")
26800         (minus:P (match_operand:P 1 "register_operand" "0")
26801                  (match_operand:P 2 "register_operand" "r")))
26802    (clobber (reg:CC FLAGS_REG))
26803    (clobber (mem:BLK (scratch)))]
26804   ""
26805   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
26806   [(set_attr "type" "alu")
26807    (set_attr "mode" "<MODE>")])
26809 (define_insn "@allocate_stack_worker_probe_<mode>"
26810   [(set (match_operand:P 0 "register_operand" "=a")
26811         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
26812                             UNSPECV_STACK_PROBE))
26813    (clobber (reg:CC FLAGS_REG))]
26814   "ix86_target_stack_probe ()"
26815   "call\t___chkstk_ms"
26816   [(set_attr "type" "multi")
26817    (set_attr "length" "5")])
26819 (define_expand "allocate_stack"
26820   [(match_operand 0 "register_operand")
26821    (match_operand 1 "general_operand")]
26822   "ix86_target_stack_probe ()"
26824   rtx x;
26826 #ifndef CHECK_STACK_LIMIT
26827 #define CHECK_STACK_LIMIT 0
26828 #endif
26830   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
26831       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
26832     x = operands[1];
26833   else
26834     {
26835       x = copy_to_mode_reg (Pmode, operands[1]);
26837       emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
26838     }
26840   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
26841                            stack_pointer_rtx, 0, OPTAB_DIRECT);
26843   if (x != stack_pointer_rtx)
26844     emit_move_insn (stack_pointer_rtx, x);
26846   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
26847   DONE;
26850 (define_expand "probe_stack"
26851   [(match_operand 0 "memory_operand")]
26852   ""
26854   emit_insn (gen_probe_stack_1
26855              (word_mode, operands[0], const0_rtx));
26856   DONE;
26859 ;; Use OR for stack probes, this is shorter.
26860 (define_insn "@probe_stack_1_<mode>"
26861   [(set (match_operand:W 0 "memory_operand" "=m")
26862         (unspec:W [(match_operand:W 1 "const0_operand")]
26863                   UNSPEC_PROBE_STACK))
26864    (clobber (reg:CC FLAGS_REG))]
26865   ""
26866   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
26867   [(set_attr "type" "alu1")
26868    (set_attr "mode" "<MODE>")
26869    (set_attr "length_immediate" "1")])
26870   
26871 (define_insn "@adjust_stack_and_probe_<mode>"
26872   [(set (match_operand:P 0 "register_operand" "=r")
26873         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
26874                             UNSPECV_PROBE_STACK_RANGE))
26875    (set (reg:P SP_REG)
26876         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand")))
26877    (clobber (reg:CC FLAGS_REG))
26878    (clobber (mem:BLK (scratch)))]
26879   ""
26880   "* return output_adjust_stack_and_probe (operands[0]);"
26881   [(set_attr "type" "multi")])
26883 (define_insn "@probe_stack_range_<mode>"
26884   [(set (match_operand:P 0 "register_operand" "=r")
26885         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
26886                             (match_operand:P 2 "const_int_operand")]
26887                             UNSPECV_PROBE_STACK_RANGE))
26888    (clobber (reg:CC FLAGS_REG))]
26889   ""
26890   "* return output_probe_stack_range (operands[0], operands[2]);"
26891   [(set_attr "type" "multi")])
26893 (define_expand "builtin_setjmp_receiver"
26894   [(label_ref (match_operand 0))]
26895   "!TARGET_64BIT && flag_pic"
26897 #if TARGET_MACHO
26898   if (TARGET_MACHO)
26899     {
26900       rtx xops[3];
26901       rtx_code_label *label_rtx = gen_label_rtx ();
26902       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
26903       xops[0] = xops[1] = pic_offset_table_rtx;
26904       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
26905       ix86_expand_binary_operator (MINUS, SImode, xops);
26906     }
26907   else
26908 #endif
26909     emit_insn (gen_set_got (pic_offset_table_rtx));
26910   DONE;
26913 (define_expand "save_stack_nonlocal"
26914   [(set (match_operand 0 "memory_operand")
26915         (match_operand 1 "register_operand"))]
26916   ""
26918   rtx stack_slot;
26920   if (flag_cf_protection & CF_RETURN)
26921     {
26922       /* Copy shadow stack pointer to the first slot
26923          and stack pointer to the second slot.  */
26924       rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
26925       stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
26927       rtx reg_ssp = force_reg (word_mode, const0_rtx);
26928       emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
26929       emit_move_insn (ssp_slot, reg_ssp);
26930     }
26931   else
26932     stack_slot = adjust_address (operands[0], Pmode, 0);
26933   emit_move_insn (stack_slot, operands[1]);
26934   DONE;
26937 (define_expand "restore_stack_nonlocal"
26938   [(set (match_operand 0 "register_operand" "")
26939         (match_operand 1 "memory_operand" ""))]
26940   ""
26942   rtx stack_slot;
26944   if (flag_cf_protection & CF_RETURN)
26945     {
26946       /* Restore shadow stack pointer from the first slot
26947          and stack pointer from the second slot.  */
26948       rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
26949       stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
26951       /* Get the current shadow stack pointer.  The code below will check if
26952          SHSTK feature is enabled.  If it is not enabled the RDSSP instruction
26953          is a NOP.  */
26954       rtx reg_ssp = force_reg (word_mode, const0_rtx);
26955       emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
26957       /* Compare through subtraction the saved and the current ssp
26958          to decide if ssp has to be adjusted.  */
26959       reg_ssp = expand_simple_binop (word_mode, MINUS,
26960                                      reg_ssp, ssp_slot,
26961                                      reg_ssp, 1, OPTAB_DIRECT);
26963       /* Compare and jump over adjustment code.  */
26964       rtx noadj_label = gen_label_rtx ();
26965       emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
26966                                word_mode, 1, noadj_label);
26968       /* Compute the number of frames to adjust.  */
26969       rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
26970       rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
26971                                             NULL_RTX, 1);
26973       reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
26974                                      GEN_INT (exact_log2 (UNITS_PER_WORD)),
26975                                      reg_adj, 1, OPTAB_DIRECT);
26977       /* Check if number of frames <= 255 so no loop is needed.  */
26978       rtx inc_label = gen_label_rtx ();
26979       emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
26980                                ptr_mode, 1, inc_label);
26982       /* Adjust the ssp in a loop.  */
26983       rtx loop_label = gen_label_rtx ();
26984       emit_label (loop_label);
26985       LABEL_NUSES (loop_label) = 1;
26987       rtx reg_255 = force_reg (word_mode, GEN_INT (255));
26988       emit_insn (gen_incssp (word_mode, reg_255));
26990       reg_adj = expand_simple_binop (ptr_mode, MINUS,
26991                                      reg_adj, GEN_INT (255),
26992                                      reg_adj, 1, OPTAB_DIRECT);
26994       /* Compare and jump to the loop label.  */
26995       emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
26996                                ptr_mode, 1, loop_label);
26998       emit_label (inc_label);
26999       LABEL_NUSES (inc_label) = 1;
27001       emit_insn (gen_incssp (word_mode, reg_ssp));
27003       emit_label (noadj_label);
27004       LABEL_NUSES (noadj_label) = 1;
27005     }
27006   else
27007     stack_slot = adjust_address (operands[1], Pmode, 0);
27008   emit_move_insn (operands[0], stack_slot);
27009   DONE;
27012 (define_expand "stack_protect_set"
27013   [(match_operand 0 "memory_operand")
27014    (match_operand 1 "memory_operand")]
27015   ""
27017   rtx scratch = gen_reg_rtx (word_mode);
27019   emit_insn (gen_stack_protect_set_1
27020              (ptr_mode, word_mode, operands[0], operands[1], scratch));
27021   DONE;
27024 (define_insn "@stack_protect_set_1_<PTR:mode>_<W:mode>"
27025   [(set (match_operand:PTR 0 "memory_operand" "=m")
27026         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
27027                     UNSPEC_SP_SET))
27028    (set (match_operand:W 2 "register_operand" "=&r") (const_int 0))
27029    (clobber (reg:CC FLAGS_REG))]
27030   ""
27032   output_asm_insn ("mov{<PTR:imodesuffix>}\t{%1, %<PTR:k>2|%<PTR:k>2, %1}",
27033                    operands);
27034   output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>2, %0|%0, %<PTR:k>2}",
27035                    operands);
27036   if (!TARGET_USE_MOV0 || optimize_insn_for_size_p ())
27037     return "xor{l}\t%k2, %k2";
27038   else
27039     return "mov{l}\t{$0, %k2|%k2, 0}";
27041   [(set_attr "type" "multi")])
27043 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
27044 ;; immediately followed by *mov{s,d}i_internal, where we can avoid
27045 ;; the xor{l} above.  We don't split this, so that scheduling or
27046 ;; anything else doesn't separate the *stack_protect_set* pattern from
27047 ;; the set of the register that overwrites the register with a new value.
27049 (define_peephole2
27050   [(parallel [(set (match_operand:PTR 0 "memory_operand")
27051                    (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
27052                                UNSPEC_SP_SET))
27053               (set (match_operand 2 "general_reg_operand") (const_int 0))
27054               (clobber (reg:CC FLAGS_REG))])
27055    (set (match_operand 3 "general_reg_operand")
27056         (match_operand 4 "const0_operand"))]
27057   "GET_MODE (operands[2]) == word_mode
27058    && GET_MODE_SIZE (GET_MODE (operands[3])) <= UNITS_PER_WORD
27059    && peep2_reg_dead_p (0, operands[3])
27060    && peep2_reg_dead_p (1, operands[2])"
27061   [(parallel [(set (match_dup 0)
27062                    (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
27063               (set (match_dup 3) (const_int 0))
27064               (clobber (reg:CC FLAGS_REG))])]
27065   "operands[3] = gen_lowpart (word_mode, operands[3]);")
27067 (define_insn "*stack_protect_set_2_<mode>_si"
27068   [(set (match_operand:PTR 0 "memory_operand" "=m")
27069         (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
27070                     UNSPEC_SP_SET))
27071    (set (match_operand:SI 1 "register_operand" "=&r")
27072         (match_operand:SI 2 "general_operand" "g"))]
27073   "reload_completed"
27075   output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
27076   output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
27077   if (pic_32bit_operand (operands[2], SImode)
27078       || ix86_use_lea_for_mov (insn, operands + 1))
27079     return "lea{l}\t{%E2, %1|%1, %E2}";
27080   else
27081     return "mov{l}\t{%2, %1|%1, %2}";
27083   [(set_attr "type" "multi")
27084    (set_attr "length" "24")])
27086 (define_insn "*stack_protect_set_2_<mode>_di"
27087   [(set (match_operand:PTR 0 "memory_operand" "=m,m,m")
27088         (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m,m,m")]
27089                     UNSPEC_SP_SET))
27090    (set (match_operand:DI 1 "register_operand" "=&r,&r,&r")
27091         (match_operand:DI 2 "general_operand" "Z,rem,i"))]
27092   "TARGET_64BIT && reload_completed"
27094   output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
27095   output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
27096   if (pic_32bit_operand (operands[2], DImode))
27097     return "lea{q}\t{%E2, %1|%1, %E2}";
27098   else if (which_alternative == 0)
27099     return "mov{l}\t{%k2, %k1|%k1, %k2}";
27100   else if (which_alternative == 2)
27101     return "movabs{q}\t{%2, %1|%1, %2}";
27102   else if (ix86_use_lea_for_mov (insn, operands + 1))
27103     return "lea{q}\t{%E2, %1|%1, %E2}";
27104   else
27105     return "mov{q}\t{%2, %1|%1, %2}";
27107   [(set_attr "type" "multi")
27108    (set_attr "length" "24")])
27110 (define_peephole2
27111   [(parallel [(set (match_operand:PTR 0 "memory_operand")
27112                    (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
27113                                UNSPEC_SP_SET))
27114               (set (match_operand 2 "general_reg_operand") (const_int 0))
27115               (clobber (reg:CC FLAGS_REG))])
27116    (set (match_operand:SWI48 3 "general_reg_operand")
27117         (match_operand:SWI48 4 "general_gr_operand"))]
27118   "GET_MODE (operands[2]) == word_mode
27119    && peep2_reg_dead_p (0, operands[3])
27120    && peep2_reg_dead_p (1, operands[2])"
27121   [(parallel [(set (match_dup 0)
27122                    (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
27123               (set (match_dup 3) (match_dup 4))])])
27125 (define_peephole2
27126   [(set (match_operand:SWI48 3 "general_reg_operand")
27127         (match_operand:SWI48 4 "general_gr_operand"))
27128    (parallel [(set (match_operand:PTR 0 "memory_operand")
27129                    (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
27130                                UNSPEC_SP_SET))
27131               (set (match_operand 2 "general_reg_operand") (const_int 0))
27132               (clobber (reg:CC FLAGS_REG))])]
27133   "GET_MODE (operands[2]) == word_mode
27134    && peep2_reg_dead_p (0, operands[3])
27135    && peep2_reg_dead_p (2, operands[2])
27136    && !reg_mentioned_p (operands[3], operands[0])
27137    && !reg_mentioned_p (operands[3], operands[1])"
27138   [(parallel [(set (match_dup 0)
27139                    (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
27140               (set (match_dup 3) (match_dup 4))])])
27142 (define_insn "*stack_protect_set_3_<PTR:mode>_<SWI48:mode>"
27143   [(set (match_operand:PTR 0 "memory_operand" "=m")
27144         (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
27145                     UNSPEC_SP_SET))
27146    (set (match_operand:SWI48 1 "register_operand" "=&r")
27147         (match_operand:SWI48 2 "address_no_seg_operand" "Ts"))]
27148   ""
27150   output_asm_insn ("mov{<PTR:imodesuffix>}\t{%3, %<PTR:k>1|%<PTR:k>1, %3}",
27151                    operands);
27152   output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>1, %0|%0, %<PTR:k>1}",
27153                    operands);
27154   if (SImode_address_operand (operands[2], VOIDmode))
27155     {
27156       gcc_assert (TARGET_64BIT);
27157       return "lea{l}\t{%E2, %k1|%k1, %E2}";
27158     }
27159   else
27160     return "lea{<SWI48:imodesuffix>}\t{%E2, %1|%1, %E2}";
27162   [(set_attr "type" "multi")
27163    (set_attr "length" "24")])
27165 (define_peephole2
27166   [(parallel [(set (match_operand:PTR 0 "memory_operand")
27167                    (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
27168                                UNSPEC_SP_SET))
27169               (set (match_operand 2 "general_reg_operand") (const_int 0))
27170               (clobber (reg:CC FLAGS_REG))])
27171    (set (match_operand:SWI48 3 "general_reg_operand")
27172         (match_operand:SWI48 4 "address_no_seg_operand"))]
27173   "GET_MODE (operands[2]) == word_mode
27174    && peep2_reg_dead_p (0, operands[3])
27175    && peep2_reg_dead_p (1, operands[2])"
27176   [(parallel [(set (match_dup 0)
27177                    (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
27178               (set (match_dup 3) (match_dup 4))])])
27180 (define_insn "*stack_protect_set_4z_<mode>_di"
27181   [(set (match_operand:PTR 0 "memory_operand" "=m")
27182         (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
27183                     UNSPEC_SP_SET))
27184    (set (match_operand:DI 1 "register_operand" "=&r")
27185         (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))]
27186   "TARGET_64BIT && reload_completed"
27188   output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
27189   output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
27190   if (ix86_use_lea_for_mov (insn, operands + 1))
27191     return "lea{l}\t{%E2, %k1|%k1, %E2}";
27192   else
27193     return "mov{l}\t{%2, %k1|%k1, %2}";
27195   [(set_attr "type" "multi")
27196    (set_attr "length" "24")])
27198 (define_insn "*stack_protect_set_4s_<mode>_di"
27199   [(set (match_operand:PTR 0 "memory_operand" "=m")
27200         (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
27201                     UNSPEC_SP_SET))
27202    (set (match_operand:DI 1 "register_operand" "=&r")
27203         (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))]
27204   "TARGET_64BIT && reload_completed"
27206   output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
27207   output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
27208   return "movs{lq|x}\t{%2, %1|%1, %2}";
27210   [(set_attr "type" "multi")
27211    (set_attr "length" "24")])
27213 (define_peephole2
27214   [(parallel [(set (match_operand:PTR 0 "memory_operand")
27215                    (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
27216                                UNSPEC_SP_SET))
27217               (set (match_operand 2 "general_reg_operand") (const_int 0))
27218               (clobber (reg:CC FLAGS_REG))])
27219    (set (match_operand:DI 3 "general_reg_operand")
27220         (any_extend:DI
27221           (match_operand:SI 4 "nonimmediate_gr_operand")))]
27222   "TARGET_64BIT
27223    && GET_MODE (operands[2]) == word_mode
27224    && peep2_reg_dead_p (0, operands[3])
27225    && peep2_reg_dead_p (1, operands[2])"
27226   [(parallel [(set (match_dup 0)
27227                    (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
27228               (set (match_dup 3)
27229                    (any_extend:DI (match_dup 4)))])])
27231 (define_expand "stack_protect_test"
27232   [(match_operand 0 "memory_operand")
27233    (match_operand 1 "memory_operand")
27234    (match_operand 2)]
27235   ""
27237   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
27239   emit_insn (gen_stack_protect_test_1
27240              (ptr_mode, flags, operands[0], operands[1]));
27242   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
27243                                   flags, const0_rtx, operands[2]));
27244   DONE;
27247 (define_insn "@stack_protect_test_1_<mode>"
27248   [(set (match_operand:CCZ 0 "flags_reg_operand")
27249         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
27250                      (match_operand:PTR 2 "memory_operand" "m")]
27251                     UNSPEC_SP_TEST))
27252    (clobber (match_scratch:PTR 3 "=&r"))]
27253   ""
27255   output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
27256   return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
27258   [(set_attr "type" "multi")])
27260 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
27261 ;; Do not split instructions with mask registers.
27262 (define_split
27263   [(set (match_operand 0 "general_reg_operand")
27264         (match_operator 3 "promotable_binary_operator"
27265            [(match_operand 1 "general_reg_operand")
27266             (match_operand 2 "aligned_operand")]))
27267    (clobber (reg:CC FLAGS_REG))]
27268   "! TARGET_PARTIAL_REG_STALL && reload_completed
27269    && ((GET_MODE (operands[0]) == HImode
27270         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
27271             /* ??? next two lines just !satisfies_constraint_K (...) */
27272             || !CONST_INT_P (operands[2])
27273             || satisfies_constraint_K (operands[2])))
27274        || (GET_MODE (operands[0]) == QImode
27275            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
27276   [(parallel [(set (match_dup 0)
27277                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
27278               (clobber (reg:CC FLAGS_REG))])]
27280   operands[0] = gen_lowpart (SImode, operands[0]);
27281   operands[1] = gen_lowpart (SImode, operands[1]);
27282   if (GET_CODE (operands[3]) != ASHIFT)
27283     operands[2] = gen_lowpart (SImode, operands[2]);
27284   operands[3] = shallow_copy_rtx (operands[3]);
27285   PUT_MODE (operands[3], SImode);
27288 ; Promote the QImode tests, as i386 has encoding of the AND
27289 ; instruction with 32-bit sign-extended immediate and thus the
27290 ; instruction size is unchanged, except in the %eax case for
27291 ; which it is increased by one byte, hence the ! optimize_size.
27292 (define_split
27293   [(set (match_operand 0 "flags_reg_operand")
27294         (match_operator 2 "compare_operator"
27295           [(and (match_operand 3 "aligned_operand")
27296                 (match_operand 4 "const_int_operand"))
27297            (const_int 0)]))
27298    (set (match_operand 1 "register_operand")
27299         (and (match_dup 3) (match_dup 4)))]
27300   "! TARGET_PARTIAL_REG_STALL && reload_completed
27301    && optimize_insn_for_speed_p ()
27302    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
27303        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
27304    /* Ensure that the operand will remain sign-extended immediate.  */
27305    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
27306   [(parallel [(set (match_dup 0)
27307                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
27308                                     (const_int 0)]))
27309               (set (match_dup 1)
27310                    (and:SI (match_dup 3) (match_dup 4)))])]
27312   operands[4]
27313     = gen_int_mode (INTVAL (operands[4])
27314                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
27315   operands[1] = gen_lowpart (SImode, operands[1]);
27316   operands[3] = gen_lowpart (SImode, operands[3]);
27319 ; Don't promote the QImode tests, as i386 doesn't have encoding of
27320 ; the TEST instruction with 32-bit sign-extended immediate and thus
27321 ; the instruction size would at least double, which is not what we
27322 ; want even with ! optimize_size.
27323 (define_split
27324   [(set (match_operand 0 "flags_reg_operand")
27325         (match_operator 1 "compare_operator"
27326           [(and (match_operand:HI 2 "aligned_operand")
27327                 (match_operand:HI 3 "const_int_operand"))
27328            (const_int 0)]))]
27329   "! TARGET_PARTIAL_REG_STALL && reload_completed
27330    && ! TARGET_FAST_PREFIX
27331    && optimize_insn_for_speed_p ()
27332    /* Ensure that the operand will remain sign-extended immediate.  */
27333    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
27334   [(set (match_dup 0)
27335         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
27336                          (const_int 0)]))]
27338   operands[3]
27339     = gen_int_mode (INTVAL (operands[3])
27340                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
27341   operands[2] = gen_lowpart (SImode, operands[2]);
27344 (define_split
27345   [(set (match_operand 0 "register_operand")
27346         (neg (match_operand 1 "register_operand")))
27347    (clobber (reg:CC FLAGS_REG))]
27348   "! TARGET_PARTIAL_REG_STALL && reload_completed
27349    && (GET_MODE (operands[0]) == HImode
27350        || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
27351   [(parallel [(set (match_dup 0)
27352                    (neg:SI (match_dup 1)))
27353               (clobber (reg:CC FLAGS_REG))])]
27355   operands[0] = gen_lowpart (SImode, operands[0]);
27356   operands[1] = gen_lowpart (SImode, operands[1]);
27359 ;; Do not split instructions with mask regs.
27360 (define_split
27361   [(set (match_operand 0 "general_reg_operand")
27362         (not (match_operand 1 "general_reg_operand")))]
27363   "! TARGET_PARTIAL_REG_STALL && reload_completed
27364    && (GET_MODE (operands[0]) == HImode
27365        || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
27366   [(set (match_dup 0)
27367         (not:SI (match_dup 1)))]
27369   operands[0] = gen_lowpart (SImode, operands[0]);
27370   operands[1] = gen_lowpart (SImode, operands[1]);
27373 (define_split
27374   [(set (match_operand 0 "general_reg_operand")
27375         (neg (match_operator 1 "ix86_carry_flag_operator"
27376               [(reg FLAGS_REG) (const_int 0)])))
27377    (clobber (reg:CC FLAGS_REG))]
27378   "! TARGET_PARTIAL_REG_STALL && reload_completed
27379    && (GET_MODE (operands[0]) == HImode
27380        || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
27381   [(parallel [(set (match_dup 0)
27382                    (neg:SI (match_dup 1)))
27383               (clobber (reg:CC FLAGS_REG))])]
27385   operands[0] = gen_lowpart (SImode, operands[0]);
27386   operands[1] = shallow_copy_rtx (operands[1]);
27387   PUT_MODE (operands[1], SImode);
27390 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
27391 ;; transform a complex memory operation into two memory to register operations.
27393 ;; Don't push memory operands
27394 (define_peephole2
27395   [(set (match_operand:SWI 0 "push_operand")
27396         (match_operand:SWI 1 "memory_operand"))
27397    (match_scratch:SWI 2 "<r>")]
27398   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
27399    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
27400   [(set (match_dup 2) (match_dup 1))
27401    (set (match_dup 0) (match_dup 2))])
27403 ;; We need to handle SFmode only, because DFmode and XFmode are split to
27404 ;; SImode pushes.
27405 (define_peephole2
27406   [(set (match_operand:SF 0 "push_operand")
27407         (match_operand:SF 1 "memory_operand"))
27408    (match_scratch:SF 2 "r")]
27409   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
27410    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
27411   [(set (match_dup 2) (match_dup 1))
27412    (set (match_dup 0) (match_dup 2))])
27414 ;; Don't move an immediate directly to memory when the instruction
27415 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
27416 (define_peephole2
27417   [(match_scratch:SWI124 1 "<r>")
27418    (set (match_operand:SWI124 0 "memory_operand")
27419         (const_int 0))]
27420   "optimize_insn_for_speed_p ()
27421    && ((<MODE>mode == HImode
27422        && TARGET_LCP_STALL)
27423        || (!TARGET_USE_MOV0
27424           && TARGET_SPLIT_LONG_MOVES
27425           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
27426    && peep2_regno_dead_p (0, FLAGS_REG)"
27427   [(parallel [(set (match_dup 2) (const_int 0))
27428               (clobber (reg:CC FLAGS_REG))])
27429    (set (match_dup 0) (match_dup 1))]
27430   "operands[2] = gen_lowpart (SImode, operands[1]);")
27432 (define_peephole2
27433   [(match_scratch:SWI124 2 "<r>")
27434    (set (match_operand:SWI124 0 "memory_operand")
27435         (match_operand:SWI124 1 "immediate_operand"))]
27436   "optimize_insn_for_speed_p ()
27437    && ((<MODE>mode == HImode
27438        && TARGET_LCP_STALL)
27439        || (TARGET_SPLIT_LONG_MOVES
27440           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
27441   [(set (match_dup 2) (match_dup 1))
27442    (set (match_dup 0) (match_dup 2))])
27444 ;; Don't compare memory with zero, load and use a test instead.
27445 (define_peephole2
27446   [(set (match_operand 0 "flags_reg_operand")
27447         (match_operator 1 "compare_operator"
27448           [(match_operand:SI 2 "memory_operand")
27449            (const_int 0)]))
27450    (match_scratch:SI 3 "r")]
27451   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
27452   [(set (match_dup 3) (match_dup 2))
27453    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
27455 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
27456 ;; Don't split NOTs with a displacement operand, because resulting XOR
27457 ;; will not be pairable anyway.
27459 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
27460 ;; represented using a modRM byte.  The XOR replacement is long decoded,
27461 ;; so this split helps here as well.
27463 ;; Note: Can't do this as a regular split because we can't get proper
27464 ;; lifetime information then.
27466 (define_peephole2
27467   [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
27468         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
27469   "optimize_insn_for_speed_p ()
27470    && ((TARGET_NOT_UNPAIRABLE
27471         && (!MEM_P (operands[0])
27472             || !memory_displacement_operand (operands[0], <MODE>mode)))
27473        || (TARGET_NOT_VECTORMODE
27474            && long_memory_operand (operands[0], <MODE>mode)))
27475    && peep2_regno_dead_p (0, FLAGS_REG)"
27476   [(parallel [(set (match_dup 0)
27477                    (xor:SWI124 (match_dup 1) (const_int -1)))
27478               (clobber (reg:CC FLAGS_REG))])])
27480 ;; Non pairable "test imm, reg" instructions can be translated to
27481 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
27482 ;; byte opcode instead of two, have a short form for byte operands),
27483 ;; so do it for other CPUs as well.  Given that the value was dead,
27484 ;; this should not create any new dependencies.  Pass on the sub-word
27485 ;; versions if we're concerned about partial register stalls.
27487 (define_peephole2
27488   [(set (match_operand 0 "flags_reg_operand")
27489         (match_operator 1 "compare_operator"
27490           [(and:SI (match_operand:SI 2 "register_operand")
27491                    (match_operand:SI 3 "immediate_operand"))
27492            (const_int 0)]))]
27493   "ix86_match_ccmode (insn, CCNOmode)
27494    && (REGNO (operands[2]) != AX_REG
27495        || satisfies_constraint_K (operands[3]))
27496    && peep2_reg_dead_p (1, operands[2])"
27497   [(parallel
27498      [(set (match_dup 0)
27499            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
27500                             (const_int 0)]))
27501       (set (match_dup 2)
27502            (and:SI (match_dup 2) (match_dup 3)))])])
27504 ;; We don't need to handle HImode case, because it will be promoted to SImode
27505 ;; on ! TARGET_PARTIAL_REG_STALL
27507 (define_peephole2
27508   [(set (match_operand 0 "flags_reg_operand")
27509         (match_operator 1 "compare_operator"
27510           [(and:QI (match_operand:QI 2 "register_operand")
27511                    (match_operand:QI 3 "immediate_operand"))
27512            (const_int 0)]))]
27513   "! TARGET_PARTIAL_REG_STALL
27514    && ix86_match_ccmode (insn, CCNOmode)
27515    && REGNO (operands[2]) != AX_REG
27516    && peep2_reg_dead_p (1, operands[2])"
27517   [(parallel
27518      [(set (match_dup 0)
27519            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
27520                             (const_int 0)]))
27521       (set (match_dup 2)
27522            (and:QI (match_dup 2) (match_dup 3)))])])
27524 (define_peephole2
27525   [(set (match_operand 0 "flags_reg_operand")
27526         (match_operator 1 "compare_operator"
27527           [(and:QI
27528              (subreg:QI
27529                (match_operator:SWI248 4 "extract_operator"
27530                  [(match_operand 2 "int248_register_operand")
27531                   (const_int 8)
27532                   (const_int 8)]) 0)
27533              (match_operand 3 "const_int_operand"))
27534            (const_int 0)]))]
27535   "! TARGET_PARTIAL_REG_STALL
27536    && ix86_match_ccmode (insn, CCNOmode)
27537    && REGNO (operands[2]) != AX_REG
27538    && peep2_reg_dead_p (1, operands[2])"
27539   [(parallel
27540      [(set (match_dup 0)
27541            (match_op_dup 1
27542              [(and:QI
27543                 (subreg:QI
27544                   (match_op_dup 4 [(match_dup 2)
27545                                    (const_int 8)
27546                                    (const_int 8)]) 0)
27547                 (match_dup 3))
27548               (const_int 0)]))
27549       (set (zero_extract:SWI248 (match_dup 2)
27550                                 (const_int 8)
27551                                 (const_int 8))
27552            (subreg:SWI248
27553              (and:QI
27554                (subreg:QI
27555                  (match_op_dup 4 [(match_dup 2)
27556                                   (const_int 8)
27557                                   (const_int 8)]) 0)
27558                (match_dup 3)) 0))])])
27560 ;; Don't do logical operations with memory inputs.
27561 (define_peephole2
27562   [(match_scratch:SWI 2 "<r>")
27563    (parallel [(set (match_operand:SWI 0 "register_operand")
27564                    (match_operator:SWI 3 "arith_or_logical_operator"
27565                      [(match_dup 0)
27566                       (match_operand:SWI 1 "memory_operand")]))
27567               (clobber (reg:CC FLAGS_REG))])]
27568   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
27569   [(set (match_dup 2) (match_dup 1))
27570    (parallel [(set (match_dup 0)
27571                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
27572               (clobber (reg:CC FLAGS_REG))])])
27574 (define_peephole2
27575   [(match_scratch:SWI 2 "<r>")
27576    (parallel [(set (match_operand:SWI 0 "register_operand")
27577                    (match_operator:SWI 3 "arith_or_logical_operator"
27578                      [(match_operand:SWI 1 "memory_operand")
27579                       (match_dup 0)]))
27580               (clobber (reg:CC FLAGS_REG))])]
27581   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
27582   [(set (match_dup 2) (match_dup 1))
27583    (parallel [(set (match_dup 0)
27584                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
27585               (clobber (reg:CC FLAGS_REG))])])
27587 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when
27588 ;; the memory address refers to the destination of the load!
27590 (define_peephole2
27591   [(set (match_operand:SWI 0 "general_reg_operand")
27592         (match_operand:SWI 1 "general_reg_operand"))
27593    (parallel [(set (match_dup 0)
27594                    (match_operator:SWI 3 "commutative_operator"
27595                      [(match_dup 0)
27596                       (match_operand:SWI 2 "memory_operand")]))
27597               (clobber (reg:CC FLAGS_REG))])]
27598   "REGNO (operands[0]) != REGNO (operands[1])
27599    && (<MODE>mode != QImode
27600        || any_QIreg_operand (operands[1], QImode))"
27601   [(set (match_dup 0) (match_dup 4))
27602    (parallel [(set (match_dup 0)
27603                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
27604               (clobber (reg:CC FLAGS_REG))])]
27606   operands[4]
27607     = ix86_replace_reg_with_reg (operands[2], operands[0], operands[1]);
27610 (define_peephole2
27611   [(set (match_operand 0 "mmx_reg_operand")
27612         (match_operand 1 "mmx_reg_operand"))
27613    (set (match_dup 0)
27614         (match_operator 3 "commutative_operator"
27615           [(match_dup 0)
27616            (match_operand 2 "memory_operand")]))]
27617   "REGNO (operands[0]) != REGNO (operands[1])"
27618   [(set (match_dup 0) (match_dup 2))
27619    (set (match_dup 0)
27620         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
27622 (define_peephole2
27623   [(set (match_operand 0 "sse_reg_operand")
27624         (match_operand 1 "sse_reg_operand"))
27625    (set (match_dup 0)
27626         (match_operator 3 "commutative_operator"
27627           [(match_dup 0)
27628            (match_operand 2 "memory_operand")]))]
27629   "REGNO (operands[0]) != REGNO (operands[1])
27630    /* Punt if operands[1] is %[xy]mm16+ and AVX512BW is not enabled,
27631       as EVEX encoded vpadd[bw], vpmullw, vpmin[su][bw] and vpmax[su][bw]
27632       instructions require AVX512BW and AVX512VL, but with the original
27633       instructions it might require just AVX512VL.
27634       AVX512VL is implied from TARGET_HARD_REGNO_MODE_OK.  */
27635    && (!EXT_REX_SSE_REGNO_P (REGNO (operands[1]))
27636        || TARGET_AVX512BW
27637        || GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (operands[0]))) > 2
27638        || logic_operator (operands[3], VOIDmode))"
27639   [(set (match_dup 0) (match_dup 2))
27640    (set (match_dup 0)
27641         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
27643 ; Don't do logical operations with memory outputs
27645 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
27646 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
27647 ; the same decoder scheduling characteristics as the original.
27649 (define_peephole2
27650   [(match_scratch:SWI 2 "<r>")
27651    (parallel [(set (match_operand:SWI 0 "memory_operand")
27652                    (match_operator:SWI 3 "arith_or_logical_operator"
27653                      [(match_dup 0)
27654                       (match_operand:SWI 1 "<nonmemory_operand>")]))
27655               (clobber (reg:CC FLAGS_REG))])]
27656   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
27657   [(set (match_dup 2) (match_dup 0))
27658    (parallel [(set (match_dup 2)
27659                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
27660               (clobber (reg:CC FLAGS_REG))])
27661    (set (match_dup 0) (match_dup 2))])
27663 (define_peephole2
27664   [(match_scratch:SWI 2 "<r>")
27665    (parallel [(set (match_operand:SWI 0 "memory_operand")
27666                    (match_operator:SWI 3 "arith_or_logical_operator"
27667                      [(match_operand:SWI 1 "<nonmemory_operand>")
27668                       (match_dup 0)]))
27669               (clobber (reg:CC FLAGS_REG))])]
27670   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
27671   [(set (match_dup 2) (match_dup 0))
27672    (parallel [(set (match_dup 2)
27673                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
27674               (clobber (reg:CC FLAGS_REG))])
27675    (set (match_dup 0) (match_dup 2))])
27677 ;; Attempt to use arith or logical operations with memory outputs with
27678 ;; setting of flags.
27679 (define_peephole2
27680   [(set (match_operand:SWI 0 "register_operand")
27681         (match_operand:SWI 1 "memory_operand"))
27682    (parallel [(set (match_dup 0)
27683                    (match_operator:SWI 3 "plusminuslogic_operator"
27684                      [(match_dup 0)
27685                       (match_operand:SWI 2 "<nonmemory_operand>")]))
27686               (clobber (reg:CC FLAGS_REG))])
27687    (set (match_dup 1) (match_dup 0))
27688    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
27689   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
27690    && peep2_reg_dead_p (4, operands[0])
27691    && !reg_overlap_mentioned_p (operands[0], operands[1])
27692    && !reg_overlap_mentioned_p (operands[0], operands[2])
27693    && (<MODE>mode != QImode
27694        || immediate_operand (operands[2], QImode)
27695        || any_QIreg_operand (operands[2], QImode))
27696    && ix86_match_ccmode (peep2_next_insn (3),
27697                          (GET_CODE (operands[3]) == PLUS
27698                           || GET_CODE (operands[3]) == MINUS)
27699                          ? CCGOCmode : CCNOmode)"
27700   [(parallel [(set (match_dup 4) (match_dup 6))
27701               (set (match_dup 1) (match_dup 5))])]
27703   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
27704   operands[5]
27705     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
27706                       copy_rtx (operands[1]),
27707                       operands[2]);
27708   operands[6]
27709     = gen_rtx_COMPARE (GET_MODE (operands[4]),
27710                        copy_rtx (operands[5]),
27711                        const0_rtx);
27714 ;; Likewise for cmpelim optimized pattern.
27715 (define_peephole2
27716   [(set (match_operand:SWI 0 "register_operand")
27717         (match_operand:SWI 1 "memory_operand"))
27718    (parallel [(set (reg FLAGS_REG)
27719                    (compare (match_operator:SWI 3 "plusminuslogic_operator"
27720                               [(match_dup 0)
27721                                (match_operand:SWI 2 "<nonmemory_operand>")])
27722                             (const_int 0)))
27723               (set (match_dup 0) (match_dup 3))])
27724    (set (match_dup 1) (match_dup 0))]
27725   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
27726    && peep2_reg_dead_p (3, operands[0])
27727    && !reg_overlap_mentioned_p (operands[0], operands[1])
27728    && !reg_overlap_mentioned_p (operands[0], operands[2])
27729    && ix86_match_ccmode (peep2_next_insn (1),
27730                          (GET_CODE (operands[3]) == PLUS
27731                           || GET_CODE (operands[3]) == MINUS)
27732                          ? CCGOCmode : CCNOmode)"
27733   [(parallel [(set (match_dup 4) (match_dup 6))
27734               (set (match_dup 1) (match_dup 5))])]
27736   operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
27737   operands[5]
27738     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
27739                       copy_rtx (operands[1]), operands[2]);
27740   operands[6]
27741     = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
27742                        const0_rtx);
27745 ;; Likewise for instances where we have a lea pattern.
27746 (define_peephole2
27747   [(set (match_operand:SWI 0 "register_operand")
27748         (match_operand:SWI 1 "memory_operand"))
27749    (set (match_operand:<LEAMODE> 3 "register_operand")
27750         (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
27751                         (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
27752    (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
27753    (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
27754   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
27755    && REGNO (operands[4]) == REGNO (operands[0])
27756    && REGNO (operands[5]) == REGNO (operands[3])
27757    && peep2_reg_dead_p (4, operands[3])
27758    && ((REGNO (operands[0]) == REGNO (operands[3]))
27759        || peep2_reg_dead_p (2, operands[0]))
27760    && !reg_overlap_mentioned_p (operands[0], operands[1])
27761    && !reg_overlap_mentioned_p (operands[3], operands[1])
27762    && !reg_overlap_mentioned_p (operands[0], operands[2])
27763    && (<MODE>mode != QImode
27764        || immediate_operand (operands[2], QImode)
27765        || any_QIreg_operand (operands[2], QImode))
27766    && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
27767   [(parallel [(set (match_dup 6) (match_dup 8))
27768               (set (match_dup 1) (match_dup 7))])]
27770   operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
27771   operands[7]
27772     = gen_rtx_PLUS (<MODE>mode,
27773                     copy_rtx (operands[1]),
27774                     gen_lowpart (<MODE>mode, operands[2]));
27775   operands[8]
27776     = gen_rtx_COMPARE (GET_MODE (operands[6]),
27777                        copy_rtx (operands[7]),
27778                        const0_rtx);
27781 (define_peephole2
27782   [(parallel [(set (match_operand:SWI 0 "register_operand")
27783                    (match_operator:SWI 2 "plusminuslogic_operator"
27784                      [(match_dup 0)
27785                       (match_operand:SWI 1 "memory_operand")]))
27786               (clobber (reg:CC FLAGS_REG))])
27787    (set (match_dup 1) (match_dup 0))
27788    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
27789   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
27790    && COMMUTATIVE_ARITH_P (operands[2])
27791    && peep2_reg_dead_p (3, operands[0])
27792    && !reg_overlap_mentioned_p (operands[0], operands[1])
27793    && ix86_match_ccmode (peep2_next_insn (2),
27794                          GET_CODE (operands[2]) == PLUS
27795                          ? CCGOCmode : CCNOmode)"
27796   [(parallel [(set (match_dup 3) (match_dup 5))
27797               (set (match_dup 1) (match_dup 4))])]
27799   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
27800   operands[4]
27801     = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
27802                       copy_rtx (operands[1]),
27803                       operands[0]);
27804   operands[5]
27805     = gen_rtx_COMPARE (GET_MODE (operands[3]),
27806                        copy_rtx (operands[4]),
27807                        const0_rtx);
27810 ;; Likewise for cmpelim optimized pattern.
27811 (define_peephole2
27812   [(parallel [(set (reg FLAGS_REG)
27813                    (compare (match_operator:SWI 2 "plusminuslogic_operator"
27814                               [(match_operand:SWI 0 "register_operand")
27815                                (match_operand:SWI 1 "memory_operand")])
27816                             (const_int 0)))
27817               (set (match_dup 0) (match_dup 2))])
27818    (set (match_dup 1) (match_dup 0))]
27819   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
27820    && COMMUTATIVE_ARITH_P (operands[2])
27821    && peep2_reg_dead_p (2, operands[0])
27822    && !reg_overlap_mentioned_p (operands[0], operands[1])
27823    && ix86_match_ccmode (peep2_next_insn (0),
27824                          GET_CODE (operands[2]) == PLUS
27825                          ? CCGOCmode : CCNOmode)"
27826   [(parallel [(set (match_dup 3) (match_dup 5))
27827               (set (match_dup 1) (match_dup 4))])]
27829   operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
27830   operands[4]
27831     = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
27832                       copy_rtx (operands[1]), operands[0]);
27833   operands[5]
27834     = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
27835                        const0_rtx);
27838 (define_peephole2
27839   [(set (match_operand:SWI12 0 "register_operand")
27840         (match_operand:SWI12 1 "memory_operand"))
27841    (parallel [(set (match_operand:SI 4 "register_operand")
27842                    (match_operator:SI 3 "plusminuslogic_operator"
27843                      [(match_dup 4)
27844                       (match_operand:SI 2 "nonmemory_operand")]))
27845               (clobber (reg:CC FLAGS_REG))])
27846    (set (match_dup 1) (match_dup 0))
27847    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
27848   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
27849    && REGNO (operands[0]) == REGNO (operands[4])
27850    && peep2_reg_dead_p (4, operands[0])
27851    && (<MODE>mode != QImode
27852        || immediate_operand (operands[2], SImode)
27853        || any_QIreg_operand (operands[2], SImode))
27854    && !reg_overlap_mentioned_p (operands[0], operands[1])
27855    && !reg_overlap_mentioned_p (operands[0], operands[2])
27856    && ix86_match_ccmode (peep2_next_insn (3),
27857                          (GET_CODE (operands[3]) == PLUS
27858                           || GET_CODE (operands[3]) == MINUS)
27859                          ? CCGOCmode : CCNOmode)"
27860   [(parallel [(set (match_dup 5) (match_dup 7))
27861               (set (match_dup 1) (match_dup 6))])]
27863   operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
27864   operands[6]
27865     = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
27866                       copy_rtx (operands[1]),
27867                       gen_lowpart (<MODE>mode, operands[2]));
27868   operands[7]
27869     = gen_rtx_COMPARE (GET_MODE (operands[5]),
27870                        copy_rtx (operands[6]),
27871                        const0_rtx);
27874 ;; peephole2 comes before regcprop, so deal also with a case that
27875 ;; would be cleaned up by regcprop.
27876 (define_peephole2
27877   [(set (match_operand:SWI 0 "register_operand")
27878         (match_operand:SWI 1 "memory_operand"))
27879    (parallel [(set (match_dup 0)
27880                    (match_operator:SWI 3 "plusminuslogic_operator"
27881                      [(match_dup 0)
27882                       (match_operand:SWI 2 "<nonmemory_operand>")]))
27883               (clobber (reg:CC FLAGS_REG))])
27884    (set (match_operand:SWI 4 "register_operand") (match_dup 0))
27885    (set (match_dup 1) (match_dup 4))
27886    (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
27887   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
27888    && peep2_reg_dead_p (3, operands[0])
27889    && peep2_reg_dead_p (5, operands[4])
27890    && !reg_overlap_mentioned_p (operands[0], operands[1])
27891    && !reg_overlap_mentioned_p (operands[0], operands[2])
27892    && !reg_overlap_mentioned_p (operands[4], operands[1])
27893    && (<MODE>mode != QImode
27894        || immediate_operand (operands[2], QImode)
27895        || any_QIreg_operand (operands[2], QImode))
27896    && ix86_match_ccmode (peep2_next_insn (4),
27897                          (GET_CODE (operands[3]) == PLUS
27898                           || GET_CODE (operands[3]) == MINUS)
27899                          ? CCGOCmode : CCNOmode)"
27900   [(parallel [(set (match_dup 5) (match_dup 7))
27901               (set (match_dup 1) (match_dup 6))])]
27903   operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
27904   operands[6]
27905     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
27906                       copy_rtx (operands[1]),
27907                       operands[2]);
27908   operands[7]
27909     = gen_rtx_COMPARE (GET_MODE (operands[5]),
27910                        copy_rtx (operands[6]),
27911                        const0_rtx);
27914 (define_peephole2
27915   [(set (match_operand:SWI12 0 "register_operand")
27916         (match_operand:SWI12 1 "memory_operand"))
27917    (parallel [(set (match_operand:SI 4 "register_operand")
27918                    (match_operator:SI 3 "plusminuslogic_operator"
27919                      [(match_dup 4)
27920                       (match_operand:SI 2 "nonmemory_operand")]))
27921               (clobber (reg:CC FLAGS_REG))])
27922    (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
27923    (set (match_dup 1) (match_dup 5))
27924    (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
27925   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
27926    && REGNO (operands[0]) == REGNO (operands[4])
27927    && peep2_reg_dead_p (3, operands[0])
27928    && peep2_reg_dead_p (5, operands[5])
27929    && (<MODE>mode != QImode
27930        || immediate_operand (operands[2], SImode)
27931        || any_QIreg_operand (operands[2], SImode))
27932    && !reg_overlap_mentioned_p (operands[0], operands[1])
27933    && !reg_overlap_mentioned_p (operands[0], operands[2])
27934    && !reg_overlap_mentioned_p (operands[5], operands[1])
27935    && ix86_match_ccmode (peep2_next_insn (4),
27936                          (GET_CODE (operands[3]) == PLUS
27937                           || GET_CODE (operands[3]) == MINUS)
27938                          ? CCGOCmode : CCNOmode)"
27939   [(parallel [(set (match_dup 6) (match_dup 8))
27940               (set (match_dup 1) (match_dup 7))])]
27942   operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
27943   operands[7]
27944     = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
27945                       copy_rtx (operands[1]),
27946                       gen_lowpart (<MODE>mode, operands[2]));
27947   operands[8]
27948     = gen_rtx_COMPARE (GET_MODE (operands[6]),
27949                        copy_rtx (operands[7]),
27950                        const0_rtx);
27953 ;; Likewise for cmpelim optimized pattern.
27954 (define_peephole2
27955   [(set (match_operand:SWI 0 "register_operand")
27956         (match_operand:SWI 1 "memory_operand"))
27957    (parallel [(set (reg FLAGS_REG)
27958                    (compare (match_operator:SWI 3 "plusminuslogic_operator"
27959                               [(match_dup 0)
27960                                (match_operand:SWI 2 "<nonmemory_operand>")])
27961                             (const_int 0)))
27962               (set (match_dup 0) (match_dup 3))])
27963    (set (match_operand:SWI 4 "register_operand") (match_dup 0))
27964    (set (match_dup 1) (match_dup 4))]
27965   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
27966    && peep2_reg_dead_p (3, operands[0])
27967    && peep2_reg_dead_p (4, operands[4])
27968    && !reg_overlap_mentioned_p (operands[0], operands[1])
27969    && !reg_overlap_mentioned_p (operands[0], operands[2])
27970    && !reg_overlap_mentioned_p (operands[4], operands[1])
27971    && ix86_match_ccmode (peep2_next_insn (1),
27972                          (GET_CODE (operands[3]) == PLUS
27973                           || GET_CODE (operands[3]) == MINUS)
27974                          ? CCGOCmode : CCNOmode)"
27975   [(parallel [(set (match_dup 5) (match_dup 7))
27976               (set (match_dup 1) (match_dup 6))])]
27978   operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
27979   operands[6]
27980     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
27981                       copy_rtx (operands[1]), operands[2]);
27982   operands[7]
27983     = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
27984                        const0_rtx);
27987 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
27988 ;; into x = z; x ^= y; x != z
27989 (define_peephole2
27990   [(set (match_operand:SWI 0 "register_operand")
27991         (match_operand:SWI 1 "memory_operand"))
27992    (set (match_operand:SWI 3 "register_operand") (match_dup 0))
27993    (parallel [(set (match_operand:SWI 4 "register_operand")
27994                    (xor:SWI (match_dup 4)
27995                             (match_operand:SWI 2 "<nonmemory_operand>")))
27996               (clobber (reg:CC FLAGS_REG))])
27997    (set (match_dup 1) (match_dup 4))
27998    (set (reg:CCZ FLAGS_REG)
27999         (compare:CCZ (match_operand:SWI 5 "register_operand")
28000                      (match_operand:SWI 6 "<nonmemory_operand>")))]
28001   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
28002    && (REGNO (operands[4]) == REGNO (operands[0])
28003        || REGNO (operands[4]) == REGNO (operands[3]))
28004    && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
28005                              ? 3 : 0], operands[5])
28006        ? rtx_equal_p (operands[2], operands[6])
28007        : rtx_equal_p (operands[2], operands[5])
28008          && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
28009                                   ? 3 : 0], operands[6]))
28010    && peep2_reg_dead_p (4, operands[4])
28011    && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
28012                                     ? 3 : 0])
28013    && !reg_overlap_mentioned_p (operands[0], operands[1])
28014    && !reg_overlap_mentioned_p (operands[0], operands[2])
28015    && !reg_overlap_mentioned_p (operands[3], operands[0])
28016    && !reg_overlap_mentioned_p (operands[3], operands[1])
28017    && !reg_overlap_mentioned_p (operands[3], operands[2])
28018    && (<MODE>mode != QImode
28019        || immediate_operand (operands[2], QImode)
28020        || any_QIreg_operand (operands[2], QImode))"
28021   [(parallel [(set (match_dup 7) (match_dup 9))
28022               (set (match_dup 1) (match_dup 8))])]
28024   operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
28025   operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
28026                              operands[2]);
28027   operands[9]
28028     = gen_rtx_COMPARE (GET_MODE (operands[7]),
28029                        copy_rtx (operands[8]),
28030                        const0_rtx);
28033 (define_peephole2
28034   [(set (match_operand:SWI12 0 "register_operand")
28035         (match_operand:SWI12 1 "memory_operand"))
28036    (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
28037    (parallel [(set (match_operand:SI 4 "register_operand")
28038                    (xor:SI (match_dup 4)
28039                            (match_operand:SI 2 "<nonmemory_operand>")))
28040               (clobber (reg:CC FLAGS_REG))])
28041    (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
28042    (set (reg:CCZ FLAGS_REG)
28043         (compare:CCZ (match_operand:SWI12 6 "register_operand")
28044                      (match_operand:SWI12 7 "<nonmemory_operand>")))]
28045   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
28046    && (REGNO (operands[5]) == REGNO (operands[0])
28047        || REGNO (operands[5]) == REGNO (operands[3]))
28048    && REGNO (operands[5]) == REGNO (operands[4])
28049    && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
28050                              ? 3 : 0], operands[6])
28051        ? (REG_P (operands[2])
28052           ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
28053           : rtx_equal_p (operands[2], operands[7]))
28054        : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
28055                                 ? 3 : 0], operands[7])
28056           && REG_P (operands[2])
28057           && REGNO (operands[2]) == REGNO (operands[6])))
28058    && peep2_reg_dead_p (4, operands[5])
28059    && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
28060                                     ? 3 : 0])
28061    && !reg_overlap_mentioned_p (operands[0], operands[1])
28062    && !reg_overlap_mentioned_p (operands[0], operands[2])
28063    && !reg_overlap_mentioned_p (operands[3], operands[0])
28064    && !reg_overlap_mentioned_p (operands[3], operands[1])
28065    && !reg_overlap_mentioned_p (operands[3], operands[2])
28066    && (<MODE>mode != QImode
28067        || immediate_operand (operands[2], SImode)
28068        || any_QIreg_operand (operands[2], SImode))"
28069   [(parallel [(set (match_dup 8) (match_dup 10))
28070               (set (match_dup 1) (match_dup 9))])]
28072   operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
28073   operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
28074                              gen_lowpart (<MODE>mode, operands[2]));
28075   operands[10]
28076     = gen_rtx_COMPARE (GET_MODE (operands[8]),
28077                        copy_rtx (operands[9]),
28078                        const0_rtx);
28081 ;; Attempt to optimize away memory stores of values the memory already
28082 ;; has.  See PR79593.
28083 (define_peephole2
28084   [(set (match_operand 0 "register_operand")
28085         (match_operand 1 "memory_operand"))
28086    (set (match_operand 2 "memory_operand") (match_dup 0))]
28087   "!MEM_VOLATILE_P (operands[1])
28088    && !MEM_VOLATILE_P (operands[2])
28089    && rtx_equal_p (operands[1], operands[2])
28090    && !reg_overlap_mentioned_p (operands[0], operands[2])"
28091   [(set (match_dup 0) (match_dup 1))])
28093 ;; Attempt to always use XOR for zeroing registers (including FP modes).
28094 (define_peephole2
28095   [(set (match_operand 0 "general_reg_operand")
28096         (match_operand 1 "const0_operand"))]
28097   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
28098    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
28099    && peep2_regno_dead_p (0, FLAGS_REG)"
28100   [(parallel [(set (match_dup 0) (const_int 0))
28101               (clobber (reg:CC FLAGS_REG))])]
28102   "operands[0] = gen_lowpart (word_mode, operands[0]);")
28104 (define_peephole2
28105   [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
28106         (const_int 0))]
28107   "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
28108    && peep2_regno_dead_p (0, FLAGS_REG)"
28109   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
28110               (clobber (reg:CC FLAGS_REG))])])
28112 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
28113 (define_peephole2
28114   [(set (match_operand:SWI248 0 "general_reg_operand")
28115         (const_int -1))]
28116   "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
28117    && peep2_regno_dead_p (0, FLAGS_REG)"
28118   [(parallel [(set (match_dup 0) (const_int -1))
28119               (clobber (reg:CC FLAGS_REG))])]
28121   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
28122     operands[0] = gen_lowpart (SImode, operands[0]);
28125 ;; Attempt to convert simple lea to add/shift.
28126 ;; These can be created by move expanders.
28127 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
28128 ;; relevant lea instructions were already split.
28130 (define_peephole2
28131   [(set (match_operand:SWI48 0 "register_operand")
28132         (plus:SWI48 (match_dup 0)
28133                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
28134   "!TARGET_OPT_AGU
28135    && peep2_regno_dead_p (0, FLAGS_REG)"
28136   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
28137               (clobber (reg:CC FLAGS_REG))])])
28139 (define_peephole2
28140   [(set (match_operand:SWI48 0 "register_operand")
28141         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
28142                     (match_dup 0)))]
28143   "!TARGET_OPT_AGU
28144    && peep2_regno_dead_p (0, FLAGS_REG)"
28145   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
28146               (clobber (reg:CC FLAGS_REG))])])
28148 (define_peephole2
28149   [(set (match_operand:DI 0 "register_operand")
28150         (zero_extend:DI
28151           (plus:SI (match_operand:SI 1 "register_operand")
28152                    (match_operand:SI 2 "nonmemory_operand"))))]
28153   "TARGET_64BIT && !TARGET_OPT_AGU
28154    && REGNO (operands[0]) == REGNO (operands[1])
28155    && peep2_regno_dead_p (0, FLAGS_REG)"
28156   [(parallel [(set (match_dup 0)
28157                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
28158               (clobber (reg:CC FLAGS_REG))])])
28160 (define_peephole2
28161   [(set (match_operand:DI 0 "register_operand")
28162         (zero_extend:DI
28163           (plus:SI (match_operand:SI 1 "nonmemory_operand")
28164                    (match_operand:SI 2 "register_operand"))))]
28165   "TARGET_64BIT && !TARGET_OPT_AGU
28166    && REGNO (operands[0]) == REGNO (operands[2])
28167    && peep2_regno_dead_p (0, FLAGS_REG)"
28168   [(parallel [(set (match_dup 0)
28169                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
28170               (clobber (reg:CC FLAGS_REG))])])
28172 (define_peephole2
28173   [(set (match_operand:SWI48 0 "register_operand")
28174         (mult:SWI48 (match_dup 0)
28175                     (match_operand:SWI48 1 "const_int_operand")))]
28176   "pow2p_hwi (INTVAL (operands[1]))
28177    && peep2_regno_dead_p (0, FLAGS_REG)"
28178   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
28179               (clobber (reg:CC FLAGS_REG))])]
28180   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
28182 (define_peephole2
28183   [(set (match_operand:DI 0 "register_operand")
28184         (zero_extend:DI
28185           (mult:SI (match_operand:SI 1 "register_operand")
28186                    (match_operand:SI 2 "const_int_operand"))))]
28187   "TARGET_64BIT
28188    && pow2p_hwi (INTVAL (operands[2]))
28189    && REGNO (operands[0]) == REGNO (operands[1])
28190    && peep2_regno_dead_p (0, FLAGS_REG)"
28191   [(parallel [(set (match_dup 0)
28192                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
28193               (clobber (reg:CC FLAGS_REG))])]
28194   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
28196 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
28197 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
28198 ;; On many CPUs it is also faster, since special hardware to avoid esp
28199 ;; dependencies is present.
28201 ;; While some of these conversions may be done using splitters, we use
28202 ;; peepholes in order to allow combine_stack_adjustments pass to see
28203 ;; nonobfuscated RTL.
28205 ;; Convert prologue esp subtractions to push.
28206 ;; We need register to push.  In order to keep verify_flow_info happy we have
28207 ;; two choices
28208 ;; - use scratch and clobber it in order to avoid dependencies
28209 ;; - use already live register
28210 ;; We can't use the second way right now, since there is no reliable way how to
28211 ;; verify that given register is live.  First choice will also most likely in
28212 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
28213 ;; call clobbered registers are dead.  We may want to use base pointer as an
28214 ;; alternative when no register is available later.
28216 (define_peephole2
28217   [(match_scratch:W 1 "r")
28218    (parallel [(set (reg:P SP_REG)
28219                    (plus:P (reg:P SP_REG)
28220                            (match_operand:P 0 "const_int_operand")))
28221               (clobber (reg:CC FLAGS_REG))
28222               (clobber (mem:BLK (scratch)))])]
28223   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
28224    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
28225    && !ix86_red_zone_used"
28226   [(clobber (match_dup 1))
28227    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
28228               (clobber (mem:BLK (scratch)))])])
28230 (define_peephole2
28231   [(match_scratch:W 1 "r")
28232    (parallel [(set (reg:P SP_REG)
28233                    (plus:P (reg:P SP_REG)
28234                            (match_operand:P 0 "const_int_operand")))
28235               (clobber (reg:CC FLAGS_REG))
28236               (clobber (mem:BLK (scratch)))])]
28237   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
28238    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
28239    && !ix86_red_zone_used"
28240   [(clobber (match_dup 1))
28241    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
28242    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
28243               (clobber (mem:BLK (scratch)))])])
28245 ;; Convert esp subtractions to push.
28246 (define_peephole2
28247   [(match_scratch:W 1 "r")
28248    (parallel [(set (reg:P SP_REG)
28249                    (plus:P (reg:P SP_REG)
28250                            (match_operand:P 0 "const_int_operand")))
28251               (clobber (reg:CC FLAGS_REG))])]
28252   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
28253    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
28254    && !ix86_red_zone_used"
28255   [(clobber (match_dup 1))
28256    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
28258 (define_peephole2
28259   [(match_scratch:W 1 "r")
28260    (parallel [(set (reg:P SP_REG)
28261                    (plus:P (reg:P SP_REG)
28262                            (match_operand:P 0 "const_int_operand")))
28263               (clobber (reg:CC FLAGS_REG))])]
28264   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
28265    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
28266    && !ix86_red_zone_used"
28267   [(clobber (match_dup 1))
28268    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
28269    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
28271 ;; Convert epilogue deallocator to pop.
28272 (define_peephole2
28273   [(match_scratch:W 1 "r")
28274    (parallel [(set (reg:P SP_REG)
28275                    (plus:P (reg:P SP_REG)
28276                            (match_operand:P 0 "const_int_operand")))
28277               (clobber (reg:CC FLAGS_REG))
28278               (clobber (mem:BLK (scratch)))])]
28279   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
28280    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
28281   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
28282               (clobber (mem:BLK (scratch)))])])
28284 ;; Two pops case is tricky, since pop causes dependency
28285 ;; on destination register.  We use two registers if available.
28286 (define_peephole2
28287   [(match_scratch:W 1 "r")
28288    (match_scratch:W 2 "r")
28289    (parallel [(set (reg:P SP_REG)
28290                    (plus:P (reg:P SP_REG)
28291                            (match_operand:P 0 "const_int_operand")))
28292               (clobber (reg:CC FLAGS_REG))
28293               (clobber (mem:BLK (scratch)))])]
28294   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
28295    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
28296   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
28297               (clobber (mem:BLK (scratch)))])
28298    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
28300 (define_peephole2
28301   [(match_scratch:W 1 "r")
28302    (parallel [(set (reg:P SP_REG)
28303                    (plus:P (reg:P SP_REG)
28304                            (match_operand:P 0 "const_int_operand")))
28305               (clobber (reg:CC FLAGS_REG))
28306               (clobber (mem:BLK (scratch)))])]
28307   "optimize_insn_for_size_p ()
28308    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
28309   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
28310               (clobber (mem:BLK (scratch)))])
28311    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
28313 ;; Convert esp additions to pop.
28314 (define_peephole2
28315   [(match_scratch:W 1 "r")
28316    (parallel [(set (reg:P SP_REG)
28317                    (plus:P (reg:P SP_REG)
28318                            (match_operand:P 0 "const_int_operand")))
28319               (clobber (reg:CC FLAGS_REG))])]
28320   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
28321   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
28323 ;; Two pops case is tricky, since pop causes dependency
28324 ;; on destination register.  We use two registers if available.
28325 (define_peephole2
28326   [(match_scratch:W 1 "r")
28327    (match_scratch:W 2 "r")
28328    (parallel [(set (reg:P SP_REG)
28329                    (plus:P (reg:P SP_REG)
28330                            (match_operand:P 0 "const_int_operand")))
28331               (clobber (reg:CC FLAGS_REG))])]
28332   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
28333   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
28334    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
28336 (define_peephole2
28337   [(match_scratch:W 1 "r")
28338    (parallel [(set (reg:P SP_REG)
28339                    (plus:P (reg:P SP_REG)
28340                            (match_operand:P 0 "const_int_operand")))
28341               (clobber (reg:CC FLAGS_REG))])]
28342   "optimize_insn_for_size_p ()
28343    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
28344   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
28345    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
28347 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
28348 ;; required and register dies.  Similarly for 128 to -128.
28349 (define_peephole2
28350   [(set (match_operand 0 "flags_reg_operand")
28351         (match_operator 1 "compare_operator"
28352           [(match_operand 2 "register_operand")
28353            (match_operand 3 "const_int_operand")]))]
28354   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
28355      && incdec_operand (operands[3], GET_MODE (operands[3])))
28356     || (!TARGET_FUSE_CMP_AND_BRANCH
28357         && INTVAL (operands[3]) == 128))
28358    && ix86_match_ccmode (insn, CCGCmode)
28359    && peep2_reg_dead_p (1, operands[2])"
28360   [(parallel [(set (match_dup 0)
28361                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
28362               (clobber (match_dup 2))])])
28364 ;; Convert imul by three, five and nine into lea
28365 (define_peephole2
28366   [(parallel
28367     [(set (match_operand:SWI48 0 "register_operand")
28368           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
28369                       (match_operand:SWI48 2 "const359_operand")))
28370      (clobber (reg:CC FLAGS_REG))])]
28371   "!TARGET_PARTIAL_REG_STALL
28372    || <MODE>mode == SImode
28373    || optimize_function_for_size_p (cfun)"
28374   [(set (match_dup 0)
28375         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
28376                     (match_dup 1)))]
28377   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
28379 (define_peephole2
28380   [(parallel
28381     [(set (match_operand:SWI48 0 "register_operand")
28382           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
28383                       (match_operand:SWI48 2 "const359_operand")))
28384      (clobber (reg:CC FLAGS_REG))])]
28385   "optimize_insn_for_speed_p ()
28386    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
28387   [(set (match_dup 0) (match_dup 1))
28388    (set (match_dup 0)
28389         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
28390                     (match_dup 0)))]
28391   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
28393 ;; imul $32bit_imm, mem, reg is vector decoded, while
28394 ;; imul $32bit_imm, reg, reg is direct decoded.
28395 (define_peephole2
28396   [(match_scratch:SWI48 3 "r")
28397    (parallel [(set (match_operand:SWI48 0 "register_operand")
28398                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
28399                                (match_operand:SWI48 2 "immediate_operand")))
28400               (clobber (reg:CC FLAGS_REG))])]
28401   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
28402    && !satisfies_constraint_K (operands[2])"
28403   [(set (match_dup 3) (match_dup 1))
28404    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
28405               (clobber (reg:CC FLAGS_REG))])])
28407 (define_peephole2
28408   [(match_scratch:SI 3 "r")
28409    (parallel [(set (match_operand:DI 0 "register_operand")
28410                    (zero_extend:DI
28411                      (mult:SI (match_operand:SI 1 "memory_operand")
28412                               (match_operand:SI 2 "immediate_operand"))))
28413               (clobber (reg:CC FLAGS_REG))])]
28414   "TARGET_64BIT
28415    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
28416    && !satisfies_constraint_K (operands[2])"
28417   [(set (match_dup 3) (match_dup 1))
28418    (parallel [(set (match_dup 0)
28419                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
28420               (clobber (reg:CC FLAGS_REG))])])
28422 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
28423 ;; Convert it into imul reg, reg
28424 ;; It would be better to force assembler to encode instruction using long
28425 ;; immediate, but there is apparently no way to do so.
28426 (define_peephole2
28427   [(parallel [(set (match_operand:SWI248 0 "register_operand")
28428                    (mult:SWI248
28429                     (match_operand:SWI248 1 "nonimmediate_operand")
28430                     (match_operand:SWI248 2 "const_int_operand")))
28431               (clobber (reg:CC FLAGS_REG))])
28432    (match_scratch:SWI248 3 "r")]
28433   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
28434    && satisfies_constraint_K (operands[2])"
28435   [(set (match_dup 3) (match_dup 2))
28436    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
28437               (clobber (reg:CC FLAGS_REG))])]
28439   if (!rtx_equal_p (operands[0], operands[1]))
28440     emit_move_insn (operands[0], operands[1]);
28443 ;; After splitting up read-modify operations, array accesses with memory
28444 ;; operands might end up in form:
28445 ;;  sall    $2, %eax
28446 ;;  movl    4(%esp), %edx
28447 ;;  addl    %edx, %eax
28448 ;; instead of pre-splitting:
28449 ;;  sall    $2, %eax
28450 ;;  addl    4(%esp), %eax
28451 ;; Turn it into:
28452 ;;  movl    4(%esp), %edx
28453 ;;  leal    (%edx,%eax,4), %eax
28455 (define_peephole2
28456   [(match_scratch:W 5 "r")
28457    (parallel [(set (match_operand 0 "register_operand")
28458                    (ashift (match_operand 1 "register_operand")
28459                            (match_operand 2 "const_int_operand")))
28460                (clobber (reg:CC FLAGS_REG))])
28461    (parallel [(set (match_operand 3 "register_operand")
28462                    (plus (match_dup 0)
28463                          (match_operand 4 "x86_64_general_operand")))
28464                    (clobber (reg:CC FLAGS_REG))])]
28465   "IN_RANGE (INTVAL (operands[2]), 1, 3)
28466    /* Validate MODE for lea.  */
28467    && ((!TARGET_PARTIAL_REG_STALL
28468         && (GET_MODE (operands[0]) == QImode
28469             || GET_MODE (operands[0]) == HImode))
28470        || GET_MODE (operands[0]) == SImode
28471        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
28472    && (rtx_equal_p (operands[0], operands[3])
28473        || peep2_reg_dead_p (2, operands[0]))
28474    /* We reorder load and the shift.  */
28475    && !reg_overlap_mentioned_p (operands[0], operands[4])"
28476   [(set (match_dup 5) (match_dup 4))
28477    (set (match_dup 0) (match_dup 1))]
28479   machine_mode op1mode = GET_MODE (operands[1]);
28480   machine_mode mode = op1mode == DImode ? DImode : SImode;
28481   int scale = 1 << INTVAL (operands[2]);
28482   rtx index = gen_lowpart (word_mode, operands[1]);
28483   rtx base = gen_lowpart (word_mode, operands[5]);
28484   rtx dest = gen_lowpart (mode, operands[3]);
28486   operands[1] = gen_rtx_PLUS (word_mode, base,
28487                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
28488   if (mode != word_mode)
28489     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
28491   operands[5] = base;
28492   if (op1mode != word_mode)
28493     operands[5] = gen_lowpart (op1mode, operands[5]);
28495   operands[0] = dest;
28498 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
28499 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
28500 ;; caught for use by garbage collectors and the like.  Using an insn that
28501 ;; maps to SIGILL makes it more likely the program will rightfully die.
28502 ;; Keeping with tradition, "6" is in honor of #UD.
28503 (define_insn "trap"
28504   [(trap_if (const_int 1) (const_int 6))]
28505   ""
28507 #ifdef HAVE_AS_IX86_UD2
28508   return "ud2";
28509 #else
28510   return ASM_SHORT "0x0b0f";
28511 #endif
28513   [(set_attr "length" "2")])
28515 (define_insn "ud2"
28516   [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
28517   ""
28519 #ifdef HAVE_AS_IX86_UD2
28520   return "ud2";
28521 #else
28522   return ASM_SHORT "0x0b0f";
28523 #endif
28525   [(set_attr "length" "2")])
28527 (define_expand "prefetch"
28528   [(prefetch (match_operand 0 "address_operand")
28529              (match_operand:SI 1 "const_int_operand")
28530              (match_operand:SI 2 "const_int_operand"))]
28531   "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW"
28533   bool write = operands[1] != const0_rtx;
28534   int locality = INTVAL (operands[2]);
28536   gcc_assert (IN_RANGE (locality, 0, 3));
28538   /* Use 3dNOW prefetch in case we are asking for write prefetch not
28539      supported by SSE counterpart (non-SSE2 athlon machines) or the
28540      SSE prefetch is not available (K6 machines).  Otherwise use SSE
28541      prefetch as it allows specifying of locality.  */
28543   if (write)
28544     {
28545       if (TARGET_PRFCHW)
28546         operands[2] = GEN_INT (3);
28547       else if (TARGET_3DNOW && !TARGET_SSE2)
28548         operands[2] = GEN_INT (3);
28549       else if (TARGET_PREFETCH_SSE)
28550         operands[1] = const0_rtx;
28551       else
28552         {
28553           gcc_assert (TARGET_3DNOW);
28554           operands[2] = GEN_INT (3);
28555         }
28556     }
28557   else
28558     {
28559       if (TARGET_PREFETCH_SSE)
28560         ;
28561       else
28562         {
28563           gcc_assert (TARGET_3DNOW);
28564           operands[2] = GEN_INT (3);
28565         }
28566     }
28569 (define_insn "*prefetch_sse"
28570   [(prefetch (match_operand 0 "address_operand" "p")
28571              (const_int 0)
28572              (match_operand:SI 1 "const_int_operand"))]
28573   "TARGET_PREFETCH_SSE"
28575   static const char * const patterns[4] = {
28576    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
28577   };
28579   int locality = INTVAL (operands[1]);
28580   gcc_assert (IN_RANGE (locality, 0, 3));
28582   return patterns[locality];
28584   [(set_attr "type" "sse")
28585    (set_attr "atom_sse_attr" "prefetch")
28586    (set (attr "length_address")
28587         (symbol_ref "memory_address_length (operands[0], false)"))
28588    (set_attr "memory" "none")])
28590 (define_insn "*prefetch_3dnow"
28591   [(prefetch (match_operand 0 "address_operand" "p")
28592              (match_operand:SI 1 "const_int_operand")
28593              (const_int 3))]
28594   "TARGET_3DNOW || TARGET_PRFCHW"
28596   if (operands[1] == const0_rtx)
28597     return "prefetch\t%a0";
28598   else
28599     return "prefetchw\t%a0";
28601   [(set_attr "type" "mmx")
28602    (set (attr "length_address")
28603         (symbol_ref "memory_address_length (operands[0], false)"))
28604    (set_attr "memory" "none")])
28606 (define_insn "prefetchi"
28607   [(unspec_volatile [(match_operand 0 "local_func_symbolic_operand" "p")
28608                      (match_operand:SI 1 "const_int_operand")]
28609                     UNSPECV_PREFETCHI)]
28610   "TARGET_PREFETCHI && TARGET_64BIT"
28612   static const char * const patterns[2] = {
28613     "prefetchit1\t%a0", "prefetchit0\t%a0"
28614   };
28616   int locality = INTVAL (operands[1]);
28617   gcc_assert (IN_RANGE (locality, 2, 3));
28619   return patterns[locality - 2];
28621   [(set_attr "type" "sse")
28622    (set (attr "length_address")
28623         (symbol_ref "memory_address_length (operands[0], false)"))
28624    (set_attr "memory" "none")])
28626 (define_insn "sse4_2_crc32<mode>"
28627   [(set (match_operand:SI 0 "register_operand" "=r")
28628         (unspec:SI
28629           [(match_operand:SI 1 "register_operand" "0")
28630            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
28631           UNSPEC_CRC32))]
28632   "TARGET_CRC32"
28633   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
28634   [(set_attr "type" "sselog1")
28635    (set_attr "prefix_rep" "1")
28636    (set_attr "prefix_extra" "1")
28637    (set (attr "prefix_data16")
28638      (if_then_else (match_operand:HI 2)
28639        (const_string "1")
28640        (const_string "*")))
28641    (set (attr "prefix_rex")
28642      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
28643        (const_string "1")
28644        (const_string "*")))
28645    (set_attr "mode" "SI")])
28647 (define_insn "sse4_2_crc32di"
28648   [(set (match_operand:DI 0 "register_operand" "=r")
28649         (zero_extend:DI
28650           (unspec:SI
28651             [(match_operand:SI 1 "register_operand" "0")
28652              (match_operand:DI 2 "nonimmediate_operand" "rm")]
28653           UNSPEC_CRC32)))]
28654   "TARGET_64BIT && TARGET_CRC32"
28655   "crc32{q}\t{%2, %0|%0, %2}"
28656   [(set_attr "type" "sselog1")
28657    (set_attr "prefix_rep" "1")
28658    (set_attr "prefix_extra" "1")
28659    (set_attr "mode" "DI")])
28661 (define_insn "rdpmc"
28662   [(set (match_operand:DI 0 "register_operand" "=A")
28663         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
28664                             UNSPECV_RDPMC))]
28665   "!TARGET_64BIT"
28666   "rdpmc"
28667   [(set_attr "type" "other")
28668    (set_attr "length" "2")])
28670 (define_insn "rdpmc_rex64"
28671   [(set (match_operand:DI 0 "register_operand" "=a")
28672         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
28673                             UNSPECV_RDPMC))
28674    (set (match_operand:DI 1 "register_operand" "=d")
28675         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
28676   "TARGET_64BIT"
28677   "rdpmc"
28678   [(set_attr "type" "other")
28679    (set_attr "length" "2")])
28681 (define_insn "rdtsc"
28682   [(set (match_operand:DI 0 "register_operand" "=A")
28683         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
28684   "!TARGET_64BIT"
28685   "rdtsc"
28686   [(set_attr "type" "other")
28687    (set_attr "length" "2")])
28689 (define_insn "rdtsc_rex64"
28690   [(set (match_operand:DI 0 "register_operand" "=a")
28691         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
28692    (set (match_operand:DI 1 "register_operand" "=d")
28693         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
28694   "TARGET_64BIT"
28695   "rdtsc"
28696   [(set_attr "type" "other")
28697    (set_attr "length" "2")])
28699 (define_insn "rdtscp"
28700   [(set (match_operand:DI 0 "register_operand" "=A")
28701         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
28702    (set (match_operand:SI 1 "register_operand" "=c")
28703         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
28704   "!TARGET_64BIT"
28705   "rdtscp"
28706   [(set_attr "type" "other")
28707    (set_attr "length" "3")])
28709 (define_insn "rdtscp_rex64"
28710   [(set (match_operand:DI 0 "register_operand" "=a")
28711         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
28712    (set (match_operand:DI 1 "register_operand" "=d")
28713         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
28714    (set (match_operand:SI 2 "register_operand" "=c")
28715         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
28716   "TARGET_64BIT"
28717   "rdtscp"
28718   [(set_attr "type" "other")
28719    (set_attr "length" "3")])
28721 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28723 ;; FXSR, XSAVE and XSAVEOPT instructions
28725 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28727 (define_insn "fxsave"
28728   [(set (match_operand:BLK 0 "memory_operand" "=m")
28729         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
28730   "TARGET_FXSR"
28731   "fxsave\t%0"
28732   [(set_attr "type" "other")
28733    (set_attr "memory" "store")
28734    (set (attr "length")
28735         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
28737 (define_insn "fxsave64"
28738   [(set (match_operand:BLK 0 "memory_operand" "=jm")
28739         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
28740   "TARGET_64BIT && TARGET_FXSR"
28741   "fxsave64\t%0"
28742   [(set_attr "type" "other")
28743    (set_attr "addr" "gpr16")
28744    (set_attr "memory" "store")
28745    (set (attr "length")
28746         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
28748 (define_insn "fxrstor"
28749   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
28750                     UNSPECV_FXRSTOR)]
28751   "TARGET_FXSR"
28752   "fxrstor\t%0"
28753   [(set_attr "type" "other")
28754    (set_attr "memory" "load")
28755    (set (attr "length")
28756         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
28758 (define_insn "fxrstor64"
28759   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "jm")]
28760                     UNSPECV_FXRSTOR64)]
28761   "TARGET_64BIT && TARGET_FXSR"
28762   "fxrstor64\t%0"
28763   [(set_attr "type" "other")
28764    (set_attr "addr" "gpr16")
28765    (set_attr "memory" "load")
28766    (set (attr "length")
28767         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
28769 (define_int_iterator ANY_XSAVE
28770         [UNSPECV_XSAVE
28771          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
28772          (UNSPECV_XSAVEC "TARGET_XSAVEC")
28773          (UNSPECV_XSAVES "TARGET_XSAVES")])
28775 (define_int_iterator ANY_XSAVE64
28776         [UNSPECV_XSAVE64
28777          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
28778          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
28779          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
28781 (define_int_attr xsave
28782         [(UNSPECV_XSAVE "xsave")
28783          (UNSPECV_XSAVE64 "xsave64")
28784          (UNSPECV_XSAVEOPT "xsaveopt")
28785          (UNSPECV_XSAVEOPT64 "xsaveopt64")
28786          (UNSPECV_XSAVEC "xsavec")
28787          (UNSPECV_XSAVEC64 "xsavec64")
28788          (UNSPECV_XSAVES "xsaves")
28789          (UNSPECV_XSAVES64 "xsaves64")])
28791 (define_int_iterator ANY_XRSTOR
28792         [UNSPECV_XRSTOR
28793          (UNSPECV_XRSTORS "TARGET_XSAVES")])
28795 (define_int_iterator ANY_XRSTOR64
28796         [UNSPECV_XRSTOR64
28797          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
28799 (define_int_attr xrstor
28800         [(UNSPECV_XRSTOR "xrstor")
28801          (UNSPECV_XRSTOR64 "xrstor")
28802          (UNSPECV_XRSTORS "xrstors")
28803          (UNSPECV_XRSTORS64 "xrstors")])
28805 (define_insn "<xsave>"
28806   [(set (match_operand:BLK 0 "memory_operand" "=m")
28807         (unspec_volatile:BLK
28808          [(match_operand:DI 1 "register_operand" "A")]
28809          ANY_XSAVE))]
28810   "!TARGET_64BIT && TARGET_XSAVE"
28811   "<xsave>\t%0"
28812   [(set_attr "type" "other")
28813    (set_attr "memory" "store")
28814    (set (attr "length")
28815         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
28817 (define_insn "<xsave>_rex64"
28818   [(set (match_operand:BLK 0 "memory_operand" "=jm")
28819         (unspec_volatile:BLK
28820          [(match_operand:SI 1 "register_operand" "a")
28821           (match_operand:SI 2 "register_operand" "d")]
28822          ANY_XSAVE))]
28823   "TARGET_64BIT && TARGET_XSAVE"
28824   "<xsave>\t%0"
28825   [(set_attr "type" "other")
28826    (set_attr "memory" "store")
28827    (set_attr "addr" "gpr16")
28828    (set (attr "length")
28829         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
28831 (define_insn "<xsave>"
28832   [(set (match_operand:BLK 0 "memory_operand" "=jm")
28833         (unspec_volatile:BLK
28834          [(match_operand:SI 1 "register_operand" "a")
28835           (match_operand:SI 2 "register_operand" "d")]
28836          ANY_XSAVE64))]
28837   "TARGET_64BIT && TARGET_XSAVE"
28838   "<xsave>\t%0"
28839   [(set_attr "type" "other")
28840    (set_attr "memory" "store")
28841    (set_attr "addr" "gpr16")
28842    (set (attr "length")
28843         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
28845 (define_insn "<xrstor>"
28846    [(unspec_volatile:BLK
28847      [(match_operand:BLK 0 "memory_operand" "m")
28848       (match_operand:DI 1 "register_operand" "A")]
28849      ANY_XRSTOR)]
28850   "!TARGET_64BIT && TARGET_XSAVE"
28851   "<xrstor>\t%0"
28852   [(set_attr "type" "other")
28853    (set_attr "memory" "load")
28854    (set (attr "length")
28855         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
28857 (define_insn "<xrstor>_rex64"
28858    [(unspec_volatile:BLK
28859      [(match_operand:BLK 0 "memory_operand" "jm")
28860       (match_operand:SI 1 "register_operand" "a")
28861       (match_operand:SI 2 "register_operand" "d")]
28862      ANY_XRSTOR)]
28863   "TARGET_64BIT && TARGET_XSAVE"
28864   "<xrstor>\t%0"
28865   [(set_attr "type" "other")
28866    (set_attr "memory" "load")
28867    (set_attr "addr" "gpr16")
28868    (set (attr "length")
28869         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
28871 (define_insn "<xrstor>64"
28872    [(unspec_volatile:BLK
28873      [(match_operand:BLK 0 "memory_operand" "jm")
28874       (match_operand:SI 1 "register_operand" "a")
28875       (match_operand:SI 2 "register_operand" "d")]
28876      ANY_XRSTOR64)]
28877   "TARGET_64BIT && TARGET_XSAVE"
28878   "<xrstor>64\t%0"
28879   [(set_attr "type" "other")
28880    (set_attr "memory" "load")
28881    (set_attr "addr" "gpr16")
28882    (set (attr "length")
28883         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
28885 (define_insn "xsetbv"
28886   [(unspec_volatile:SI
28887          [(match_operand:SI 0 "register_operand" "c")
28888           (match_operand:DI 1 "register_operand" "A")]
28889          UNSPECV_XSETBV)]
28890   "!TARGET_64BIT && TARGET_XSAVE"
28891   "xsetbv"
28892   [(set_attr "type" "other")])
28894 (define_insn "xsetbv_rex64"
28895   [(unspec_volatile:SI
28896          [(match_operand:SI 0 "register_operand" "c")
28897           (match_operand:SI 1 "register_operand" "a")
28898           (match_operand:SI 2 "register_operand" "d")]
28899          UNSPECV_XSETBV)]
28900   "TARGET_64BIT && TARGET_XSAVE"
28901   "xsetbv"
28902   [(set_attr "type" "other")])
28904 (define_insn "xgetbv"
28905   [(set (match_operand:DI 0 "register_operand" "=A")
28906         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
28907                             UNSPECV_XGETBV))]
28908   "!TARGET_64BIT && TARGET_XSAVE"
28909   "xgetbv"
28910   [(set_attr "type" "other")])
28912 (define_insn "xgetbv_rex64"
28913   [(set (match_operand:DI 0 "register_operand" "=a")
28914         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
28915                             UNSPECV_XGETBV))
28916    (set (match_operand:DI 1 "register_operand" "=d")
28917         (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
28918   "TARGET_64BIT && TARGET_XSAVE"
28919   "xgetbv"
28920   [(set_attr "type" "other")])
28922 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28924 ;; Floating-point instructions for atomic compound assignments
28926 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28928 ; Clobber all floating-point registers on environment save and restore
28929 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
28930 (define_insn "fnstenv"
28931   [(set (match_operand:BLK 0 "memory_operand" "=m")
28932         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
28933    (clobber (reg:XF ST0_REG))
28934    (clobber (reg:XF ST1_REG))
28935    (clobber (reg:XF ST2_REG))
28936    (clobber (reg:XF ST3_REG))
28937    (clobber (reg:XF ST4_REG))
28938    (clobber (reg:XF ST5_REG))
28939    (clobber (reg:XF ST6_REG))
28940    (clobber (reg:XF ST7_REG))]
28941   "TARGET_80387"
28942   "fnstenv\t%0"
28943   [(set_attr "type" "other")
28944    (set_attr "memory" "store")
28945    (set (attr "length")
28946         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
28948 (define_insn "fldenv"
28949   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
28950                     UNSPECV_FLDENV)
28951    (clobber (reg:XF ST0_REG))
28952    (clobber (reg:XF ST1_REG))
28953    (clobber (reg:XF ST2_REG))
28954    (clobber (reg:XF ST3_REG))
28955    (clobber (reg:XF ST4_REG))
28956    (clobber (reg:XF ST5_REG))
28957    (clobber (reg:XF ST6_REG))
28958    (clobber (reg:XF ST7_REG))]
28959   "TARGET_80387"
28960   "fldenv\t%0"
28961   [(set_attr "type" "other")
28962    (set_attr "memory" "load")
28963    (set (attr "length")
28964         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
28966 (define_insn "fnstsw"
28967   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
28968         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
28969   "TARGET_80387"
28970   "fnstsw\t%0"
28971   [(set_attr "type" "other,other")
28972    (set_attr "memory" "none,store")
28973    (set (attr "length")
28974         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
28976 (define_insn "fnclex"
28977   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
28978   "TARGET_80387"
28979   "fnclex"
28980   [(set_attr "type" "other")
28981    (set_attr "memory" "none")
28982    (set_attr "length" "2")])
28984 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28986 ;; LWP instructions
28988 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28990 (define_insn "@lwp_llwpcb<mode>"
28991   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
28992                     UNSPECV_LLWP_INTRINSIC)]
28993   "TARGET_LWP"
28994   "llwpcb\t%0"
28995   [(set_attr "type" "lwp")
28996    (set_attr "mode" "<MODE>")
28997    (set_attr "length" "5")])
28999 (define_insn "@lwp_slwpcb<mode>"
29000   [(set (match_operand:P 0 "register_operand" "=r")
29001         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
29002   "TARGET_LWP"
29003   "slwpcb\t%0"
29004   [(set_attr "type" "lwp")
29005    (set_attr "mode" "<MODE>")
29006    (set_attr "length" "5")])
29008 (define_insn "@lwp_lwpval<mode>"
29009   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
29010                      (match_operand:SI 1 "nonimmediate_operand" "rm")
29011                      (match_operand:SI 2 "const_int_operand")]
29012                     UNSPECV_LWPVAL_INTRINSIC)]
29013   "TARGET_LWP"
29014   "lwpval\t{%2, %1, %0|%0, %1, %2}"
29015   [(set_attr "type" "lwp")
29016    (set_attr "mode" "<MODE>")
29017    (set (attr "length")
29018         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
29020 (define_insn "@lwp_lwpins<mode>"
29021   [(set (reg:CCC FLAGS_REG)
29022         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
29023                               (match_operand:SI 1 "nonimmediate_operand" "rm")
29024                               (match_operand:SI 2 "const_int_operand")]
29025                              UNSPECV_LWPINS_INTRINSIC))]
29026   "TARGET_LWP"
29027   "lwpins\t{%2, %1, %0|%0, %1, %2}"
29028   [(set_attr "type" "lwp")
29029    (set_attr "mode" "<MODE>")
29030    (set (attr "length")
29031         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
29033 (define_int_iterator RDFSGSBASE
29034         [UNSPECV_RDFSBASE
29035          UNSPECV_RDGSBASE])
29037 (define_int_iterator WRFSGSBASE
29038         [UNSPECV_WRFSBASE
29039          UNSPECV_WRGSBASE])
29041 (define_int_attr fsgs
29042         [(UNSPECV_RDFSBASE "fs")
29043          (UNSPECV_RDGSBASE "gs")
29044          (UNSPECV_WRFSBASE "fs")
29045          (UNSPECV_WRGSBASE "gs")])
29047 (define_insn "rd<fsgs>base<mode>"
29048   [(set (match_operand:SWI48 0 "register_operand" "=r")
29049         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
29050   "TARGET_64BIT && TARGET_FSGSBASE"
29051   "rd<fsgs>base\t%0"
29052   [(set_attr "type" "other")
29053    (set_attr "prefix_0f" "1")
29054    (set_attr "prefix_rep" "1")])
29056 (define_insn "wr<fsgs>base<mode>"
29057   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
29058                     WRFSGSBASE)]
29059   "TARGET_64BIT && TARGET_FSGSBASE"
29060   "wr<fsgs>base\t%0"
29061   [(set_attr "type" "other")
29062    (set_attr "prefix_0f" "1")
29063    (set_attr "prefix_rep" "1")])
29065 (define_insn "ptwrite<mode>"
29066   [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
29067                     UNSPECV_PTWRITE)]
29068   "TARGET_PTWRITE"
29069   "ptwrite\t%0"
29070   [(set_attr "type" "other")
29071    (set_attr "prefix_0f" "1")
29072    (set_attr "prefix_rep" "1")])
29074 (define_insn "@rdrand<mode>"
29075   [(set (match_operand:SWI248 0 "register_operand" "=r")
29076         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
29077    (set (reg:CCC FLAGS_REG)
29078         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
29079   "TARGET_RDRND"
29080   "rdrand\t%0"
29081   [(set_attr "type" "other")
29082    (set_attr "prefix_0f" "1")])
29084 (define_insn "@rdseed<mode>"
29085   [(set (match_operand:SWI248 0 "register_operand" "=r")
29086         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
29087    (set (reg:CCC FLAGS_REG)
29088         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
29089   "TARGET_RDSEED"
29090   "rdseed\t%0"
29091   [(set_attr "type" "other")
29092    (set_attr "prefix_0f" "1")])
29094 (define_expand "pause"
29095   [(set (match_dup 0)
29096         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
29097   ""
29099   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
29100   MEM_VOLATILE_P (operands[0]) = 1;
29103 ;; Use "rep; nop", instead of "pause", to support older assemblers.
29104 ;; They have the same encoding.
29105 (define_insn "*pause"
29106   [(set (match_operand:BLK 0)
29107         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
29108   ""
29109   "rep%; nop"
29110   [(set_attr "length" "2")
29111    (set_attr "memory" "unknown")])
29113 ;; CET instructions
29114 (define_insn "@rdssp<mode>"
29115   [(set (match_operand:SWI48 0 "register_operand" "=r")
29116         (unspec_volatile:SWI48 [(match_operand:SWI48 1 "register_operand" "0")]
29117                                UNSPECV_NOP_RDSSP))]
29118   "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
29119   "rdssp<mskmodesuffix>\t%0"
29120   [(set_attr "length" "6")
29121    (set_attr "type" "other")])
29123 (define_insn "@incssp<mode>"
29124   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
29125                     UNSPECV_INCSSP)]
29126   "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
29127   "incssp<mskmodesuffix>\t%0"
29128   [(set_attr "length" "4")
29129    (set_attr "type" "other")])
29131 (define_insn "saveprevssp"
29132   [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
29133   "TARGET_SHSTK"
29134   "saveprevssp"
29135   [(set_attr "length" "5")
29136    (set_attr "type" "other")])
29138 (define_insn "rstorssp"
29139   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
29140                     UNSPECV_RSTORSSP)]
29141   "TARGET_SHSTK"
29142   "rstorssp\t%0"
29143   [(set_attr "length" "5")
29144    (set_attr "type" "other")])
29146 (define_insn "@wrss<mode>"
29147   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
29148                      (match_operand:SWI48 1 "memory_operand" "m")]
29149                     UNSPECV_WRSS)]
29150   "TARGET_SHSTK"
29151   "wrss<mskmodesuffix>\t%0, %1"
29152   [(set_attr "length" "3")
29153    (set_attr "type" "other")])
29155 (define_insn "@wruss<mode>"
29156   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
29157                      (match_operand:SWI48 1 "memory_operand" "m")]
29158                     UNSPECV_WRUSS)]
29159   "TARGET_SHSTK"
29160   "wruss<mskmodesuffix>\t%0, %1"
29161   [(set_attr "length" "4")
29162    (set_attr "type" "other")])
29164 (define_insn "setssbsy"
29165   [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
29166   "TARGET_SHSTK"
29167   "setssbsy"
29168   [(set_attr "length" "4")
29169    (set_attr "type" "other")])
29171 (define_insn "clrssbsy"
29172   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
29173                     UNSPECV_CLRSSBSY)]
29174   "TARGET_SHSTK"
29175   "clrssbsy\t%0"
29176   [(set_attr "length" "4")
29177    (set_attr "type" "other")])
29179 (define_insn "nop_endbr"
29180   [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
29181   "(flag_cf_protection & CF_BRANCH)"
29183   return TARGET_64BIT ? "endbr64" : "endbr32";
29185   [(set_attr "length" "4")
29186    (set_attr "length_immediate" "0")
29187    (set_attr "modrm" "0")])
29189 ;; For RTM support
29190 (define_expand "xbegin"
29191   [(set (match_operand:SI 0 "register_operand")
29192         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
29193   "TARGET_RTM"
29195   rtx_code_label *label = gen_label_rtx ();
29197   /* xbegin is emitted as jump_insn, so reload won't be able
29198      to reload its operand.  Force the value into AX hard register.  */
29199   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
29200   emit_move_insn (ax_reg, constm1_rtx);
29202   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
29204   emit_label (label);
29205   LABEL_NUSES (label) = 1;
29207   emit_move_insn (operands[0], ax_reg);
29209   DONE;
29212 (define_insn "xbegin_1"
29213   [(set (pc)
29214         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
29215                           (const_int 0))
29216                       (label_ref (match_operand 1))
29217                       (pc)))
29218    (set (match_operand:SI 0 "register_operand" "+a")
29219         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
29220   "TARGET_RTM"
29221   "xbegin\t%l1"
29222   [(set_attr "type" "other")
29223    (set_attr "length" "6")])
29225 (define_insn "xend"
29226   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
29227   "TARGET_RTM"
29228   "xend"
29229   [(set_attr "type" "other")
29230    (set_attr "length" "3")])
29232 (define_insn "xabort"
29233   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand")]
29234                     UNSPECV_XABORT)]
29235   "TARGET_RTM"
29236   "xabort\t%0"
29237   [(set_attr "type" "other")
29238    (set_attr "length" "3")])
29240 (define_expand "xtest"
29241   [(set (match_operand:QI 0 "register_operand")
29242         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
29243   "TARGET_RTM"
29245   emit_insn (gen_xtest_1 ());
29247   ix86_expand_setcc (operands[0], NE,
29248                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
29249   DONE;
29252 (define_insn "xtest_1"
29253   [(set (reg:CCZ FLAGS_REG)
29254         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
29255   "TARGET_RTM"
29256   "xtest"
29257   [(set_attr "type" "other")
29258    (set_attr "length" "3")])
29260 (define_insn "clwb"
29261   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
29262                    UNSPECV_CLWB)]
29263   "TARGET_CLWB"
29264   "clwb\t%a0"
29265   [(set_attr "type" "sse")
29266    (set_attr "atom_sse_attr" "fence")
29267    (set_attr "memory" "unknown")])
29269 (define_insn "clflushopt"
29270   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
29271                    UNSPECV_CLFLUSHOPT)]
29272   "TARGET_CLFLUSHOPT"
29273   "clflushopt\t%a0"
29274   [(set_attr "type" "sse")
29275    (set_attr "atom_sse_attr" "fence")
29276    (set_attr "memory" "unknown")])
29278 ;; MONITORX and MWAITX
29279 (define_insn "mwaitx"
29280   [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
29281                      (match_operand:SI 1 "register_operand" "a")
29282                      (match_operand:SI 2 "register_operand" "b")]
29283                    UNSPECV_MWAITX)]
29284   "TARGET_MWAITX"
29285 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
29286 ;; Since 32bit register operands are implicitly zero extended to 64bit,
29287 ;; we only need to set up 32bit registers.
29288   "mwaitx"
29289   [(set_attr "length" "3")])
29291 (define_insn "@monitorx_<mode>"
29292   [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
29293                      (match_operand:SI 1 "register_operand" "c")
29294                      (match_operand:SI 2 "register_operand" "d")]
29295                    UNSPECV_MONITORX)]
29296   "TARGET_MWAITX"
29297 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
29298 ;; RCX and RDX are used.  Since 32bit register operands are implicitly
29299 ;; zero extended to 64bit, we only need to set up 32bit registers.
29300   "%^monitorx"
29301   [(set (attr "length")
29302      (symbol_ref ("(Pmode != word_mode) + 3")))])
29304 ;; CLZERO
29305 (define_insn "@clzero_<mode>"
29306   [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
29307                    UNSPECV_CLZERO)]
29308   "TARGET_CLZERO"
29309   "clzero"
29310   [(set_attr "length" "3")
29311   (set_attr "memory" "unknown")])
29313 ;; RDPKRU and WRPKRU
29315 (define_expand "rdpkru"
29316   [(parallel
29317      [(set (match_operand:SI 0 "register_operand")
29318            (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
29319       (set (match_dup 2) (const_int 0))])]
29320   "TARGET_PKU"
29322   operands[1] = force_reg (SImode, const0_rtx);
29323   operands[2] = gen_reg_rtx (SImode);
29326 (define_insn "*rdpkru"
29327   [(set (match_operand:SI 0 "register_operand" "=a")
29328         (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
29329                             UNSPECV_PKU))
29330    (set (match_operand:SI 1 "register_operand" "=d")
29331         (const_int 0))]
29332   "TARGET_PKU"
29333   "rdpkru"
29334   [(set_attr "type" "other")])
29336 (define_expand "wrpkru"
29337   [(unspec_volatile:SI
29338      [(match_operand:SI 0 "register_operand")
29339       (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
29340   "TARGET_PKU"
29342   operands[1] = force_reg (SImode, const0_rtx);
29343   operands[2] = force_reg (SImode, const0_rtx);
29346 (define_insn "*wrpkru"
29347   [(unspec_volatile:SI
29348      [(match_operand:SI 0 "register_operand" "a")
29349       (match_operand:SI 1 "register_operand" "d")
29350       (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
29351   "TARGET_PKU"
29352   "wrpkru"
29353   [(set_attr "type" "other")])
29355 (define_insn "rdpid"
29356   [(set (match_operand:SI 0 "register_operand" "=r")
29357         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
29358   "!TARGET_64BIT && TARGET_RDPID"
29359   "rdpid\t%0"
29360   [(set_attr "type" "other")])
29362 (define_insn "rdpid_rex64"
29363   [(set (match_operand:DI 0 "register_operand" "=r")
29364         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
29365   "TARGET_64BIT && TARGET_RDPID"
29366   "rdpid\t%0"
29367   [(set_attr "type" "other")])
29369 ;; Intirinsics for > i486
29371 (define_insn "wbinvd"
29372   [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
29373   ""
29374   "wbinvd"
29375   [(set_attr "type" "other")])
29377 (define_insn "wbnoinvd"
29378   [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
29379   "TARGET_WBNOINVD"
29380   "wbnoinvd"
29381   [(set_attr "type" "other")])
29383 ;; MOVDIRI and MOVDIR64B
29385 (define_insn "movdiri<mode>"
29386   [(set (match_operand:SWI48 0 "memory_operand" "=m")
29387         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
29388                       UNSPEC_MOVDIRI))]
29389   "TARGET_MOVDIRI"
29390   "movdiri\t{%1, %0|%0, %1}"
29391   [(set_attr "type" "other")])
29393 (define_insn "@movdir64b_<mode>"
29394   [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
29395         (unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
29396                    UNSPEC_MOVDIR64B))]
29397   "TARGET_MOVDIR64B"
29398   "movdir64b\t{%1, %0|%0, %1}"
29399   [(set_attr "type" "other")])
29401 ;; TSXLDTRK
29402 (define_int_iterator TSXLDTRK [UNSPECV_XSUSLDTRK UNSPECV_XRESLDTRK])
29403 (define_int_attr tsxldtrk [(UNSPECV_XSUSLDTRK "xsusldtrk")
29404                  (UNSPECV_XRESLDTRK "xresldtrk")])
29405 (define_insn "<tsxldtrk>"
29406   [(unspec_volatile [(const_int 0)] TSXLDTRK)]
29407   "TARGET_TSXLDTRK"
29408   "<tsxldtrk>"
29409   [(set_attr "type" "other")
29410    (set_attr "length" "4")])
29412 ;; ENQCMD and ENQCMDS
29414 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
29415 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
29417 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
29418   [(set (reg:CCZ FLAGS_REG)
29419         (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
29420                               (match_operand:XI 1 "memory_operand" "m")]
29421                              ENQCMD))]
29422   "TARGET_ENQCMD"
29423   "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
29424   [(set_attr "type" "other")])
29426 ;; UINTR
29427 (define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI])
29428 (define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")])
29430 (define_insn "<uintr>"
29431   [(unspec_volatile [(const_int 0)] UINTR)]
29432   "TARGET_UINTR && TARGET_64BIT"
29433   "<uintr>"
29434   [(set_attr "type" "other")
29435    (set_attr "length" "4")])
29437 (define_insn "testui"
29438   [(set (reg:CCC FLAGS_REG)
29439         (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))]
29440   "TARGET_UINTR && TARGET_64BIT"
29441   "testui"
29442   [(set_attr "type" "other")
29443    (set_attr "length" "4")])
29445 (define_insn "senduipi"
29446   [(unspec_volatile
29447     [(match_operand:DI 0 "register_operand" "r")]
29448     UNSPECV_SENDUIPI)]
29449   "TARGET_UINTR && TARGET_64BIT"
29450   "senduipi\t%0"
29451   [(set_attr "type" "other")
29452    (set_attr "length" "4")])
29454 ;; WAITPKG
29456 (define_insn "umwait"
29457   [(set (reg:CCC FLAGS_REG)
29458         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
29459                               (match_operand:DI 1 "register_operand" "A")]
29460                              UNSPECV_UMWAIT))]
29461   "!TARGET_64BIT && TARGET_WAITPKG"
29462   "umwait\t%0"
29463   [(set_attr "length" "3")])
29465 (define_insn "umwait_rex64"
29466   [(set (reg:CCC FLAGS_REG)
29467         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
29468                               (match_operand:SI 1 "register_operand" "a")
29469                               (match_operand:SI 2 "register_operand" "d")]
29470                              UNSPECV_UMWAIT))]
29471   "TARGET_64BIT && TARGET_WAITPKG"
29472   "umwait\t%0"
29473   [(set_attr "length" "3")])
29475 (define_insn "@umonitor_<mode>"
29476   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
29477                     UNSPECV_UMONITOR)]
29478   "TARGET_WAITPKG"
29479   "umonitor\t%0"
29480   [(set (attr "length")
29481      (symbol_ref ("(Pmode != word_mode) + 3")))])
29483 (define_insn "tpause"
29484   [(set (reg:CCC FLAGS_REG)
29485         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
29486                               (match_operand:DI 1 "register_operand" "A")]
29487                              UNSPECV_TPAUSE))]
29488   "!TARGET_64BIT && TARGET_WAITPKG"
29489   "tpause\t%0"
29490   [(set_attr "length" "3")])
29492 (define_insn "tpause_rex64"
29493   [(set (reg:CCC FLAGS_REG)
29494         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
29495                               (match_operand:SI 1 "register_operand" "a")
29496                               (match_operand:SI 2 "register_operand" "d")]
29497                              UNSPECV_TPAUSE))]
29498   "TARGET_64BIT && TARGET_WAITPKG"
29499   "tpause\t%0"
29500   [(set_attr "length" "3")])
29502 (define_insn "cldemote"
29503   [(unspec_volatile[(match_operand 0 "address_operand" "p")]
29504                  UNSPECV_CLDEMOTE)]
29505   "TARGET_CLDEMOTE"
29506   "cldemote\t%a0"
29507   [(set_attr "type" "other")
29508    (set_attr "memory" "unknown")])
29510 (define_insn "speculation_barrier"
29511   [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
29512   ""
29513   "lfence"
29514   [(set_attr "type" "other")
29515    (set_attr "length" "3")])
29517 (define_insn "serialize"
29518   [(unspec_volatile [(const_int 0)] UNSPECV_SERIALIZE)]
29519   "TARGET_SERIALIZE"
29520   "serialize"
29521   [(set_attr "type" "other")
29522    (set_attr "length" "3")])
29524 (define_insn "patchable_area"
29525   [(unspec_volatile [(match_operand 0 "const_int_operand")
29526                      (match_operand 1 "const_int_operand")]
29527                     UNSPECV_PATCHABLE_AREA)]
29528   ""
29530   ix86_output_patchable_area (INTVAL (operands[0]),
29531                               INTVAL (operands[1]) != 0);
29532   return "";
29534   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
29535    (set_attr "length_immediate" "0")
29536    (set_attr "modrm" "0")])
29538 (define_insn "hreset"
29539   [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")]
29540                      UNSPECV_HRESET)]
29541   "TARGET_HRESET"
29542   "hreset\t{$0|0}"
29543   [(set_attr "type" "other")
29544    (set_attr "length" "4")])
29546 ;; Spaceship optimization
29547 (define_expand "spaceship<mode>4"
29548   [(match_operand:SI 0 "register_operand")
29549    (match_operand:MODEF 1 "cmp_fp_expander_operand")
29550    (match_operand:MODEF 2 "cmp_fp_expander_operand")
29551    (match_operand:SI 3 "const_int_operand")]
29552   "(TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
29553    && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
29555   ix86_expand_fp_spaceship (operands[0], operands[1], operands[2],
29556                             operands[3]);
29557   DONE;
29560 (define_expand "spaceshipxf4"
29561   [(match_operand:SI 0 "register_operand")
29562    (match_operand:XF 1 "nonmemory_operand")
29563    (match_operand:XF 2 "nonmemory_operand")
29564    (match_operand:SI 3 "const_int_operand")]
29565   "TARGET_80387 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
29567   ix86_expand_fp_spaceship (operands[0], operands[1], operands[2],
29568                             operands[3]);
29569   DONE;
29572 (define_expand "spaceship<mode>4"
29573   [(match_operand:SI 0 "register_operand")
29574    (match_operand:SWI 1 "nonimmediate_operand")
29575    (match_operand:SWI 2 "<general_operand>")
29576    (match_operand:SI 3 "const_int_operand")]
29577   ""
29579   ix86_expand_int_spaceship (operands[0], operands[1], operands[2],
29580                              operands[3]);
29581   DONE;
29584 ;; Defined because the generic expand_builtin_issignaling for XFmode
29585 ;; only tests for sNaNs, but i387 treats also pseudo numbers as always
29586 ;; signaling.
29587 (define_expand "issignalingxf2"
29588   [(match_operand:SI 0 "register_operand")
29589    (match_operand:XF 1 "general_operand")]
29590   ""
29592   rtx temp = operands[1];
29593   if (!MEM_P (temp))
29594     {
29595       rtx mem = assign_stack_temp (XFmode, GET_MODE_SIZE (XFmode));
29596       emit_move_insn (mem, temp);
29597       temp = mem;
29598     }
29599   rtx ex = adjust_address (temp, HImode, 8);
29600   rtx hi = adjust_address (temp, SImode, 4);
29601   rtx lo = adjust_address (temp, SImode, 0);
29602   rtx val = GEN_INT (HOST_WIDE_INT_M1U << 30);
29603   rtx mask = GEN_INT (0x7fff);
29604   rtx bit = GEN_INT (HOST_WIDE_INT_1U << 30);
29605   /* Expand to:
29606      ((ex & mask) && (int) hi >= 0)
29607      || ((ex & mask) == mask && ((hi ^ bit) | ((lo | -lo) >> 31)) > val).  */
29608   rtx nlo = expand_unop (SImode, neg_optab, lo, NULL_RTX, 0);
29609   lo = expand_binop (SImode, ior_optab, lo, nlo,
29610                      NULL_RTX, 1, OPTAB_LIB_WIDEN);
29611   lo = expand_shift (RSHIFT_EXPR, SImode, lo, 31, NULL_RTX, 1);
29612   temp = expand_binop (SImode, xor_optab, hi, bit,
29613                        NULL_RTX, 1, OPTAB_LIB_WIDEN);
29614   temp = expand_binop (SImode, ior_optab, temp, lo,
29615                        NULL_RTX, 1, OPTAB_LIB_WIDEN);
29616   temp = emit_store_flag_force (gen_reg_rtx (SImode), GTU, temp, val,
29617                                 SImode, 1, 1);
29618   ex = expand_binop (HImode, and_optab, ex, mask,
29619                      NULL_RTX, 1, OPTAB_LIB_WIDEN);
29620   rtx temp2 = emit_store_flag_force (gen_reg_rtx (SImode), NE,
29621                                      ex, const0_rtx, SImode, 1, 1);
29622   ex = emit_store_flag_force (gen_reg_rtx (SImode), EQ,
29623                               ex, mask, HImode, 1, 1);
29624   temp = expand_binop (SImode, and_optab, temp, ex,
29625                        NULL_RTX, 1, OPTAB_LIB_WIDEN);
29626   rtx temp3 = emit_store_flag_force (gen_reg_rtx (SImode), GE,
29627                                      hi, const0_rtx, SImode, 0, 1);
29628   temp2 = expand_binop (SImode, and_optab, temp2, temp3,
29629                         NULL_RTX, 1, OPTAB_LIB_WIDEN);
29630   temp = expand_binop (SImode, ior_optab, temp, temp2,
29631                        NULL_RTX, 1, OPTAB_LIB_WIDEN);
29632   emit_move_insn (operands[0], temp);
29633   DONE;
29636 (define_insn "urdmsr"
29637   [(set (match_operand:DI 0 "register_operand" "=r")
29638     (unspec_volatile:DI
29639       [(match_operand:DI 1 "x86_64_szext_nonmemory_operand" "reZ")]
29640       UNSPECV_URDMSR))]
29641   "TARGET_USER_MSR && TARGET_64BIT"
29642   "urdmsr\t{%1, %0|%0, %1}"
29643   [(set_attr "prefix" "vex")
29644    (set_attr "type" "other")])
29646 (define_insn "uwrmsr"
29647   [(unspec_volatile
29648     [(match_operand:DI 0 "x86_64_szext_nonmemory_operand" "reZ")
29649       (match_operand:DI 1 "register_operand" "r")]
29650       UNSPECV_UWRMSR)]
29651   "TARGET_USER_MSR && TARGET_64BIT"
29652   "uwrmsr\t{%1, %0|%0, %1}"
29653   [(set_attr "prefix" "vex")
29654    (set_attr "type" "other")])
29656 (define_insn "ldtilecfg"
29657   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
29658             UNSPECV_LDTILECFG)]
29659   "TARGET_AMX_TILE"
29660   "ldtilecfg\t%0"
29661   [(set_attr "type" "other")
29662    (set_attr "prefix" "maybe_evex")
29663    (set_attr "memory" "load")])
29665 (define_insn "sttilecfg"
29666   [(set (match_operand:BLK 0 "memory_operand" "=m")
29667         (unspec_volatile:BLK [(const_int 0)] UNSPECV_STTILECFG))]
29668   "TARGET_AMX_TILE"
29669   "sttilecfg\t%0"
29670   [(set_attr "type" "other")
29671    (set_attr "prefix" "maybe_evex")
29672    (set_attr "memory" "store")])
29674 (include "mmx.md")
29675 (include "sse.md")
29676 (include "sync.md")