gcc/
[official-gcc.git] / gcc / config / i386 / i386.md
blobb8ce6c0b39c6e82f34a6baad66881ae66cab8440
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2014 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 a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
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
82   ;; Prologue support
83   UNSPEC_STACK_ALLOC
84   UNSPEC_SET_GOT
85   UNSPEC_SET_RIP
86   UNSPEC_SET_GOT_OFFSET
87   UNSPEC_MEMORY_BLOCKAGE
88   UNSPEC_STACK_CHECK
90   ;; TLS support
91   UNSPEC_TP
92   UNSPEC_TLS_GD
93   UNSPEC_TLS_LD_BASE
94   UNSPEC_TLSDESC
95   UNSPEC_TLS_IE_SUN
97   ;; Other random patterns
98   UNSPEC_SCAS
99   UNSPEC_FNSTSW
100   UNSPEC_SAHF
101   UNSPEC_PARITY
102   UNSPEC_FSTCW
103   UNSPEC_ADD_CARRY
104   UNSPEC_FLDCW
105   UNSPEC_REP
106   UNSPEC_LD_MPIC        ; load_macho_picbase
107   UNSPEC_TRUNC_NOOP
108   UNSPEC_DIV_ALREADY_SPLIT
109   UNSPEC_MS_TO_SYSV_CALL
110   UNSPEC_PAUSE
111   UNSPEC_LEA_ADDR
112   UNSPEC_XBEGIN_ABORT
113   UNSPEC_STOS
114   UNSPEC_PEEPSIB
116   ;; For SSE/MMX support:
117   UNSPEC_FIX_NOTRUNC
118   UNSPEC_MASKMOV
119   UNSPEC_MOVMSK
120   UNSPEC_RCP
121   UNSPEC_RSQRT
122   UNSPEC_PSADBW
124   ;; Generic math support
125   UNSPEC_COPYSIGN
126   UNSPEC_IEEE_MIN       ; not commutative
127   UNSPEC_IEEE_MAX       ; not commutative
129   ;; x87 Floating point
130   UNSPEC_SIN
131   UNSPEC_COS
132   UNSPEC_FPATAN
133   UNSPEC_FYL2X
134   UNSPEC_FYL2XP1
135   UNSPEC_FRNDINT
136   UNSPEC_FIST
137   UNSPEC_F2XM1
138   UNSPEC_TAN
139   UNSPEC_FXAM
141   ;; x87 Rounding
142   UNSPEC_FRNDINT_FLOOR
143   UNSPEC_FRNDINT_CEIL
144   UNSPEC_FRNDINT_TRUNC
145   UNSPEC_FRNDINT_MASK_PM
146   UNSPEC_FIST_FLOOR
147   UNSPEC_FIST_CEIL
149   ;; x87 Double output FP
150   UNSPEC_SINCOS_COS
151   UNSPEC_SINCOS_SIN
152   UNSPEC_XTRACT_FRACT
153   UNSPEC_XTRACT_EXP
154   UNSPEC_FSCALE_FRACT
155   UNSPEC_FSCALE_EXP
156   UNSPEC_FPREM_F
157   UNSPEC_FPREM_U
158   UNSPEC_FPREM1_F
159   UNSPEC_FPREM1_U
161   UNSPEC_C2_FLAG
162   UNSPEC_FXAM_MEM
164   ;; SSP patterns
165   UNSPEC_SP_SET
166   UNSPEC_SP_TEST
167   UNSPEC_SP_TLS_SET
168   UNSPEC_SP_TLS_TEST
170   ;; For ROUND support
171   UNSPEC_ROUND
173   ;; For CRC32 support
174   UNSPEC_CRC32
176   ;; For BMI support
177   UNSPEC_BEXTR
179   ;; For BMI2 support
180   UNSPEC_PDEP
181   UNSPEC_PEXT
183   ;; For AVX512F support
184   UNSPEC_KMOV
187 (define_c_enum "unspecv" [
188   UNSPECV_BLOCKAGE
189   UNSPECV_STACK_PROBE
190   UNSPECV_PROBE_STACK_RANGE
191   UNSPECV_ALIGN
192   UNSPECV_PROLOGUE_USE
193   UNSPECV_SPLIT_STACK_RETURN
194   UNSPECV_CLD
195   UNSPECV_NOPS
196   UNSPECV_RDTSC
197   UNSPECV_RDTSCP
198   UNSPECV_RDPMC
199   UNSPECV_LLWP_INTRINSIC
200   UNSPECV_SLWP_INTRINSIC
201   UNSPECV_LWPVAL_INTRINSIC
202   UNSPECV_LWPINS_INTRINSIC
203   UNSPECV_RDFSBASE
204   UNSPECV_RDGSBASE
205   UNSPECV_WRFSBASE
206   UNSPECV_WRGSBASE
207   UNSPECV_FXSAVE
208   UNSPECV_FXRSTOR
209   UNSPECV_FXSAVE64
210   UNSPECV_FXRSTOR64
211   UNSPECV_XSAVE
212   UNSPECV_XRSTOR
213   UNSPECV_XSAVE64
214   UNSPECV_XRSTOR64
215   UNSPECV_XSAVEOPT
216   UNSPECV_XSAVEOPT64
217   UNSPECV_XSAVES
218   UNSPECV_XRSTORS
219   UNSPECV_XSAVES64
220   UNSPECV_XRSTORS64
221   UNSPECV_XSAVEC
222   UNSPECV_XSAVEC64
224   ;; For atomic compound assignments.
225   UNSPECV_FNSTENV
226   UNSPECV_FLDENV
227   UNSPECV_FNSTSW
228   UNSPECV_FNCLEX
230   ;; For RDRAND support
231   UNSPECV_RDRAND
233   ;; For RDSEED support
234   UNSPECV_RDSEED
236   ;; For RTM support
237   UNSPECV_XBEGIN
238   UNSPECV_XEND
239   UNSPECV_XABORT
240   UNSPECV_XTEST
242   UNSPECV_NLGR
244   ;; For CLFLUSHOPT support
245   UNSPECV_CLFLUSHOPT
248 ;; Constants to represent rounding modes in the ROUND instruction
249 (define_constants
250   [(ROUND_FLOOR                 0x1)
251    (ROUND_CEIL                  0x2)
252    (ROUND_TRUNC                 0x3)
253    (ROUND_MXCSR                 0x4)
254    (ROUND_NO_EXC                0x8)
255   ])
257 ;; Constants to represent AVX512F embeded rounding
258 (define_constants
259   [(ROUND_NEAREST_INT                   0)
260    (ROUND_NEG_INF                       1)
261    (ROUND_POS_INF                       2)
262    (ROUND_ZERO                          3)
263    (NO_ROUND                            4)
264    (ROUND_SAE                           8)
265   ])
267 ;; Constants to represent pcomtrue/pcomfalse variants
268 (define_constants
269   [(PCOM_FALSE                  0)
270    (PCOM_TRUE                   1)
271    (COM_FALSE_S                 2)
272    (COM_FALSE_P                 3)
273    (COM_TRUE_S                  4)
274    (COM_TRUE_P                  5)
275   ])
277 ;; Constants used in the XOP pperm instruction
278 (define_constants
279   [(PPERM_SRC                   0x00)   /* copy source */
280    (PPERM_INVERT                0x20)   /* invert source */
281    (PPERM_REVERSE               0x40)   /* bit reverse source */
282    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
283    (PPERM_ZERO                  0x80)   /* all 0's */
284    (PPERM_ONES                  0xa0)   /* all 1's */
285    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
286    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
287    (PPERM_SRC1                  0x00)   /* use first source byte */
288    (PPERM_SRC2                  0x10)   /* use second source byte */
289    ])
291 ;; Registers by name.
292 (define_constants
293   [(AX_REG                       0)
294    (DX_REG                       1)
295    (CX_REG                       2)
296    (BX_REG                       3)
297    (SI_REG                       4)
298    (DI_REG                       5)
299    (BP_REG                       6)
300    (SP_REG                       7)
301    (ST0_REG                      8)
302    (ST1_REG                      9)
303    (ST2_REG                     10)
304    (ST3_REG                     11)
305    (ST4_REG                     12)
306    (ST5_REG                     13)
307    (ST6_REG                     14)
308    (ST7_REG                     15)
309    (FLAGS_REG                   17)
310    (FPSR_REG                    18)
311    (FPCR_REG                    19)
312    (XMM0_REG                    21)
313    (XMM1_REG                    22)
314    (XMM2_REG                    23)
315    (XMM3_REG                    24)
316    (XMM4_REG                    25)
317    (XMM5_REG                    26)
318    (XMM6_REG                    27)
319    (XMM7_REG                    28)
320    (MM0_REG                     29)
321    (MM1_REG                     30)
322    (MM2_REG                     31)
323    (MM3_REG                     32)
324    (MM4_REG                     33)
325    (MM5_REG                     34)
326    (MM6_REG                     35)
327    (MM7_REG                     36)
328    (R8_REG                      37)
329    (R9_REG                      38)
330    (R10_REG                     39)
331    (R11_REG                     40)
332    (R12_REG                     41)
333    (R13_REG                     42)
334    (R14_REG                     43)
335    (R15_REG                     44)
336    (XMM8_REG                    45)
337    (XMM9_REG                    46)
338    (XMM10_REG                   47)
339    (XMM11_REG                   48)
340    (XMM12_REG                   49)
341    (XMM13_REG                   50)
342    (XMM14_REG                   51)
343    (XMM15_REG                   52)
344    (XMM16_REG                   53)
345    (XMM17_REG                   54)
346    (XMM18_REG                   55)
347    (XMM19_REG                   56)
348    (XMM20_REG                   57)
349    (XMM21_REG                   58)
350    (XMM22_REG                   59)
351    (XMM23_REG                   60)
352    (XMM24_REG                   61)
353    (XMM25_REG                   62)
354    (XMM26_REG                   63)
355    (XMM27_REG                   64)
356    (XMM28_REG                   65)
357    (XMM29_REG                   66)
358    (XMM30_REG                   67)
359    (XMM31_REG                   68)
360    (MASK0_REG                   69)
361    (MASK1_REG                   70)
362    (MASK2_REG                   71)
363    (MASK3_REG                   72)
364    (MASK4_REG                   73)
365    (MASK5_REG                   74)
366    (MASK6_REG                   75)
367    (MASK7_REG                   76)
368   ])
370 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
371 ;; from i386.c.
373 ;; In C guard expressions, put expressions which may be compile-time
374 ;; constants first.  This allows for better optimization.  For
375 ;; example, write "TARGET_64BIT && reload_completed", not
376 ;; "reload_completed && TARGET_64BIT".
379 ;; Processor type.
380 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
381                     atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
382                     btver2"
383   (const (symbol_ref "ix86_schedule")))
385 ;; A basic instruction type.  Refinements due to arguments to be
386 ;; provided in other attributes.
387 (define_attr "type"
388   "other,multi,
389    alu,alu1,negnot,imov,imovx,lea,
390    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
391    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
392    push,pop,call,callv,leave,
393    str,bitmanip,
394    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
395    fxch,fistp,fisttp,frndint,
396    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
397    ssemul,sseimul,ssediv,sselog,sselog1,
398    sseishft,sseishft1,ssecmp,ssecomi,
399    ssecvt,ssecvt1,sseicvt,sseins,
400    sseshuf,sseshuf1,ssemuladd,sse4arg,
401    lwp,mskmov,msklog,
402    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
403   (const_string "other"))
405 ;; Main data type used by the insn
406 (define_attr "mode"
407   "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
408   V2DF,V2SF,V1DF,V8DF"
409   (const_string "unknown"))
411 ;; The CPU unit operations uses.
412 (define_attr "unit" "integer,i387,sse,mmx,unknown"
413   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
414                           fxch,fistp,fisttp,frndint")
415            (const_string "i387")
416          (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
417                           ssemul,sseimul,ssediv,sselog,sselog1,
418                           sseishft,sseishft1,ssecmp,ssecomi,
419                           ssecvt,ssecvt1,sseicvt,sseins,
420                           sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
421            (const_string "sse")
422          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
423            (const_string "mmx")
424          (eq_attr "type" "other")
425            (const_string "unknown")]
426          (const_string "integer")))
428 ;; The minimum required alignment of vector mode memory operands of the SSE
429 ;; (non-VEX/EVEX) instruction in bits, if it is different from
430 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0.  If an instruction has
431 ;; multiple alternatives, this should be conservative maximum of those minimum
432 ;; required alignments.
433 (define_attr "ssememalign" "" (const_int 0))
435 ;; The (bounding maximum) length of an instruction immediate.
436 (define_attr "length_immediate" ""
437   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
438                           bitmanip,imulx,msklog,mskmov")
439            (const_int 0)
440          (eq_attr "unit" "i387,sse,mmx")
441            (const_int 0)
442          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
443                           rotate,rotatex,rotate1,imul,icmp,push,pop")
444            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
445          (eq_attr "type" "imov,test")
446            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
447          (eq_attr "type" "call")
448            (if_then_else (match_operand 0 "constant_call_address_operand")
449              (const_int 4)
450              (const_int 0))
451          (eq_attr "type" "callv")
452            (if_then_else (match_operand 1 "constant_call_address_operand")
453              (const_int 4)
454              (const_int 0))
455          ;; We don't know the size before shorten_branches.  Expect
456          ;; the instruction to fit for better scheduling.
457          (eq_attr "type" "ibr")
458            (const_int 1)
459          ]
460          (symbol_ref "/* Update immediate_length and other attributes! */
461                       gcc_unreachable (),1")))
463 ;; The (bounding maximum) length of an instruction address.
464 (define_attr "length_address" ""
465   (cond [(eq_attr "type" "str,other,multi,fxch")
466            (const_int 0)
467          (and (eq_attr "type" "call")
468               (match_operand 0 "constant_call_address_operand"))
469              (const_int 0)
470          (and (eq_attr "type" "callv")
471               (match_operand 1 "constant_call_address_operand"))
472              (const_int 0)
473          ]
474          (symbol_ref "ix86_attr_length_address_default (insn)")))
476 ;; Set when length prefix is used.
477 (define_attr "prefix_data16" ""
478   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
479            (const_int 0)
480          (eq_attr "mode" "HI")
481            (const_int 1)
482          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
483            (const_int 1)
484         ]
485         (const_int 0)))
487 ;; Set when string REP prefix is used.
488 (define_attr "prefix_rep" ""
489   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
490            (const_int 0)
491          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
492            (const_int 1)
493         ]
494         (const_int 0)))
496 ;; Set when 0f opcode prefix is used.
497 (define_attr "prefix_0f" ""
498   (if_then_else
499     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
500          (eq_attr "unit" "sse,mmx"))
501     (const_int 1)
502     (const_int 0)))
504 ;; Set when REX opcode prefix is used.
505 (define_attr "prefix_rex" ""
506   (cond [(not (match_test "TARGET_64BIT"))
507            (const_int 0)
508          (and (eq_attr "mode" "DI")
509               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
510                    (eq_attr "unit" "!mmx")))
511            (const_int 1)
512          (and (eq_attr "mode" "QI")
513               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
514            (const_int 1)
515          (match_test "x86_extended_reg_mentioned_p (insn)")
516            (const_int 1)
517          (and (eq_attr "type" "imovx")
518               (match_operand:QI 1 "ext_QIreg_operand"))
519            (const_int 1)
520         ]
521         (const_int 0)))
523 ;; There are also additional prefixes in 3DNOW, SSSE3.
524 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
525 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
526 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
527 (define_attr "prefix_extra" ""
528   (cond [(eq_attr "type" "ssemuladd,sse4arg")
529            (const_int 2)
530          (eq_attr "type" "sseiadd1,ssecvt1")
531            (const_int 1)
532         ]
533         (const_int 0)))
535 ;; Prefix used: original, VEX or maybe VEX.
536 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
537   (cond [(eq_attr "mode" "OI,V8SF,V4DF")
538            (const_string "vex")
539          (eq_attr "mode" "XI,V16SF,V8DF")
540            (const_string "evex")
541         ]
542         (const_string "orig")))
544 ;; VEX W bit is used.
545 (define_attr "prefix_vex_w" "" (const_int 0))
547 ;; The length of VEX prefix
548 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
549 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
550 ;; still prefix_0f 1, with prefix_extra 1.
551 (define_attr "length_vex" ""
552   (if_then_else (and (eq_attr "prefix_0f" "1")
553                      (eq_attr "prefix_extra" "0"))
554     (if_then_else (eq_attr "prefix_vex_w" "1")
555       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
556       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
557     (if_then_else (eq_attr "prefix_vex_w" "1")
558       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
559       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
561 ;; 4-bytes evex prefix and 1 byte opcode.
562 (define_attr "length_evex" "" (const_int 5))
564 ;; Set when modrm byte is used.
565 (define_attr "modrm" ""
566   (cond [(eq_attr "type" "str,leave")
567            (const_int 0)
568          (eq_attr "unit" "i387")
569            (const_int 0)
570          (and (eq_attr "type" "incdec")
571               (and (not (match_test "TARGET_64BIT"))
572                    (ior (match_operand:SI 1 "register_operand")
573                         (match_operand:HI 1 "register_operand"))))
574            (const_int 0)
575          (and (eq_attr "type" "push")
576               (not (match_operand 1 "memory_operand")))
577            (const_int 0)
578          (and (eq_attr "type" "pop")
579               (not (match_operand 0 "memory_operand")))
580            (const_int 0)
581          (and (eq_attr "type" "imov")
582               (and (not (eq_attr "mode" "DI"))
583                    (ior (and (match_operand 0 "register_operand")
584                              (match_operand 1 "immediate_operand"))
585                         (ior (and (match_operand 0 "ax_reg_operand")
586                                   (match_operand 1 "memory_displacement_only_operand"))
587                              (and (match_operand 0 "memory_displacement_only_operand")
588                                   (match_operand 1 "ax_reg_operand"))))))
589            (const_int 0)
590          (and (eq_attr "type" "call")
591               (match_operand 0 "constant_call_address_operand"))
592              (const_int 0)
593          (and (eq_attr "type" "callv")
594               (match_operand 1 "constant_call_address_operand"))
595              (const_int 0)
596          (and (eq_attr "type" "alu,alu1,icmp,test")
597               (match_operand 0 "ax_reg_operand"))
598              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
599          ]
600          (const_int 1)))
602 ;; The (bounding maximum) length of an instruction in bytes.
603 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
604 ;; Later we may want to split them and compute proper length as for
605 ;; other insns.
606 (define_attr "length" ""
607   (cond [(eq_attr "type" "other,multi,fistp,frndint")
608            (const_int 16)
609          (eq_attr "type" "fcmp")
610            (const_int 4)
611          (eq_attr "unit" "i387")
612            (plus (const_int 2)
613                  (plus (attr "prefix_data16")
614                        (attr "length_address")))
615          (ior (eq_attr "prefix" "evex")
616               (and (ior (eq_attr "prefix" "maybe_evex")
617                         (eq_attr "prefix" "maybe_vex"))
618                    (match_test "TARGET_AVX512F")))
619            (plus (attr "length_evex")
620                  (plus (attr "length_immediate")
621                        (plus (attr "modrm")
622                              (attr "length_address"))))
623          (ior (eq_attr "prefix" "vex")
624               (and (ior (eq_attr "prefix" "maybe_vex")
625                         (eq_attr "prefix" "maybe_evex"))
626                    (match_test "TARGET_AVX")))
627            (plus (attr "length_vex")
628                  (plus (attr "length_immediate")
629                        (plus (attr "modrm")
630                              (attr "length_address"))))]
631          (plus (plus (attr "modrm")
632                      (plus (attr "prefix_0f")
633                            (plus (attr "prefix_rex")
634                                  (plus (attr "prefix_extra")
635                                        (const_int 1)))))
636                (plus (attr "prefix_rep")
637                      (plus (attr "prefix_data16")
638                            (plus (attr "length_immediate")
639                                  (attr "length_address")))))))
641 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
642 ;; `store' if there is a simple memory reference therein, or `unknown'
643 ;; if the instruction is complex.
645 (define_attr "memory" "none,load,store,both,unknown"
646   (cond [(eq_attr "type" "other,multi,str,lwp")
647            (const_string "unknown")
648          (eq_attr "type" "lea,fcmov,fpspc")
649            (const_string "none")
650          (eq_attr "type" "fistp,leave")
651            (const_string "both")
652          (eq_attr "type" "frndint")
653            (const_string "load")
654          (eq_attr "type" "push")
655            (if_then_else (match_operand 1 "memory_operand")
656              (const_string "both")
657              (const_string "store"))
658          (eq_attr "type" "pop")
659            (if_then_else (match_operand 0 "memory_operand")
660              (const_string "both")
661              (const_string "load"))
662          (eq_attr "type" "setcc")
663            (if_then_else (match_operand 0 "memory_operand")
664              (const_string "store")
665              (const_string "none"))
666          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
667            (if_then_else (ior (match_operand 0 "memory_operand")
668                               (match_operand 1 "memory_operand"))
669              (const_string "load")
670              (const_string "none"))
671          (eq_attr "type" "ibr")
672            (if_then_else (match_operand 0 "memory_operand")
673              (const_string "load")
674              (const_string "none"))
675          (eq_attr "type" "call")
676            (if_then_else (match_operand 0 "constant_call_address_operand")
677              (const_string "none")
678              (const_string "load"))
679          (eq_attr "type" "callv")
680            (if_then_else (match_operand 1 "constant_call_address_operand")
681              (const_string "none")
682              (const_string "load"))
683          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
684               (match_operand 1 "memory_operand"))
685            (const_string "both")
686          (and (match_operand 0 "memory_operand")
687               (match_operand 1 "memory_operand"))
688            (const_string "both")
689          (match_operand 0 "memory_operand")
690            (const_string "store")
691          (match_operand 1 "memory_operand")
692            (const_string "load")
693          (and (eq_attr "type"
694                  "!alu1,negnot,ishift1,
695                    imov,imovx,icmp,test,bitmanip,
696                    fmov,fcmp,fsgn,
697                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
698                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
699                    mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
700               (match_operand 2 "memory_operand"))
701            (const_string "load")
702          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
703               (match_operand 3 "memory_operand"))
704            (const_string "load")
705         ]
706         (const_string "none")))
708 ;; Indicates if an instruction has both an immediate and a displacement.
710 (define_attr "imm_disp" "false,true,unknown"
711   (cond [(eq_attr "type" "other,multi")
712            (const_string "unknown")
713          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
714               (and (match_operand 0 "memory_displacement_operand")
715                    (match_operand 1 "immediate_operand")))
716            (const_string "true")
717          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
718               (and (match_operand 0 "memory_displacement_operand")
719                    (match_operand 2 "immediate_operand")))
720            (const_string "true")
721         ]
722         (const_string "false")))
724 ;; Indicates if an FP operation has an integer source.
726 (define_attr "fp_int_src" "false,true"
727   (const_string "false"))
729 ;; Defines rounding mode of an FP operation.
731 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
732   (const_string "any"))
734 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
735 (define_attr "use_carry" "0,1" (const_string "0"))
737 ;; Define attribute to indicate unaligned ssemov insns
738 (define_attr "movu" "0,1" (const_string "0"))
740 ;; Used to control the "enabled" attribute on a per-instruction basis.
741 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
742                     sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
743                     avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
744                     fma_avx512f,avx512bw,noavx512bw"
745   (const_string "base"))
747 (define_attr "enabled" ""
748   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
749          (eq_attr "isa" "x64_sse4")
750            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
751          (eq_attr "isa" "x64_sse4_noavx")
752            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
753          (eq_attr "isa" "x64_avx")
754            (symbol_ref "TARGET_64BIT && TARGET_AVX")
755          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
756          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
757          (eq_attr "isa" "sse2_noavx")
758            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
759          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
760          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
761          (eq_attr "isa" "sse4_noavx")
762            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
763          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
764          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
765          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
766          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
767          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
768          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
769          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
770          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
771          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
772          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
773          (eq_attr "isa" "fma_avx512f")
774            (symbol_ref "TARGET_FMA || TARGET_AVX512F")
775          (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
776          (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
777         ]
778         (const_int 1)))
780 ;; Describe a user's asm statement.
781 (define_asm_attributes
782   [(set_attr "length" "128")
783    (set_attr "type" "multi")])
785 (define_code_iterator plusminus [plus minus])
787 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
789 (define_code_iterator multdiv [mult div])
791 ;; Base name for define_insn
792 (define_code_attr plusminus_insn
793   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
794    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
796 ;; Base name for insn mnemonic.
797 (define_code_attr plusminus_mnemonic
798   [(plus "add") (ss_plus "adds") (us_plus "addus")
799    (minus "sub") (ss_minus "subs") (us_minus "subus")])
800 (define_code_attr plusminus_carry_mnemonic
801   [(plus "adc") (minus "sbb")])
802 (define_code_attr multdiv_mnemonic
803   [(mult "mul") (div "div")])
805 ;; Mark commutative operators as such in constraints.
806 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
807                         (minus "") (ss_minus "") (us_minus "")])
809 ;; Mapping of max and min
810 (define_code_iterator maxmin [smax smin umax umin])
812 ;; Mapping of signed max and min
813 (define_code_iterator smaxmin [smax smin])
815 ;; Mapping of unsigned max and min
816 (define_code_iterator umaxmin [umax umin])
818 ;; Base name for integer and FP insn mnemonic
819 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
820                               (umax "maxu") (umin "minu")])
821 (define_code_attr maxmin_float [(smax "max") (smin "min")])
823 ;; Mapping of logic operators
824 (define_code_iterator any_logic [and ior xor])
825 (define_code_iterator any_or [ior xor])
826 (define_code_iterator fpint_logic [and xor])
828 ;; Base name for insn mnemonic.
829 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
831 ;; Mapping of logic-shift operators
832 (define_code_iterator any_lshift [ashift lshiftrt])
834 ;; Mapping of shift-right operators
835 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
837 ;; Mapping of all shift operators
838 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
840 ;; Base name for define_insn
841 (define_code_attr shift_insn
842   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
844 ;; Base name for insn mnemonic.
845 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
846 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
848 ;; Mapping of rotate operators
849 (define_code_iterator any_rotate [rotate rotatert])
851 ;; Base name for define_insn
852 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
854 ;; Base name for insn mnemonic.
855 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
857 ;; Mapping of abs neg operators
858 (define_code_iterator absneg [abs neg])
860 ;; Base name for x87 insn mnemonic.
861 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
863 ;; Used in signed and unsigned widening multiplications.
864 (define_code_iterator any_extend [sign_extend zero_extend])
866 ;; Prefix for insn menmonic.
867 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
869 ;; Prefix for define_insn
870 (define_code_attr u [(sign_extend "") (zero_extend "u")])
871 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
872 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
874 ;; Used in signed and unsigned truncations.
875 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
876 ;; Instruction suffix for truncations.
877 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
879 ;; Used in signed and unsigned fix.
880 (define_code_iterator any_fix [fix unsigned_fix])
881 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
883 ;; All integer modes.
884 (define_mode_iterator SWI1248x [QI HI SI DI])
886 ;; All integer modes without QImode.
887 (define_mode_iterator SWI248x [HI SI DI])
889 ;; All integer modes without QImode and HImode.
890 (define_mode_iterator SWI48x [SI DI])
892 ;; All integer modes without SImode and DImode.
893 (define_mode_iterator SWI12 [QI HI])
895 ;; All integer modes without DImode.
896 (define_mode_iterator SWI124 [QI HI SI])
898 ;; All integer modes without QImode and DImode.
899 (define_mode_iterator SWI24 [HI SI])
901 ;; Single word integer modes.
902 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
904 ;; Single word integer modes without QImode.
905 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
907 ;; Single word integer modes without QImode and HImode.
908 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
910 ;; All math-dependant single and double word integer modes.
911 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
912                              (HI "TARGET_HIMODE_MATH")
913                              SI DI (TI "TARGET_64BIT")])
915 ;; Math-dependant single word integer modes.
916 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
917                             (HI "TARGET_HIMODE_MATH")
918                             SI (DI "TARGET_64BIT")])
920 ;; Math-dependant integer modes without DImode.
921 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
922                                (HI "TARGET_HIMODE_MATH")
923                                SI])
925 ;; Math-dependant single word integer modes without QImode.
926 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
927                                SI (DI "TARGET_64BIT")])
929 ;; Double word integer modes.
930 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
931                            (TI "TARGET_64BIT")])
933 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
934 ;; compile time constant, it is faster to use <MODE_SIZE> than
935 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
936 ;; command line options just use GET_MODE_SIZE macro.
937 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
938                              (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
939                              (V16QI "16") (V32QI "32") (V64QI "64")
940                              (V8HI "16") (V16HI "32") (V32HI "64")
941                              (V4SI "16") (V8SI "32") (V16SI "64")
942                              (V2DI "16") (V4DI "32") (V8DI "64")
943                              (V1TI "16") (V2TI "32") (V4TI "64")
944                              (V2DF "16") (V4DF "32") (V8DF "64")
945                              (V4SF "16") (V8SF "32") (V16SF "64")])
947 ;; Double word integer modes as mode attribute.
948 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
949 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
951 ;; Half mode for double word integer modes.
952 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
953                             (DI "TARGET_64BIT")])
955 ;; Instruction suffix for integer modes.
956 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
958 ;; Instruction suffix for masks.
959 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
961 ;; Pointer size prefix for integer modes (Intel asm dialect)
962 (define_mode_attr iptrsize [(QI "BYTE")
963                             (HI "WORD")
964                             (SI "DWORD")
965                             (DI "QWORD")])
967 ;; Register class for integer modes.
968 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
970 ;; Immediate operand constraint for integer modes.
971 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
973 ;; General operand constraint for word modes.
974 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
976 ;; Immediate operand constraint for double integer modes.
977 (define_mode_attr di [(SI "nF") (DI "e")])
979 ;; Immediate operand constraint for shifts.
980 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
982 ;; General operand predicate for integer modes.
983 (define_mode_attr general_operand
984         [(QI "general_operand")
985          (HI "general_operand")
986          (SI "x86_64_general_operand")
987          (DI "x86_64_general_operand")
988          (TI "x86_64_general_operand")])
990 ;; General sign extend operand predicate for integer modes,
991 ;; which disallows VOIDmode operands and thus it is suitable
992 ;; for use inside sign_extend.
993 (define_mode_attr general_sext_operand
994         [(QI "sext_operand")
995          (HI "sext_operand")
996          (SI "x86_64_sext_operand")
997          (DI "x86_64_sext_operand")])
999 ;; General sign/zero extend operand predicate for integer modes.
1000 (define_mode_attr general_szext_operand
1001         [(QI "general_operand")
1002          (HI "general_operand")
1003          (SI "x86_64_szext_general_operand")
1004          (DI "x86_64_szext_general_operand")])
1006 ;; Immediate operand predicate for integer modes.
1007 (define_mode_attr immediate_operand
1008         [(QI "immediate_operand")
1009          (HI "immediate_operand")
1010          (SI "x86_64_immediate_operand")
1011          (DI "x86_64_immediate_operand")])
1013 ;; Nonmemory operand predicate for integer modes.
1014 (define_mode_attr nonmemory_operand
1015         [(QI "nonmemory_operand")
1016          (HI "nonmemory_operand")
1017          (SI "x86_64_nonmemory_operand")
1018          (DI "x86_64_nonmemory_operand")])
1020 ;; Operand predicate for shifts.
1021 (define_mode_attr shift_operand
1022         [(QI "nonimmediate_operand")
1023          (HI "nonimmediate_operand")
1024          (SI "nonimmediate_operand")
1025          (DI "shiftdi_operand")
1026          (TI "register_operand")])
1028 ;; Operand predicate for shift argument.
1029 (define_mode_attr shift_immediate_operand
1030         [(QI "const_1_to_31_operand")
1031          (HI "const_1_to_31_operand")
1032          (SI "const_1_to_31_operand")
1033          (DI "const_1_to_63_operand")])
1035 ;; Input operand predicate for arithmetic left shifts.
1036 (define_mode_attr ashl_input_operand
1037         [(QI "nonimmediate_operand")
1038          (HI "nonimmediate_operand")
1039          (SI "nonimmediate_operand")
1040          (DI "ashldi_input_operand")
1041          (TI "reg_or_pm1_operand")])
1043 ;; SSE and x87 SFmode and DFmode floating point modes
1044 (define_mode_iterator MODEF [SF DF])
1046 ;; All x87 floating point modes
1047 (define_mode_iterator X87MODEF [SF DF XF])
1049 ;; SSE instruction suffix for various modes
1050 (define_mode_attr ssemodesuffix
1051   [(SF "ss") (DF "sd")
1052    (V16SF "ps") (V8DF "pd")
1053    (V8SF "ps") (V4DF "pd")
1054    (V4SF "ps") (V2DF "pd")
1055    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1056    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1057    (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1059 ;; SSE vector suffix for floating point modes
1060 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1062 ;; SSE vector mode corresponding to a scalar mode
1063 (define_mode_attr ssevecmode
1064   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1065 (define_mode_attr ssevecmodelower
1066   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1068 ;; Instruction suffix for REX 64bit operators.
1069 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1071 ;; This mode iterator allows :P to be used for patterns that operate on
1072 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1073 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1075 ;; This mode iterator allows :W to be used for patterns that operate on
1076 ;; word_mode sized quantities.
1077 (define_mode_iterator W
1078   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1080 ;; This mode iterator allows :PTR to be used for patterns that operate on
1081 ;; ptr_mode sized quantities.
1082 (define_mode_iterator PTR
1083   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1085 ;; Scheduling descriptions
1087 (include "pentium.md")
1088 (include "ppro.md")
1089 (include "k6.md")
1090 (include "athlon.md")
1091 (include "bdver1.md")
1092 (include "bdver3.md")
1093 (include "btver2.md")
1094 (include "geode.md")
1095 (include "atom.md")
1096 (include "slm.md")
1097 (include "core2.md")
1100 ;; Operand and operator predicates and constraints
1102 (include "predicates.md")
1103 (include "constraints.md")
1106 ;; Compare and branch/compare and store instructions.
1108 (define_expand "cbranch<mode>4"
1109   [(set (reg:CC FLAGS_REG)
1110         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1111                     (match_operand:SDWIM 2 "<general_operand>")))
1112    (set (pc) (if_then_else
1113                (match_operator 0 "ordered_comparison_operator"
1114                 [(reg:CC FLAGS_REG) (const_int 0)])
1115                (label_ref (match_operand 3))
1116                (pc)))]
1117   ""
1119   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1120     operands[1] = force_reg (<MODE>mode, operands[1]);
1121   ix86_expand_branch (GET_CODE (operands[0]),
1122                       operands[1], operands[2], operands[3]);
1123   DONE;
1126 (define_expand "cstore<mode>4"
1127   [(set (reg:CC FLAGS_REG)
1128         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1129                     (match_operand:SWIM 3 "<general_operand>")))
1130    (set (match_operand:QI 0 "register_operand")
1131         (match_operator 1 "ordered_comparison_operator"
1132           [(reg:CC FLAGS_REG) (const_int 0)]))]
1133   ""
1135   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1136     operands[2] = force_reg (<MODE>mode, operands[2]);
1137   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1138                      operands[2], operands[3]);
1139   DONE;
1142 (define_expand "cmp<mode>_1"
1143   [(set (reg:CC FLAGS_REG)
1144         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1145                     (match_operand:SWI48 1 "<general_operand>")))])
1147 (define_insn "*cmp<mode>_ccno_1"
1148   [(set (reg FLAGS_REG)
1149         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1150                  (match_operand:SWI 1 "const0_operand")))]
1151   "ix86_match_ccmode (insn, CCNOmode)"
1152   "@
1153    test{<imodesuffix>}\t%0, %0
1154    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1155   [(set_attr "type" "test,icmp")
1156    (set_attr "length_immediate" "0,1")
1157    (set_attr "mode" "<MODE>")])
1159 (define_insn "*cmp<mode>_1"
1160   [(set (reg FLAGS_REG)
1161         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1162                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1163   "ix86_match_ccmode (insn, CCmode)"
1164   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1165   [(set_attr "type" "icmp")
1166    (set_attr "mode" "<MODE>")])
1168 (define_insn "*cmp<mode>_minus_1"
1169   [(set (reg FLAGS_REG)
1170         (compare
1171           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1172                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1173           (const_int 0)))]
1174   "ix86_match_ccmode (insn, CCGOCmode)"
1175   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1176   [(set_attr "type" "icmp")
1177    (set_attr "mode" "<MODE>")])
1179 (define_insn "*cmpqi_ext_1"
1180   [(set (reg FLAGS_REG)
1181         (compare
1182           (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1183           (subreg:QI
1184             (zero_extract:SI
1185               (match_operand 1 "ext_register_operand" "Q,Q")
1186               (const_int 8)
1187               (const_int 8)) 0)))]
1188   "ix86_match_ccmode (insn, CCmode)"
1189   "cmp{b}\t{%h1, %0|%0, %h1}"
1190   [(set_attr "isa" "*,nox64")
1191    (set_attr "type" "icmp")
1192    (set_attr "mode" "QI")])
1194 (define_insn "*cmpqi_ext_2"
1195   [(set (reg FLAGS_REG)
1196         (compare
1197           (subreg:QI
1198             (zero_extract:SI
1199               (match_operand 0 "ext_register_operand" "Q")
1200               (const_int 8)
1201               (const_int 8)) 0)
1202           (match_operand:QI 1 "const0_operand")))]
1203   "ix86_match_ccmode (insn, CCNOmode)"
1204   "test{b}\t%h0, %h0"
1205   [(set_attr "type" "test")
1206    (set_attr "length_immediate" "0")
1207    (set_attr "mode" "QI")])
1209 (define_expand "cmpqi_ext_3"
1210   [(set (reg:CC FLAGS_REG)
1211         (compare:CC
1212           (subreg:QI
1213             (zero_extract:SI
1214               (match_operand 0 "ext_register_operand")
1215               (const_int 8)
1216               (const_int 8)) 0)
1217           (match_operand:QI 1 "const_int_operand")))])
1219 (define_insn "*cmpqi_ext_3"
1220   [(set (reg FLAGS_REG)
1221         (compare
1222           (subreg:QI
1223             (zero_extract:SI
1224               (match_operand 0 "ext_register_operand" "Q,Q")
1225               (const_int 8)
1226               (const_int 8)) 0)
1227           (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1228   "ix86_match_ccmode (insn, CCmode)"
1229   "cmp{b}\t{%1, %h0|%h0, %1}"
1230   [(set_attr "isa" "*,nox64")
1231    (set_attr "type" "icmp")
1232    (set_attr "modrm" "1")
1233    (set_attr "mode" "QI")])
1235 (define_insn "*cmpqi_ext_4"
1236   [(set (reg FLAGS_REG)
1237         (compare
1238           (subreg:QI
1239             (zero_extract:SI
1240               (match_operand 0 "ext_register_operand" "Q")
1241               (const_int 8)
1242               (const_int 8)) 0)
1243           (subreg:QI
1244             (zero_extract:SI
1245               (match_operand 1 "ext_register_operand" "Q")
1246               (const_int 8)
1247               (const_int 8)) 0)))]
1248   "ix86_match_ccmode (insn, CCmode)"
1249   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1250   [(set_attr "type" "icmp")
1251    (set_attr "mode" "QI")])
1253 ;; These implement float point compares.
1254 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1255 ;; which would allow mix and match FP modes on the compares.  Which is what
1256 ;; the old patterns did, but with many more of them.
1258 (define_expand "cbranchxf4"
1259   [(set (reg:CC FLAGS_REG)
1260         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1261                     (match_operand:XF 2 "nonmemory_operand")))
1262    (set (pc) (if_then_else
1263               (match_operator 0 "ix86_fp_comparison_operator"
1264                [(reg:CC FLAGS_REG)
1265                 (const_int 0)])
1266               (label_ref (match_operand 3))
1267               (pc)))]
1268   "TARGET_80387"
1270   ix86_expand_branch (GET_CODE (operands[0]),
1271                       operands[1], operands[2], operands[3]);
1272   DONE;
1275 (define_expand "cstorexf4"
1276   [(set (reg:CC FLAGS_REG)
1277         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1278                     (match_operand:XF 3 "nonmemory_operand")))
1279    (set (match_operand:QI 0 "register_operand")
1280               (match_operator 1 "ix86_fp_comparison_operator"
1281                [(reg:CC FLAGS_REG)
1282                 (const_int 0)]))]
1283   "TARGET_80387"
1285   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1286                      operands[2], operands[3]);
1287   DONE;
1290 (define_expand "cbranch<mode>4"
1291   [(set (reg:CC FLAGS_REG)
1292         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1293                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1294    (set (pc) (if_then_else
1295               (match_operator 0 "ix86_fp_comparison_operator"
1296                [(reg:CC FLAGS_REG)
1297                 (const_int 0)])
1298               (label_ref (match_operand 3))
1299               (pc)))]
1300   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1302   ix86_expand_branch (GET_CODE (operands[0]),
1303                       operands[1], operands[2], operands[3]);
1304   DONE;
1307 (define_expand "cstore<mode>4"
1308   [(set (reg:CC FLAGS_REG)
1309         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1310                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1311    (set (match_operand:QI 0 "register_operand")
1312               (match_operator 1 "ix86_fp_comparison_operator"
1313                [(reg:CC FLAGS_REG)
1314                 (const_int 0)]))]
1315   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1317   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1318                      operands[2], operands[3]);
1319   DONE;
1322 (define_expand "cbranchcc4"
1323   [(set (pc) (if_then_else
1324               (match_operator 0 "comparison_operator"
1325                [(match_operand 1 "flags_reg_operand")
1326                 (match_operand 2 "const0_operand")])
1327               (label_ref (match_operand 3))
1328               (pc)))]
1329   ""
1331   ix86_expand_branch (GET_CODE (operands[0]),
1332                       operands[1], operands[2], operands[3]);
1333   DONE;
1336 (define_expand "cstorecc4"
1337   [(set (match_operand:QI 0 "register_operand")
1338               (match_operator 1 "comparison_operator"
1339                [(match_operand 2 "flags_reg_operand")
1340                 (match_operand 3 "const0_operand")]))]
1341   ""
1343   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1344                      operands[2], operands[3]);
1345   DONE;
1349 ;; FP compares, step 1:
1350 ;; Set the FP condition codes.
1352 ;; CCFPmode     compare with exceptions
1353 ;; CCFPUmode    compare with no exceptions
1355 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1356 ;; used to manage the reg stack popping would not be preserved.
1358 (define_insn "*cmp<mode>_0_i387"
1359   [(set (match_operand:HI 0 "register_operand" "=a")
1360         (unspec:HI
1361           [(compare:CCFP
1362              (match_operand:X87MODEF 1 "register_operand" "f")
1363              (match_operand:X87MODEF 2 "const0_operand"))]
1364         UNSPEC_FNSTSW))]
1365   "TARGET_80387"
1366   "* return output_fp_compare (insn, operands, false, false);"
1367   [(set_attr "type" "multi")
1368    (set_attr "unit" "i387")
1369    (set_attr "mode" "<MODE>")])
1371 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1372   [(set (reg:CCFP FLAGS_REG)
1373         (compare:CCFP
1374           (match_operand:X87MODEF 1 "register_operand" "f")
1375           (match_operand:X87MODEF 2 "const0_operand")))
1376    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1377   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1378   "#"
1379   "&& reload_completed"
1380   [(set (match_dup 0)
1381         (unspec:HI
1382           [(compare:CCFP (match_dup 1)(match_dup 2))]
1383         UNSPEC_FNSTSW))
1384    (set (reg:CC FLAGS_REG)
1385         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1386   ""
1387   [(set_attr "type" "multi")
1388    (set_attr "unit" "i387")
1389    (set_attr "mode" "<MODE>")])
1391 (define_insn "*cmpxf_i387"
1392   [(set (match_operand:HI 0 "register_operand" "=a")
1393         (unspec:HI
1394           [(compare:CCFP
1395              (match_operand:XF 1 "register_operand" "f")
1396              (match_operand:XF 2 "register_operand" "f"))]
1397           UNSPEC_FNSTSW))]
1398   "TARGET_80387"
1399   "* return output_fp_compare (insn, operands, false, false);"
1400   [(set_attr "type" "multi")
1401    (set_attr "unit" "i387")
1402    (set_attr "mode" "XF")])
1404 (define_insn_and_split "*cmpxf_cc_i387"
1405   [(set (reg:CCFP FLAGS_REG)
1406         (compare:CCFP
1407           (match_operand:XF 1 "register_operand" "f")
1408           (match_operand:XF 2 "register_operand" "f")))
1409    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1410   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1411   "#"
1412   "&& reload_completed"
1413   [(set (match_dup 0)
1414         (unspec:HI
1415           [(compare:CCFP (match_dup 1)(match_dup 2))]
1416         UNSPEC_FNSTSW))
1417    (set (reg:CC FLAGS_REG)
1418         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1419   ""
1420   [(set_attr "type" "multi")
1421    (set_attr "unit" "i387")
1422    (set_attr "mode" "XF")])
1424 (define_insn "*cmp<mode>_i387"
1425   [(set (match_operand:HI 0 "register_operand" "=a")
1426         (unspec:HI
1427           [(compare:CCFP
1428              (match_operand:MODEF 1 "register_operand" "f")
1429              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1430           UNSPEC_FNSTSW))]
1431   "TARGET_80387"
1432   "* return output_fp_compare (insn, operands, false, false);"
1433   [(set_attr "type" "multi")
1434    (set_attr "unit" "i387")
1435    (set_attr "mode" "<MODE>")])
1437 (define_insn_and_split "*cmp<mode>_cc_i387"
1438   [(set (reg:CCFP FLAGS_REG)
1439         (compare:CCFP
1440           (match_operand:MODEF 1 "register_operand" "f")
1441           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1442    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1443   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1444   "#"
1445   "&& reload_completed"
1446   [(set (match_dup 0)
1447         (unspec:HI
1448           [(compare:CCFP (match_dup 1)(match_dup 2))]
1449         UNSPEC_FNSTSW))
1450    (set (reg:CC FLAGS_REG)
1451         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1452   ""
1453   [(set_attr "type" "multi")
1454    (set_attr "unit" "i387")
1455    (set_attr "mode" "<MODE>")])
1457 (define_insn "*cmpu<mode>_i387"
1458   [(set (match_operand:HI 0 "register_operand" "=a")
1459         (unspec:HI
1460           [(compare:CCFPU
1461              (match_operand:X87MODEF 1 "register_operand" "f")
1462              (match_operand:X87MODEF 2 "register_operand" "f"))]
1463           UNSPEC_FNSTSW))]
1464   "TARGET_80387"
1465   "* return output_fp_compare (insn, operands, false, true);"
1466   [(set_attr "type" "multi")
1467    (set_attr "unit" "i387")
1468    (set_attr "mode" "<MODE>")])
1470 (define_insn_and_split "*cmpu<mode>_cc_i387"
1471   [(set (reg:CCFPU FLAGS_REG)
1472         (compare:CCFPU
1473           (match_operand:X87MODEF 1 "register_operand" "f")
1474           (match_operand:X87MODEF 2 "register_operand" "f")))
1475    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1476   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1477   "#"
1478   "&& reload_completed"
1479   [(set (match_dup 0)
1480         (unspec:HI
1481           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1482         UNSPEC_FNSTSW))
1483    (set (reg:CC FLAGS_REG)
1484         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1485   ""
1486   [(set_attr "type" "multi")
1487    (set_attr "unit" "i387")
1488    (set_attr "mode" "<MODE>")])
1490 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1491   [(set (match_operand:HI 0 "register_operand" "=a")
1492         (unspec:HI
1493           [(compare:CCFP
1494              (match_operand:X87MODEF 1 "register_operand" "f")
1495              (match_operator:X87MODEF 3 "float_operator"
1496                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1497           UNSPEC_FNSTSW))]
1498   "TARGET_80387
1499    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1500        || optimize_function_for_size_p (cfun))"
1501   "* return output_fp_compare (insn, operands, false, false);"
1502   [(set_attr "type" "multi")
1503    (set_attr "unit" "i387")
1504    (set_attr "fp_int_src" "true")
1505    (set_attr "mode" "<SWI24:MODE>")])
1507 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1508   [(set (reg:CCFP FLAGS_REG)
1509         (compare:CCFP
1510           (match_operand:X87MODEF 1 "register_operand" "f")
1511           (match_operator:X87MODEF 3 "float_operator"
1512             [(match_operand:SWI24 2 "memory_operand" "m")])))
1513    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1514   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1515    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1516        || optimize_function_for_size_p (cfun))"
1517   "#"
1518   "&& reload_completed"
1519   [(set (match_dup 0)
1520         (unspec:HI
1521           [(compare:CCFP
1522              (match_dup 1)
1523              (match_op_dup 3 [(match_dup 2)]))]
1524         UNSPEC_FNSTSW))
1525    (set (reg:CC FLAGS_REG)
1526         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1527   ""
1528   [(set_attr "type" "multi")
1529    (set_attr "unit" "i387")
1530    (set_attr "fp_int_src" "true")
1531    (set_attr "mode" "<SWI24:MODE>")])
1533 ;; FP compares, step 2
1534 ;; Move the fpsw to ax.
1536 (define_insn "x86_fnstsw_1"
1537   [(set (match_operand:HI 0 "register_operand" "=a")
1538         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1539   "TARGET_80387"
1540   "fnstsw\t%0"
1541   [(set_attr "length" "2")
1542    (set_attr "mode" "SI")
1543    (set_attr "unit" "i387")])
1545 ;; FP compares, step 3
1546 ;; Get ax into flags, general case.
1548 (define_insn "x86_sahf_1"
1549   [(set (reg:CC FLAGS_REG)
1550         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1551                    UNSPEC_SAHF))]
1552   "TARGET_SAHF"
1554 #ifndef HAVE_AS_IX86_SAHF
1555   if (TARGET_64BIT)
1556     return ASM_BYTE "0x9e";
1557   else
1558 #endif
1559   return "sahf";
1561   [(set_attr "length" "1")
1562    (set_attr "athlon_decode" "vector")
1563    (set_attr "amdfam10_decode" "direct")
1564    (set_attr "bdver1_decode" "direct")
1565    (set_attr "mode" "SI")])
1567 ;; Pentium Pro can do steps 1 through 3 in one go.
1568 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1569 ;; (these i387 instructions set flags directly)
1571 (define_mode_iterator FPCMP [CCFP CCFPU])
1572 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1574 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1575   [(set (reg:FPCMP FLAGS_REG)
1576         (compare:FPCMP
1577           (match_operand:MODEF 0 "register_operand" "f,x")
1578           (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1579   "TARGET_MIX_SSE_I387
1580    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1581   "* return output_fp_compare (insn, operands, true,
1582                                <FPCMP:MODE>mode == CCFPUmode);"
1583   [(set_attr "type" "fcmp,ssecomi")
1584    (set_attr "prefix" "orig,maybe_vex")
1585    (set_attr "mode" "<MODEF:MODE>")
1586    (set (attr "prefix_rep")
1587         (if_then_else (eq_attr "type" "ssecomi")
1588                       (const_string "0")
1589                       (const_string "*")))
1590    (set (attr "prefix_data16")
1591         (cond [(eq_attr "type" "fcmp")
1592                  (const_string "*")
1593                (eq_attr "mode" "DF")
1594                  (const_string "1")
1595               ]
1596               (const_string "0")))
1597    (set_attr "athlon_decode" "vector")
1598    (set_attr "amdfam10_decode" "direct")
1599    (set_attr "bdver1_decode" "double")])
1601 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1602   [(set (reg:FPCMP FLAGS_REG)
1603         (compare:FPCMP
1604           (match_operand:MODEF 0 "register_operand" "x")
1605           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1606   "TARGET_SSE_MATH
1607    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1608   "* return output_fp_compare (insn, operands, true,
1609                                <FPCMP:MODE>mode == CCFPUmode);"
1610   [(set_attr "type" "ssecomi")
1611    (set_attr "prefix" "maybe_vex")
1612    (set_attr "mode" "<MODEF:MODE>")
1613    (set_attr "prefix_rep" "0")
1614    (set (attr "prefix_data16")
1615         (if_then_else (eq_attr "mode" "DF")
1616                       (const_string "1")
1617                       (const_string "0")))
1618    (set_attr "athlon_decode" "vector")
1619    (set_attr "amdfam10_decode" "direct")
1620    (set_attr "bdver1_decode" "double")])
1622 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1623   [(set (reg:FPCMP FLAGS_REG)
1624         (compare:FPCMP
1625           (match_operand:X87MODEF 0 "register_operand" "f")
1626           (match_operand:X87MODEF 1 "register_operand" "f")))]
1627   "TARGET_80387 && TARGET_CMOVE
1628    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1629   "* return output_fp_compare (insn, operands, true,
1630                                <FPCMP:MODE>mode == CCFPUmode);"
1631   [(set_attr "type" "fcmp")
1632    (set_attr "mode" "<X87MODEF:MODE>")
1633    (set_attr "athlon_decode" "vector")
1634    (set_attr "amdfam10_decode" "direct")
1635    (set_attr "bdver1_decode" "double")])
1637 ;; Push/pop instructions.
1639 (define_insn "*push<mode>2"
1640   [(set (match_operand:DWI 0 "push_operand" "=<")
1641         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1642   ""
1643   "#"
1644   [(set_attr "type" "multi")
1645    (set_attr "mode" "<MODE>")])
1647 (define_split
1648   [(set (match_operand:TI 0 "push_operand")
1649         (match_operand:TI 1 "general_operand"))]
1650   "TARGET_64BIT && reload_completed
1651    && !SSE_REG_P (operands[1])"
1652   [(const_int 0)]
1653   "ix86_split_long_move (operands); DONE;")
1655 (define_insn "*pushdi2_rex64"
1656   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1657         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1658   "TARGET_64BIT"
1659   "@
1660    push{q}\t%1
1661    #"
1662   [(set_attr "type" "push,multi")
1663    (set_attr "mode" "DI")])
1665 ;; Convert impossible pushes of immediate to existing instructions.
1666 ;; First try to get scratch register and go through it.  In case this
1667 ;; fails, push sign extended lower part first and then overwrite
1668 ;; upper part by 32bit move.
1669 (define_peephole2
1670   [(match_scratch:DI 2 "r")
1671    (set (match_operand:DI 0 "push_operand")
1672         (match_operand:DI 1 "immediate_operand"))]
1673   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1674    && !x86_64_immediate_operand (operands[1], DImode)"
1675   [(set (match_dup 2) (match_dup 1))
1676    (set (match_dup 0) (match_dup 2))])
1678 ;; We need to define this as both peepholer and splitter for case
1679 ;; peephole2 pass is not run.
1680 ;; "&& 1" is needed to keep it from matching the previous pattern.
1681 (define_peephole2
1682   [(set (match_operand:DI 0 "push_operand")
1683         (match_operand:DI 1 "immediate_operand"))]
1684   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1685    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1686   [(set (match_dup 0) (match_dup 1))
1687    (set (match_dup 2) (match_dup 3))]
1689   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1691   operands[1] = gen_lowpart (DImode, operands[2]);
1692   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1693                                                    GEN_INT (4)));
1696 (define_split
1697   [(set (match_operand:DI 0 "push_operand")
1698         (match_operand:DI 1 "immediate_operand"))]
1699   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1700                     ? epilogue_completed : reload_completed)
1701    && !symbolic_operand (operands[1], DImode)
1702    && !x86_64_immediate_operand (operands[1], DImode)"
1703   [(set (match_dup 0) (match_dup 1))
1704    (set (match_dup 2) (match_dup 3))]
1706   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1708   operands[1] = gen_lowpart (DImode, operands[2]);
1709   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1710                                                    GEN_INT (4)));
1713 (define_split
1714   [(set (match_operand:DI 0 "push_operand")
1715         (match_operand:DI 1 "general_operand"))]
1716   "!TARGET_64BIT && reload_completed
1717    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1718   [(const_int 0)]
1719   "ix86_split_long_move (operands); DONE;")
1721 (define_insn "*pushsi2"
1722   [(set (match_operand:SI 0 "push_operand" "=<")
1723         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1724   "!TARGET_64BIT"
1725   "push{l}\t%1"
1726   [(set_attr "type" "push")
1727    (set_attr "mode" "SI")])
1729 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1730 ;; "push a byte/word".  But actually we use pushl, which has the effect
1731 ;; of rounding the amount pushed up to a word.
1733 ;; For TARGET_64BIT we always round up to 8 bytes.
1734 (define_insn "*push<mode>2_rex64"
1735   [(set (match_operand:SWI124 0 "push_operand" "=X")
1736         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1737   "TARGET_64BIT"
1738   "push{q}\t%q1"
1739   [(set_attr "type" "push")
1740    (set_attr "mode" "DI")])
1742 (define_insn "*push<mode>2"
1743   [(set (match_operand:SWI12 0 "push_operand" "=X")
1744         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1745   "!TARGET_64BIT"
1746   "push{l}\t%k1"
1747   [(set_attr "type" "push")
1748    (set_attr "mode" "SI")])
1750 (define_insn "*push<mode>2_prologue"
1751   [(set (match_operand:W 0 "push_operand" "=<")
1752         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1753    (clobber (mem:BLK (scratch)))]
1754   ""
1755   "push{<imodesuffix>}\t%1"
1756   [(set_attr "type" "push")
1757    (set_attr "mode" "<MODE>")])
1759 (define_insn "*pop<mode>1"
1760   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1761         (match_operand:W 1 "pop_operand" ">"))]
1762   ""
1763   "pop{<imodesuffix>}\t%0"
1764   [(set_attr "type" "pop")
1765    (set_attr "mode" "<MODE>")])
1767 (define_insn "*pop<mode>1_epilogue"
1768   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1769         (match_operand:W 1 "pop_operand" ">"))
1770    (clobber (mem:BLK (scratch)))]
1771   ""
1772   "pop{<imodesuffix>}\t%0"
1773   [(set_attr "type" "pop")
1774    (set_attr "mode" "<MODE>")])
1776 (define_insn "*pushfl<mode>2"
1777   [(set (match_operand:W 0 "push_operand" "=<")
1778         (match_operand:W 1 "flags_reg_operand"))]
1779   ""
1780   "pushf{<imodesuffix>}"
1781   [(set_attr "type" "push")
1782    (set_attr "mode" "<MODE>")])
1784 (define_insn "*popfl<mode>1"
1785   [(set (match_operand:W 0 "flags_reg_operand")
1786         (match_operand:W 1 "pop_operand" ">"))]
1787   ""
1788   "popf{<imodesuffix>}"
1789   [(set_attr "type" "pop")
1790    (set_attr "mode" "<MODE>")])
1793 ;; Move instructions.
1795 (define_expand "movxi"
1796   [(set (match_operand:XI 0 "nonimmediate_operand")
1797         (match_operand:XI 1 "general_operand"))]
1798   "TARGET_AVX512F"
1799   "ix86_expand_move (XImode, operands); DONE;")
1801 ;; Reload patterns to support multi-word load/store
1802 ;; with non-offsetable address.
1803 (define_expand "reload_noff_store"
1804   [(parallel [(match_operand 0 "memory_operand" "=m")
1805               (match_operand 1 "register_operand" "r")
1806               (match_operand:DI 2 "register_operand" "=&r")])]
1807   "TARGET_64BIT"
1809   rtx mem = operands[0];
1810   rtx addr = XEXP (mem, 0);
1812   emit_move_insn (operands[2], addr);
1813   mem = replace_equiv_address_nv (mem, operands[2]);
1815   emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1816   DONE;
1819 (define_expand "reload_noff_load"
1820   [(parallel [(match_operand 0 "register_operand" "=r")
1821               (match_operand 1 "memory_operand" "m")
1822               (match_operand:DI 2 "register_operand" "=r")])]
1823   "TARGET_64BIT"
1825   rtx mem = operands[1];
1826   rtx addr = XEXP (mem, 0);
1828   emit_move_insn (operands[2], addr);
1829   mem = replace_equiv_address_nv (mem, operands[2]);
1831   emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1832   DONE;
1835 (define_expand "movoi"
1836   [(set (match_operand:OI 0 "nonimmediate_operand")
1837         (match_operand:OI 1 "general_operand"))]
1838   "TARGET_AVX"
1839   "ix86_expand_move (OImode, operands); DONE;")
1841 (define_expand "movti"
1842   [(set (match_operand:TI 0 "nonimmediate_operand")
1843         (match_operand:TI 1 "nonimmediate_operand"))]
1844   "TARGET_64BIT || TARGET_SSE"
1846   if (TARGET_64BIT)
1847     ix86_expand_move (TImode, operands);
1848   else
1849     ix86_expand_vector_move (TImode, operands);
1850   DONE;
1853 ;; This expands to what emit_move_complex would generate if we didn't
1854 ;; have a movti pattern.  Having this avoids problems with reload on
1855 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1856 ;; to have around all the time.
1857 (define_expand "movcdi"
1858   [(set (match_operand:CDI 0 "nonimmediate_operand")
1859         (match_operand:CDI 1 "general_operand"))]
1860   ""
1862   if (push_operand (operands[0], CDImode))
1863     emit_move_complex_push (CDImode, operands[0], operands[1]);
1864   else
1865     emit_move_complex_parts (operands[0], operands[1]);
1866   DONE;
1869 (define_expand "mov<mode>"
1870   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1871         (match_operand:SWI1248x 1 "general_operand"))]
1872   ""
1873   "ix86_expand_move (<MODE>mode, operands); DONE;")
1875 (define_insn "*mov<mode>_xor"
1876   [(set (match_operand:SWI48 0 "register_operand" "=r")
1877         (match_operand:SWI48 1 "const0_operand"))
1878    (clobber (reg:CC FLAGS_REG))]
1879   "reload_completed"
1880   "xor{l}\t%k0, %k0"
1881   [(set_attr "type" "alu1")
1882    (set_attr "mode" "SI")
1883    (set_attr "length_immediate" "0")])
1885 (define_insn "*mov<mode>_or"
1886   [(set (match_operand:SWI48 0 "register_operand" "=r")
1887         (match_operand:SWI48 1 "const_int_operand"))
1888    (clobber (reg:CC FLAGS_REG))]
1889   "reload_completed
1890    && operands[1] == constm1_rtx"
1891   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1892   [(set_attr "type" "alu1")
1893    (set_attr "mode" "<MODE>")
1894    (set_attr "length_immediate" "1")])
1896 (define_insn "*movxi_internal_avx512f"
1897   [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1898         (match_operand:XI 1 "vector_move_operand"  "C ,xm,x"))]
1899   "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1901   switch (which_alternative)
1902     {
1903     case 0:
1904       return standard_sse_constant_opcode (insn, operands[1]);
1905     case 1:
1906     case 2:
1907       if (misaligned_operand (operands[0], XImode)
1908           || misaligned_operand (operands[1], XImode))
1909         return "vmovdqu32\t{%1, %0|%0, %1}";
1910       else
1911         return "vmovdqa32\t{%1, %0|%0, %1}";
1912     default:
1913       gcc_unreachable ();
1914     }
1916   [(set_attr "type" "sselog1,ssemov,ssemov")
1917    (set_attr "prefix" "evex")
1918    (set_attr "mode" "XI")])
1920 (define_insn "*movoi_internal_avx"
1921   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1922         (match_operand:OI 1 "vector_move_operand"  "C ,xm,x"))]
1923   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1925   switch (get_attr_type (insn))
1926     {
1927     case TYPE_SSELOG1:
1928       return standard_sse_constant_opcode (insn, operands[1]);
1930     case TYPE_SSEMOV:
1931       if (misaligned_operand (operands[0], OImode)
1932           || misaligned_operand (operands[1], OImode))
1933         {
1934           if (get_attr_mode (insn) == MODE_V8SF)
1935             return "vmovups\t{%1, %0|%0, %1}";
1936           else
1937             return "vmovdqu\t{%1, %0|%0, %1}";
1938         }
1939       else
1940         {
1941           if (get_attr_mode (insn) == MODE_V8SF)
1942             return "vmovaps\t{%1, %0|%0, %1}";
1943           else
1944             return "vmovdqa\t{%1, %0|%0, %1}";
1945         }
1947     default:
1948       gcc_unreachable ();
1949     }
1951   [(set_attr "type" "sselog1,ssemov,ssemov")
1952    (set_attr "prefix" "vex")
1953    (set (attr "mode")
1954         (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1955                  (const_string "V8SF")
1956                (and (eq_attr "alternative" "2")
1957                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1958                  (const_string "V8SF")
1959               ]
1960               (const_string "OI")))])
1962 (define_insn "*movti_internal"
1963   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1964         (match_operand:TI 1 "general_operand"      "riFo,re,C,xm,x"))]
1965   "(TARGET_64BIT || TARGET_SSE)
1966    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1968   switch (get_attr_type (insn))
1969     {
1970     case TYPE_MULTI:
1971       return "#";
1973     case TYPE_SSELOG1:
1974       return standard_sse_constant_opcode (insn, operands[1]);
1976     case TYPE_SSEMOV:
1977       /* TDmode values are passed as TImode on the stack.  Moving them
1978          to stack may result in unaligned memory access.  */
1979       if (misaligned_operand (operands[0], TImode)
1980           || misaligned_operand (operands[1], TImode))
1981         {
1982           if (get_attr_mode (insn) == MODE_V4SF)
1983             return "%vmovups\t{%1, %0|%0, %1}";
1984           else
1985             return "%vmovdqu\t{%1, %0|%0, %1}";
1986         }
1987       else
1988         {
1989           if (get_attr_mode (insn) == MODE_V4SF)
1990             return "%vmovaps\t{%1, %0|%0, %1}";
1991           else
1992             return "%vmovdqa\t{%1, %0|%0, %1}";
1993         }
1995     default:
1996       gcc_unreachable ();
1997     }
1999   [(set_attr "isa" "x64,x64,*,*,*")
2000    (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2001    (set (attr "prefix")
2002      (if_then_else (eq_attr "type" "sselog1,ssemov")
2003        (const_string "maybe_vex")
2004        (const_string "orig")))
2005    (set (attr "mode")
2006         (cond [(eq_attr "alternative" "0,1")
2007                  (const_string "DI")
2008                (ior (not (match_test "TARGET_SSE2"))
2009                     (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2010                  (const_string "V4SF")
2011                (and (eq_attr "alternative" "4")
2012                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2013                  (const_string "V4SF")
2014                (match_test "TARGET_AVX")
2015                  (const_string "TI")
2016                (match_test "optimize_function_for_size_p (cfun)")
2017                  (const_string "V4SF")
2018                ]
2019                (const_string "TI")))])
2021 (define_split
2022   [(set (match_operand:TI 0 "nonimmediate_operand")
2023         (match_operand:TI 1 "general_operand"))]
2024   "reload_completed
2025    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2026   [(const_int 0)]
2027   "ix86_split_long_move (operands); DONE;")
2029 (define_insn "*movdi_internal"
2030   [(set (match_operand:DI 0 "nonimmediate_operand"
2031     "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r ,*m")
2032         (match_operand:DI 1 "general_operand"
2033     "riFo,riF,Z,rem,i,re,C ,*y,m  ,*y,*Yn,r   ,C ,*v,m ,*v,*Yj,*v,r   ,*Yj ,*Yn ,*r ,*km,*k,*k"))]
2034   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2036   switch (get_attr_type (insn))
2037     {
2038     case TYPE_MSKMOV:
2039       return "kmovq\t{%1, %0|%0, %1}";
2041     case TYPE_MULTI:
2042       return "#";
2044     case TYPE_MMX:
2045       return "pxor\t%0, %0";
2047     case TYPE_MMXMOV:
2048       /* Handle broken assemblers that require movd instead of movq.  */
2049       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2050           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2051         return "movd\t{%1, %0|%0, %1}";
2052       return "movq\t{%1, %0|%0, %1}";
2054     case TYPE_SSELOG1:
2055       if (GENERAL_REG_P (operands[0]))
2056         return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2058       return standard_sse_constant_opcode (insn, operands[1]);
2060     case TYPE_SSEMOV:
2061       switch (get_attr_mode (insn))
2062         {
2063         case MODE_DI:
2064           /* Handle broken assemblers that require movd instead of movq.  */
2065           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2066               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2067             return "%vmovd\t{%1, %0|%0, %1}";
2068           return "%vmovq\t{%1, %0|%0, %1}";
2069         case MODE_TI:
2070           return "%vmovdqa\t{%1, %0|%0, %1}";
2071         case MODE_XI:
2072           return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2074         case MODE_V2SF:
2075           gcc_assert (!TARGET_AVX);
2076           return "movlps\t{%1, %0|%0, %1}";
2077         case MODE_V4SF:
2078           return "%vmovaps\t{%1, %0|%0, %1}";
2080         default:
2081           gcc_unreachable ();
2082         }
2084     case TYPE_SSECVT:
2085       if (SSE_REG_P (operands[0]))
2086         return "movq2dq\t{%1, %0|%0, %1}";
2087       else
2088         return "movdq2q\t{%1, %0|%0, %1}";
2090     case TYPE_LEA:
2091       return "lea{q}\t{%E1, %0|%0, %E1}";
2093     case TYPE_IMOV:
2094       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2095       if (get_attr_mode (insn) == MODE_SI)
2096         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2097       else if (which_alternative == 4)
2098         return "movabs{q}\t{%1, %0|%0, %1}";
2099       else if (ix86_use_lea_for_mov (insn, operands))
2100         return "lea{q}\t{%E1, %0|%0, %E1}";
2101       else
2102         return "mov{q}\t{%1, %0|%0, %1}";
2104     default:
2105       gcc_unreachable ();
2106     }
2108   [(set (attr "isa")
2109      (cond [(eq_attr "alternative" "0,1")
2110               (const_string "nox64")
2111             (eq_attr "alternative" "2,3,4,5,10,11,16,18,21,23")
2112               (const_string "x64")
2113             (eq_attr "alternative" "17")
2114               (const_string "x64_sse4")
2115            ]
2116            (const_string "*")))
2117    (set (attr "type")
2118      (cond [(eq_attr "alternative" "0,1")
2119               (const_string "multi")
2120             (eq_attr "alternative" "6")
2121               (const_string "mmx")
2122             (eq_attr "alternative" "7,8,9,10,11")
2123               (const_string "mmxmov")
2124             (eq_attr "alternative" "12,17")
2125               (const_string "sselog1")
2126             (eq_attr "alternative" "13,14,15,16,18")
2127               (const_string "ssemov")
2128             (eq_attr "alternative" "19,20")
2129               (const_string "ssecvt")
2130             (eq_attr "alternative" "21,22,23,24")
2131               (const_string "mskmov")
2132             (match_operand 1 "pic_32bit_operand")
2133               (const_string "lea")
2134            ]
2135            (const_string "imov")))
2136    (set (attr "modrm")
2137      (if_then_else
2138        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2139          (const_string "0")
2140          (const_string "*")))
2141    (set (attr "length_immediate")
2142      (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2143               (const_string "8")
2144             (eq_attr "alternative" "17")
2145               (const_string "1")
2146            ]
2147            (const_string "*")))
2148    (set (attr "prefix_rex")
2149      (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2150        (const_string "1")
2151        (const_string "*")))
2152    (set (attr "prefix_extra")
2153      (if_then_else (eq_attr "alternative" "17")
2154        (const_string "1")
2155        (const_string "*")))
2156    (set (attr "prefix")
2157      (if_then_else (eq_attr "type" "sselog1,ssemov")
2158        (const_string "maybe_vex")
2159        (const_string "orig")))
2160    (set (attr "prefix_data16")
2161      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2162        (const_string "1")
2163        (const_string "*")))
2164    (set (attr "mode")
2165      (cond [(eq_attr "alternative" "2")
2166               (const_string "SI")
2167             (eq_attr "alternative" "12,13")
2168               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2169                           (match_operand 1 "ext_sse_reg_operand"))
2170                        (const_string "XI")
2171                      (ior (not (match_test "TARGET_SSE2"))
2172                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2173                        (const_string "V4SF")
2174                      (match_test "TARGET_AVX")
2175                        (const_string "TI")
2176                      (match_test "optimize_function_for_size_p (cfun)")
2177                        (const_string "V4SF")
2178                     ]
2179                     (const_string "TI"))
2181             (and (eq_attr "alternative" "14,15")
2182                  (not (match_test "TARGET_SSE2")))
2183               (const_string "V2SF")
2184             (eq_attr "alternative" "17")
2185               (const_string "TI")
2186            ]
2187            (const_string "DI")))])
2189 (define_split
2190   [(set (match_operand:DI 0 "nonimmediate_operand")
2191         (match_operand:DI 1 "general_operand"))]
2192   "!TARGET_64BIT && reload_completed
2193    && !(MMX_REG_P (operands[0])
2194         || SSE_REG_P (operands[0])
2195         || MASK_REG_P (operands[0]))
2196    && !(MMX_REG_P (operands[1])
2197         || SSE_REG_P (operands[1])
2198         || MASK_REG_P (operands[1]))"
2199   [(const_int 0)]
2200   "ix86_split_long_move (operands); DONE;")
2202 (define_insn "*movsi_internal"
2203   [(set (match_operand:SI 0 "nonimmediate_operand"
2204                         "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k  ,*rm")
2205         (match_operand:SI 1 "general_operand"
2206                         "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r   ,*krm,*k"))]
2207   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2209   switch (get_attr_type (insn))
2210     {
2211     case TYPE_SSELOG1:
2212       if (GENERAL_REG_P (operands[0]))
2213         return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2215       return standard_sse_constant_opcode (insn, operands[1]);
2217     case TYPE_MSKMOV:
2218       return "kmovd\t{%1, %0|%0, %1}";
2220     case TYPE_SSEMOV:
2221       switch (get_attr_mode (insn))
2222         {
2223         case MODE_SI:
2224           return "%vmovd\t{%1, %0|%0, %1}";
2225         case MODE_TI:
2226           return "%vmovdqa\t{%1, %0|%0, %1}";
2227         case MODE_XI:
2228           return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2230         case MODE_V4SF:
2231           return "%vmovaps\t{%1, %0|%0, %1}";
2233         case MODE_SF:
2234           gcc_assert (!TARGET_AVX);
2235           return "movss\t{%1, %0|%0, %1}";
2237         default:
2238           gcc_unreachable ();
2239         }
2241     case TYPE_MMX:
2242       return "pxor\t%0, %0";
2244     case TYPE_MMXMOV:
2245       switch (get_attr_mode (insn))
2246         {
2247         case MODE_DI:
2248           return "movq\t{%1, %0|%0, %1}";
2249         case MODE_SI:
2250           return "movd\t{%1, %0|%0, %1}";
2252         default:
2253           gcc_unreachable ();
2254         }
2256     case TYPE_LEA:
2257       return "lea{l}\t{%E1, %0|%0, %E1}";
2259     case TYPE_IMOV:
2260       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2261       if (ix86_use_lea_for_mov (insn, operands))
2262         return "lea{l}\t{%E1, %0|%0, %E1}";
2263       else
2264         return "mov{l}\t{%1, %0|%0, %1}";
2266     default:
2267       gcc_unreachable ();
2268     }
2270   [(set (attr "isa")
2271      (if_then_else (eq_attr "alternative" "11")
2272        (const_string "sse4")
2273        (const_string "*")))
2274    (set (attr "type")
2275      (cond [(eq_attr "alternative" "2")
2276               (const_string "mmx")
2277             (eq_attr "alternative" "3,4,5")
2278               (const_string "mmxmov")
2279             (eq_attr "alternative" "6,11")
2280               (const_string "sselog1")
2281             (eq_attr "alternative" "7,8,9,10,12")
2282               (const_string "ssemov")
2283             (eq_attr "alternative" "13,14")
2284               (const_string "mskmov")
2285             (match_operand 1 "pic_32bit_operand")
2286               (const_string "lea")
2287            ]
2288            (const_string "imov")))
2289    (set (attr "length_immediate")
2290      (if_then_else (eq_attr "alternative" "11")
2291        (const_string "1")
2292        (const_string "*")))
2293    (set (attr "prefix_extra")
2294      (if_then_else (eq_attr "alternative" "11")
2295        (const_string "1")
2296        (const_string "*")))
2297    (set (attr "prefix")
2298      (if_then_else (eq_attr "type" "sselog1,ssemov")
2299        (const_string "maybe_vex")
2300        (const_string "orig")))
2301    (set (attr "prefix_data16")
2302      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2303        (const_string "1")
2304        (const_string "*")))
2305    (set (attr "mode")
2306      (cond [(eq_attr "alternative" "2,3")
2307               (const_string "DI")
2308             (eq_attr "alternative" "6,7")
2309               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2310                           (match_operand 1 "ext_sse_reg_operand"))
2311                        (const_string "XI")
2312                      (ior (not (match_test "TARGET_SSE2"))
2313                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2314                        (const_string "V4SF")
2315                      (match_test "TARGET_AVX")
2316                        (const_string "TI")
2317                      (match_test "optimize_function_for_size_p (cfun)")
2318                        (const_string "V4SF")
2319                     ]
2320                     (const_string "TI"))
2322             (and (eq_attr "alternative" "8,9")
2323                  (not (match_test "TARGET_SSE2")))
2324               (const_string "SF")
2325             (eq_attr "alternative" "11")
2326               (const_string "TI")
2327            ]
2328            (const_string "SI")))])
2330 (define_insn "kmovw"
2331   [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2332         (unspec:HI
2333           [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2334           UNSPEC_KMOV))]
2335   "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2336   "@
2337    kmovw\t{%k1, %0|%0, %k1}
2338    kmovw\t{%1, %0|%0, %1}";
2339   [(set_attr "mode" "HI")
2340    (set_attr "type" "mskmov")
2341    (set_attr "prefix" "vex")])
2344 (define_insn "*movhi_internal"
2345   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2346         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,rm,k,k"))]
2347   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2349   switch (get_attr_type (insn))
2350     {
2351     case TYPE_IMOVX:
2352       /* movzwl is faster than movw on p2 due to partial word stalls,
2353          though not as fast as an aligned movl.  */
2354       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2356     case TYPE_MSKMOV:
2357       switch (which_alternative)
2358         {
2359         case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2360         case 5: return "kmovw\t{%1, %0|%0, %1}";
2361         case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2362         default: gcc_unreachable ();
2363         }
2365     default:
2366       if (get_attr_mode (insn) == MODE_SI)
2367         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2368       else
2369         return "mov{w}\t{%1, %0|%0, %1}";
2370     }
2372   [(set (attr "type")
2373      (cond [(match_test "optimize_function_for_size_p (cfun)")
2374               (const_string "imov")
2375             (and (eq_attr "alternative" "0")
2376                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2377                       (not (match_test "TARGET_HIMODE_MATH"))))
2378               (const_string "imov")
2379             (and (eq_attr "alternative" "1,2")
2380                  (match_operand:HI 1 "aligned_operand"))
2381               (const_string "imov")
2382             (eq_attr "alternative" "4,5,6")
2383               (const_string "mskmov")
2384             (and (match_test "TARGET_MOVX")
2385                  (eq_attr "alternative" "0,2"))
2386               (const_string "imovx")
2387            ]
2388            (const_string "imov")))
2389     (set (attr "prefix")
2390       (if_then_else (eq_attr "alternative" "4,5,6")
2391         (const_string "vex")
2392         (const_string "orig")))
2393     (set (attr "mode")
2394       (cond [(eq_attr "type" "imovx")
2395                (const_string "SI")
2396              (and (eq_attr "alternative" "1,2")
2397                   (match_operand:HI 1 "aligned_operand"))
2398                (const_string "SI")
2399              (and (eq_attr "alternative" "0")
2400                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2401                        (not (match_test "TARGET_HIMODE_MATH"))))
2402                (const_string "SI")
2403             ]
2404             (const_string "HI")))])
2406 ;; Situation is quite tricky about when to choose full sized (SImode) move
2407 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2408 ;; partial register dependency machines (such as AMD Athlon), where QImode
2409 ;; moves issue extra dependency and for partial register stalls machines
2410 ;; that don't use QImode patterns (and QImode move cause stall on the next
2411 ;; instruction).
2413 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2414 ;; register stall machines with, where we use QImode instructions, since
2415 ;; partial register stall can be caused there.  Then we use movzx.
2417 (define_insn "*movqi_internal"
2418   [(set (match_operand:QI 0 "nonimmediate_operand"
2419                         "=q,q ,q ,r,r ,?r,m ,k,k,r")
2420         (match_operand:QI 1 "general_operand"
2421                         "q ,qn,qm,q,rn,qm,qn,r ,k,k"))]
2422   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2424   switch (get_attr_type (insn))
2425     {
2426     case TYPE_IMOVX:
2427       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2428       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2430     case TYPE_MSKMOV:
2431       switch (which_alternative)
2432         {
2433         case 7: return TARGET_AVX512BW ? "kmovb\t{%k1, %0|%0, %k1}"
2434                                        : "kmovw\t{%k1, %0|%0, %k1}";
2435         case 8: return TARGET_AVX512BW ? "kmovb\t{%1, %0|%0, %1}"
2436                                        : "kmovw\t{%1, %0|%0, %1}";
2437         case 9: return TARGET_AVX512BW ? "kmovb\t{%1, %k0|%k0, %1}"
2438                                        : "kmovw\t{%1, %k0|%k0, %1}";
2439         default: gcc_unreachable ();
2440         }
2442     default:
2443       if (get_attr_mode (insn) == MODE_SI)
2444         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2445       else
2446         return "mov{b}\t{%1, %0|%0, %1}";
2447     }
2449   [(set (attr "type")
2450      (cond [(and (eq_attr "alternative" "5")
2451                  (not (match_operand:QI 1 "aligned_operand")))
2452               (const_string "imovx")
2453             (match_test "optimize_function_for_size_p (cfun)")
2454               (const_string "imov")
2455             (and (eq_attr "alternative" "3")
2456                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2457                       (not (match_test "TARGET_QIMODE_MATH"))))
2458               (const_string "imov")
2459             (eq_attr "alternative" "3,5")
2460               (const_string "imovx")
2461             (eq_attr "alternative" "7,8,9")
2462               (const_string "mskmov")
2463             (and (match_test "TARGET_MOVX")
2464                  (eq_attr "alternative" "2"))
2465               (const_string "imovx")
2466            ]
2467            (const_string "imov")))
2468    (set (attr "prefix")
2469      (if_then_else (eq_attr "alternative" "7,8,9")
2470        (const_string "vex")
2471        (const_string "orig")))
2472    (set (attr "mode")
2473       (cond [(eq_attr "alternative" "3,4,5")
2474                (const_string "SI")
2475              (eq_attr "alternative" "6")
2476                (const_string "QI")
2477              (eq_attr "type" "imovx")
2478                (const_string "SI")
2479              (and (eq_attr "type" "imov")
2480                   (and (eq_attr "alternative" "0,1")
2481                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2482                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2483                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2484                (const_string "SI")
2485              ;; Avoid partial register stalls when not using QImode arithmetic
2486              (and (eq_attr "type" "imov")
2487                   (and (eq_attr "alternative" "0,1")
2488                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2489                             (not (match_test "TARGET_QIMODE_MATH")))))
2490                (const_string "SI")
2491            ]
2492            (const_string "QI")))])
2494 ;; Stores and loads of ax to arbitrary constant address.
2495 ;; We fake an second form of instruction to force reload to load address
2496 ;; into register when rax is not available
2497 (define_insn "*movabs<mode>_1"
2498   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2499         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2500   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2501   "@
2502    movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2503    mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2504   [(set_attr "type" "imov")
2505    (set_attr "modrm" "0,*")
2506    (set_attr "length_address" "8,0")
2507    (set_attr "length_immediate" "0,*")
2508    (set_attr "memory" "store")
2509    (set_attr "mode" "<MODE>")])
2511 (define_insn "*movabs<mode>_2"
2512   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2513         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2514   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2515   "@
2516    movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2517    mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2518   [(set_attr "type" "imov")
2519    (set_attr "modrm" "0,*")
2520    (set_attr "length_address" "8,0")
2521    (set_attr "length_immediate" "0")
2522    (set_attr "memory" "load")
2523    (set_attr "mode" "<MODE>")])
2525 (define_insn "*swap<mode>"
2526   [(set (match_operand:SWI48 0 "register_operand" "+r")
2527         (match_operand:SWI48 1 "register_operand" "+r"))
2528    (set (match_dup 1)
2529         (match_dup 0))]
2530   ""
2531   "xchg{<imodesuffix>}\t%1, %0"
2532   [(set_attr "type" "imov")
2533    (set_attr "mode" "<MODE>")
2534    (set_attr "pent_pair" "np")
2535    (set_attr "athlon_decode" "vector")
2536    (set_attr "amdfam10_decode" "double")
2537    (set_attr "bdver1_decode" "double")])
2539 (define_insn "*swap<mode>_1"
2540   [(set (match_operand:SWI12 0 "register_operand" "+r")
2541         (match_operand:SWI12 1 "register_operand" "+r"))
2542    (set (match_dup 1)
2543         (match_dup 0))]
2544   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2545   "xchg{l}\t%k1, %k0"
2546   [(set_attr "type" "imov")
2547    (set_attr "mode" "SI")
2548    (set_attr "pent_pair" "np")
2549    (set_attr "athlon_decode" "vector")
2550    (set_attr "amdfam10_decode" "double")
2551    (set_attr "bdver1_decode" "double")])
2553 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2554 ;; is disabled for AMDFAM10
2555 (define_insn "*swap<mode>_2"
2556   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2557         (match_operand:SWI12 1 "register_operand" "+<r>"))
2558    (set (match_dup 1)
2559         (match_dup 0))]
2560   "TARGET_PARTIAL_REG_STALL"
2561   "xchg{<imodesuffix>}\t%1, %0"
2562   [(set_attr "type" "imov")
2563    (set_attr "mode" "<MODE>")
2564    (set_attr "pent_pair" "np")
2565    (set_attr "athlon_decode" "vector")])
2567 (define_expand "movstrict<mode>"
2568   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2569         (match_operand:SWI12 1 "general_operand"))]
2570   ""
2572   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2573     FAIL;
2574   if (GET_CODE (operands[0]) == SUBREG
2575       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2576     FAIL;
2577   /* Don't generate memory->memory moves, go through a register */
2578   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2579     operands[1] = force_reg (<MODE>mode, operands[1]);
2582 (define_insn "*movstrict<mode>_1"
2583   [(set (strict_low_part
2584           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2585         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2586   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2587    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2588   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2589   [(set_attr "type" "imov")
2590    (set_attr "mode" "<MODE>")])
2592 (define_insn "*movstrict<mode>_xor"
2593   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2594         (match_operand:SWI12 1 "const0_operand"))
2595    (clobber (reg:CC FLAGS_REG))]
2596   "reload_completed"
2597   "xor{<imodesuffix>}\t%0, %0"
2598   [(set_attr "type" "alu1")
2599    (set_attr "mode" "<MODE>")
2600    (set_attr "length_immediate" "0")])
2602 (define_insn "*mov<mode>_extv_1"
2603   [(set (match_operand:SWI24 0 "register_operand" "=R")
2604         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2605                             (const_int 8)
2606                             (const_int 8)))]
2607   ""
2608   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2609   [(set_attr "type" "imovx")
2610    (set_attr "mode" "SI")])
2612 (define_insn "*movqi_extv_1"
2613   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2614         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2615                          (const_int 8)
2616                          (const_int 8)))]
2617   ""
2619   switch (get_attr_type (insn))
2620     {
2621     case TYPE_IMOVX:
2622       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2623     default:
2624       return "mov{b}\t{%h1, %0|%0, %h1}";
2625     }
2627   [(set_attr "isa" "*,*,nox64")
2628    (set (attr "type")
2629      (if_then_else (and (match_operand:QI 0 "register_operand")
2630                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2631                              (match_test "TARGET_MOVX")))
2632         (const_string "imovx")
2633         (const_string "imov")))
2634    (set (attr "mode")
2635      (if_then_else (eq_attr "type" "imovx")
2636         (const_string "SI")
2637         (const_string "QI")))])
2639 (define_insn "*mov<mode>_extzv_1"
2640   [(set (match_operand:SWI48 0 "register_operand" "=R")
2641         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2642                             (const_int 8)
2643                             (const_int 8)))]
2644   ""
2645   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2646   [(set_attr "type" "imovx")
2647    (set_attr "mode" "SI")])
2649 (define_insn "*movqi_extzv_2"
2650   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2651         (subreg:QI
2652           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2653                            (const_int 8)
2654                            (const_int 8)) 0))]
2655   ""
2657   switch (get_attr_type (insn))
2658     {
2659     case TYPE_IMOVX:
2660       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2661     default:
2662       return "mov{b}\t{%h1, %0|%0, %h1}";
2663     }
2665   [(set_attr "isa" "*,*,nox64")
2666    (set (attr "type")
2667      (if_then_else (and (match_operand:QI 0 "register_operand")
2668                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2669                              (match_test "TARGET_MOVX")))
2670         (const_string "imovx")
2671         (const_string "imov")))
2672    (set (attr "mode")
2673      (if_then_else (eq_attr "type" "imovx")
2674         (const_string "SI")
2675         (const_string "QI")))])
2677 (define_insn "mov<mode>_insv_1"
2678   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2679                              (const_int 8)
2680                              (const_int 8))
2681         (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2682   ""
2684   if (CONST_INT_P (operands[1]))
2685     operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2686   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2688   [(set_attr "isa" "*,nox64")
2689    (set_attr "type" "imov")
2690    (set_attr "mode" "QI")])
2692 (define_insn "*movqi_insv_2"
2693   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2694                          (const_int 8)
2695                          (const_int 8))
2696         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2697                      (const_int 8)))]
2698   ""
2699   "mov{b}\t{%h1, %h0|%h0, %h1}"
2700   [(set_attr "type" "imov")
2701    (set_attr "mode" "QI")])
2703 ;; Floating point push instructions.
2705 (define_insn "*pushtf"
2706   [(set (match_operand:TF 0 "push_operand" "=<,<")
2707         (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2708   "TARGET_64BIT || TARGET_SSE"
2710   /* This insn should be already split before reg-stack.  */
2711   gcc_unreachable ();
2713   [(set_attr "isa" "*,x64")
2714    (set_attr "type" "multi")
2715    (set_attr "unit" "sse,*")
2716    (set_attr "mode" "TF,DI")])
2718 ;; %%% Kill this when call knows how to work this out.
2719 (define_split
2720   [(set (match_operand:TF 0 "push_operand")
2721         (match_operand:TF 1 "sse_reg_operand"))]
2722   "TARGET_SSE && reload_completed"
2723   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2724    (set (match_dup 0) (match_dup 1))]
2726   /* Preserve memory attributes. */
2727   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2730 (define_insn "*pushxf"
2731   [(set (match_operand:XF 0 "push_operand" "=<,<")
2732         (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2733   ""
2735   /* This insn should be already split before reg-stack.  */
2736   gcc_unreachable ();
2738   [(set_attr "type" "multi")
2739    (set_attr "unit" "i387,*")
2740    (set (attr "mode")
2741         (cond [(eq_attr "alternative" "1")
2742                  (if_then_else (match_test "TARGET_64BIT")
2743                    (const_string "DI")
2744                    (const_string "SI"))
2745               ]
2746               (const_string "XF")))])
2748 ;; %%% Kill this when call knows how to work this out.
2749 (define_split
2750   [(set (match_operand:XF 0 "push_operand")
2751         (match_operand:XF 1 "fp_register_operand"))]
2752   "reload_completed"
2753   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2754    (set (match_dup 0) (match_dup 1))]
2756   operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2757   /* Preserve memory attributes. */
2758   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2761 (define_insn "*pushdf"
2762   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2763         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2764   ""
2766   /* This insn should be already split before reg-stack.  */
2767   gcc_unreachable ();
2769   [(set_attr "isa" "*,nox64,x64,sse2")
2770    (set_attr "type" "multi")
2771    (set_attr "unit" "i387,*,*,sse")
2772    (set_attr "mode" "DF,SI,DI,DF")])
2774 ;; %%% Kill this when call knows how to work this out.
2775 (define_split
2776   [(set (match_operand:DF 0 "push_operand")
2777         (match_operand:DF 1 "any_fp_register_operand"))]
2778   "reload_completed"
2779   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2780    (set (match_dup 0) (match_dup 1))]
2782   /* Preserve memory attributes. */
2783   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2786 (define_insn "*pushsf_rex64"
2787   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2788         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2789   "TARGET_64BIT"
2791   /* Anything else should be already split before reg-stack.  */
2792   gcc_assert (which_alternative == 1);
2793   return "push{q}\t%q1";
2795   [(set_attr "type" "multi,push,multi")
2796    (set_attr "unit" "i387,*,*")
2797    (set_attr "mode" "SF,DI,SF")])
2799 (define_insn "*pushsf"
2800   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2801         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2802   "!TARGET_64BIT"
2804   /* Anything else should be already split before reg-stack.  */
2805   gcc_assert (which_alternative == 1);
2806   return "push{l}\t%1";
2808   [(set_attr "type" "multi,push,multi")
2809    (set_attr "unit" "i387,*,*")
2810    (set_attr "mode" "SF,SI,SF")])
2812 ;; %%% Kill this when call knows how to work this out.
2813 (define_split
2814   [(set (match_operand:SF 0 "push_operand")
2815         (match_operand:SF 1 "any_fp_register_operand"))]
2816   "reload_completed"
2817   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2818    (set (match_dup 0) (match_dup 1))]
2820   rtx op = XEXP (operands[0], 0);
2821   if (GET_CODE (op) == PRE_DEC)
2822     {
2823       gcc_assert (!TARGET_64BIT);
2824       op = GEN_INT (-4);
2825     }
2826   else
2827     {
2828       op = XEXP (XEXP (op, 1), 1);
2829       gcc_assert (CONST_INT_P (op));
2830     }
2831   operands[2] = op;
2832   /* Preserve memory attributes. */
2833   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2836 (define_split
2837   [(set (match_operand:SF 0 "push_operand")
2838         (match_operand:SF 1 "memory_operand"))]
2839   "reload_completed
2840    && (operands[2] = find_constant_src (insn))"
2841   [(set (match_dup 0) (match_dup 2))])
2843 (define_split
2844   [(set (match_operand 0 "push_operand")
2845         (match_operand 1 "general_operand"))]
2846   "reload_completed
2847    && (GET_MODE (operands[0]) == TFmode
2848        || GET_MODE (operands[0]) == XFmode
2849        || GET_MODE (operands[0]) == DFmode)
2850    && !ANY_FP_REG_P (operands[1])"
2851   [(const_int 0)]
2852   "ix86_split_long_move (operands); DONE;")
2854 ;; Floating point move instructions.
2856 (define_expand "movtf"
2857   [(set (match_operand:TF 0 "nonimmediate_operand")
2858         (match_operand:TF 1 "nonimmediate_operand"))]
2859   "TARGET_64BIT || TARGET_SSE"
2860   "ix86_expand_move (TFmode, operands); DONE;")
2862 (define_expand "mov<mode>"
2863   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2864         (match_operand:X87MODEF 1 "general_operand"))]
2865   ""
2866   "ix86_expand_move (<MODE>mode, operands); DONE;")
2868 (define_insn "*movtf_internal"
2869   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2870         (match_operand:TF 1 "general_operand"      "C ,xm,x,*roF,*rC"))]
2871   "(TARGET_64BIT || TARGET_SSE)
2872    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2873    && (!can_create_pseudo_p ()
2874        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2875        || GET_CODE (operands[1]) != CONST_DOUBLE
2876        || (optimize_function_for_size_p (cfun)
2877            && standard_sse_constant_p (operands[1])
2878            && !memory_operand (operands[0], TFmode))
2879        || (!TARGET_MEMORY_MISMATCH_STALL
2880            && memory_operand (operands[0], TFmode)))"
2882   switch (get_attr_type (insn))
2883     {
2884     case TYPE_SSELOG1:
2885       return standard_sse_constant_opcode (insn, operands[1]);
2887     case TYPE_SSEMOV:
2888       /* Handle misaligned load/store since we
2889          don't have movmisaligntf pattern. */
2890       if (misaligned_operand (operands[0], TFmode)
2891           || misaligned_operand (operands[1], TFmode))
2892         {
2893           if (get_attr_mode (insn) == MODE_V4SF)
2894             return "%vmovups\t{%1, %0|%0, %1}";
2895           else
2896             return "%vmovdqu\t{%1, %0|%0, %1}";
2897         }
2898       else
2899         {
2900           if (get_attr_mode (insn) == MODE_V4SF)
2901             return "%vmovaps\t{%1, %0|%0, %1}";
2902           else
2903             return "%vmovdqa\t{%1, %0|%0, %1}";
2904         }
2906     case TYPE_MULTI:
2907         return "#";
2909     default:
2910       gcc_unreachable ();
2911     }
2913   [(set_attr "isa" "*,*,*,x64,x64")
2914    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2915    (set (attr "prefix")
2916      (if_then_else (eq_attr "type" "sselog1,ssemov")
2917        (const_string "maybe_vex")
2918        (const_string "orig")))
2919    (set (attr "mode")
2920         (cond [(eq_attr "alternative" "3,4")
2921                  (const_string "DI")
2922                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2923                  (const_string "V4SF")
2924                (and (eq_attr "alternative" "2")
2925                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2926                  (const_string "V4SF")
2927                (match_test "TARGET_AVX")
2928                  (const_string "TI")
2929                (ior (not (match_test "TARGET_SSE2"))
2930                     (match_test "optimize_function_for_size_p (cfun)"))
2931                  (const_string "V4SF")
2932                ]
2933                (const_string "TI")))])
2935 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2936 (define_insn "*movxf_internal"
2937   [(set (match_operand:XF 0 "nonimmediate_operand"
2938          "=f,m,f,?Yx*r ,!o   ,!o")
2939         (match_operand:XF 1 "general_operand"
2940          "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2941   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2942    && (!can_create_pseudo_p ()
2943        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2944        || GET_CODE (operands[1]) != CONST_DOUBLE
2945        || (optimize_function_for_size_p (cfun)
2946            && standard_80387_constant_p (operands[1]) > 0
2947            && !memory_operand (operands[0], XFmode))
2948        || (!TARGET_MEMORY_MISMATCH_STALL
2949            && memory_operand (operands[0], XFmode)))"
2951   switch (get_attr_type (insn))
2952     {
2953     case TYPE_FMOV:
2954       if (which_alternative == 2)
2955         return standard_80387_constant_opcode (operands[1]);
2956       return output_387_reg_move (insn, operands);
2958     case TYPE_MULTI:
2959       return "#";
2961     default:
2962       gcc_unreachable ();
2963     }
2965   [(set_attr "isa" "*,*,*,*,nox64,x64")
2966    (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
2967    (set (attr "mode")
2968         (cond [(eq_attr "alternative" "3,4,5")
2969                  (if_then_else (match_test "TARGET_64BIT")
2970                    (const_string "DI")
2971                    (const_string "SI"))
2972               ]
2973               (const_string "XF")))])
2975 ;; Possible store forwarding (partial memory) stall in alternative 4.
2976 (define_insn "*movdf_internal"
2977   [(set (match_operand:DF 0 "nonimmediate_operand"
2978     "=Yf*f,m   ,Yf*f,?Yd*r ,!o   ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
2979         (match_operand:DF 1 "general_operand"
2980     "Yf*fm,Yf*f,G   ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
2981   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2982    && (!can_create_pseudo_p ()
2983        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2984        || GET_CODE (operands[1]) != CONST_DOUBLE
2985        || (optimize_function_for_size_p (cfun)
2986            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2987                 && standard_80387_constant_p (operands[1]) > 0)
2988                || (TARGET_SSE2 && TARGET_SSE_MATH
2989                    && standard_sse_constant_p (operands[1])))
2990            && !memory_operand (operands[0], DFmode))
2991        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
2992            && memory_operand (operands[0], DFmode)))"
2994   switch (get_attr_type (insn))
2995     {
2996     case TYPE_FMOV:
2997       if (which_alternative == 2)
2998         return standard_80387_constant_opcode (operands[1]);
2999       return output_387_reg_move (insn, operands);
3001     case TYPE_MULTI:
3002       return "#";
3004     case TYPE_IMOV:
3005       if (get_attr_mode (insn) == MODE_SI)
3006         return "mov{l}\t{%1, %k0|%k0, %1}";
3007       else if (which_alternative == 8)
3008         return "movabs{q}\t{%1, %0|%0, %1}";
3009       else
3010         return "mov{q}\t{%1, %0|%0, %1}";
3012     case TYPE_SSELOG1:
3013       return standard_sse_constant_opcode (insn, operands[1]);
3015     case TYPE_SSEMOV:
3016       switch (get_attr_mode (insn))
3017         {
3018         case MODE_DF:
3019           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3020             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3021           return "%vmovsd\t{%1, %0|%0, %1}";
3023         case MODE_V4SF:
3024           return "%vmovaps\t{%1, %0|%0, %1}";
3025         case MODE_V8DF:
3026           return "vmovapd\t{%g1, %g0|%g0, %g1}";
3027         case MODE_V2DF:
3028           return "%vmovapd\t{%1, %0|%0, %1}";
3030         case MODE_V2SF:
3031           gcc_assert (!TARGET_AVX);
3032           return "movlps\t{%1, %0|%0, %1}";
3033         case MODE_V1DF:
3034           gcc_assert (!TARGET_AVX);
3035           return "movlpd\t{%1, %0|%0, %1}";
3037         case MODE_DI:
3038           /* Handle broken assemblers that require movd instead of movq.  */
3039           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3040               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3041             return "%vmovd\t{%1, %0|%0, %1}";
3042           return "%vmovq\t{%1, %0|%0, %1}";
3044         default:
3045           gcc_unreachable ();
3046         }
3048     default:
3049       gcc_unreachable ();
3050     }
3052   [(set (attr "isa")
3053         (cond [(eq_attr "alternative" "3,4")
3054                  (const_string "nox64")
3055                (eq_attr "alternative" "5,6,7,8,17,18")
3056                  (const_string "x64")
3057                (eq_attr "alternative" "9,10,11,12")
3058                  (const_string "sse2")
3059               ]
3060               (const_string "*")))
3061    (set (attr "type")
3062         (cond [(eq_attr "alternative" "0,1,2")
3063                  (const_string "fmov")
3064                (eq_attr "alternative" "3,4")
3065                  (const_string "multi")
3066                (eq_attr "alternative" "5,6,7,8")
3067                  (const_string "imov")
3068                (eq_attr "alternative" "9,13")
3069                  (const_string "sselog1")
3070               ]
3071               (const_string "ssemov")))
3072    (set (attr "modrm")
3073      (if_then_else (eq_attr "alternative" "8")
3074        (const_string "0")
3075        (const_string "*")))
3076    (set (attr "length_immediate")
3077      (if_then_else (eq_attr "alternative" "8")
3078        (const_string "8")
3079        (const_string "*")))
3080    (set (attr "prefix")
3081      (if_then_else (eq_attr "type" "sselog1,ssemov")
3082        (const_string "maybe_vex")
3083        (const_string "orig")))
3084    (set (attr "prefix_data16")
3085      (if_then_else
3086        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3087             (eq_attr "mode" "V1DF"))
3088        (const_string "1")
3089        (const_string "*")))
3090    (set (attr "mode")
3091         (cond [(eq_attr "alternative" "3,4,7")
3092                  (const_string "SI")
3093                (eq_attr "alternative" "5,6,8,17,18")
3094                  (const_string "DI")
3096                /* xorps is one byte shorter for non-AVX targets.  */
3097                (eq_attr "alternative" "9,13")
3098                  (cond [(not (match_test "TARGET_SSE2"))
3099                           (const_string "V4SF")
3100                         (match_test "TARGET_AVX512F")
3101                           (const_string "XI")
3102                         (match_test "TARGET_AVX")
3103                           (const_string "V2DF")
3104                         (match_test "optimize_function_for_size_p (cfun)")
3105                           (const_string "V4SF")
3106                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3107                           (const_string "TI")
3108                        ]
3109                        (const_string "V2DF"))
3111                /* For architectures resolving dependencies on
3112                   whole SSE registers use movapd to break dependency
3113                   chains, otherwise use short move to avoid extra work.  */
3115                /* movaps is one byte shorter for non-AVX targets.  */
3116                (eq_attr "alternative" "10,14")
3117                  (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3118                              (match_operand 1 "ext_sse_reg_operand"))
3119                           (const_string "V8DF")
3120                         (ior (not (match_test "TARGET_SSE2"))
3121                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3122                           (const_string "V4SF")
3123                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3124                           (const_string "V2DF")
3125                         (match_test "TARGET_AVX")
3126                           (const_string "DF")
3127                         (match_test "optimize_function_for_size_p (cfun)")
3128                           (const_string "V4SF")
3129                        ]
3130                        (const_string "DF"))
3132                /* For architectures resolving dependencies on register
3133                   parts we may avoid extra work to zero out upper part
3134                   of register.  */
3135                (eq_attr "alternative" "11,15")
3136                  (cond [(not (match_test "TARGET_SSE2"))
3137                           (const_string "V2SF")
3138                         (match_test "TARGET_AVX")
3139                           (const_string "DF")
3140                         (match_test "TARGET_SSE_SPLIT_REGS")
3141                           (const_string "V1DF")
3142                        ]
3143                        (const_string "DF"))
3145                (and (eq_attr "alternative" "12,16")
3146                     (not (match_test "TARGET_SSE2")))
3147                  (const_string "V2SF")
3148               ]
3149               (const_string "DF")))])
3151 (define_insn "*movsf_internal"
3152   [(set (match_operand:SF 0 "nonimmediate_operand"
3153           "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3154         (match_operand:SF 1 "general_operand"
3155           "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,Yj,r  ,*y ,m  ,*y,*Yn,r"))]
3156   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3157    && (!can_create_pseudo_p ()
3158        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3159        || GET_CODE (operands[1]) != CONST_DOUBLE
3160        || (optimize_function_for_size_p (cfun)
3161            && ((!TARGET_SSE_MATH
3162                 && standard_80387_constant_p (operands[1]) > 0)
3163                || (TARGET_SSE_MATH
3164                    && standard_sse_constant_p (operands[1]))))
3165        || memory_operand (operands[0], SFmode))"
3167   switch (get_attr_type (insn))
3168     {
3169     case TYPE_FMOV:
3170       if (which_alternative == 2)
3171         return standard_80387_constant_opcode (operands[1]);
3172       return output_387_reg_move (insn, operands);
3174     case TYPE_IMOV:
3175       return "mov{l}\t{%1, %0|%0, %1}";
3177     case TYPE_SSELOG1:
3178       return standard_sse_constant_opcode (insn, operands[1]);
3180     case TYPE_SSEMOV:
3181       switch (get_attr_mode (insn))
3182         {
3183         case MODE_SF:
3184           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3185             return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3186           return "%vmovss\t{%1, %0|%0, %1}";
3188         case MODE_V16SF:
3189           return "vmovaps\t{%g1, %g0|%g0, %g1}";
3190         case MODE_V4SF:
3191           return "%vmovaps\t{%1, %0|%0, %1}";
3193         case MODE_SI:
3194           return "%vmovd\t{%1, %0|%0, %1}";
3196         default:
3197           gcc_unreachable ();
3198         }
3200     case TYPE_MMXMOV:
3201       switch (get_attr_mode (insn))
3202         {
3203         case MODE_DI:
3204           return "movq\t{%1, %0|%0, %1}";
3205         case MODE_SI:
3206           return "movd\t{%1, %0|%0, %1}";
3208         default:
3209           gcc_unreachable ();
3210         }
3212     default:
3213       gcc_unreachable ();
3214     }
3216   [(set (attr "type")
3217         (cond [(eq_attr "alternative" "0,1,2")
3218                  (const_string "fmov")
3219                (eq_attr "alternative" "3,4")
3220                  (const_string "imov")
3221                (eq_attr "alternative" "5")
3222                  (const_string "sselog1")
3223                (eq_attr "alternative" "11,12,13,14,15")
3224                  (const_string "mmxmov")
3225               ]
3226               (const_string "ssemov")))
3227    (set (attr "prefix")
3228      (if_then_else (eq_attr "type" "sselog1,ssemov")
3229        (const_string "maybe_vex")
3230        (const_string "orig")))
3231    (set (attr "prefix_data16")
3232      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3233        (const_string "1")
3234        (const_string "*")))
3235    (set (attr "mode")
3236         (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
3237                  (const_string "SI")
3238                (eq_attr "alternative" "11")
3239                  (const_string "DI")
3240                (eq_attr "alternative" "5")
3241                  (cond [(not (match_test "TARGET_SSE2"))
3242                           (const_string "V4SF")
3243                         (match_test "TARGET_AVX512F")
3244                           (const_string "V16SF")
3245                         (match_test "TARGET_AVX")
3246                           (const_string "V4SF")
3247                         (match_test "optimize_function_for_size_p (cfun)")
3248                           (const_string "V4SF")
3249                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3250                           (const_string "TI")
3251                        ]
3252                        (const_string "V4SF"))
3254                /* For architectures resolving dependencies on
3255                   whole SSE registers use APS move to break dependency
3256                   chains, otherwise use short move to avoid extra work.
3258                   Do the same for architectures resolving dependencies on
3259                   the parts.  While in DF mode it is better to always handle
3260                   just register parts, the SF mode is different due to lack
3261                   of instructions to load just part of the register.  It is
3262                   better to maintain the whole registers in single format
3263                   to avoid problems on using packed logical operations.  */
3264                (eq_attr "alternative" "6")
3265                  (cond [(ior  (match_operand 0 "ext_sse_reg_operand")
3266                               (match_operand 1 "ext_sse_reg_operand"))
3267                           (const_string "V16SF")
3268                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3269                              (match_test "TARGET_SSE_SPLIT_REGS"))
3270                           (const_string "V4SF")
3271                        ]
3272                        (const_string "SF"))
3273               ]
3274               (const_string "SF")))])
3276 (define_split
3277   [(set (match_operand 0 "any_fp_register_operand")
3278         (match_operand 1 "memory_operand"))]
3279   "reload_completed
3280    && (GET_MODE (operands[0]) == TFmode
3281        || GET_MODE (operands[0]) == XFmode
3282        || GET_MODE (operands[0]) == DFmode
3283        || GET_MODE (operands[0]) == SFmode)
3284    && (operands[2] = find_constant_src (insn))"
3285   [(set (match_dup 0) (match_dup 2))]
3287   rtx c = operands[2];
3288   int r = REGNO (operands[0]);
3290   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3291       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3292     FAIL;
3295 (define_split
3296   [(set (match_operand 0 "any_fp_register_operand")
3297         (float_extend (match_operand 1 "memory_operand")))]
3298   "reload_completed
3299    && (GET_MODE (operands[0]) == TFmode
3300        || GET_MODE (operands[0]) == XFmode
3301        || GET_MODE (operands[0]) == DFmode)
3302    && (operands[2] = find_constant_src (insn))"
3303   [(set (match_dup 0) (match_dup 2))]
3305   rtx c = operands[2];
3306   int r = REGNO (operands[0]);
3308   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3309       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3310     FAIL;
3313 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3314 (define_split
3315   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3316         (match_operand:X87MODEF 1 "immediate_operand"))]
3317   "reload_completed
3318    && (standard_80387_constant_p (operands[1]) == 8
3319        || standard_80387_constant_p (operands[1]) == 9)"
3320   [(set (match_dup 0)(match_dup 1))
3321    (set (match_dup 0)
3322         (neg:X87MODEF (match_dup 0)))]
3324   REAL_VALUE_TYPE r;
3326   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3327   if (real_isnegzero (&r))
3328     operands[1] = CONST0_RTX (<MODE>mode);
3329   else
3330     operands[1] = CONST1_RTX (<MODE>mode);
3333 (define_split
3334   [(set (match_operand 0 "nonimmediate_operand")
3335         (match_operand 1 "general_operand"))]
3336   "reload_completed
3337    && (GET_MODE (operands[0]) == TFmode
3338        || GET_MODE (operands[0]) == XFmode
3339        || GET_MODE (operands[0]) == DFmode)
3340    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3341   [(const_int 0)]
3342   "ix86_split_long_move (operands); DONE;")
3344 (define_insn "swapxf"
3345   [(set (match_operand:XF 0 "register_operand" "+f")
3346         (match_operand:XF 1 "register_operand" "+f"))
3347    (set (match_dup 1)
3348         (match_dup 0))]
3349   "TARGET_80387"
3351   if (STACK_TOP_P (operands[0]))
3352     return "fxch\t%1";
3353   else
3354     return "fxch\t%0";
3356   [(set_attr "type" "fxch")
3357    (set_attr "mode" "XF")])
3359 (define_insn "*swap<mode>"
3360   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3361         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3362    (set (match_dup 1)
3363         (match_dup 0))]
3364   "TARGET_80387 || reload_completed"
3366   if (STACK_TOP_P (operands[0]))
3367     return "fxch\t%1";
3368   else
3369     return "fxch\t%0";
3371   [(set_attr "type" "fxch")
3372    (set_attr "mode" "<MODE>")])
3374 ;; Zero extension instructions
3376 (define_expand "zero_extendsidi2"
3377   [(set (match_operand:DI 0 "nonimmediate_operand")
3378         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3380 (define_insn "*zero_extendsidi2"
3381   [(set (match_operand:DI 0 "nonimmediate_operand"
3382                         "=r,?r,?o,r   ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3383         (zero_extend:DI
3384          (match_operand:SI 1 "x86_64_zext_operand"
3385                         "0 ,rm,r ,rmWz,0,r   ,m   ,*Yj,*x,r   ,m")))]
3386   ""
3388   switch (get_attr_type (insn))
3389     {
3390     case TYPE_IMOVX:
3391       if (ix86_use_lea_for_mov (insn, operands))
3392         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3393       else
3394         return "mov{l}\t{%1, %k0|%k0, %1}";
3396     case TYPE_MULTI:
3397       return "#";
3399     case TYPE_MMXMOV:
3400       return "movd\t{%1, %0|%0, %1}";
3402     case TYPE_SSELOG1:
3403       return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3405     case TYPE_SSEMOV:
3406       if (GENERAL_REG_P (operands[0]))
3407         return "%vmovd\t{%1, %k0|%k0, %1}";
3409       return "%vmovd\t{%1, %0|%0, %1}";
3411     default:
3412       gcc_unreachable ();
3413     }
3415   [(set (attr "isa")
3416      (cond [(eq_attr "alternative" "0,1,2")
3417               (const_string "nox64")
3418             (eq_attr "alternative" "3,7")
3419               (const_string "x64")
3420             (eq_attr "alternative" "8")
3421               (const_string "x64_sse4")
3422             (eq_attr "alternative" "10")
3423               (const_string "sse2")
3424            ]
3425            (const_string "*")))
3426    (set (attr "type")
3427      (cond [(eq_attr "alternative" "0,1,2,4")
3428               (const_string "multi")
3429             (eq_attr "alternative" "5,6")
3430               (const_string "mmxmov")
3431             (eq_attr "alternative" "7,9,10")
3432               (const_string "ssemov")
3433             (eq_attr "alternative" "8")
3434               (const_string "sselog1")
3435            ]
3436            (const_string "imovx")))
3437    (set (attr "prefix_extra")
3438      (if_then_else (eq_attr "alternative" "8")
3439        (const_string "1")
3440        (const_string "*")))
3441    (set (attr "length_immediate")
3442      (if_then_else (eq_attr "alternative" "8")
3443        (const_string "1")
3444        (const_string "*")))
3445    (set (attr "prefix")
3446      (if_then_else (eq_attr "type" "ssemov,sselog1")
3447        (const_string "maybe_vex")
3448        (const_string "orig")))
3449    (set (attr "prefix_0f")
3450      (if_then_else (eq_attr "type" "imovx")
3451        (const_string "0")
3452        (const_string "*")))
3453    (set (attr "mode")
3454      (cond [(eq_attr "alternative" "5,6")
3455               (const_string "DI")
3456             (eq_attr "alternative" "7,8,9")
3457               (const_string "TI")
3458            ]
3459            (const_string "SI")))])
3461 (define_split
3462   [(set (match_operand:DI 0 "memory_operand")
3463         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3464   "reload_completed"
3465   [(set (match_dup 4) (const_int 0))]
3466   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3468 (define_split
3469   [(set (match_operand:DI 0 "register_operand")
3470         (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3471   "!TARGET_64BIT && reload_completed
3472    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3473    && true_regnum (operands[0]) == true_regnum (operands[1])"
3474   [(set (match_dup 4) (const_int 0))]
3475   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3477 (define_split
3478   [(set (match_operand:DI 0 "nonimmediate_operand")
3479         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3480   "!TARGET_64BIT && reload_completed
3481    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3482    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3483   [(set (match_dup 3) (match_dup 1))
3484    (set (match_dup 4) (const_int 0))]
3485   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3487 (define_insn "zero_extend<mode>di2"
3488   [(set (match_operand:DI 0 "register_operand" "=r")
3489         (zero_extend:DI
3490          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3491   "TARGET_64BIT"
3492   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3493   [(set_attr "type" "imovx")
3494    (set_attr "mode" "SI")])
3496 (define_expand "zero_extend<mode>si2"
3497   [(set (match_operand:SI 0 "register_operand")
3498         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3499   ""
3501   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3502     {
3503       operands[1] = force_reg (<MODE>mode, operands[1]);
3504       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3505       DONE;
3506     }
3509 (define_insn_and_split "zero_extend<mode>si2_and"
3510   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3511         (zero_extend:SI
3512           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3513    (clobber (reg:CC FLAGS_REG))]
3514   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3515   "#"
3516   "&& reload_completed"
3517   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3518               (clobber (reg:CC FLAGS_REG))])]
3520   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3521     {
3522       ix86_expand_clear (operands[0]);
3524       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3525       emit_insn (gen_movstrict<mode>
3526                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3527       DONE;
3528     }
3530   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3532   [(set_attr "type" "alu1")
3533    (set_attr "mode" "SI")])
3535 (define_insn "*zero_extend<mode>si2"
3536   [(set (match_operand:SI 0 "register_operand" "=r")
3537         (zero_extend:SI
3538           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3539   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3540   "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3541   [(set_attr "type" "imovx")
3542    (set_attr "mode" "SI")])
3544 (define_expand "zero_extendqihi2"
3545   [(set (match_operand:HI 0 "register_operand")
3546         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3547   ""
3549   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3550     {
3551       operands[1] = force_reg (QImode, operands[1]);
3552       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3553       DONE;
3554     }
3557 (define_insn_and_split "zero_extendqihi2_and"
3558   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3559         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3560    (clobber (reg:CC FLAGS_REG))]
3561   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3562   "#"
3563   "&& reload_completed"
3564   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3565               (clobber (reg:CC FLAGS_REG))])]
3567   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3568     {
3569       ix86_expand_clear (operands[0]);
3571       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3572       emit_insn (gen_movstrictqi
3573                   (gen_lowpart (QImode, operands[0]), operands[1]));
3574       DONE;
3575     }
3577   operands[0] = gen_lowpart (SImode, operands[0]);
3579   [(set_attr "type" "alu1")
3580    (set_attr "mode" "SI")])
3582 ; zero extend to SImode to avoid partial register stalls
3583 (define_insn "*zero_extendqihi2"
3584   [(set (match_operand:HI 0 "register_operand" "=r")
3585         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3586   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3587   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3588   [(set_attr "type" "imovx")
3589    (set_attr "mode" "SI")])
3591 ;; Sign extension instructions
3593 (define_expand "extendsidi2"
3594   [(set (match_operand:DI 0 "register_operand")
3595         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3596   ""
3598   if (!TARGET_64BIT)
3599     {
3600       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3601       DONE;
3602     }
3605 (define_insn "*extendsidi2_rex64"
3606   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3607         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3608   "TARGET_64BIT"
3609   "@
3610    {cltq|cdqe}
3611    movs{lq|x}\t{%1, %0|%0, %1}"
3612   [(set_attr "type" "imovx")
3613    (set_attr "mode" "DI")
3614    (set_attr "prefix_0f" "0")
3615    (set_attr "modrm" "0,1")])
3617 (define_insn "extendsidi2_1"
3618   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3619         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3620    (clobber (reg:CC FLAGS_REG))
3621    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3622   "!TARGET_64BIT"
3623   "#")
3625 ;; Split the memory case.  If the source register doesn't die, it will stay
3626 ;; this way, if it does die, following peephole2s take care of it.
3627 (define_split
3628   [(set (match_operand:DI 0 "memory_operand")
3629         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3630    (clobber (reg:CC FLAGS_REG))
3631    (clobber (match_operand:SI 2 "register_operand"))]
3632   "reload_completed"
3633   [(const_int 0)]
3635   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3637   emit_move_insn (operands[3], operands[1]);
3639   /* Generate a cltd if possible and doing so it profitable.  */
3640   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3641       && true_regnum (operands[1]) == AX_REG
3642       && true_regnum (operands[2]) == DX_REG)
3643     {
3644       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3645     }
3646   else
3647     {
3648       emit_move_insn (operands[2], operands[1]);
3649       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3650     }
3651   emit_move_insn (operands[4], operands[2]);
3652   DONE;
3655 ;; Peepholes for the case where the source register does die, after
3656 ;; being split with the above splitter.
3657 (define_peephole2
3658   [(set (match_operand:SI 0 "memory_operand")
3659         (match_operand:SI 1 "register_operand"))
3660    (set (match_operand:SI 2 "register_operand") (match_dup 1))
3661    (parallel [(set (match_dup 2)
3662                    (ashiftrt:SI (match_dup 2) (const_int 31)))
3663                (clobber (reg:CC FLAGS_REG))])
3664    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3665   "REGNO (operands[1]) != REGNO (operands[2])
3666    && peep2_reg_dead_p (2, operands[1])
3667    && peep2_reg_dead_p (4, operands[2])
3668    && !reg_mentioned_p (operands[2], operands[3])"
3669   [(set (match_dup 0) (match_dup 1))
3670    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3671               (clobber (reg:CC FLAGS_REG))])
3672    (set (match_dup 3) (match_dup 1))])
3674 (define_peephole2
3675   [(set (match_operand:SI 0 "memory_operand")
3676         (match_operand:SI 1 "register_operand"))
3677    (parallel [(set (match_operand:SI 2 "register_operand")
3678                    (ashiftrt:SI (match_dup 1) (const_int 31)))
3679                (clobber (reg:CC FLAGS_REG))])
3680    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3681   "/* cltd is shorter than sarl $31, %eax */
3682    !optimize_function_for_size_p (cfun)
3683    && true_regnum (operands[1]) == AX_REG
3684    && true_regnum (operands[2]) == DX_REG
3685    && peep2_reg_dead_p (2, operands[1])
3686    && peep2_reg_dead_p (3, operands[2])
3687    && !reg_mentioned_p (operands[2], operands[3])"
3688   [(set (match_dup 0) (match_dup 1))
3689    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3690               (clobber (reg:CC FLAGS_REG))])
3691    (set (match_dup 3) (match_dup 1))])
3693 ;; Extend to register case.  Optimize case where source and destination
3694 ;; registers match and cases where we can use cltd.
3695 (define_split
3696   [(set (match_operand:DI 0 "register_operand")
3697         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3698    (clobber (reg:CC FLAGS_REG))
3699    (clobber (match_scratch:SI 2))]
3700   "reload_completed"
3701   [(const_int 0)]
3703   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3705   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3706     emit_move_insn (operands[3], operands[1]);
3708   /* Generate a cltd if possible and doing so it profitable.  */
3709   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3710       && true_regnum (operands[3]) == AX_REG
3711       && true_regnum (operands[4]) == DX_REG)
3712     {
3713       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3714       DONE;
3715     }
3717   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3718     emit_move_insn (operands[4], operands[1]);
3720   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3721   DONE;
3724 (define_insn "extend<mode>di2"
3725   [(set (match_operand:DI 0 "register_operand" "=r")
3726         (sign_extend:DI
3727          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3728   "TARGET_64BIT"
3729   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3730   [(set_attr "type" "imovx")
3731    (set_attr "mode" "DI")])
3733 (define_insn "extendhisi2"
3734   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3735         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3736   ""
3738   switch (get_attr_prefix_0f (insn))
3739     {
3740     case 0:
3741       return "{cwtl|cwde}";
3742     default:
3743       return "movs{wl|x}\t{%1, %0|%0, %1}";
3744     }
3746   [(set_attr "type" "imovx")
3747    (set_attr "mode" "SI")
3748    (set (attr "prefix_0f")
3749      ;; movsx is short decodable while cwtl is vector decoded.
3750      (if_then_else (and (eq_attr "cpu" "!k6")
3751                         (eq_attr "alternative" "0"))
3752         (const_string "0")
3753         (const_string "1")))
3754    (set (attr "modrm")
3755      (if_then_else (eq_attr "prefix_0f" "0")
3756         (const_string "0")
3757         (const_string "1")))])
3759 (define_insn "*extendhisi2_zext"
3760   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3761         (zero_extend:DI
3762          (sign_extend:SI
3763           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3764   "TARGET_64BIT"
3766   switch (get_attr_prefix_0f (insn))
3767     {
3768     case 0:
3769       return "{cwtl|cwde}";
3770     default:
3771       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3772     }
3774   [(set_attr "type" "imovx")
3775    (set_attr "mode" "SI")
3776    (set (attr "prefix_0f")
3777      ;; movsx is short decodable while cwtl is vector decoded.
3778      (if_then_else (and (eq_attr "cpu" "!k6")
3779                         (eq_attr "alternative" "0"))
3780         (const_string "0")
3781         (const_string "1")))
3782    (set (attr "modrm")
3783      (if_then_else (eq_attr "prefix_0f" "0")
3784         (const_string "0")
3785         (const_string "1")))])
3787 (define_insn "extendqisi2"
3788   [(set (match_operand:SI 0 "register_operand" "=r")
3789         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3790   ""
3791   "movs{bl|x}\t{%1, %0|%0, %1}"
3792    [(set_attr "type" "imovx")
3793     (set_attr "mode" "SI")])
3795 (define_insn "*extendqisi2_zext"
3796   [(set (match_operand:DI 0 "register_operand" "=r")
3797         (zero_extend:DI
3798           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3799   "TARGET_64BIT"
3800   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3801    [(set_attr "type" "imovx")
3802     (set_attr "mode" "SI")])
3804 (define_insn "extendqihi2"
3805   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3806         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3807   ""
3809   switch (get_attr_prefix_0f (insn))
3810     {
3811     case 0:
3812       return "{cbtw|cbw}";
3813     default:
3814       return "movs{bw|x}\t{%1, %0|%0, %1}";
3815     }
3817   [(set_attr "type" "imovx")
3818    (set_attr "mode" "HI")
3819    (set (attr "prefix_0f")
3820      ;; movsx is short decodable while cwtl is vector decoded.
3821      (if_then_else (and (eq_attr "cpu" "!k6")
3822                         (eq_attr "alternative" "0"))
3823         (const_string "0")
3824         (const_string "1")))
3825    (set (attr "modrm")
3826      (if_then_else (eq_attr "prefix_0f" "0")
3827         (const_string "0")
3828         (const_string "1")))])
3830 ;; Conversions between float and double.
3832 ;; These are all no-ops in the model used for the 80387.
3833 ;; So just emit moves.
3835 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3836 (define_split
3837   [(set (match_operand:DF 0 "push_operand")
3838         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3839   "reload_completed"
3840   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3841    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3843 (define_split
3844   [(set (match_operand:XF 0 "push_operand")
3845         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3846   "reload_completed"
3847   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3848    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3849   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3851 (define_expand "extendsfdf2"
3852   [(set (match_operand:DF 0 "nonimmediate_operand")
3853         (float_extend:DF (match_operand:SF 1 "general_operand")))]
3854   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3856   /* ??? Needed for compress_float_constant since all fp constants
3857      are TARGET_LEGITIMATE_CONSTANT_P.  */
3858   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3859     {
3860       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3861           && standard_80387_constant_p (operands[1]) > 0)
3862         {
3863           operands[1] = simplify_const_unary_operation
3864             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3865           emit_move_insn_1 (operands[0], operands[1]);
3866           DONE;
3867         }
3868       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3869     }
3872 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3873    cvtss2sd:
3874       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3875       cvtps2pd xmm2,xmm1
3876    We do the conversion post reload to avoid producing of 128bit spills
3877    that might lead to ICE on 32bit target.  The sequence unlikely combine
3878    anyway.  */
3879 (define_split
3880   [(set (match_operand:DF 0 "register_operand")
3881         (float_extend:DF
3882           (match_operand:SF 1 "nonimmediate_operand")))]
3883   "TARGET_USE_VECTOR_FP_CONVERTS
3884    && optimize_insn_for_speed_p ()
3885    && reload_completed && SSE_REG_P (operands[0])"
3886    [(set (match_dup 2)
3887          (float_extend:V2DF
3888            (vec_select:V2SF
3889              (match_dup 3)
3890              (parallel [(const_int 0) (const_int 1)]))))]
3892   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3893   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3894   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3895      Try to avoid move when unpacking can be done in source.  */
3896   if (REG_P (operands[1]))
3897     {
3898       /* If it is unsafe to overwrite upper half of source, we need
3899          to move to destination and unpack there.  */
3900       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3901            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3902           && true_regnum (operands[0]) != true_regnum (operands[1]))
3903         {
3904           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3905           emit_move_insn (tmp, operands[1]);
3906         }
3907       else
3908         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3909       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3910                                              operands[3]));
3911     }
3912   else
3913     emit_insn (gen_vec_setv4sf_0 (operands[3],
3914                                   CONST0_RTX (V4SFmode), operands[1]));
3917 ;; It's more profitable to split and then extend in the same register.
3918 (define_peephole2
3919   [(set (match_operand:DF 0 "register_operand")
3920         (float_extend:DF
3921           (match_operand:SF 1 "memory_operand")))]
3922   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3923    && optimize_insn_for_speed_p ()
3924    && SSE_REG_P (operands[0])"
3925   [(set (match_dup 2) (match_dup 1))
3926    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
3927   "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
3929 (define_insn "*extendsfdf2_mixed"
3930   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3931         (float_extend:DF
3932           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3933   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3935   switch (which_alternative)
3936     {
3937     case 0:
3938     case 1:
3939       return output_387_reg_move (insn, operands);
3941     case 2:
3942       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3944     default:
3945       gcc_unreachable ();
3946     }
3948   [(set_attr "type" "fmov,fmov,ssecvt")
3949    (set_attr "prefix" "orig,orig,maybe_vex")
3950    (set_attr "mode" "SF,XF,DF")])
3952 (define_insn "*extendsfdf2_sse"
3953   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3954         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3955   "TARGET_SSE2 && TARGET_SSE_MATH"
3956   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3957   [(set_attr "type" "ssecvt")
3958    (set_attr "prefix" "maybe_vex")
3959    (set_attr "mode" "DF")])
3961 (define_insn "*extendsfdf2_i387"
3962   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3963         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3964   "TARGET_80387"
3965   "* return output_387_reg_move (insn, operands);"
3966   [(set_attr "type" "fmov")
3967    (set_attr "mode" "SF,XF")])
3969 (define_expand "extend<mode>xf2"
3970   [(set (match_operand:XF 0 "nonimmediate_operand")
3971         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3972   "TARGET_80387"
3974   /* ??? Needed for compress_float_constant since all fp constants
3975      are TARGET_LEGITIMATE_CONSTANT_P.  */
3976   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3977     {
3978       if (standard_80387_constant_p (operands[1]) > 0)
3979         {
3980           operands[1] = simplify_const_unary_operation
3981             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3982           emit_move_insn_1 (operands[0], operands[1]);
3983           DONE;
3984         }
3985       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3986     }
3989 (define_insn "*extend<mode>xf2_i387"
3990   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3991         (float_extend:XF
3992           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3993   "TARGET_80387"
3994   "* return output_387_reg_move (insn, operands);"
3995   [(set_attr "type" "fmov")
3996    (set_attr "mode" "<MODE>,XF")])
3998 ;; %%% This seems bad bad news.
3999 ;; This cannot output into an f-reg because there is no way to be sure
4000 ;; of truncating in that case.  Otherwise this is just like a simple move
4001 ;; insn.  So we pretend we can output to a reg in order to get better
4002 ;; register preferencing, but we really use a stack slot.
4004 ;; Conversion from DFmode to SFmode.
4006 (define_expand "truncdfsf2"
4007   [(set (match_operand:SF 0 "nonimmediate_operand")
4008         (float_truncate:SF
4009           (match_operand:DF 1 "nonimmediate_operand")))]
4010   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4012   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4013     ;
4014   else if (flag_unsafe_math_optimizations)
4015     ;
4016   else
4017     {
4018       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4019       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4020       DONE;
4021     }
4024 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4025    cvtsd2ss:
4026       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4027       cvtpd2ps xmm2,xmm1
4028    We do the conversion post reload to avoid producing of 128bit spills
4029    that might lead to ICE on 32bit target.  The sequence unlikely combine
4030    anyway.  */
4031 (define_split
4032   [(set (match_operand:SF 0 "register_operand")
4033         (float_truncate:SF
4034           (match_operand:DF 1 "nonimmediate_operand")))]
4035   "TARGET_USE_VECTOR_FP_CONVERTS
4036    && optimize_insn_for_speed_p ()
4037    && reload_completed && SSE_REG_P (operands[0])"
4038    [(set (match_dup 2)
4039          (vec_concat:V4SF
4040            (float_truncate:V2SF
4041              (match_dup 4))
4042            (match_dup 3)))]
4044   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4045   operands[3] = CONST0_RTX (V2SFmode);
4046   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4047   /* Use movsd for loading from memory, unpcklpd for registers.
4048      Try to avoid move when unpacking can be done in source, or SSE3
4049      movddup is available.  */
4050   if (REG_P (operands[1]))
4051     {
4052       if (!TARGET_SSE3
4053           && true_regnum (operands[0]) != true_regnum (operands[1])
4054           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4055               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4056         {
4057           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4058           emit_move_insn (tmp, operands[1]);
4059           operands[1] = tmp;
4060         }
4061       else if (!TARGET_SSE3)
4062         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4063       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4064     }
4065   else
4066     emit_insn (gen_sse2_loadlpd (operands[4],
4067                                  CONST0_RTX (V2DFmode), operands[1]));
4070 ;; It's more profitable to split and then extend in the same register.
4071 (define_peephole2
4072   [(set (match_operand:SF 0 "register_operand")
4073         (float_truncate:SF
4074           (match_operand:DF 1 "memory_operand")))]
4075   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4076    && optimize_insn_for_speed_p ()
4077    && SSE_REG_P (operands[0])"
4078   [(set (match_dup 2) (match_dup 1))
4079    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4080   "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4082 (define_expand "truncdfsf2_with_temp"
4083   [(parallel [(set (match_operand:SF 0)
4084                    (float_truncate:SF (match_operand:DF 1)))
4085               (clobber (match_operand:SF 2))])])
4087 (define_insn "*truncdfsf_fast_mixed"
4088   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4089         (float_truncate:SF
4090           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4091   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4093   switch (which_alternative)
4094     {
4095     case 0:
4096       return output_387_reg_move (insn, operands);
4097     case 1:
4098       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4099     default:
4100       gcc_unreachable ();
4101     }
4103   [(set_attr "type" "fmov,ssecvt")
4104    (set_attr "prefix" "orig,maybe_vex")
4105    (set_attr "mode" "SF")])
4107 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4108 ;; because nothing we do here is unsafe.
4109 (define_insn "*truncdfsf_fast_sse"
4110   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4111         (float_truncate:SF
4112           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4113   "TARGET_SSE2 && TARGET_SSE_MATH"
4114   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4115   [(set_attr "type" "ssecvt")
4116    (set_attr "prefix" "maybe_vex")
4117    (set_attr "mode" "SF")])
4119 (define_insn "*truncdfsf_fast_i387"
4120   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4121         (float_truncate:SF
4122           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4123   "TARGET_80387 && flag_unsafe_math_optimizations"
4124   "* return output_387_reg_move (insn, operands);"
4125   [(set_attr "type" "fmov")
4126    (set_attr "mode" "SF")])
4128 (define_insn "*truncdfsf_mixed"
4129   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4130         (float_truncate:SF
4131           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4132    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4133   "TARGET_MIX_SSE_I387"
4135   switch (which_alternative)
4136     {
4137     case 0:
4138       return output_387_reg_move (insn, operands);
4139     case 1:
4140       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4142     default:
4143       return "#";
4144     }
4146   [(set_attr "isa" "*,sse2,*,*,*")
4147    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4148    (set_attr "unit" "*,*,i387,i387,i387")
4149    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4150    (set_attr "mode" "SF")])
4152 (define_insn "*truncdfsf_i387"
4153   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4154         (float_truncate:SF
4155           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4156    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4157   "TARGET_80387"
4159   switch (which_alternative)
4160     {
4161     case 0:
4162       return output_387_reg_move (insn, operands);
4164     default:
4165       return "#";
4166     }
4168   [(set_attr "type" "fmov,multi,multi,multi")
4169    (set_attr "unit" "*,i387,i387,i387")
4170    (set_attr "mode" "SF")])
4172 (define_insn "*truncdfsf2_i387_1"
4173   [(set (match_operand:SF 0 "memory_operand" "=m")
4174         (float_truncate:SF
4175           (match_operand:DF 1 "register_operand" "f")))]
4176   "TARGET_80387
4177    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4178    && !TARGET_MIX_SSE_I387"
4179   "* return output_387_reg_move (insn, operands);"
4180   [(set_attr "type" "fmov")
4181    (set_attr "mode" "SF")])
4183 (define_split
4184   [(set (match_operand:SF 0 "register_operand")
4185         (float_truncate:SF
4186          (match_operand:DF 1 "fp_register_operand")))
4187    (clobber (match_operand 2))]
4188   "reload_completed"
4189   [(set (match_dup 2) (match_dup 1))
4190    (set (match_dup 0) (match_dup 2))]
4191   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4193 ;; Conversion from XFmode to {SF,DF}mode
4195 (define_expand "truncxf<mode>2"
4196   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4197                    (float_truncate:MODEF
4198                      (match_operand:XF 1 "register_operand")))
4199               (clobber (match_dup 2))])]
4200   "TARGET_80387"
4202   if (flag_unsafe_math_optimizations)
4203     {
4204       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4205       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4206       if (reg != operands[0])
4207         emit_move_insn (operands[0], reg);
4208       DONE;
4209     }
4210   else
4211     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4214 (define_insn "*truncxfsf2_mixed"
4215   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4216         (float_truncate:SF
4217           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4218    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4219   "TARGET_80387"
4221   gcc_assert (!which_alternative);
4222   return output_387_reg_move (insn, operands);
4224   [(set_attr "type" "fmov,multi,multi,multi")
4225    (set_attr "unit" "*,i387,i387,i387")
4226    (set_attr "mode" "SF")])
4228 (define_insn "*truncxfdf2_mixed"
4229   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4230         (float_truncate:DF
4231           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4232    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4233   "TARGET_80387"
4235   gcc_assert (!which_alternative);
4236   return output_387_reg_move (insn, operands);
4238   [(set_attr "isa" "*,*,sse2,*")
4239    (set_attr "type" "fmov,multi,multi,multi")
4240    (set_attr "unit" "*,i387,i387,i387")
4241    (set_attr "mode" "DF")])
4243 (define_insn "truncxf<mode>2_i387_noop"
4244   [(set (match_operand:MODEF 0 "register_operand" "=f")
4245         (float_truncate:MODEF
4246           (match_operand:XF 1 "register_operand" "f")))]
4247   "TARGET_80387 && flag_unsafe_math_optimizations"
4248   "* return output_387_reg_move (insn, operands);"
4249   [(set_attr "type" "fmov")
4250    (set_attr "mode" "<MODE>")])
4252 (define_insn "*truncxf<mode>2_i387"
4253   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4254         (float_truncate:MODEF
4255           (match_operand:XF 1 "register_operand" "f")))]
4256   "TARGET_80387"
4257   "* return output_387_reg_move (insn, operands);"
4258   [(set_attr "type" "fmov")
4259    (set_attr "mode" "<MODE>")])
4261 (define_split
4262   [(set (match_operand:MODEF 0 "register_operand")
4263         (float_truncate:MODEF
4264           (match_operand:XF 1 "register_operand")))
4265    (clobber (match_operand:MODEF 2 "memory_operand"))]
4266   "TARGET_80387 && reload_completed"
4267   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4268    (set (match_dup 0) (match_dup 2))])
4270 (define_split
4271   [(set (match_operand:MODEF 0 "memory_operand")
4272         (float_truncate:MODEF
4273           (match_operand:XF 1 "register_operand")))
4274    (clobber (match_operand:MODEF 2 "memory_operand"))]
4275   "TARGET_80387"
4276   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4278 ;; Signed conversion to DImode.
4280 (define_expand "fix_truncxfdi2"
4281   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4282                    (fix:DI (match_operand:XF 1 "register_operand")))
4283               (clobber (reg:CC FLAGS_REG))])]
4284   "TARGET_80387"
4286   if (TARGET_FISTTP)
4287    {
4288      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4289      DONE;
4290    }
4293 (define_expand "fix_trunc<mode>di2"
4294   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4295                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4296               (clobber (reg:CC FLAGS_REG))])]
4297   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4299   if (TARGET_FISTTP
4300       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4301    {
4302      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4303      DONE;
4304    }
4305   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4306    {
4307      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4308      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4309      if (out != operands[0])
4310         emit_move_insn (operands[0], out);
4311      DONE;
4312    }
4315 ;; Signed conversion to SImode.
4317 (define_expand "fix_truncxfsi2"
4318   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4319                    (fix:SI (match_operand:XF 1 "register_operand")))
4320               (clobber (reg:CC FLAGS_REG))])]
4321   "TARGET_80387"
4323   if (TARGET_FISTTP)
4324    {
4325      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4326      DONE;
4327    }
4330 (define_expand "fix_trunc<mode>si2"
4331   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4332                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4333               (clobber (reg:CC FLAGS_REG))])]
4334   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4336   if (TARGET_FISTTP
4337       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4338    {
4339      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4340      DONE;
4341    }
4342   if (SSE_FLOAT_MODE_P (<MODE>mode))
4343    {
4344      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4345      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4346      if (out != operands[0])
4347         emit_move_insn (operands[0], out);
4348      DONE;
4349    }
4352 ;; Signed conversion to HImode.
4354 (define_expand "fix_trunc<mode>hi2"
4355   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4356                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4357               (clobber (reg:CC FLAGS_REG))])]
4358   "TARGET_80387
4359    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4361   if (TARGET_FISTTP)
4362    {
4363      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4364      DONE;
4365    }
4368 ;; Unsigned conversion to SImode.
4370 (define_expand "fixuns_trunc<mode>si2"
4371   [(parallel
4372     [(set (match_operand:SI 0 "register_operand")
4373           (unsigned_fix:SI
4374             (match_operand:MODEF 1 "nonimmediate_operand")))
4375      (use (match_dup 2))
4376      (clobber (match_scratch:<ssevecmode> 3))
4377      (clobber (match_scratch:<ssevecmode> 4))])]
4378   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4380   enum machine_mode mode = <MODE>mode;
4381   enum machine_mode vecmode = <ssevecmode>mode;
4382   REAL_VALUE_TYPE TWO31r;
4383   rtx two31;
4385   if (optimize_insn_for_size_p ())
4386     FAIL;
4388   real_ldexp (&TWO31r, &dconst1, 31);
4389   two31 = const_double_from_real_value (TWO31r, mode);
4390   two31 = ix86_build_const_vector (vecmode, true, two31);
4391   operands[2] = force_reg (vecmode, two31);
4394 (define_insn_and_split "*fixuns_trunc<mode>_1"
4395   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4396         (unsigned_fix:SI
4397           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4398    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4399    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4400    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4401   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4402    && optimize_function_for_speed_p (cfun)"
4403   "#"
4404   "&& reload_completed"
4405   [(const_int 0)]
4407   ix86_split_convert_uns_si_sse (operands);
4408   DONE;
4411 ;; Unsigned conversion to HImode.
4412 ;; Without these patterns, we'll try the unsigned SI conversion which
4413 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4415 (define_expand "fixuns_trunc<mode>hi2"
4416   [(set (match_dup 2)
4417         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4418    (set (match_operand:HI 0 "nonimmediate_operand")
4419         (subreg:HI (match_dup 2) 0))]
4420   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4421   "operands[2] = gen_reg_rtx (SImode);")
4423 ;; When SSE is available, it is always faster to use it!
4424 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4425   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4426         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4427   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4428    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4429   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4430   [(set_attr "type" "sseicvt")
4431    (set_attr "prefix" "maybe_vex")
4432    (set (attr "prefix_rex")
4433         (if_then_else
4434           (match_test "<SWI48:MODE>mode == DImode")
4435           (const_string "1")
4436           (const_string "*")))
4437    (set_attr "mode" "<MODEF:MODE>")
4438    (set_attr "athlon_decode" "double,vector")
4439    (set_attr "amdfam10_decode" "double,double")
4440    (set_attr "bdver1_decode" "double,double")])
4442 ;; Avoid vector decoded forms of the instruction.
4443 (define_peephole2
4444   [(match_scratch:MODEF 2 "x")
4445    (set (match_operand:SWI48 0 "register_operand")
4446         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4447   "TARGET_AVOID_VECTOR_DECODE
4448    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4449    && optimize_insn_for_speed_p ()"
4450   [(set (match_dup 2) (match_dup 1))
4451    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4453 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4454   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4455         (fix:SWI248x (match_operand 1 "register_operand")))]
4456   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4457    && TARGET_FISTTP
4458    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4459          && (TARGET_64BIT || <MODE>mode != DImode))
4460         && TARGET_SSE_MATH)
4461    && can_create_pseudo_p ()"
4462   "#"
4463   "&& 1"
4464   [(const_int 0)]
4466   if (memory_operand (operands[0], VOIDmode))
4467     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4468   else
4469     {
4470       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4471       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4472                                                             operands[1],
4473                                                             operands[2]));
4474     }
4475   DONE;
4477   [(set_attr "type" "fisttp")
4478    (set_attr "mode" "<MODE>")])
4480 (define_insn "fix_trunc<mode>_i387_fisttp"
4481   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4482         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4483    (clobber (match_scratch:XF 2 "=&1f"))]
4484   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4485    && TARGET_FISTTP
4486    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4487          && (TARGET_64BIT || <MODE>mode != DImode))
4488         && TARGET_SSE_MATH)"
4489   "* return output_fix_trunc (insn, operands, true);"
4490   [(set_attr "type" "fisttp")
4491    (set_attr "mode" "<MODE>")])
4493 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4494   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4495         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4496    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4497    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4498   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4499    && TARGET_FISTTP
4500    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4501         && (TARGET_64BIT || <MODE>mode != DImode))
4502         && TARGET_SSE_MATH)"
4503   "#"
4504   [(set_attr "type" "fisttp")
4505    (set_attr "mode" "<MODE>")])
4507 (define_split
4508   [(set (match_operand:SWI248x 0 "register_operand")
4509         (fix:SWI248x (match_operand 1 "register_operand")))
4510    (clobber (match_operand:SWI248x 2 "memory_operand"))
4511    (clobber (match_scratch 3))]
4512   "reload_completed"
4513   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4514               (clobber (match_dup 3))])
4515    (set (match_dup 0) (match_dup 2))])
4517 (define_split
4518   [(set (match_operand:SWI248x 0 "memory_operand")
4519         (fix:SWI248x (match_operand 1 "register_operand")))
4520    (clobber (match_operand:SWI248x 2 "memory_operand"))
4521    (clobber (match_scratch 3))]
4522   "reload_completed"
4523   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4524               (clobber (match_dup 3))])])
4526 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4527 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4528 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4529 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4530 ;; function in i386.c.
4531 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4532   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4533         (fix:SWI248x (match_operand 1 "register_operand")))
4534    (clobber (reg:CC FLAGS_REG))]
4535   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4536    && !TARGET_FISTTP
4537    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4538          && (TARGET_64BIT || <MODE>mode != DImode))
4539    && can_create_pseudo_p ()"
4540   "#"
4541   "&& 1"
4542   [(const_int 0)]
4544   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4546   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4547   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4548   if (memory_operand (operands[0], VOIDmode))
4549     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4550                                          operands[2], operands[3]));
4551   else
4552     {
4553       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4554       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4555                                                      operands[2], operands[3],
4556                                                      operands[4]));
4557     }
4558   DONE;
4560   [(set_attr "type" "fistp")
4561    (set_attr "i387_cw" "trunc")
4562    (set_attr "mode" "<MODE>")])
4564 (define_insn "fix_truncdi_i387"
4565   [(set (match_operand:DI 0 "memory_operand" "=m")
4566         (fix:DI (match_operand 1 "register_operand" "f")))
4567    (use (match_operand:HI 2 "memory_operand" "m"))
4568    (use (match_operand:HI 3 "memory_operand" "m"))
4569    (clobber (match_scratch:XF 4 "=&1f"))]
4570   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4571    && !TARGET_FISTTP
4572    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4573   "* return output_fix_trunc (insn, operands, false);"
4574   [(set_attr "type" "fistp")
4575    (set_attr "i387_cw" "trunc")
4576    (set_attr "mode" "DI")])
4578 (define_insn "fix_truncdi_i387_with_temp"
4579   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4580         (fix:DI (match_operand 1 "register_operand" "f,f")))
4581    (use (match_operand:HI 2 "memory_operand" "m,m"))
4582    (use (match_operand:HI 3 "memory_operand" "m,m"))
4583    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4584    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4585   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4586    && !TARGET_FISTTP
4587    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4588   "#"
4589   [(set_attr "type" "fistp")
4590    (set_attr "i387_cw" "trunc")
4591    (set_attr "mode" "DI")])
4593 (define_split
4594   [(set (match_operand:DI 0 "register_operand")
4595         (fix:DI (match_operand 1 "register_operand")))
4596    (use (match_operand:HI 2 "memory_operand"))
4597    (use (match_operand:HI 3 "memory_operand"))
4598    (clobber (match_operand:DI 4 "memory_operand"))
4599    (clobber (match_scratch 5))]
4600   "reload_completed"
4601   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4602               (use (match_dup 2))
4603               (use (match_dup 3))
4604               (clobber (match_dup 5))])
4605    (set (match_dup 0) (match_dup 4))])
4607 (define_split
4608   [(set (match_operand:DI 0 "memory_operand")
4609         (fix:DI (match_operand 1 "register_operand")))
4610    (use (match_operand:HI 2 "memory_operand"))
4611    (use (match_operand:HI 3 "memory_operand"))
4612    (clobber (match_operand:DI 4 "memory_operand"))
4613    (clobber (match_scratch 5))]
4614   "reload_completed"
4615   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4616               (use (match_dup 2))
4617               (use (match_dup 3))
4618               (clobber (match_dup 5))])])
4620 (define_insn "fix_trunc<mode>_i387"
4621   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4622         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4623    (use (match_operand:HI 2 "memory_operand" "m"))
4624    (use (match_operand:HI 3 "memory_operand" "m"))]
4625   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4626    && !TARGET_FISTTP
4627    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4628   "* return output_fix_trunc (insn, operands, false);"
4629   [(set_attr "type" "fistp")
4630    (set_attr "i387_cw" "trunc")
4631    (set_attr "mode" "<MODE>")])
4633 (define_insn "fix_trunc<mode>_i387_with_temp"
4634   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4635         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4636    (use (match_operand:HI 2 "memory_operand" "m,m"))
4637    (use (match_operand:HI 3 "memory_operand" "m,m"))
4638    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4639   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4640    && !TARGET_FISTTP
4641    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4642   "#"
4643   [(set_attr "type" "fistp")
4644    (set_attr "i387_cw" "trunc")
4645    (set_attr "mode" "<MODE>")])
4647 (define_split
4648   [(set (match_operand:SWI24 0 "register_operand")
4649         (fix:SWI24 (match_operand 1 "register_operand")))
4650    (use (match_operand:HI 2 "memory_operand"))
4651    (use (match_operand:HI 3 "memory_operand"))
4652    (clobber (match_operand:SWI24 4 "memory_operand"))]
4653   "reload_completed"
4654   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4655               (use (match_dup 2))
4656               (use (match_dup 3))])
4657    (set (match_dup 0) (match_dup 4))])
4659 (define_split
4660   [(set (match_operand:SWI24 0 "memory_operand")
4661         (fix:SWI24 (match_operand 1 "register_operand")))
4662    (use (match_operand:HI 2 "memory_operand"))
4663    (use (match_operand:HI 3 "memory_operand"))
4664    (clobber (match_operand:SWI24 4 "memory_operand"))]
4665   "reload_completed"
4666   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4667               (use (match_dup 2))
4668               (use (match_dup 3))])])
4670 (define_insn "x86_fnstcw_1"
4671   [(set (match_operand:HI 0 "memory_operand" "=m")
4672         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4673   "TARGET_80387"
4674   "fnstcw\t%0"
4675   [(set (attr "length")
4676         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4677    (set_attr "mode" "HI")
4678    (set_attr "unit" "i387")
4679    (set_attr "bdver1_decode" "vector")])
4681 (define_insn "x86_fldcw_1"
4682   [(set (reg:HI FPCR_REG)
4683         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4684   "TARGET_80387"
4685   "fldcw\t%0"
4686   [(set (attr "length")
4687         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4688    (set_attr "mode" "HI")
4689    (set_attr "unit" "i387")
4690    (set_attr "athlon_decode" "vector")
4691    (set_attr "amdfam10_decode" "vector")
4692    (set_attr "bdver1_decode" "vector")])
4694 ;; Conversion between fixed point and floating point.
4696 ;; Even though we only accept memory inputs, the backend _really_
4697 ;; wants to be able to do this between registers.  Thankfully, LRA
4698 ;; will fix this up for us during register allocation.
4700 (define_insn "floathi<mode>2"
4701   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4702         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4703   "TARGET_80387
4704    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4705        || TARGET_MIX_SSE_I387)"
4706   "fild%Z1\t%1"
4707   [(set_attr "type" "fmov")
4708    (set_attr "mode" "<MODE>")
4709    (set_attr "fp_int_src" "true")])
4711 (define_insn "float<SWI48x:mode>xf2"
4712   [(set (match_operand:XF 0 "register_operand" "=f")
4713         (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4714   "TARGET_80387"
4715   "fild%Z1\t%1"
4716   [(set_attr "type" "fmov")
4717    (set_attr "mode" "XF")
4718    (set_attr "fp_int_src" "true")])
4720 (define_expand "float<SWI48:mode><MODEF:mode>2"
4721   [(set (match_operand:MODEF 0 "register_operand")
4722         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4723   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4725   if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4726       && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4727     {
4728       rtx reg = gen_reg_rtx (XFmode);
4729       rtx (*insn)(rtx, rtx);
4731       emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4733       if (<MODEF:MODE>mode == SFmode)
4734         insn = gen_truncxfsf2;
4735       else if (<MODEF:MODE>mode == DFmode)
4736         insn = gen_truncxfdf2;
4737       else
4738         gcc_unreachable ();
4740       emit_insn (insn (operands[0], reg));
4741       DONE;
4742     }
4745 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse"
4746   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4747         (float:MODEF
4748           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4749   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4750   "@
4751    fild%Z1\t%1
4752    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4753    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4754   [(set_attr "type" "fmov,sseicvt,sseicvt")
4755    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4756    (set_attr "mode" "<MODEF:MODE>")
4757    (set (attr "prefix_rex")
4758      (if_then_else
4759        (and (eq_attr "prefix" "maybe_vex")
4760             (match_test "<SWI48:MODE>mode == DImode"))
4761        (const_string "1")
4762        (const_string "*")))
4763    (set_attr "unit" "i387,*,*")
4764    (set_attr "athlon_decode" "*,double,direct")
4765    (set_attr "amdfam10_decode" "*,vector,double")
4766    (set_attr "bdver1_decode" "*,double,direct")
4767    (set_attr "fp_int_src" "true")
4768    (set (attr "enabled")
4769      (cond [(eq_attr "alternative" "0")
4770               (symbol_ref "TARGET_MIX_SSE_I387
4771                            && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4772                                                 <SWI48:MODE>mode)")
4773             (eq_attr "alternative" "1")
4774               /* ??? For sched1 we need constrain_operands to be able to
4775                  select an alternative.  Leave this enabled before RA.  */
4776               (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS
4777                            || optimize_function_for_size_p (cfun)
4778                            || !(reload_completed
4779                                 || reload_in_progress
4780                                 || lra_in_progress)")
4781            ]
4782            (symbol_ref "true")))
4783    ])
4785 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4786   [(set (match_operand:MODEF 0 "register_operand" "=f")
4787         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4788   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4789   "fild%Z1\t%1"
4790   [(set_attr "type" "fmov")
4791    (set_attr "mode" "<MODEF:MODE>")
4792    (set_attr "fp_int_src" "true")])
4794 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4795 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4796 ;; alternative in sse2_loadld.
4797 (define_split
4798   [(set (match_operand:MODEF 0 "register_operand")
4799         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4800   "TARGET_SSE2 && TARGET_SSE_MATH
4801    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4802    && reload_completed && SSE_REG_P (operands[0])
4803    && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)"
4804   [(const_int 0)]
4806   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4807                                      <MODE>mode, 0);
4808   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4810   emit_insn (gen_sse2_loadld (operands[4],
4811                               CONST0_RTX (V4SImode), operands[1]));
4813   if (<ssevecmode>mode == V4SFmode)
4814     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4815   else
4816     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4817   DONE;
4820 ;; Avoid partial SSE register dependency stalls
4821 (define_split
4822   [(set (match_operand:MODEF 0 "register_operand")
4823         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4824   "TARGET_SSE2 && TARGET_SSE_MATH
4825    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4826    && optimize_function_for_speed_p (cfun)
4827    && reload_completed && SSE_REG_P (operands[0])"
4828   [(const_int 0)]
4830   const enum machine_mode vmode = <MODEF:ssevecmode>mode;
4831   const enum machine_mode mode = <MODEF:MODE>mode;
4832   rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4834   emit_move_insn (op0, CONST0_RTX (vmode));
4836   t = gen_rtx_FLOAT (mode, operands[1]);
4837   t = gen_rtx_VEC_DUPLICATE (vmode, t);
4838   t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4839   emit_insn (gen_rtx_SET (VOIDmode, op0, t));
4840   DONE;
4843 ;; Break partial reg stall for cvtsd2ss.
4845 (define_peephole2
4846   [(set (match_operand:SF 0 "register_operand")
4847         (float_truncate:SF
4848           (match_operand:DF 1 "nonimmediate_operand")))]
4849   "TARGET_SSE2 && TARGET_SSE_MATH
4850    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4851    && optimize_function_for_speed_p (cfun)
4852    && SSE_REG_P (operands[0])
4853    && (!SSE_REG_P (operands[1])
4854        || REGNO (operands[0]) != REGNO (operands[1]))"
4855   [(set (match_dup 0)
4856         (vec_merge:V4SF
4857           (vec_duplicate:V4SF
4858             (float_truncate:V2SF
4859               (match_dup 1)))
4860           (match_dup 0)
4861           (const_int 1)))]
4863   operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4864                                      SFmode, 0);
4865   operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4866                                      DFmode, 0);
4867   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4870 ;; Break partial reg stall for cvtss2sd.
4872 (define_peephole2
4873   [(set (match_operand:DF 0 "register_operand")
4874         (float_extend:DF
4875           (match_operand:SF 1 "nonimmediate_operand")))]
4876   "TARGET_SSE2 && TARGET_SSE_MATH
4877    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4878    && optimize_function_for_speed_p (cfun)
4879    && SSE_REG_P (operands[0])
4880    && (!SSE_REG_P (operands[1])
4881        || REGNO (operands[0]) != REGNO (operands[1]))"
4882   [(set (match_dup 0)
4883         (vec_merge:V2DF
4884           (float_extend:V2DF
4885             (vec_select:V2SF
4886               (match_dup 1)
4887               (parallel [(const_int 0) (const_int 1)])))
4888           (match_dup 0)
4889           (const_int 1)))]
4891   operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
4892                                      DFmode, 0);
4893   operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
4894                                      SFmode, 0);
4895   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4898 ;; Avoid store forwarding (partial memory) stall penalty
4899 ;; by passing DImode value through XMM registers.  */
4901 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
4902   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4903         (float:X87MODEF
4904           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
4905    (clobber (match_scratch:V4SI 3 "=X,x"))
4906    (clobber (match_scratch:V4SI 4 "=X,x"))
4907    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
4908   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4909    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4910    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
4911   "#"
4912   [(set_attr "type" "multi")
4913    (set_attr "mode" "<X87MODEF:MODE>")
4914    (set_attr "unit" "i387")
4915    (set_attr "fp_int_src" "true")])
4917 (define_split
4918   [(set (match_operand:X87MODEF 0 "fp_register_operand")
4919         (float:X87MODEF (match_operand:DI 1 "register_operand")))
4920    (clobber (match_scratch:V4SI 3))
4921    (clobber (match_scratch:V4SI 4))
4922    (clobber (match_operand:DI 2 "memory_operand"))]
4923   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4924    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4925    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4926    && reload_completed"
4927   [(set (match_dup 2) (match_dup 3))
4928    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4930   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
4931      Assemble the 64-bit DImode value in an xmm register.  */
4932   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
4933                               gen_rtx_SUBREG (SImode, operands[1], 0)));
4934   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
4935                               gen_rtx_SUBREG (SImode, operands[1], 4)));
4936   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
4937                                          operands[4]));
4939   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
4942 (define_split
4943   [(set (match_operand:X87MODEF 0 "fp_register_operand")
4944         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
4945    (clobber (match_scratch:V4SI 3))
4946    (clobber (match_scratch:V4SI 4))
4947    (clobber (match_operand:DI 2 "memory_operand"))]
4948   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4949    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4950    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4951    && reload_completed"
4952   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4954 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
4955   [(set (match_operand:MODEF 0 "register_operand")
4956         (unsigned_float:MODEF
4957           (match_operand:SWI12 1 "nonimmediate_operand")))]
4958   "!TARGET_64BIT
4959    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4961   operands[1] = convert_to_mode (SImode, operands[1], 1);
4962   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
4963   DONE;
4966 ;; Avoid store forwarding (partial memory) stall penalty by extending
4967 ;; SImode value to DImode through XMM register instead of pushing two
4968 ;; SImode values to stack. Also note that fild loads from memory only.
4970 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
4971   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4972         (unsigned_float:X87MODEF
4973           (match_operand:SI 1 "nonimmediate_operand" "rm")))
4974    (clobber (match_scratch:DI 3 "=x"))
4975    (clobber (match_operand:DI 2 "memory_operand" "=m"))]
4976   "!TARGET_64BIT
4977    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4978    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
4979   "#"
4980   "&& reload_completed"
4981   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
4982    (set (match_dup 2) (match_dup 3))
4983    (set (match_dup 0)
4984         (float:X87MODEF (match_dup 2)))]
4985   ""
4986   [(set_attr "type" "multi")
4987    (set_attr "mode" "<MODE>")])
4989 (define_expand "floatunssi<mode>2"
4990   [(parallel
4991      [(set (match_operand:X87MODEF 0 "register_operand")
4992            (unsigned_float:X87MODEF
4993              (match_operand:SI 1 "nonimmediate_operand")))
4994       (clobber (match_scratch:DI 3))
4995       (clobber (match_dup 2))])]
4996   "!TARGET_64BIT
4997    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4998         && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
4999        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5001   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5002     {
5003       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5004       DONE;
5005     }
5006   else
5007     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5010 (define_expand "floatunsdisf2"
5011   [(use (match_operand:SF 0 "register_operand"))
5012    (use (match_operand:DI 1 "nonimmediate_operand"))]
5013   "TARGET_64BIT && TARGET_SSE_MATH"
5014   "x86_emit_floatuns (operands); DONE;")
5016 (define_expand "floatunsdidf2"
5017   [(use (match_operand:DF 0 "register_operand"))
5018    (use (match_operand:DI 1 "nonimmediate_operand"))]
5019   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5020    && TARGET_SSE2 && TARGET_SSE_MATH"
5022   if (TARGET_64BIT)
5023     x86_emit_floatuns (operands);
5024   else
5025     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5026   DONE;
5029 ;; Load effective address instructions
5031 (define_insn_and_split "*lea<mode>"
5032   [(set (match_operand:SWI48 0 "register_operand" "=r")
5033         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5034   ""
5036   if (SImode_address_operand (operands[1], VOIDmode))
5037     {
5038       gcc_assert (TARGET_64BIT);
5039       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5040     }
5041   else 
5042     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5044   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5045   [(const_int 0)]
5047   enum machine_mode mode = <MODE>mode;
5048   rtx pat;
5050   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5051      change operands[] array behind our back.  */
5052   pat = PATTERN (curr_insn);
5054   operands[0] = SET_DEST (pat);
5055   operands[1] = SET_SRC (pat);
5057   /* Emit all operations in SImode for zero-extended addresses.  */
5058   if (SImode_address_operand (operands[1], VOIDmode))
5059     mode = SImode;
5061   ix86_split_lea_for_addr (curr_insn, operands, mode);
5063   /* Zero-extend return register to DImode for zero-extended addresses.  */
5064   if (mode != <MODE>mode)
5065     emit_insn (gen_zero_extendsidi2
5066                (operands[0], gen_lowpart (mode, operands[0])));
5068   DONE;
5070   [(set_attr "type" "lea")
5071    (set (attr "mode")
5072      (if_then_else
5073        (match_operand 1 "SImode_address_operand")
5074        (const_string "SI")
5075        (const_string "<MODE>")))])
5077 ;; Add instructions
5079 (define_expand "add<mode>3"
5080   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5081         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5082                     (match_operand:SDWIM 2 "<general_operand>")))]
5083   ""
5084   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5086 (define_insn_and_split "*add<dwi>3_doubleword"
5087   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5088         (plus:<DWI>
5089           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5090           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5091    (clobber (reg:CC FLAGS_REG))]
5092   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5093   "#"
5094   "reload_completed"
5095   [(parallel [(set (reg:CC FLAGS_REG)
5096                    (unspec:CC [(match_dup 1) (match_dup 2)]
5097                               UNSPEC_ADD_CARRY))
5098               (set (match_dup 0)
5099                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5100    (parallel [(set (match_dup 3)
5101                    (plus:DWIH
5102                      (match_dup 4)
5103                      (plus:DWIH
5104                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5105                        (match_dup 5))))
5106               (clobber (reg:CC FLAGS_REG))])]
5107   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5109 (define_insn "*add<mode>3_cc"
5110   [(set (reg:CC FLAGS_REG)
5111         (unspec:CC
5112           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5113            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5114           UNSPEC_ADD_CARRY))
5115    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5116         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5117   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5118   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5119   [(set_attr "type" "alu")
5120    (set_attr "mode" "<MODE>")])
5122 (define_insn "addqi3_cc"
5123   [(set (reg:CC FLAGS_REG)
5124         (unspec:CC
5125           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5126            (match_operand:QI 2 "general_operand" "qn,qm")]
5127           UNSPEC_ADD_CARRY))
5128    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5129         (plus:QI (match_dup 1) (match_dup 2)))]
5130   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5131   "add{b}\t{%2, %0|%0, %2}"
5132   [(set_attr "type" "alu")
5133    (set_attr "mode" "QI")])
5135 (define_insn "*add<mode>_1"
5136   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5137         (plus:SWI48
5138           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5139           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5140    (clobber (reg:CC FLAGS_REG))]
5141   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5143   switch (get_attr_type (insn))
5144     {
5145     case TYPE_LEA:
5146       return "#";
5148     case TYPE_INCDEC:
5149       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5150       if (operands[2] == const1_rtx)
5151         return "inc{<imodesuffix>}\t%0";
5152       else
5153         {
5154           gcc_assert (operands[2] == constm1_rtx);
5155           return "dec{<imodesuffix>}\t%0";
5156         }
5158     default:
5159       /* For most processors, ADD is faster than LEA.  This alternative
5160          was added to use ADD as much as possible.  */
5161       if (which_alternative == 2)
5162         {
5163           rtx tmp;
5164           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5165         }
5166         
5167       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5168       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5169         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5171       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5172     }
5174   [(set (attr "type")
5175      (cond [(eq_attr "alternative" "3")
5176               (const_string "lea")
5177             (match_operand:SWI48 2 "incdec_operand")
5178               (const_string "incdec")
5179            ]
5180            (const_string "alu")))
5181    (set (attr "length_immediate")
5182       (if_then_else
5183         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5184         (const_string "1")
5185         (const_string "*")))
5186    (set_attr "mode" "<MODE>")])
5188 ;; It may seem that nonimmediate operand is proper one for operand 1.
5189 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5190 ;; we take care in ix86_binary_operator_ok to not allow two memory
5191 ;; operands so proper swapping will be done in reload.  This allow
5192 ;; patterns constructed from addsi_1 to match.
5194 (define_insn "addsi_1_zext"
5195   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5196         (zero_extend:DI
5197           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5198                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5199    (clobber (reg:CC FLAGS_REG))]
5200   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5202   switch (get_attr_type (insn))
5203     {
5204     case TYPE_LEA:
5205       return "#";
5207     case TYPE_INCDEC:
5208       if (operands[2] == const1_rtx)
5209         return "inc{l}\t%k0";
5210       else
5211         {
5212           gcc_assert (operands[2] == constm1_rtx);
5213           return "dec{l}\t%k0";
5214         }
5216     default:
5217       /* For most processors, ADD is faster than LEA.  This alternative
5218          was added to use ADD as much as possible.  */
5219       if (which_alternative == 1)
5220         {
5221           rtx tmp;
5222           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5223         }
5225       if (x86_maybe_negate_const_int (&operands[2], SImode))
5226         return "sub{l}\t{%2, %k0|%k0, %2}";
5228       return "add{l}\t{%2, %k0|%k0, %2}";
5229     }
5231   [(set (attr "type")
5232      (cond [(eq_attr "alternative" "2")
5233               (const_string "lea")
5234             (match_operand:SI 2 "incdec_operand")
5235               (const_string "incdec")
5236            ]
5237            (const_string "alu")))
5238    (set (attr "length_immediate")
5239       (if_then_else
5240         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5241         (const_string "1")
5242         (const_string "*")))
5243    (set_attr "mode" "SI")])
5245 (define_insn "*addhi_1"
5246   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5247         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5248                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5249    (clobber (reg:CC FLAGS_REG))]
5250   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5252   switch (get_attr_type (insn))
5253     {
5254     case TYPE_LEA:
5255       return "#";
5257     case TYPE_INCDEC:
5258       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5259       if (operands[2] == const1_rtx)
5260         return "inc{w}\t%0";
5261       else
5262         {
5263           gcc_assert (operands[2] == constm1_rtx);
5264           return "dec{w}\t%0";
5265         }
5267     default:
5268       /* For most processors, ADD is faster than LEA.  This alternative
5269          was added to use ADD as much as possible.  */
5270       if (which_alternative == 2)
5271         {
5272           rtx tmp;
5273           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5274         }
5276       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5277       if (x86_maybe_negate_const_int (&operands[2], HImode))
5278         return "sub{w}\t{%2, %0|%0, %2}";
5280       return "add{w}\t{%2, %0|%0, %2}";
5281     }
5283   [(set (attr "type")
5284      (cond [(eq_attr "alternative" "3")
5285               (const_string "lea")
5286             (match_operand:HI 2 "incdec_operand")
5287               (const_string "incdec")
5288            ]
5289            (const_string "alu")))
5290    (set (attr "length_immediate")
5291       (if_then_else
5292         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5293         (const_string "1")
5294         (const_string "*")))
5295    (set_attr "mode" "HI,HI,HI,SI")])
5297 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5298 (define_insn "*addqi_1"
5299   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5300         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5301                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5302    (clobber (reg:CC FLAGS_REG))]
5303   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5305   bool widen = (which_alternative == 3 || which_alternative == 4);
5307   switch (get_attr_type (insn))
5308     {
5309     case TYPE_LEA:
5310       return "#";
5312     case TYPE_INCDEC:
5313       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5314       if (operands[2] == const1_rtx)
5315         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5316       else
5317         {
5318           gcc_assert (operands[2] == constm1_rtx);
5319           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5320         }
5322     default:
5323       /* For most processors, ADD is faster than LEA.  These alternatives
5324          were added to use ADD as much as possible.  */
5325       if (which_alternative == 2 || which_alternative == 4)
5326         {
5327           rtx tmp;
5328           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5329         }
5331       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5332       if (x86_maybe_negate_const_int (&operands[2], QImode))
5333         {
5334           if (widen)
5335             return "sub{l}\t{%2, %k0|%k0, %2}";
5336           else
5337             return "sub{b}\t{%2, %0|%0, %2}";
5338         }
5339       if (widen)
5340         return "add{l}\t{%k2, %k0|%k0, %k2}";
5341       else
5342         return "add{b}\t{%2, %0|%0, %2}";
5343     }
5345   [(set (attr "type")
5346      (cond [(eq_attr "alternative" "5")
5347               (const_string "lea")
5348             (match_operand:QI 2 "incdec_operand")
5349               (const_string "incdec")
5350            ]
5351            (const_string "alu")))
5352    (set (attr "length_immediate")
5353       (if_then_else
5354         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5355         (const_string "1")
5356         (const_string "*")))
5357    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5359 (define_insn "*addqi_1_slp"
5360   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5361         (plus:QI (match_dup 0)
5362                  (match_operand:QI 1 "general_operand" "qn,qm")))
5363    (clobber (reg:CC FLAGS_REG))]
5364   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5365    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5367   switch (get_attr_type (insn))
5368     {
5369     case TYPE_INCDEC:
5370       if (operands[1] == const1_rtx)
5371         return "inc{b}\t%0";
5372       else
5373         {
5374           gcc_assert (operands[1] == constm1_rtx);
5375           return "dec{b}\t%0";
5376         }
5378     default:
5379       if (x86_maybe_negate_const_int (&operands[1], QImode))
5380         return "sub{b}\t{%1, %0|%0, %1}";
5382       return "add{b}\t{%1, %0|%0, %1}";
5383     }
5385   [(set (attr "type")
5386      (if_then_else (match_operand:QI 1 "incdec_operand")
5387         (const_string "incdec")
5388         (const_string "alu1")))
5389    (set (attr "memory")
5390      (if_then_else (match_operand 1 "memory_operand")
5391         (const_string "load")
5392         (const_string "none")))
5393    (set_attr "mode" "QI")])
5395 ;; Split non destructive adds if we cannot use lea.
5396 (define_split
5397   [(set (match_operand:SWI48 0 "register_operand")
5398         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5399                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5400    (clobber (reg:CC FLAGS_REG))]
5401   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5402   [(set (match_dup 0) (match_dup 1))
5403    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5404               (clobber (reg:CC FLAGS_REG))])])
5406 ;; Convert add to the lea pattern to avoid flags dependency.
5407 (define_split
5408   [(set (match_operand:SWI 0 "register_operand")
5409         (plus:SWI (match_operand:SWI 1 "register_operand")
5410                   (match_operand:SWI 2 "<nonmemory_operand>")))
5411    (clobber (reg:CC FLAGS_REG))]
5412   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5413   [(const_int 0)]
5415   enum machine_mode mode = <MODE>mode;
5416   rtx pat;
5418   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5419     { 
5420       mode = SImode; 
5421       operands[0] = gen_lowpart (mode, operands[0]);
5422       operands[1] = gen_lowpart (mode, operands[1]);
5423       operands[2] = gen_lowpart (mode, operands[2]);
5424     }
5426   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5428   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5429   DONE;
5432 ;; Split non destructive adds if we cannot use lea.
5433 (define_split
5434   [(set (match_operand:DI 0 "register_operand")
5435         (zero_extend:DI
5436           (plus:SI (match_operand:SI 1 "register_operand")
5437                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5438    (clobber (reg:CC FLAGS_REG))]
5439   "TARGET_64BIT
5440    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5441   [(set (match_dup 3) (match_dup 1))
5442    (parallel [(set (match_dup 0)
5443                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5444               (clobber (reg:CC FLAGS_REG))])]
5445   "operands[3] = gen_lowpart (SImode, operands[0]);")
5447 ;; Convert add to the lea pattern to avoid flags dependency.
5448 (define_split
5449   [(set (match_operand:DI 0 "register_operand")
5450         (zero_extend:DI
5451           (plus:SI (match_operand:SI 1 "register_operand")
5452                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5453    (clobber (reg:CC FLAGS_REG))]
5454   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5455   [(set (match_dup 0)
5456         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5458 (define_insn "*add<mode>_2"
5459   [(set (reg FLAGS_REG)
5460         (compare
5461           (plus:SWI
5462             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5463             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5464           (const_int 0)))
5465    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5466         (plus:SWI (match_dup 1) (match_dup 2)))]
5467   "ix86_match_ccmode (insn, CCGOCmode)
5468    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5470   switch (get_attr_type (insn))
5471     {
5472     case TYPE_INCDEC:
5473       if (operands[2] == const1_rtx)
5474         return "inc{<imodesuffix>}\t%0";
5475       else
5476         {
5477           gcc_assert (operands[2] == constm1_rtx);
5478           return "dec{<imodesuffix>}\t%0";
5479         }
5481     default:
5482       if (which_alternative == 2)
5483         {
5484           rtx tmp;
5485           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5486         }
5487         
5488       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5489       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5490         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5492       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5493     }
5495   [(set (attr "type")
5496      (if_then_else (match_operand:SWI 2 "incdec_operand")
5497         (const_string "incdec")
5498         (const_string "alu")))
5499    (set (attr "length_immediate")
5500       (if_then_else
5501         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5502         (const_string "1")
5503         (const_string "*")))
5504    (set_attr "mode" "<MODE>")])
5506 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5507 (define_insn "*addsi_2_zext"
5508   [(set (reg FLAGS_REG)
5509         (compare
5510           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5511                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5512           (const_int 0)))
5513    (set (match_operand:DI 0 "register_operand" "=r,r")
5514         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5515   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5516    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5518   switch (get_attr_type (insn))
5519     {
5520     case TYPE_INCDEC:
5521       if (operands[2] == const1_rtx)
5522         return "inc{l}\t%k0";
5523       else
5524         {
5525           gcc_assert (operands[2] == constm1_rtx);
5526           return "dec{l}\t%k0";
5527         }
5529     default:
5530       if (which_alternative == 1)
5531         {
5532           rtx tmp;
5533           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5534         }
5536       if (x86_maybe_negate_const_int (&operands[2], SImode))
5537         return "sub{l}\t{%2, %k0|%k0, %2}";
5539       return "add{l}\t{%2, %k0|%k0, %2}";
5540     }
5542   [(set (attr "type")
5543      (if_then_else (match_operand:SI 2 "incdec_operand")
5544         (const_string "incdec")
5545         (const_string "alu")))
5546    (set (attr "length_immediate")
5547       (if_then_else
5548         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5549         (const_string "1")
5550         (const_string "*")))
5551    (set_attr "mode" "SI")])
5553 (define_insn "*add<mode>_3"
5554   [(set (reg FLAGS_REG)
5555         (compare
5556           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5557           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5558    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5559   "ix86_match_ccmode (insn, CCZmode)
5560    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5562   switch (get_attr_type (insn))
5563     {
5564     case TYPE_INCDEC:
5565       if (operands[2] == const1_rtx)
5566         return "inc{<imodesuffix>}\t%0";
5567       else
5568         {
5569           gcc_assert (operands[2] == constm1_rtx);
5570           return "dec{<imodesuffix>}\t%0";
5571         }
5573     default:
5574       if (which_alternative == 1)
5575         {
5576           rtx tmp;
5577           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5578         }
5580       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5581       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5582         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5584       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5585     }
5587   [(set (attr "type")
5588      (if_then_else (match_operand:SWI 2 "incdec_operand")
5589         (const_string "incdec")
5590         (const_string "alu")))
5591    (set (attr "length_immediate")
5592       (if_then_else
5593         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5594         (const_string "1")
5595         (const_string "*")))
5596    (set_attr "mode" "<MODE>")])
5598 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5599 (define_insn "*addsi_3_zext"
5600   [(set (reg FLAGS_REG)
5601         (compare
5602           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5603           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5604    (set (match_operand:DI 0 "register_operand" "=r,r")
5605         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5606   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5607    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5609   switch (get_attr_type (insn))
5610     {
5611     case TYPE_INCDEC:
5612       if (operands[2] == const1_rtx)
5613         return "inc{l}\t%k0";
5614       else
5615         {
5616           gcc_assert (operands[2] == constm1_rtx);
5617           return "dec{l}\t%k0";
5618         }
5620     default:
5621       if (which_alternative == 1)
5622         {
5623           rtx tmp;
5624           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5625         }
5627       if (x86_maybe_negate_const_int (&operands[2], SImode))
5628         return "sub{l}\t{%2, %k0|%k0, %2}";
5630       return "add{l}\t{%2, %k0|%k0, %2}";
5631     }
5633   [(set (attr "type")
5634      (if_then_else (match_operand:SI 2 "incdec_operand")
5635         (const_string "incdec")
5636         (const_string "alu")))
5637    (set (attr "length_immediate")
5638       (if_then_else
5639         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5640         (const_string "1")
5641         (const_string "*")))
5642    (set_attr "mode" "SI")])
5644 ; For comparisons against 1, -1 and 128, we may generate better code
5645 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5646 ; is matched then.  We can't accept general immediate, because for
5647 ; case of overflows,  the result is messed up.
5648 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5649 ; only for comparisons not depending on it.
5651 (define_insn "*adddi_4"
5652   [(set (reg FLAGS_REG)
5653         (compare
5654           (match_operand:DI 1 "nonimmediate_operand" "0")
5655           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5656    (clobber (match_scratch:DI 0 "=rm"))]
5657   "TARGET_64BIT
5658    && ix86_match_ccmode (insn, CCGCmode)"
5660   switch (get_attr_type (insn))
5661     {
5662     case TYPE_INCDEC:
5663       if (operands[2] == constm1_rtx)
5664         return "inc{q}\t%0";
5665       else
5666         {
5667           gcc_assert (operands[2] == const1_rtx);
5668           return "dec{q}\t%0";
5669         }
5671     default:
5672       if (x86_maybe_negate_const_int (&operands[2], DImode))
5673         return "add{q}\t{%2, %0|%0, %2}";
5675       return "sub{q}\t{%2, %0|%0, %2}";
5676     }
5678   [(set (attr "type")
5679      (if_then_else (match_operand:DI 2 "incdec_operand")
5680         (const_string "incdec")
5681         (const_string "alu")))
5682    (set (attr "length_immediate")
5683       (if_then_else
5684         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5685         (const_string "1")
5686         (const_string "*")))
5687    (set_attr "mode" "DI")])
5689 ; For comparisons against 1, -1 and 128, we may generate better code
5690 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5691 ; is matched then.  We can't accept general immediate, because for
5692 ; case of overflows,  the result is messed up.
5693 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5694 ; only for comparisons not depending on it.
5696 (define_insn "*add<mode>_4"
5697   [(set (reg FLAGS_REG)
5698         (compare
5699           (match_operand:SWI124 1 "nonimmediate_operand" "0")
5700           (match_operand:SWI124 2 "const_int_operand" "n")))
5701    (clobber (match_scratch:SWI124 0 "=<r>m"))]
5702   "ix86_match_ccmode (insn, CCGCmode)"
5704   switch (get_attr_type (insn))
5705     {
5706     case TYPE_INCDEC:
5707       if (operands[2] == constm1_rtx)
5708         return "inc{<imodesuffix>}\t%0";
5709       else
5710         {
5711           gcc_assert (operands[2] == const1_rtx);
5712           return "dec{<imodesuffix>}\t%0";
5713         }
5715     default:
5716       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5717         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5719       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5720     }
5722   [(set (attr "type")
5723      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5724         (const_string "incdec")
5725         (const_string "alu")))
5726    (set (attr "length_immediate")
5727       (if_then_else
5728         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5729         (const_string "1")
5730         (const_string "*")))
5731    (set_attr "mode" "<MODE>")])
5733 (define_insn "*add<mode>_5"
5734   [(set (reg FLAGS_REG)
5735         (compare
5736           (plus:SWI
5737             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5738             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5739           (const_int 0)))
5740    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5741   "ix86_match_ccmode (insn, CCGOCmode)
5742    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5744   switch (get_attr_type (insn))
5745     {
5746     case TYPE_INCDEC:
5747       if (operands[2] == const1_rtx)
5748         return "inc{<imodesuffix>}\t%0";
5749       else
5750         {
5751           gcc_assert (operands[2] == constm1_rtx);
5752           return "dec{<imodesuffix>}\t%0";
5753         }
5755     default:
5756       if (which_alternative == 1)
5757         {
5758           rtx tmp;
5759           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5760         }
5762       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5763       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5764         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5766       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5767     }
5769   [(set (attr "type")
5770      (if_then_else (match_operand:SWI 2 "incdec_operand")
5771         (const_string "incdec")
5772         (const_string "alu")))
5773    (set (attr "length_immediate")
5774       (if_then_else
5775         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5776         (const_string "1")
5777         (const_string "*")))
5778    (set_attr "mode" "<MODE>")])
5780 (define_insn "addqi_ext_1"
5781   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5782                          (const_int 8)
5783                          (const_int 8))
5784         (plus:SI
5785           (zero_extract:SI
5786             (match_operand 1 "ext_register_operand" "0,0")
5787             (const_int 8)
5788             (const_int 8))
5789           (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5790    (clobber (reg:CC FLAGS_REG))]
5791   ""
5793   switch (get_attr_type (insn))
5794     {
5795     case TYPE_INCDEC:
5796       if (operands[2] == const1_rtx)
5797         return "inc{b}\t%h0";
5798       else
5799         {
5800           gcc_assert (operands[2] == constm1_rtx);
5801           return "dec{b}\t%h0";
5802         }
5804     default:
5805       return "add{b}\t{%2, %h0|%h0, %2}";
5806     }
5808   [(set_attr "isa" "*,nox64")
5809    (set (attr "type")
5810      (if_then_else (match_operand:QI 2 "incdec_operand")
5811         (const_string "incdec")
5812         (const_string "alu")))
5813    (set_attr "modrm" "1")
5814    (set_attr "mode" "QI")])
5816 (define_insn "*addqi_ext_2"
5817   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5818                          (const_int 8)
5819                          (const_int 8))
5820         (plus:SI
5821           (zero_extract:SI
5822             (match_operand 1 "ext_register_operand" "%0")
5823             (const_int 8)
5824             (const_int 8))
5825           (zero_extract:SI
5826             (match_operand 2 "ext_register_operand" "Q")
5827             (const_int 8)
5828             (const_int 8))))
5829    (clobber (reg:CC FLAGS_REG))]
5830   ""
5831   "add{b}\t{%h2, %h0|%h0, %h2}"
5832   [(set_attr "type" "alu")
5833    (set_attr "mode" "QI")])
5835 ;; Add with jump on overflow.
5836 (define_expand "addv<mode>4"
5837   [(parallel [(set (reg:CCO FLAGS_REG)
5838                    (eq:CCO (plus:<DWI>
5839                               (sign_extend:<DWI>
5840                                  (match_operand:SWI 1 "nonimmediate_operand"))
5841                               (match_dup 4))
5842                            (sign_extend:<DWI>
5843                               (plus:SWI (match_dup 1)
5844                                         (match_operand:SWI 2
5845                                            "<general_operand>")))))
5846               (set (match_operand:SWI 0 "register_operand")
5847                    (plus:SWI (match_dup 1) (match_dup 2)))])
5848    (set (pc) (if_then_else
5849                (eq (reg:CCO FLAGS_REG) (const_int 0))
5850                (label_ref (match_operand 3))
5851                (pc)))]
5852   ""
5854   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5855   if (CONST_INT_P (operands[2]))
5856     operands[4] = operands[2];
5857   else
5858     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5861 (define_insn "*addv<mode>4"
5862   [(set (reg:CCO FLAGS_REG)
5863         (eq:CCO (plus:<DWI>
5864                    (sign_extend:<DWI>
5865                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5866                    (sign_extend:<DWI>
5867                       (match_operand:SWI 2 "<general_sext_operand>"
5868                                            "<r>mWe,<r>We")))
5869                 (sign_extend:<DWI>
5870                    (plus:SWI (match_dup 1) (match_dup 2)))))
5871    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5872         (plus:SWI (match_dup 1) (match_dup 2)))]
5873   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5874   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5875   [(set_attr "type" "alu")
5876    (set_attr "mode" "<MODE>")])
5878 (define_insn "*addv<mode>4_1"
5879   [(set (reg:CCO FLAGS_REG)
5880         (eq:CCO (plus:<DWI>
5881                    (sign_extend:<DWI>
5882                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
5883                    (match_operand:<DWI> 3 "const_int_operand" "i"))
5884                 (sign_extend:<DWI>
5885                    (plus:SWI (match_dup 1)
5886                              (match_operand:SWI 2 "x86_64_immediate_operand"
5887                                                   "<i>")))))
5888    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5889         (plus:SWI (match_dup 1) (match_dup 2)))]
5890   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5891    && CONST_INT_P (operands[2])
5892    && INTVAL (operands[2]) == INTVAL (operands[3])"
5893   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5894   [(set_attr "type" "alu")
5895    (set_attr "mode" "<MODE>")
5896    (set (attr "length_immediate")
5897         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5898                   (const_string "1")
5899                (match_test "<MODE_SIZE> == 8")
5900                   (const_string "4")]
5901               (const_string "<MODE_SIZE>")))])
5903 ;; The lea patterns for modes less than 32 bits need to be matched by
5904 ;; several insns converted to real lea by splitters.
5906 (define_insn_and_split "*lea_general_1"
5907   [(set (match_operand 0 "register_operand" "=r")
5908         (plus (plus (match_operand 1 "index_register_operand" "l")
5909                     (match_operand 2 "register_operand" "r"))
5910               (match_operand 3 "immediate_operand" "i")))]
5911   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5912    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5913    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5914    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5915    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5916        || GET_MODE (operands[3]) == VOIDmode)"
5917   "#"
5918   "&& reload_completed"
5919   [(const_int 0)]
5921   enum machine_mode mode = SImode;
5922   rtx pat;
5924   operands[0] = gen_lowpart (mode, operands[0]);
5925   operands[1] = gen_lowpart (mode, operands[1]);
5926   operands[2] = gen_lowpart (mode, operands[2]);
5927   operands[3] = gen_lowpart (mode, operands[3]);
5929   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
5930                       operands[3]);
5932   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5933   DONE;
5935   [(set_attr "type" "lea")
5936    (set_attr "mode" "SI")])
5938 (define_insn_and_split "*lea_general_2"
5939   [(set (match_operand 0 "register_operand" "=r")
5940         (plus (mult (match_operand 1 "index_register_operand" "l")
5941                     (match_operand 2 "const248_operand" "n"))
5942               (match_operand 3 "nonmemory_operand" "ri")))]
5943   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5944    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5945    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5946    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5947        || GET_MODE (operands[3]) == VOIDmode)"
5948   "#"
5949   "&& reload_completed"
5950   [(const_int 0)]
5952   enum machine_mode mode = SImode;
5953   rtx pat;
5955   operands[0] = gen_lowpart (mode, operands[0]);
5956   operands[1] = gen_lowpart (mode, operands[1]);
5957   operands[3] = gen_lowpart (mode, operands[3]);
5959   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
5960                       operands[3]);
5962   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5963   DONE;
5965   [(set_attr "type" "lea")
5966    (set_attr "mode" "SI")])
5968 (define_insn_and_split "*lea_general_3"
5969   [(set (match_operand 0 "register_operand" "=r")
5970         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5971                           (match_operand 2 "const248_operand" "n"))
5972                     (match_operand 3 "register_operand" "r"))
5973               (match_operand 4 "immediate_operand" "i")))]
5974   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5975    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5976    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5977    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5978   "#"
5979   "&& reload_completed"
5980   [(const_int 0)]
5982   enum machine_mode mode = SImode;
5983   rtx pat;
5985   operands[0] = gen_lowpart (mode, operands[0]);
5986   operands[1] = gen_lowpart (mode, operands[1]);
5987   operands[3] = gen_lowpart (mode, operands[3]);
5988   operands[4] = gen_lowpart (mode, operands[4]);
5990   pat = gen_rtx_PLUS (mode,
5991                       gen_rtx_PLUS (mode,
5992                                     gen_rtx_MULT (mode, operands[1],
5993                                                         operands[2]),
5994                                     operands[3]),
5995                       operands[4]);
5997   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5998   DONE;
6000   [(set_attr "type" "lea")
6001    (set_attr "mode" "SI")])
6003 (define_insn_and_split "*lea_general_4"
6004   [(set (match_operand 0 "register_operand" "=r")
6005         (any_or (ashift
6006                   (match_operand 1 "index_register_operand" "l")
6007                   (match_operand 2 "const_int_operand" "n"))
6008                 (match_operand 3 "const_int_operand" "n")))]
6009   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6010       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6011     || GET_MODE (operands[0]) == SImode
6012     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6013    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6014    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6015    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6016        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6017   "#"
6018   "&& reload_completed"
6019   [(const_int 0)]
6021   enum machine_mode mode = GET_MODE (operands[0]);
6022   rtx pat;
6024   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6025     { 
6026       mode = SImode; 
6027       operands[0] = gen_lowpart (mode, operands[0]);
6028       operands[1] = gen_lowpart (mode, operands[1]);
6029     }
6031   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6033   pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6034                        INTVAL (operands[3]));
6036   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6037   DONE;
6039   [(set_attr "type" "lea")
6040    (set (attr "mode")
6041       (if_then_else (match_operand:DI 0)
6042         (const_string "DI")
6043         (const_string "SI")))])
6045 ;; Subtract instructions
6047 (define_expand "sub<mode>3"
6048   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6049         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6050                      (match_operand:SDWIM 2 "<general_operand>")))]
6051   ""
6052   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6054 (define_insn_and_split "*sub<dwi>3_doubleword"
6055   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6056         (minus:<DWI>
6057           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6058           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6059    (clobber (reg:CC FLAGS_REG))]
6060   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6061   "#"
6062   "reload_completed"
6063   [(parallel [(set (reg:CC FLAGS_REG)
6064                    (compare:CC (match_dup 1) (match_dup 2)))
6065               (set (match_dup 0)
6066                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6067    (parallel [(set (match_dup 3)
6068                    (minus:DWIH
6069                      (match_dup 4)
6070                      (plus:DWIH
6071                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6072                        (match_dup 5))))
6073               (clobber (reg:CC FLAGS_REG))])]
6074   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6076 (define_insn "*sub<mode>_1"
6077   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6078         (minus:SWI
6079           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6080           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6081    (clobber (reg:CC FLAGS_REG))]
6082   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6083   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6084   [(set_attr "type" "alu")
6085    (set_attr "mode" "<MODE>")])
6087 (define_insn "*subsi_1_zext"
6088   [(set (match_operand:DI 0 "register_operand" "=r")
6089         (zero_extend:DI
6090           (minus:SI (match_operand:SI 1 "register_operand" "0")
6091                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6092    (clobber (reg:CC FLAGS_REG))]
6093   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6094   "sub{l}\t{%2, %k0|%k0, %2}"
6095   [(set_attr "type" "alu")
6096    (set_attr "mode" "SI")])
6098 (define_insn "*subqi_1_slp"
6099   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6100         (minus:QI (match_dup 0)
6101                   (match_operand:QI 1 "general_operand" "qn,qm")))
6102    (clobber (reg:CC FLAGS_REG))]
6103   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6104    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6105   "sub{b}\t{%1, %0|%0, %1}"
6106   [(set_attr "type" "alu1")
6107    (set_attr "mode" "QI")])
6109 (define_insn "*sub<mode>_2"
6110   [(set (reg FLAGS_REG)
6111         (compare
6112           (minus:SWI
6113             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6114             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6115           (const_int 0)))
6116    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6117         (minus:SWI (match_dup 1) (match_dup 2)))]
6118   "ix86_match_ccmode (insn, CCGOCmode)
6119    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6120   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6121   [(set_attr "type" "alu")
6122    (set_attr "mode" "<MODE>")])
6124 (define_insn "*subsi_2_zext"
6125   [(set (reg FLAGS_REG)
6126         (compare
6127           (minus:SI (match_operand:SI 1 "register_operand" "0")
6128                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6129           (const_int 0)))
6130    (set (match_operand:DI 0 "register_operand" "=r")
6131         (zero_extend:DI
6132           (minus:SI (match_dup 1)
6133                     (match_dup 2))))]
6134   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6135    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6136   "sub{l}\t{%2, %k0|%k0, %2}"
6137   [(set_attr "type" "alu")
6138    (set_attr "mode" "SI")])
6140 ;; Subtract with jump on overflow.
6141 (define_expand "subv<mode>4"
6142   [(parallel [(set (reg:CCO FLAGS_REG)
6143                    (eq:CCO (minus:<DWI>
6144                               (sign_extend:<DWI>
6145                                  (match_operand:SWI 1 "nonimmediate_operand"))
6146                               (match_dup 4))
6147                            (sign_extend:<DWI>
6148                               (minus:SWI (match_dup 1)
6149                                          (match_operand:SWI 2
6150                                             "<general_operand>")))))
6151               (set (match_operand:SWI 0 "register_operand")
6152                    (minus:SWI (match_dup 1) (match_dup 2)))])
6153    (set (pc) (if_then_else
6154                (eq (reg:CCO FLAGS_REG) (const_int 0))
6155                (label_ref (match_operand 3))
6156                (pc)))]
6157   ""
6159   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6160   if (CONST_INT_P (operands[2]))
6161     operands[4] = operands[2];
6162   else
6163     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6166 (define_insn "*subv<mode>4"
6167   [(set (reg:CCO FLAGS_REG)
6168         (eq:CCO (minus:<DWI>
6169                    (sign_extend:<DWI>
6170                       (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6171                    (sign_extend:<DWI>
6172                       (match_operand:SWI 2 "<general_sext_operand>"
6173                                            "<r>We,<r>m")))
6174                 (sign_extend:<DWI>
6175                    (minus:SWI (match_dup 1) (match_dup 2)))))
6176    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6177         (minus:SWI (match_dup 1) (match_dup 2)))]
6178   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6179   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6180   [(set_attr "type" "alu")
6181    (set_attr "mode" "<MODE>")])
6183 (define_insn "*subv<mode>4_1"
6184   [(set (reg:CCO FLAGS_REG)
6185         (eq:CCO (minus:<DWI>
6186                    (sign_extend:<DWI>
6187                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6188                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6189                 (sign_extend:<DWI>
6190                    (minus:SWI (match_dup 1)
6191                               (match_operand:SWI 2 "x86_64_immediate_operand"
6192                                                    "<i>")))))
6193    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6194         (minus:SWI (match_dup 1) (match_dup 2)))]
6195   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6196    && CONST_INT_P (operands[2])
6197    && INTVAL (operands[2]) == INTVAL (operands[3])"
6198   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6199   [(set_attr "type" "alu")
6200    (set_attr "mode" "<MODE>")
6201    (set (attr "length_immediate")
6202         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6203                   (const_string "1")
6204                (match_test "<MODE_SIZE> == 8")
6205                   (const_string "4")]
6206               (const_string "<MODE_SIZE>")))])
6208 (define_insn "*sub<mode>_3"
6209   [(set (reg FLAGS_REG)
6210         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6211                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6212    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6213         (minus:SWI (match_dup 1) (match_dup 2)))]
6214   "ix86_match_ccmode (insn, CCmode)
6215    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6216   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6217   [(set_attr "type" "alu")
6218    (set_attr "mode" "<MODE>")])
6220 (define_insn "*subsi_3_zext"
6221   [(set (reg FLAGS_REG)
6222         (compare (match_operand:SI 1 "register_operand" "0")
6223                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6224    (set (match_operand:DI 0 "register_operand" "=r")
6225         (zero_extend:DI
6226           (minus:SI (match_dup 1)
6227                     (match_dup 2))))]
6228   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6229    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6230   "sub{l}\t{%2, %1|%1, %2}"
6231   [(set_attr "type" "alu")
6232    (set_attr "mode" "SI")])
6234 ;; Add with carry and subtract with borrow
6236 (define_expand "<plusminus_insn><mode>3_carry"
6237   [(parallel
6238     [(set (match_operand:SWI 0 "nonimmediate_operand")
6239           (plusminus:SWI
6240             (match_operand:SWI 1 "nonimmediate_operand")
6241             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6242                        [(match_operand 3 "flags_reg_operand")
6243                         (const_int 0)])
6244                       (match_operand:SWI 2 "<general_operand>"))))
6245      (clobber (reg:CC FLAGS_REG))])]
6246   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6248 (define_insn "*<plusminus_insn><mode>3_carry"
6249   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6250         (plusminus:SWI
6251           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6252           (plus:SWI
6253             (match_operator 3 "ix86_carry_flag_operator"
6254              [(reg FLAGS_REG) (const_int 0)])
6255             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6256    (clobber (reg:CC FLAGS_REG))]
6257   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6258   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6259   [(set_attr "type" "alu")
6260    (set_attr "use_carry" "1")
6261    (set_attr "pent_pair" "pu")
6262    (set_attr "mode" "<MODE>")])
6264 (define_insn "*addsi3_carry_zext"
6265   [(set (match_operand:DI 0 "register_operand" "=r")
6266         (zero_extend:DI
6267           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6268                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6269                              [(reg FLAGS_REG) (const_int 0)])
6270                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6271    (clobber (reg:CC FLAGS_REG))]
6272   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6273   "adc{l}\t{%2, %k0|%k0, %2}"
6274   [(set_attr "type" "alu")
6275    (set_attr "use_carry" "1")
6276    (set_attr "pent_pair" "pu")
6277    (set_attr "mode" "SI")])
6279 (define_insn "*subsi3_carry_zext"
6280   [(set (match_operand:DI 0 "register_operand" "=r")
6281         (zero_extend:DI
6282           (minus:SI (match_operand:SI 1 "register_operand" "0")
6283                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6284                               [(reg FLAGS_REG) (const_int 0)])
6285                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6286    (clobber (reg:CC FLAGS_REG))]
6287   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6288   "sbb{l}\t{%2, %k0|%k0, %2}"
6289   [(set_attr "type" "alu")
6290    (set_attr "pent_pair" "pu")
6291    (set_attr "mode" "SI")])
6293 ;; ADCX instruction
6295 (define_insn "adcx<mode>3"
6296   [(set (reg:CCC FLAGS_REG)
6297         (compare:CCC
6298           (plus:SWI48
6299             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6300             (plus:SWI48
6301               (match_operator 4 "ix86_carry_flag_operator"
6302                [(match_operand 3 "flags_reg_operand") (const_int 0)])
6303               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6304           (const_int 0)))
6305    (set (match_operand:SWI48 0 "register_operand" "=r")
6306         (plus:SWI48 (match_dup 1)
6307                     (plus:SWI48 (match_op_dup 4
6308                                  [(match_dup 3) (const_int 0)])
6309                                 (match_dup 2))))]
6310   "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6311   "adcx\t{%2, %0|%0, %2}"
6312   [(set_attr "type" "alu")
6313    (set_attr "use_carry" "1")
6314    (set_attr "mode" "<MODE>")])
6316 ;; Overflow setting add instructions
6318 (define_insn "*add<mode>3_cconly_overflow"
6319   [(set (reg:CCC FLAGS_REG)
6320         (compare:CCC
6321           (plus:SWI
6322             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6323             (match_operand:SWI 2 "<general_operand>" "<g>"))
6324           (match_dup 1)))
6325    (clobber (match_scratch:SWI 0 "=<r>"))]
6326   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6327   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6328   [(set_attr "type" "alu")
6329    (set_attr "mode" "<MODE>")])
6331 (define_insn "*add<mode>3_cc_overflow"
6332   [(set (reg:CCC FLAGS_REG)
6333         (compare:CCC
6334             (plus:SWI
6335                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6336                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6337             (match_dup 1)))
6338    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6339         (plus:SWI (match_dup 1) (match_dup 2)))]
6340   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6341   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6342   [(set_attr "type" "alu")
6343    (set_attr "mode" "<MODE>")])
6345 (define_insn "*addsi3_zext_cc_overflow"
6346   [(set (reg:CCC FLAGS_REG)
6347         (compare:CCC
6348           (plus:SI
6349             (match_operand:SI 1 "nonimmediate_operand" "%0")
6350             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6351           (match_dup 1)))
6352    (set (match_operand:DI 0 "register_operand" "=r")
6353         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6354   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6355   "add{l}\t{%2, %k0|%k0, %2}"
6356   [(set_attr "type" "alu")
6357    (set_attr "mode" "SI")])
6359 ;; The patterns that match these are at the end of this file.
6361 (define_expand "<plusminus_insn>xf3"
6362   [(set (match_operand:XF 0 "register_operand")
6363         (plusminus:XF
6364           (match_operand:XF 1 "register_operand")
6365           (match_operand:XF 2 "register_operand")))]
6366   "TARGET_80387")
6368 (define_expand "<plusminus_insn><mode>3"
6369   [(set (match_operand:MODEF 0 "register_operand")
6370         (plusminus:MODEF
6371           (match_operand:MODEF 1 "register_operand")
6372           (match_operand:MODEF 2 "nonimmediate_operand")))]
6373   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6374     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6376 ;; Multiply instructions
6378 (define_expand "mul<mode>3"
6379   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6380                    (mult:SWIM248
6381                      (match_operand:SWIM248 1 "register_operand")
6382                      (match_operand:SWIM248 2 "<general_operand>")))
6383               (clobber (reg:CC FLAGS_REG))])])
6385 (define_expand "mulqi3"
6386   [(parallel [(set (match_operand:QI 0 "register_operand")
6387                    (mult:QI
6388                      (match_operand:QI 1 "register_operand")
6389                      (match_operand:QI 2 "nonimmediate_operand")))
6390               (clobber (reg:CC FLAGS_REG))])]
6391   "TARGET_QIMODE_MATH")
6393 ;; On AMDFAM10
6394 ;; IMUL reg32/64, reg32/64, imm8        Direct
6395 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6396 ;; IMUL reg32/64, reg32/64, imm32       Direct
6397 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6398 ;; IMUL reg32/64, reg32/64              Direct
6399 ;; IMUL reg32/64, mem32/64              Direct
6401 ;; On BDVER1, all above IMULs use DirectPath
6403 (define_insn "*mul<mode>3_1"
6404   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6405         (mult:SWI48
6406           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6407           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6408    (clobber (reg:CC FLAGS_REG))]
6409   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6410   "@
6411    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6412    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6413    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6414   [(set_attr "type" "imul")
6415    (set_attr "prefix_0f" "0,0,1")
6416    (set (attr "athlon_decode")
6417         (cond [(eq_attr "cpu" "athlon")
6418                   (const_string "vector")
6419                (eq_attr "alternative" "1")
6420                   (const_string "vector")
6421                (and (eq_attr "alternative" "2")
6422                     (match_operand 1 "memory_operand"))
6423                   (const_string "vector")]
6424               (const_string "direct")))
6425    (set (attr "amdfam10_decode")
6426         (cond [(and (eq_attr "alternative" "0,1")
6427                     (match_operand 1 "memory_operand"))
6428                   (const_string "vector")]
6429               (const_string "direct")))
6430    (set_attr "bdver1_decode" "direct")
6431    (set_attr "mode" "<MODE>")])
6433 (define_insn "*mulsi3_1_zext"
6434   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6435         (zero_extend:DI
6436           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6437                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6438    (clobber (reg:CC FLAGS_REG))]
6439   "TARGET_64BIT
6440    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6441   "@
6442    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6443    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6444    imul{l}\t{%2, %k0|%k0, %2}"
6445   [(set_attr "type" "imul")
6446    (set_attr "prefix_0f" "0,0,1")
6447    (set (attr "athlon_decode")
6448         (cond [(eq_attr "cpu" "athlon")
6449                   (const_string "vector")
6450                (eq_attr "alternative" "1")
6451                   (const_string "vector")
6452                (and (eq_attr "alternative" "2")
6453                     (match_operand 1 "memory_operand"))
6454                   (const_string "vector")]
6455               (const_string "direct")))
6456    (set (attr "amdfam10_decode")
6457         (cond [(and (eq_attr "alternative" "0,1")
6458                     (match_operand 1 "memory_operand"))
6459                   (const_string "vector")]
6460               (const_string "direct")))
6461    (set_attr "bdver1_decode" "direct")
6462    (set_attr "mode" "SI")])
6464 ;; On AMDFAM10
6465 ;; IMUL reg16, reg16, imm8      VectorPath
6466 ;; IMUL reg16, mem16, imm8      VectorPath
6467 ;; IMUL reg16, reg16, imm16     VectorPath
6468 ;; IMUL reg16, mem16, imm16     VectorPath
6469 ;; IMUL reg16, reg16            Direct
6470 ;; IMUL reg16, mem16            Direct
6472 ;; On BDVER1, all HI MULs use DoublePath
6474 (define_insn "*mulhi3_1"
6475   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6476         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6477                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6478    (clobber (reg:CC FLAGS_REG))]
6479   "TARGET_HIMODE_MATH
6480    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6481   "@
6482    imul{w}\t{%2, %1, %0|%0, %1, %2}
6483    imul{w}\t{%2, %1, %0|%0, %1, %2}
6484    imul{w}\t{%2, %0|%0, %2}"
6485   [(set_attr "type" "imul")
6486    (set_attr "prefix_0f" "0,0,1")
6487    (set (attr "athlon_decode")
6488         (cond [(eq_attr "cpu" "athlon")
6489                   (const_string "vector")
6490                (eq_attr "alternative" "1,2")
6491                   (const_string "vector")]
6492               (const_string "direct")))
6493    (set (attr "amdfam10_decode")
6494         (cond [(eq_attr "alternative" "0,1")
6495                   (const_string "vector")]
6496               (const_string "direct")))
6497    (set_attr "bdver1_decode" "double")
6498    (set_attr "mode" "HI")])
6500 ;;On AMDFAM10 and BDVER1
6501 ;; MUL reg8     Direct
6502 ;; MUL mem8     Direct
6504 (define_insn "*mulqi3_1"
6505   [(set (match_operand:QI 0 "register_operand" "=a")
6506         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6507                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6508    (clobber (reg:CC FLAGS_REG))]
6509   "TARGET_QIMODE_MATH
6510    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6511   "mul{b}\t%2"
6512   [(set_attr "type" "imul")
6513    (set_attr "length_immediate" "0")
6514    (set (attr "athlon_decode")
6515      (if_then_else (eq_attr "cpu" "athlon")
6516         (const_string "vector")
6517         (const_string "direct")))
6518    (set_attr "amdfam10_decode" "direct")
6519    (set_attr "bdver1_decode" "direct")
6520    (set_attr "mode" "QI")])
6522 ;; Multiply with jump on overflow.
6523 (define_expand "mulv<mode>4"
6524   [(parallel [(set (reg:CCO FLAGS_REG)
6525                    (eq:CCO (mult:<DWI>
6526                               (sign_extend:<DWI>
6527                                  (match_operand:SWI48 1 "register_operand"))
6528                               (match_dup 4))
6529                            (sign_extend:<DWI>
6530                               (mult:SWI48 (match_dup 1)
6531                                           (match_operand:SWI48 2
6532                                              "<general_operand>")))))
6533               (set (match_operand:SWI48 0 "register_operand")
6534                    (mult:SWI48 (match_dup 1) (match_dup 2)))])
6535    (set (pc) (if_then_else
6536                (eq (reg:CCO FLAGS_REG) (const_int 0))
6537                (label_ref (match_operand 3))
6538                (pc)))]
6539   ""
6541   if (CONST_INT_P (operands[2]))
6542     operands[4] = operands[2];
6543   else
6544     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6547 (define_insn "*mulv<mode>4"
6548   [(set (reg:CCO FLAGS_REG)
6549         (eq:CCO (mult:<DWI>
6550                    (sign_extend:<DWI>
6551                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6552                    (sign_extend:<DWI>
6553                       (match_operand:SWI48 2 "<general_sext_operand>"
6554                                              "We,mr")))
6555                 (sign_extend:<DWI>
6556                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
6557    (set (match_operand:SWI48 0 "register_operand" "=r,r")
6558         (mult:SWI48 (match_dup 1) (match_dup 2)))]
6559   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6560   "@
6561    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6562    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6563   [(set_attr "type" "imul")
6564    (set_attr "prefix_0f" "0,1")
6565    (set (attr "athlon_decode")
6566         (cond [(eq_attr "cpu" "athlon")
6567                   (const_string "vector")
6568                (eq_attr "alternative" "0")
6569                   (const_string "vector")
6570                (and (eq_attr "alternative" "1")
6571                     (match_operand 1 "memory_operand"))
6572                   (const_string "vector")]
6573               (const_string "direct")))
6574    (set (attr "amdfam10_decode")
6575         (cond [(and (eq_attr "alternative" "1")
6576                     (match_operand 1 "memory_operand"))
6577                   (const_string "vector")]
6578               (const_string "direct")))
6579    (set_attr "bdver1_decode" "direct")
6580    (set_attr "mode" "<MODE>")])
6582 (define_insn "*mulv<mode>4_1"
6583   [(set (reg:CCO FLAGS_REG)
6584         (eq:CCO (mult:<DWI>
6585                    (sign_extend:<DWI>
6586                       (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6587                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6588                 (sign_extend:<DWI>
6589                    (mult:SWI48 (match_dup 1)
6590                                (match_operand:SWI 2 "x86_64_immediate_operand"
6591                                                     "K,<i>")))))
6592    (set (match_operand:SWI48 0 "register_operand" "=r,r")
6593         (mult:SWI48 (match_dup 1) (match_dup 2)))]
6594   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6595    && CONST_INT_P (operands[2])
6596    && INTVAL (operands[2]) == INTVAL (operands[3])"
6597   "@
6598    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6599    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6600   [(set_attr "type" "imul")
6601    (set (attr "athlon_decode")
6602         (cond [(eq_attr "cpu" "athlon")
6603                   (const_string "vector")
6604                (eq_attr "alternative" "1")
6605                   (const_string "vector")]
6606               (const_string "direct")))
6607    (set (attr "amdfam10_decode")
6608         (cond [(match_operand 1 "memory_operand")
6609                   (const_string "vector")]
6610               (const_string "direct")))
6611    (set_attr "bdver1_decode" "direct")
6612    (set_attr "mode" "<MODE>")
6613    (set (attr "length_immediate")
6614         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6615                   (const_string "1")
6616                (match_test "<MODE_SIZE> == 8")
6617                   (const_string "4")]
6618               (const_string "<MODE_SIZE>")))])
6620 (define_expand "<u>mul<mode><dwi>3"
6621   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6622                    (mult:<DWI>
6623                      (any_extend:<DWI>
6624                        (match_operand:DWIH 1 "nonimmediate_operand"))
6625                      (any_extend:<DWI>
6626                        (match_operand:DWIH 2 "register_operand"))))
6627               (clobber (reg:CC FLAGS_REG))])])
6629 (define_expand "<u>mulqihi3"
6630   [(parallel [(set (match_operand:HI 0 "register_operand")
6631                    (mult:HI
6632                      (any_extend:HI
6633                        (match_operand:QI 1 "nonimmediate_operand"))
6634                      (any_extend:HI
6635                        (match_operand:QI 2 "register_operand"))))
6636               (clobber (reg:CC FLAGS_REG))])]
6637   "TARGET_QIMODE_MATH")
6639 (define_insn "*bmi2_umulditi3_1"
6640   [(set (match_operand:DI 0 "register_operand" "=r")
6641         (mult:DI
6642           (match_operand:DI 2 "nonimmediate_operand" "%d")
6643           (match_operand:DI 3 "nonimmediate_operand" "rm")))
6644    (set (match_operand:DI 1 "register_operand" "=r")
6645         (truncate:DI
6646           (lshiftrt:TI
6647             (mult:TI (zero_extend:TI (match_dup 2))
6648                      (zero_extend:TI (match_dup 3)))
6649             (const_int 64))))]
6650   "TARGET_64BIT && TARGET_BMI2
6651    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6652   "mulx\t{%3, %0, %1|%1, %0, %3}"
6653   [(set_attr "type" "imulx")
6654    (set_attr "prefix" "vex")
6655    (set_attr "mode" "DI")])
6657 (define_insn "*bmi2_umulsidi3_1"
6658   [(set (match_operand:SI 0 "register_operand" "=r")
6659         (mult:SI
6660           (match_operand:SI 2 "nonimmediate_operand" "%d")
6661           (match_operand:SI 3 "nonimmediate_operand" "rm")))
6662    (set (match_operand:SI 1 "register_operand" "=r")
6663         (truncate:SI
6664           (lshiftrt:DI
6665             (mult:DI (zero_extend:DI (match_dup 2))
6666                      (zero_extend:DI (match_dup 3)))
6667             (const_int 32))))]
6668   "!TARGET_64BIT && TARGET_BMI2
6669    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6670   "mulx\t{%3, %0, %1|%1, %0, %3}"
6671   [(set_attr "type" "imulx")
6672    (set_attr "prefix" "vex")
6673    (set_attr "mode" "SI")])
6675 (define_insn "*umul<mode><dwi>3_1"
6676   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6677         (mult:<DWI>
6678           (zero_extend:<DWI>
6679             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6680           (zero_extend:<DWI>
6681             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6682    (clobber (reg:CC FLAGS_REG))]
6683   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6684   "@
6685    #
6686    mul{<imodesuffix>}\t%2"
6687   [(set_attr "isa" "bmi2,*")
6688    (set_attr "type" "imulx,imul")
6689    (set_attr "length_immediate" "*,0")
6690    (set (attr "athlon_decode")
6691         (cond [(eq_attr "alternative" "1")
6692                  (if_then_else (eq_attr "cpu" "athlon")
6693                    (const_string "vector")
6694                    (const_string "double"))]
6695               (const_string "*")))
6696    (set_attr "amdfam10_decode" "*,double")
6697    (set_attr "bdver1_decode" "*,direct")
6698    (set_attr "prefix" "vex,orig")
6699    (set_attr "mode" "<MODE>")])
6701 ;; Convert mul to the mulx pattern to avoid flags dependency.
6702 (define_split
6703  [(set (match_operand:<DWI> 0 "register_operand")
6704        (mult:<DWI>
6705          (zero_extend:<DWI>
6706            (match_operand:DWIH 1 "register_operand"))
6707          (zero_extend:<DWI>
6708            (match_operand:DWIH 2 "nonimmediate_operand"))))
6709   (clobber (reg:CC FLAGS_REG))]
6710  "TARGET_BMI2 && reload_completed
6711   && true_regnum (operands[1]) == DX_REG"
6712   [(parallel [(set (match_dup 3)
6713                    (mult:DWIH (match_dup 1) (match_dup 2)))
6714               (set (match_dup 4)
6715                    (truncate:DWIH
6716                      (lshiftrt:<DWI>
6717                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6718                                    (zero_extend:<DWI> (match_dup 2)))
6719                        (match_dup 5))))])]
6721   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6723   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6726 (define_insn "*mul<mode><dwi>3_1"
6727   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6728         (mult:<DWI>
6729           (sign_extend:<DWI>
6730             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6731           (sign_extend:<DWI>
6732             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6733    (clobber (reg:CC FLAGS_REG))]
6734   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6735   "imul{<imodesuffix>}\t%2"
6736   [(set_attr "type" "imul")
6737    (set_attr "length_immediate" "0")
6738    (set (attr "athlon_decode")
6739      (if_then_else (eq_attr "cpu" "athlon")
6740         (const_string "vector")
6741         (const_string "double")))
6742    (set_attr "amdfam10_decode" "double")
6743    (set_attr "bdver1_decode" "direct")
6744    (set_attr "mode" "<MODE>")])
6746 (define_insn "*<u>mulqihi3_1"
6747   [(set (match_operand:HI 0 "register_operand" "=a")
6748         (mult:HI
6749           (any_extend:HI
6750             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6751           (any_extend:HI
6752             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6753    (clobber (reg:CC FLAGS_REG))]
6754   "TARGET_QIMODE_MATH
6755    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6756   "<sgnprefix>mul{b}\t%2"
6757   [(set_attr "type" "imul")
6758    (set_attr "length_immediate" "0")
6759    (set (attr "athlon_decode")
6760      (if_then_else (eq_attr "cpu" "athlon")
6761         (const_string "vector")
6762         (const_string "direct")))
6763    (set_attr "amdfam10_decode" "direct")
6764    (set_attr "bdver1_decode" "direct")
6765    (set_attr "mode" "QI")])
6767 (define_expand "<s>mul<mode>3_highpart"
6768   [(parallel [(set (match_operand:SWI48 0 "register_operand")
6769                    (truncate:SWI48
6770                      (lshiftrt:<DWI>
6771                        (mult:<DWI>
6772                          (any_extend:<DWI>
6773                            (match_operand:SWI48 1 "nonimmediate_operand"))
6774                          (any_extend:<DWI>
6775                            (match_operand:SWI48 2 "register_operand")))
6776                        (match_dup 4))))
6777               (clobber (match_scratch:SWI48 3))
6778               (clobber (reg:CC FLAGS_REG))])]
6779   ""
6780   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6782 (define_insn "*<s>muldi3_highpart_1"
6783   [(set (match_operand:DI 0 "register_operand" "=d")
6784         (truncate:DI
6785           (lshiftrt:TI
6786             (mult:TI
6787               (any_extend:TI
6788                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6789               (any_extend:TI
6790                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6791             (const_int 64))))
6792    (clobber (match_scratch:DI 3 "=1"))
6793    (clobber (reg:CC FLAGS_REG))]
6794   "TARGET_64BIT
6795    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6796   "<sgnprefix>mul{q}\t%2"
6797   [(set_attr "type" "imul")
6798    (set_attr "length_immediate" "0")
6799    (set (attr "athlon_decode")
6800      (if_then_else (eq_attr "cpu" "athlon")
6801         (const_string "vector")
6802         (const_string "double")))
6803    (set_attr "amdfam10_decode" "double")
6804    (set_attr "bdver1_decode" "direct")
6805    (set_attr "mode" "DI")])
6807 (define_insn "*<s>mulsi3_highpart_1"
6808   [(set (match_operand:SI 0 "register_operand" "=d")
6809         (truncate:SI
6810           (lshiftrt:DI
6811             (mult:DI
6812               (any_extend:DI
6813                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6814               (any_extend:DI
6815                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6816             (const_int 32))))
6817    (clobber (match_scratch:SI 3 "=1"))
6818    (clobber (reg:CC FLAGS_REG))]
6819   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6820   "<sgnprefix>mul{l}\t%2"
6821   [(set_attr "type" "imul")
6822    (set_attr "length_immediate" "0")
6823    (set (attr "athlon_decode")
6824      (if_then_else (eq_attr "cpu" "athlon")
6825         (const_string "vector")
6826         (const_string "double")))
6827    (set_attr "amdfam10_decode" "double")
6828    (set_attr "bdver1_decode" "direct")
6829    (set_attr "mode" "SI")])
6831 (define_insn "*<s>mulsi3_highpart_zext"
6832   [(set (match_operand:DI 0 "register_operand" "=d")
6833         (zero_extend:DI (truncate:SI
6834           (lshiftrt:DI
6835             (mult:DI (any_extend:DI
6836                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6837                      (any_extend:DI
6838                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6839             (const_int 32)))))
6840    (clobber (match_scratch:SI 3 "=1"))
6841    (clobber (reg:CC FLAGS_REG))]
6842   "TARGET_64BIT
6843    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6844   "<sgnprefix>mul{l}\t%2"
6845   [(set_attr "type" "imul")
6846    (set_attr "length_immediate" "0")
6847    (set (attr "athlon_decode")
6848      (if_then_else (eq_attr "cpu" "athlon")
6849         (const_string "vector")
6850         (const_string "double")))
6851    (set_attr "amdfam10_decode" "double")
6852    (set_attr "bdver1_decode" "direct")
6853    (set_attr "mode" "SI")])
6855 ;; The patterns that match these are at the end of this file.
6857 (define_expand "mulxf3"
6858   [(set (match_operand:XF 0 "register_operand")
6859         (mult:XF (match_operand:XF 1 "register_operand")
6860                  (match_operand:XF 2 "register_operand")))]
6861   "TARGET_80387")
6863 (define_expand "mul<mode>3"
6864   [(set (match_operand:MODEF 0 "register_operand")
6865         (mult:MODEF (match_operand:MODEF 1 "register_operand")
6866                     (match_operand:MODEF 2 "nonimmediate_operand")))]
6867   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6868     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6870 ;; Divide instructions
6872 ;; The patterns that match these are at the end of this file.
6874 (define_expand "divxf3"
6875   [(set (match_operand:XF 0 "register_operand")
6876         (div:XF (match_operand:XF 1 "register_operand")
6877                 (match_operand:XF 2 "register_operand")))]
6878   "TARGET_80387")
6880 (define_expand "divdf3"
6881   [(set (match_operand:DF 0 "register_operand")
6882         (div:DF (match_operand:DF 1 "register_operand")
6883                 (match_operand:DF 2 "nonimmediate_operand")))]
6884    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6885     || (TARGET_SSE2 && TARGET_SSE_MATH)")
6887 (define_expand "divsf3"
6888   [(set (match_operand:SF 0 "register_operand")
6889         (div:SF (match_operand:SF 1 "register_operand")
6890                 (match_operand:SF 2 "nonimmediate_operand")))]
6891   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6892     || TARGET_SSE_MATH"
6894   if (TARGET_SSE_MATH
6895       && TARGET_RECIP_DIV
6896       && optimize_insn_for_speed_p ()
6897       && flag_finite_math_only && !flag_trapping_math
6898       && flag_unsafe_math_optimizations)
6899     {
6900       ix86_emit_swdivsf (operands[0], operands[1],
6901                          operands[2], SFmode);
6902       DONE;
6903     }
6906 ;; Divmod instructions.
6908 (define_expand "divmod<mode>4"
6909   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6910                    (div:SWIM248
6911                      (match_operand:SWIM248 1 "register_operand")
6912                      (match_operand:SWIM248 2 "nonimmediate_operand")))
6913               (set (match_operand:SWIM248 3 "register_operand")
6914                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
6915               (clobber (reg:CC FLAGS_REG))])])
6917 ;; Split with 8bit unsigned divide:
6918 ;;      if (dividend an divisor are in [0-255])
6919 ;;         use 8bit unsigned integer divide
6920 ;;       else
6921 ;;         use original integer divide
6922 (define_split
6923   [(set (match_operand:SWI48 0 "register_operand")
6924         (div:SWI48 (match_operand:SWI48 2 "register_operand")
6925                     (match_operand:SWI48 3 "nonimmediate_operand")))
6926    (set (match_operand:SWI48 1 "register_operand")
6927         (mod:SWI48 (match_dup 2) (match_dup 3)))
6928    (clobber (reg:CC FLAGS_REG))]
6929   "TARGET_USE_8BIT_IDIV
6930    && TARGET_QIMODE_MATH
6931    && can_create_pseudo_p ()
6932    && !optimize_insn_for_size_p ()"
6933   [(const_int 0)]
6934   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
6936 (define_insn_and_split "divmod<mode>4_1"
6937   [(set (match_operand:SWI48 0 "register_operand" "=a")
6938         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6939                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6940    (set (match_operand:SWI48 1 "register_operand" "=&d")
6941         (mod:SWI48 (match_dup 2) (match_dup 3)))
6942    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6943    (clobber (reg:CC FLAGS_REG))]
6944   ""
6945   "#"
6946   "reload_completed"
6947   [(parallel [(set (match_dup 1)
6948                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
6949               (clobber (reg:CC FLAGS_REG))])
6950    (parallel [(set (match_dup 0)
6951                    (div:SWI48 (match_dup 2) (match_dup 3)))
6952               (set (match_dup 1)
6953                    (mod:SWI48 (match_dup 2) (match_dup 3)))
6954               (use (match_dup 1))
6955               (clobber (reg:CC FLAGS_REG))])]
6957   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6959   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
6960     operands[4] = operands[2];
6961   else
6962     {
6963       /* Avoid use of cltd in favor of a mov+shift.  */
6964       emit_move_insn (operands[1], operands[2]);
6965       operands[4] = operands[1];
6966     }
6968   [(set_attr "type" "multi")
6969    (set_attr "mode" "<MODE>")])
6971 (define_insn_and_split "*divmod<mode>4"
6972   [(set (match_operand:SWIM248 0 "register_operand" "=a")
6973         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6974                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6975    (set (match_operand:SWIM248 1 "register_operand" "=&d")
6976         (mod:SWIM248 (match_dup 2) (match_dup 3)))
6977    (clobber (reg:CC FLAGS_REG))]
6978   ""
6979   "#"
6980   "reload_completed"
6981   [(parallel [(set (match_dup 1)
6982                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
6983               (clobber (reg:CC FLAGS_REG))])
6984    (parallel [(set (match_dup 0)
6985                    (div:SWIM248 (match_dup 2) (match_dup 3)))
6986               (set (match_dup 1)
6987                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
6988               (use (match_dup 1))
6989               (clobber (reg:CC FLAGS_REG))])]
6991   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6993   if (<MODE>mode != HImode
6994       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
6995     operands[4] = operands[2];
6996   else
6997     {
6998       /* Avoid use of cltd in favor of a mov+shift.  */
6999       emit_move_insn (operands[1], operands[2]);
7000       operands[4] = operands[1];
7001     }
7003   [(set_attr "type" "multi")
7004    (set_attr "mode" "<MODE>")])
7006 (define_insn "*divmod<mode>4_noext"
7007   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7008         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7009                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7010    (set (match_operand:SWIM248 1 "register_operand" "=d")
7011         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7012    (use (match_operand:SWIM248 4 "register_operand" "1"))
7013    (clobber (reg:CC FLAGS_REG))]
7014   ""
7015   "idiv{<imodesuffix>}\t%3"
7016   [(set_attr "type" "idiv")
7017    (set_attr "mode" "<MODE>")])
7019 (define_expand "divmodqi4"
7020   [(parallel [(set (match_operand:QI 0 "register_operand")
7021                    (div:QI
7022                      (match_operand:QI 1 "register_operand")
7023                      (match_operand:QI 2 "nonimmediate_operand")))
7024               (set (match_operand:QI 3 "register_operand")
7025                    (mod:QI (match_dup 1) (match_dup 2)))
7026               (clobber (reg:CC FLAGS_REG))])]
7027   "TARGET_QIMODE_MATH"
7029   rtx div, mod, insn;
7030   rtx tmp0, tmp1;
7031   
7032   tmp0 = gen_reg_rtx (HImode);
7033   tmp1 = gen_reg_rtx (HImode);
7035   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7036      in AX.  */
7037   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7038   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7040   /* Extract remainder from AH.  */
7041   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7042   insn = emit_move_insn (operands[3], tmp1);
7044   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7045   set_unique_reg_note (insn, REG_EQUAL, mod);
7047   /* Extract quotient from AL.  */
7048   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7050   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7051   set_unique_reg_note (insn, REG_EQUAL, div);
7053   DONE;
7056 ;; Divide AX by r/m8, with result stored in
7057 ;; AL <- Quotient
7058 ;; AH <- Remainder
7059 ;; Change div/mod to HImode and extend the second argument to HImode
7060 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7061 ;; combine may fail.
7062 (define_insn "divmodhiqi3"
7063   [(set (match_operand:HI 0 "register_operand" "=a")
7064         (ior:HI
7065           (ashift:HI
7066             (zero_extend:HI
7067               (truncate:QI
7068                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7069                         (sign_extend:HI
7070                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7071             (const_int 8))
7072           (zero_extend:HI
7073             (truncate:QI
7074               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7075    (clobber (reg:CC FLAGS_REG))]
7076   "TARGET_QIMODE_MATH"
7077   "idiv{b}\t%2"
7078   [(set_attr "type" "idiv")
7079    (set_attr "mode" "QI")])
7081 (define_expand "udivmod<mode>4"
7082   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7083                    (udiv:SWIM248
7084                      (match_operand:SWIM248 1 "register_operand")
7085                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7086               (set (match_operand:SWIM248 3 "register_operand")
7087                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7088               (clobber (reg:CC FLAGS_REG))])])
7090 ;; Split with 8bit unsigned divide:
7091 ;;      if (dividend an divisor are in [0-255])
7092 ;;         use 8bit unsigned integer divide
7093 ;;       else
7094 ;;         use original integer divide
7095 (define_split
7096   [(set (match_operand:SWI48 0 "register_operand")
7097         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7098                     (match_operand:SWI48 3 "nonimmediate_operand")))
7099    (set (match_operand:SWI48 1 "register_operand")
7100         (umod:SWI48 (match_dup 2) (match_dup 3)))
7101    (clobber (reg:CC FLAGS_REG))]
7102   "TARGET_USE_8BIT_IDIV
7103    && TARGET_QIMODE_MATH
7104    && can_create_pseudo_p ()
7105    && !optimize_insn_for_size_p ()"
7106   [(const_int 0)]
7107   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7109 (define_insn_and_split "udivmod<mode>4_1"
7110   [(set (match_operand:SWI48 0 "register_operand" "=a")
7111         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7112                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7113    (set (match_operand:SWI48 1 "register_operand" "=&d")
7114         (umod:SWI48 (match_dup 2) (match_dup 3)))
7115    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7116    (clobber (reg:CC FLAGS_REG))]
7117   ""
7118   "#"
7119   "reload_completed"
7120   [(set (match_dup 1) (const_int 0))
7121    (parallel [(set (match_dup 0)
7122                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7123               (set (match_dup 1)
7124                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7125               (use (match_dup 1))
7126               (clobber (reg:CC FLAGS_REG))])]
7127   ""
7128   [(set_attr "type" "multi")
7129    (set_attr "mode" "<MODE>")])
7131 (define_insn_and_split "*udivmod<mode>4"
7132   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7133         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7134                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7135    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7136         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7137    (clobber (reg:CC FLAGS_REG))]
7138   ""
7139   "#"
7140   "reload_completed"
7141   [(set (match_dup 1) (const_int 0))
7142    (parallel [(set (match_dup 0)
7143                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7144               (set (match_dup 1)
7145                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7146               (use (match_dup 1))
7147               (clobber (reg:CC FLAGS_REG))])]
7148   ""
7149   [(set_attr "type" "multi")
7150    (set_attr "mode" "<MODE>")])
7152 (define_insn "*udivmod<mode>4_noext"
7153   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7154         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7155                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7156    (set (match_operand:SWIM248 1 "register_operand" "=d")
7157         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7158    (use (match_operand:SWIM248 4 "register_operand" "1"))
7159    (clobber (reg:CC FLAGS_REG))]
7160   ""
7161   "div{<imodesuffix>}\t%3"
7162   [(set_attr "type" "idiv")
7163    (set_attr "mode" "<MODE>")])
7165 (define_expand "udivmodqi4"
7166   [(parallel [(set (match_operand:QI 0 "register_operand")
7167                    (udiv:QI
7168                      (match_operand:QI 1 "register_operand")
7169                      (match_operand:QI 2 "nonimmediate_operand")))
7170               (set (match_operand:QI 3 "register_operand")
7171                    (umod:QI (match_dup 1) (match_dup 2)))
7172               (clobber (reg:CC FLAGS_REG))])]
7173   "TARGET_QIMODE_MATH"
7175   rtx div, mod, insn;
7176   rtx tmp0, tmp1;
7177   
7178   tmp0 = gen_reg_rtx (HImode);
7179   tmp1 = gen_reg_rtx (HImode);
7181   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7182      in AX.  */
7183   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7184   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7186   /* Extract remainder from AH.  */
7187   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7188   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7189   insn = emit_move_insn (operands[3], tmp1);
7191   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7192   set_unique_reg_note (insn, REG_EQUAL, mod);
7194   /* Extract quotient from AL.  */
7195   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7197   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7198   set_unique_reg_note (insn, REG_EQUAL, div);
7200   DONE;
7203 (define_insn "udivmodhiqi3"
7204   [(set (match_operand:HI 0 "register_operand" "=a")
7205         (ior:HI
7206           (ashift:HI
7207             (zero_extend:HI
7208               (truncate:QI
7209                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7210                         (zero_extend:HI
7211                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7212             (const_int 8))
7213           (zero_extend:HI
7214             (truncate:QI
7215               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7216    (clobber (reg:CC FLAGS_REG))]
7217   "TARGET_QIMODE_MATH"
7218   "div{b}\t%2"
7219   [(set_attr "type" "idiv")
7220    (set_attr "mode" "QI")])
7222 ;; We cannot use div/idiv for double division, because it causes
7223 ;; "division by zero" on the overflow and that's not what we expect
7224 ;; from truncate.  Because true (non truncating) double division is
7225 ;; never generated, we can't create this insn anyway.
7227 ;(define_insn ""
7228 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7229 ;       (truncate:SI
7230 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7231 ;                  (zero_extend:DI
7232 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7233 ;   (set (match_operand:SI 3 "register_operand" "=d")
7234 ;       (truncate:SI
7235 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7236 ;   (clobber (reg:CC FLAGS_REG))]
7237 ;  ""
7238 ;  "div{l}\t{%2, %0|%0, %2}"
7239 ;  [(set_attr "type" "idiv")])
7241 ;;- Logical AND instructions
7243 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7244 ;; Note that this excludes ah.
7246 (define_expand "testsi_ccno_1"
7247   [(set (reg:CCNO FLAGS_REG)
7248         (compare:CCNO
7249           (and:SI (match_operand:SI 0 "nonimmediate_operand")
7250                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
7251           (const_int 0)))])
7253 (define_expand "testqi_ccz_1"
7254   [(set (reg:CCZ FLAGS_REG)
7255         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7256                              (match_operand:QI 1 "nonmemory_operand"))
7257                  (const_int 0)))])
7259 (define_expand "testdi_ccno_1"
7260   [(set (reg:CCNO FLAGS_REG)
7261         (compare:CCNO
7262           (and:DI (match_operand:DI 0 "nonimmediate_operand")
7263                   (match_operand:DI 1 "x86_64_szext_general_operand"))
7264           (const_int 0)))]
7265   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7267 (define_insn "*testdi_1"
7268   [(set (reg FLAGS_REG)
7269         (compare
7270          (and:DI
7271           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7272           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7273          (const_int 0)))]
7274   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7275    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7276   "@
7277    test{l}\t{%k1, %k0|%k0, %k1}
7278    test{l}\t{%k1, %k0|%k0, %k1}
7279    test{q}\t{%1, %0|%0, %1}
7280    test{q}\t{%1, %0|%0, %1}
7281    test{q}\t{%1, %0|%0, %1}"
7282   [(set_attr "type" "test")
7283    (set_attr "modrm" "0,1,0,1,1")
7284    (set_attr "mode" "SI,SI,DI,DI,DI")])
7286 (define_insn "*testqi_1_maybe_si"
7287   [(set (reg FLAGS_REG)
7288         (compare
7289           (and:QI
7290             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7291             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7292           (const_int 0)))]
7293    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7294     && ix86_match_ccmode (insn,
7295                          CONST_INT_P (operands[1])
7296                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7298   if (which_alternative == 3)
7299     {
7300       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7301         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7302       return "test{l}\t{%1, %k0|%k0, %1}";
7303     }
7304   return "test{b}\t{%1, %0|%0, %1}";
7306   [(set_attr "type" "test")
7307    (set_attr "modrm" "0,1,1,1")
7308    (set_attr "mode" "QI,QI,QI,SI")
7309    (set_attr "pent_pair" "uv,np,uv,np")])
7311 (define_insn "*test<mode>_1"
7312   [(set (reg FLAGS_REG)
7313         (compare
7314          (and:SWI124
7315           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7316           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7317          (const_int 0)))]
7318   "ix86_match_ccmode (insn, CCNOmode)
7319    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7320   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7321   [(set_attr "type" "test")
7322    (set_attr "modrm" "0,1,1")
7323    (set_attr "mode" "<MODE>")
7324    (set_attr "pent_pair" "uv,np,uv")])
7326 (define_expand "testqi_ext_ccno_0"
7327   [(set (reg:CCNO FLAGS_REG)
7328         (compare:CCNO
7329           (and:SI
7330             (zero_extract:SI
7331               (match_operand 0 "ext_register_operand")
7332               (const_int 8)
7333               (const_int 8))
7334             (match_operand 1 "const_int_operand"))
7335           (const_int 0)))])
7337 (define_insn "*testqi_ext_0"
7338   [(set (reg FLAGS_REG)
7339         (compare
7340           (and:SI
7341             (zero_extract:SI
7342               (match_operand 0 "ext_register_operand" "Q")
7343               (const_int 8)
7344               (const_int 8))
7345             (match_operand 1 "const_int_operand" "n"))
7346           (const_int 0)))]
7347   "ix86_match_ccmode (insn, CCNOmode)"
7348   "test{b}\t{%1, %h0|%h0, %1}"
7349   [(set_attr "type" "test")
7350    (set_attr "mode" "QI")
7351    (set_attr "length_immediate" "1")
7352    (set_attr "modrm" "1")
7353    (set_attr "pent_pair" "np")])
7355 (define_insn "*testqi_ext_1"
7356   [(set (reg FLAGS_REG)
7357         (compare
7358           (and:SI
7359             (zero_extract:SI
7360               (match_operand 0 "ext_register_operand" "Q,Q")
7361               (const_int 8)
7362               (const_int 8))
7363             (zero_extend:SI
7364               (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7365           (const_int 0)))]
7366   "ix86_match_ccmode (insn, CCNOmode)"
7367   "test{b}\t{%1, %h0|%h0, %1}"
7368   [(set_attr "isa" "*,nox64")
7369    (set_attr "type" "test")
7370    (set_attr "mode" "QI")])
7372 (define_insn "*testqi_ext_2"
7373   [(set (reg FLAGS_REG)
7374         (compare
7375           (and:SI
7376             (zero_extract:SI
7377               (match_operand 0 "ext_register_operand" "Q")
7378               (const_int 8)
7379               (const_int 8))
7380             (zero_extract:SI
7381               (match_operand 1 "ext_register_operand" "Q")
7382               (const_int 8)
7383               (const_int 8)))
7384           (const_int 0)))]
7385   "ix86_match_ccmode (insn, CCNOmode)"
7386   "test{b}\t{%h1, %h0|%h0, %h1}"
7387   [(set_attr "type" "test")
7388    (set_attr "mode" "QI")])
7390 ;; Combine likes to form bit extractions for some tests.  Humor it.
7391 (define_insn "*testqi_ext_3"
7392   [(set (reg FLAGS_REG)
7393         (compare (zero_extract:SWI48
7394                    (match_operand 0 "nonimmediate_operand" "rm")
7395                    (match_operand:SWI48 1 "const_int_operand")
7396                    (match_operand:SWI48 2 "const_int_operand"))
7397                  (const_int 0)))]
7398   "ix86_match_ccmode (insn, CCNOmode)
7399    && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7400        || GET_MODE (operands[0]) == SImode
7401        || GET_MODE (operands[0]) == HImode
7402        || GET_MODE (operands[0]) == QImode)
7403    /* Ensure that resulting mask is zero or sign extended operand.  */
7404    && INTVAL (operands[2]) >= 0
7405    && ((INTVAL (operands[1]) > 0
7406         && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7407        || (<MODE>mode == DImode
7408            && INTVAL (operands[1]) > 32
7409            && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7410   "#")
7412 (define_split
7413   [(set (match_operand 0 "flags_reg_operand")
7414         (match_operator 1 "compare_operator"
7415           [(zero_extract
7416              (match_operand 2 "nonimmediate_operand")
7417              (match_operand 3 "const_int_operand")
7418              (match_operand 4 "const_int_operand"))
7419            (const_int 0)]))]
7420   "ix86_match_ccmode (insn, CCNOmode)"
7421   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7423   rtx val = operands[2];
7424   HOST_WIDE_INT len = INTVAL (operands[3]);
7425   HOST_WIDE_INT pos = INTVAL (operands[4]);
7426   HOST_WIDE_INT mask;
7427   enum machine_mode mode, submode;
7429   mode = GET_MODE (val);
7430   if (MEM_P (val))
7431     {
7432       /* ??? Combine likes to put non-volatile mem extractions in QImode
7433          no matter the size of the test.  So find a mode that works.  */
7434       if (! MEM_VOLATILE_P (val))
7435         {
7436           mode = smallest_mode_for_size (pos + len, MODE_INT);
7437           val = adjust_address (val, mode, 0);
7438         }
7439     }
7440   else if (GET_CODE (val) == SUBREG
7441            && (submode = GET_MODE (SUBREG_REG (val)),
7442                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7443            && pos + len <= GET_MODE_BITSIZE (submode)
7444            && GET_MODE_CLASS (submode) == MODE_INT)
7445     {
7446       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7447       mode = submode;
7448       val = SUBREG_REG (val);
7449     }
7450   else if (mode == HImode && pos + len <= 8)
7451     {
7452       /* Small HImode tests can be converted to QImode.  */
7453       mode = QImode;
7454       val = gen_lowpart (QImode, val);
7455     }
7457   if (len == HOST_BITS_PER_WIDE_INT)
7458     mask = -1;
7459   else
7460     mask = ((HOST_WIDE_INT)1 << len) - 1;
7461   mask <<= pos;
7463   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7466 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7467 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7468 ;; this is relatively important trick.
7469 ;; Do the conversion only post-reload to avoid limiting of the register class
7470 ;; to QI regs.
7471 (define_split
7472   [(set (match_operand 0 "flags_reg_operand")
7473         (match_operator 1 "compare_operator"
7474           [(and (match_operand 2 "register_operand")
7475                 (match_operand 3 "const_int_operand"))
7476            (const_int 0)]))]
7477    "reload_completed
7478     && QI_REG_P (operands[2])
7479     && GET_MODE (operands[2]) != QImode
7480     && ((ix86_match_ccmode (insn, CCZmode)
7481          && !(INTVAL (operands[3]) & ~(255 << 8)))
7482         || (ix86_match_ccmode (insn, CCNOmode)
7483             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7484   [(set (match_dup 0)
7485         (match_op_dup 1
7486           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7487                    (match_dup 3))
7488            (const_int 0)]))]
7490   operands[2] = gen_lowpart (SImode, operands[2]);
7491   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7494 (define_split
7495   [(set (match_operand 0 "flags_reg_operand")
7496         (match_operator 1 "compare_operator"
7497           [(and (match_operand 2 "nonimmediate_operand")
7498                 (match_operand 3 "const_int_operand"))
7499            (const_int 0)]))]
7500    "reload_completed
7501     && GET_MODE (operands[2]) != QImode
7502     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7503     && ((ix86_match_ccmode (insn, CCZmode)
7504          && !(INTVAL (operands[3]) & ~255))
7505         || (ix86_match_ccmode (insn, CCNOmode)
7506             && !(INTVAL (operands[3]) & ~127)))"
7507   [(set (match_dup 0)
7508         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7509                          (const_int 0)]))]
7511   operands[2] = gen_lowpart (QImode, operands[2]);
7512   operands[3] = gen_lowpart (QImode, operands[3]);
7515 (define_split
7516   [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7517         (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7518                             (match_operand:SWI1248x 2 "mask_reg_operand")))
7519    (clobber (reg:CC FLAGS_REG))]
7520   "TARGET_AVX512F && reload_completed"
7521   [(set (match_dup 0)
7522         (any_logic:SWI1248x (match_dup 1)
7523                             (match_dup 2)))])
7525 ;; TODO: It seems to be possible to macroize following
7526 ;; 3 patterns.
7527 (define_insn "*k<logic>qi"
7528   [(set (match_operand:QI 0 "mask_reg_operand" "=k")
7529         (any_logic:QI (match_operand:QI 1 "mask_reg_operand" "k")
7530                       (match_operand:QI 2 "mask_reg_operand" "k")))]
7531   "TARGET_AVX512F"
7533   return TARGET_AVX512DQ ? "k<logic>b\t{%2, %1, %0|%0, %1, %2}"
7534                          : "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7536   [(set_attr "mode" "QI")
7537    (set_attr "type" "msklog")
7538    (set_attr "prefix" "vex")])
7540 (define_insn "*k<logic>hi"
7541   [(set (match_operand:HI 0 "mask_reg_operand" "=k")
7542         (any_logic:HI (match_operand:HI 1 "mask_reg_operand" "k")
7543                       (match_operand:HI 2 "mask_reg_operand" "k")))]
7544   "TARGET_AVX512F"
7545   "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7546   [(set_attr "mode" "HI")
7547    (set_attr "type" "msklog")
7548    (set_attr "prefix" "vex")])
7550 (define_insn "*k<logic><mode>"
7551   [(set (match_operand:SWI48x 0 "mask_reg_operand" "=k")
7552         (any_logic:SWI48x (match_operand:SWI48x 1 "mask_reg_operand" "k")
7553                           (match_operand:SWI48x 2 "mask_reg_operand" "k")))]
7554   "TARGET_AVX512BW"
7555   "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7556   [(set_attr "mode" "<MODE>")
7557    (set_attr "type" "msklog")
7558    (set_attr "prefix" "vex")])
7560 ;; %%% This used to optimize known byte-wide and operations to memory,
7561 ;; and sometimes to QImode registers.  If this is considered useful,
7562 ;; it should be done with splitters.
7564 (define_expand "and<mode>3"
7565   [(set (match_operand:SWIM 0 "nonimmediate_operand")
7566         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7567                   (match_operand:SWIM 2 "<general_szext_operand>")))]
7568   ""
7570   enum machine_mode mode = <MODE>mode;
7571   rtx (*insn) (rtx, rtx);
7573   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7574     {
7575       HOST_WIDE_INT ival = INTVAL (operands[2]);
7577       if (ival == (HOST_WIDE_INT) 0xffffffff)
7578         mode = SImode;
7579       else if (ival == 0xffff)
7580         mode = HImode;
7581       else if (ival == 0xff)
7582         mode = QImode;
7583       }
7585   if (mode == <MODE>mode)
7586     {
7587       ix86_expand_binary_operator (AND, <MODE>mode, operands);
7588       DONE;
7589     }
7591   if (<MODE>mode == DImode)
7592     insn = (mode == SImode)
7593            ? gen_zero_extendsidi2
7594            : (mode == HImode)
7595            ? gen_zero_extendhidi2
7596            : gen_zero_extendqidi2;
7597   else if (<MODE>mode == SImode)
7598     insn = (mode == HImode)
7599            ? gen_zero_extendhisi2
7600            : gen_zero_extendqisi2;
7601   else if (<MODE>mode == HImode)
7602     insn = gen_zero_extendqihi2;
7603   else
7604     gcc_unreachable ();
7606   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7607   DONE;
7610 (define_insn "*anddi_1"
7611   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7612         (and:DI
7613          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7614          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7615    (clobber (reg:CC FLAGS_REG))]
7616   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7618   switch (get_attr_type (insn))
7619     {
7620     case TYPE_IMOVX:
7621       return "#";
7623     case TYPE_MSKLOG:
7624       return "kandq\t{%2, %1, %0|%0, %1, %2}";
7626     default:
7627       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7628       if (get_attr_mode (insn) == MODE_SI)
7629         return "and{l}\t{%k2, %k0|%k0, %k2}";
7630       else
7631         return "and{q}\t{%2, %0|%0, %2}";
7632     }
7634   [(set_attr "type" "alu,alu,alu,imovx,msklog")
7635    (set_attr "length_immediate" "*,*,*,0,0")
7636    (set (attr "prefix_rex")
7637      (if_then_else
7638        (and (eq_attr "type" "imovx")
7639             (and (match_test "INTVAL (operands[2]) == 0xff")
7640                  (match_operand 1 "ext_QIreg_operand")))
7641        (const_string "1")
7642        (const_string "*")))
7643    (set_attr "mode" "SI,DI,DI,SI,DI")])
7645 (define_insn "*andsi_1"
7646   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7647         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7648                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7649    (clobber (reg:CC FLAGS_REG))]
7650   "ix86_binary_operator_ok (AND, SImode, operands)"
7652   switch (get_attr_type (insn))
7653     {
7654     case TYPE_IMOVX:
7655       return "#";
7657     case TYPE_MSKLOG:
7658       return "kandd\t{%2, %1, %0|%0, %1, %2}";
7660     default:
7661       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7662       return "and{l}\t{%2, %0|%0, %2}";
7663     }
7665   [(set_attr "type" "alu,alu,imovx,msklog")
7666    (set (attr "prefix_rex")
7667      (if_then_else
7668        (and (eq_attr "type" "imovx")
7669             (and (match_test "INTVAL (operands[2]) == 0xff")
7670                  (match_operand 1 "ext_QIreg_operand")))
7671        (const_string "1")
7672        (const_string "*")))
7673    (set_attr "length_immediate" "*,*,0,0")
7674    (set_attr "mode" "SI")])
7676 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7677 (define_insn "*andsi_1_zext"
7678   [(set (match_operand:DI 0 "register_operand" "=r")
7679         (zero_extend:DI
7680           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7681                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7682    (clobber (reg:CC FLAGS_REG))]
7683   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7684   "and{l}\t{%2, %k0|%k0, %2}"
7685   [(set_attr "type" "alu")
7686    (set_attr "mode" "SI")])
7688 (define_insn "*andhi_1"
7689   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7690         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7691                 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7692    (clobber (reg:CC FLAGS_REG))]
7693   "ix86_binary_operator_ok (AND, HImode, operands)"
7695   switch (get_attr_type (insn))
7696     {
7697     case TYPE_IMOVX:
7698       return "#";
7700     case TYPE_MSKLOG:
7701       return "kandw\t{%2, %1, %0|%0, %1, %2}";
7703     default:
7704       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7705       return "and{w}\t{%2, %0|%0, %2}";
7706     }
7708   [(set_attr "type" "alu,alu,imovx,msklog")
7709    (set_attr "length_immediate" "*,*,0,*")
7710    (set (attr "prefix_rex")
7711      (if_then_else
7712        (and (eq_attr "type" "imovx")
7713             (match_operand 1 "ext_QIreg_operand"))
7714        (const_string "1")
7715        (const_string "*")))
7716    (set_attr "mode" "HI,HI,SI,HI")])
7718 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7719 (define_insn "*andqi_1"
7720   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7721         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7722                 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7723    (clobber (reg:CC FLAGS_REG))]
7724   "ix86_binary_operator_ok (AND, QImode, operands)"
7726   switch (which_alternative)
7727     {
7728     case 0:
7729     case 1:
7730       return "and{b}\t{%2, %0|%0, %2}";
7731     case 2:
7732       return "and{l}\t{%k2, %k0|%k0, %k2}";
7733     case 3:
7734       return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7735                              : "kandw\t{%2, %1, %0|%0, %1, %2}";
7736     default:
7737       gcc_unreachable ();
7738     }
7740   [(set_attr "type" "alu,alu,alu,msklog")
7741    (set_attr "mode" "QI,QI,SI,HI")])
7743 (define_insn "*andqi_1_slp"
7744   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7745         (and:QI (match_dup 0)
7746                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7747    (clobber (reg:CC FLAGS_REG))]
7748   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7749    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7750   "and{b}\t{%1, %0|%0, %1}"
7751   [(set_attr "type" "alu1")
7752    (set_attr "mode" "QI")])
7754 (define_insn "kandn<mode>"
7755   [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7756         (and:SWI12
7757           (not:SWI12
7758             (match_operand:SWI12 1 "register_operand" "r,0,k"))
7759           (match_operand:SWI12 2 "register_operand" "r,r,k")))
7760    (clobber (reg:CC FLAGS_REG))]
7761   "TARGET_AVX512F"
7763   switch (which_alternative)
7764     {
7765     case 0:
7766       return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
7767     case 1:
7768       return "#";
7769     case 2:
7770       if (TARGET_AVX512DQ && <MODE>mode == QImode)
7771         return "kandnb\t{%2, %1, %0|%0, %1, %2}";
7772       else
7773         return "kandnw\t{%2, %1, %0|%0, %1, %2}";
7774     default:
7775       gcc_unreachable ();
7776     }
7778   [(set_attr "isa" "bmi,*,avx512f")
7779    (set_attr "type" "bitmanip,*,msklog")
7780    (set_attr "prefix" "*,*,vex")
7781    (set_attr "btver2_decode" "direct,*,*")
7782    (set_attr "mode" "<MODE>")])
7784 (define_split
7785   [(set (match_operand:SWI12 0 "general_reg_operand")
7786         (and:SWI12
7787           (not:SWI12
7788             (match_dup 0))
7789           (match_operand:SWI12 1 "general_reg_operand")))
7790    (clobber (reg:CC FLAGS_REG))]
7791   "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7792   [(set (match_dup 0)
7793         (not:HI (match_dup 0)))
7794    (parallel [(set (match_dup 0)
7795                    (and:HI (match_dup 0)
7796                            (match_dup 1)))
7797               (clobber (reg:CC FLAGS_REG))])])
7799 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7800 (define_split
7801   [(set (match_operand:DI 0 "register_operand")
7802         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7803                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7804    (clobber (reg:CC FLAGS_REG))]
7805   "TARGET_64BIT"
7806   [(parallel [(set (match_dup 0)
7807                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7808               (clobber (reg:CC FLAGS_REG))])]
7809   "operands[2] = gen_lowpart (SImode, operands[2]);")
7811 (define_split
7812   [(set (match_operand:SWI248 0 "register_operand")
7813         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7814                     (match_operand:SWI248 2 "const_int_operand")))
7815    (clobber (reg:CC FLAGS_REG))]
7816   "reload_completed
7817    && true_regnum (operands[0]) != true_regnum (operands[1])"
7818   [(const_int 0)]
7820   HOST_WIDE_INT ival = INTVAL (operands[2]);
7821   enum machine_mode mode;
7822   rtx (*insn) (rtx, rtx);
7824   if (ival == (HOST_WIDE_INT) 0xffffffff)
7825     mode = SImode;
7826   else if (ival == 0xffff)
7827     mode = HImode;
7828   else
7829     {
7830       gcc_assert (ival == 0xff);
7831       mode = QImode;
7832     }
7834   if (<MODE>mode == DImode)
7835     insn = (mode == SImode)
7836            ? gen_zero_extendsidi2
7837            : (mode == HImode)
7838            ? gen_zero_extendhidi2
7839            : gen_zero_extendqidi2;
7840   else
7841     {
7842       if (<MODE>mode != SImode)
7843         /* Zero extend to SImode to avoid partial register stalls.  */
7844         operands[0] = gen_lowpart (SImode, operands[0]);
7846       insn = (mode == HImode)
7847              ? gen_zero_extendhisi2
7848              : gen_zero_extendqisi2;
7849     }
7850   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7851   DONE;
7854 (define_split
7855   [(set (match_operand 0 "register_operand")
7856         (and (match_dup 0)
7857              (const_int -65536)))
7858    (clobber (reg:CC FLAGS_REG))]
7859   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7860     || optimize_function_for_size_p (cfun)"
7861   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7862   "operands[1] = gen_lowpart (HImode, operands[0]);")
7864 (define_split
7865   [(set (match_operand 0 "ext_register_operand")
7866         (and (match_dup 0)
7867              (const_int -256)))
7868    (clobber (reg:CC FLAGS_REG))]
7869   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7870    && reload_completed"
7871   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7872   "operands[1] = gen_lowpart (QImode, operands[0]);")
7874 (define_split
7875   [(set (match_operand 0 "ext_register_operand")
7876         (and (match_dup 0)
7877              (const_int -65281)))
7878    (clobber (reg:CC FLAGS_REG))]
7879   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7880    && reload_completed"
7881   [(parallel [(set (zero_extract:SI (match_dup 0)
7882                                     (const_int 8)
7883                                     (const_int 8))
7884                    (xor:SI
7885                      (zero_extract:SI (match_dup 0)
7886                                       (const_int 8)
7887                                       (const_int 8))
7888                      (zero_extract:SI (match_dup 0)
7889                                       (const_int 8)
7890                                       (const_int 8))))
7891               (clobber (reg:CC FLAGS_REG))])]
7892   "operands[0] = gen_lowpart (SImode, operands[0]);")
7894 (define_insn "*anddi_2"
7895   [(set (reg FLAGS_REG)
7896         (compare
7897          (and:DI
7898           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7899           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7900          (const_int 0)))
7901    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7902         (and:DI (match_dup 1) (match_dup 2)))]
7903   "TARGET_64BIT
7904    && ix86_match_ccmode
7905         (insn,
7906          /* If we are going to emit andl instead of andq, and the operands[2]
7907             constant might have the SImode sign bit set, make sure the sign
7908             flag isn't tested, because the instruction will set the sign flag
7909             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
7910             conservatively assume it might have bit 31 set.  */
7911          (satisfies_constraint_Z (operands[2])
7912           && (!CONST_INT_P (operands[2])
7913               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
7914          ? CCZmode : CCNOmode)
7915    && ix86_binary_operator_ok (AND, DImode, operands)"
7916   "@
7917    and{l}\t{%k2, %k0|%k0, %k2}
7918    and{q}\t{%2, %0|%0, %2}
7919    and{q}\t{%2, %0|%0, %2}"
7920   [(set_attr "type" "alu")
7921    (set_attr "mode" "SI,DI,DI")])
7923 (define_insn "*andqi_2_maybe_si"
7924   [(set (reg FLAGS_REG)
7925         (compare (and:QI
7926                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7927                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7928                  (const_int 0)))
7929    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7930         (and:QI (match_dup 1) (match_dup 2)))]
7931   "ix86_binary_operator_ok (AND, QImode, operands)
7932    && ix86_match_ccmode (insn,
7933                          CONST_INT_P (operands[2])
7934                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7936   if (which_alternative == 2)
7937     {
7938       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7939         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7940       return "and{l}\t{%2, %k0|%k0, %2}";
7941     }
7942   return "and{b}\t{%2, %0|%0, %2}";
7944   [(set_attr "type" "alu")
7945    (set_attr "mode" "QI,QI,SI")])
7947 (define_insn "*and<mode>_2"
7948   [(set (reg FLAGS_REG)
7949         (compare (and:SWI124
7950                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7951                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7952                  (const_int 0)))
7953    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7954         (and:SWI124 (match_dup 1) (match_dup 2)))]
7955   "ix86_match_ccmode (insn, CCNOmode)
7956    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7957   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7958   [(set_attr "type" "alu")
7959    (set_attr "mode" "<MODE>")])
7961 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7962 (define_insn "*andsi_2_zext"
7963   [(set (reg FLAGS_REG)
7964         (compare (and:SI
7965                   (match_operand:SI 1 "nonimmediate_operand" "%0")
7966                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
7967                  (const_int 0)))
7968    (set (match_operand:DI 0 "register_operand" "=r")
7969         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7970   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7971    && ix86_binary_operator_ok (AND, SImode, operands)"
7972   "and{l}\t{%2, %k0|%k0, %2}"
7973   [(set_attr "type" "alu")
7974    (set_attr "mode" "SI")])
7976 (define_insn "*andqi_2_slp"
7977   [(set (reg FLAGS_REG)
7978         (compare (and:QI
7979                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7980                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7981                  (const_int 0)))
7982    (set (strict_low_part (match_dup 0))
7983         (and:QI (match_dup 0) (match_dup 1)))]
7984   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7985    && ix86_match_ccmode (insn, CCNOmode)
7986    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7987   "and{b}\t{%1, %0|%0, %1}"
7988   [(set_attr "type" "alu1")
7989    (set_attr "mode" "QI")])
7991 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7992 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
7993 ;; for a QImode operand, which of course failed.
7994 (define_insn "andqi_ext_0"
7995   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7996                          (const_int 8)
7997                          (const_int 8))
7998         (and:SI
7999           (zero_extract:SI
8000             (match_operand 1 "ext_register_operand" "0")
8001             (const_int 8)
8002             (const_int 8))
8003           (match_operand 2 "const_int_operand" "n")))
8004    (clobber (reg:CC FLAGS_REG))]
8005   ""
8006   "and{b}\t{%2, %h0|%h0, %2}"
8007   [(set_attr "type" "alu")
8008    (set_attr "length_immediate" "1")
8009    (set_attr "modrm" "1")
8010    (set_attr "mode" "QI")])
8012 ;; Generated by peephole translating test to and.  This shows up
8013 ;; often in fp comparisons.
8014 (define_insn "*andqi_ext_0_cc"
8015   [(set (reg FLAGS_REG)
8016         (compare
8017           (and:SI
8018             (zero_extract:SI
8019               (match_operand 1 "ext_register_operand" "0")
8020               (const_int 8)
8021               (const_int 8))
8022             (match_operand 2 "const_int_operand" "n"))
8023           (const_int 0)))
8024    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8025                          (const_int 8)
8026                          (const_int 8))
8027         (and:SI
8028           (zero_extract:SI
8029             (match_dup 1)
8030             (const_int 8)
8031             (const_int 8))
8032           (match_dup 2)))]
8033   "ix86_match_ccmode (insn, CCNOmode)"
8034   "and{b}\t{%2, %h0|%h0, %2}"
8035   [(set_attr "type" "alu")
8036    (set_attr "length_immediate" "1")
8037    (set_attr "modrm" "1")
8038    (set_attr "mode" "QI")])
8040 (define_insn "*andqi_ext_1"
8041   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8042                          (const_int 8)
8043                          (const_int 8))
8044         (and:SI
8045           (zero_extract:SI
8046             (match_operand 1 "ext_register_operand" "0,0")
8047             (const_int 8)
8048             (const_int 8))
8049           (zero_extend:SI
8050             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8051    (clobber (reg:CC FLAGS_REG))]
8052   ""
8053   "and{b}\t{%2, %h0|%h0, %2}"
8054   [(set_attr "isa" "*,nox64")
8055    (set_attr "type" "alu")
8056    (set_attr "length_immediate" "0")
8057    (set_attr "mode" "QI")])
8059 (define_insn "*andqi_ext_2"
8060   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8061                          (const_int 8)
8062                          (const_int 8))
8063         (and:SI
8064           (zero_extract:SI
8065             (match_operand 1 "ext_register_operand" "%0")
8066             (const_int 8)
8067             (const_int 8))
8068           (zero_extract:SI
8069             (match_operand 2 "ext_register_operand" "Q")
8070             (const_int 8)
8071             (const_int 8))))
8072    (clobber (reg:CC FLAGS_REG))]
8073   ""
8074   "and{b}\t{%h2, %h0|%h0, %h2}"
8075   [(set_attr "type" "alu")
8076    (set_attr "length_immediate" "0")
8077    (set_attr "mode" "QI")])
8079 ;; Convert wide AND instructions with immediate operand to shorter QImode
8080 ;; equivalents when possible.
8081 ;; Don't do the splitting with memory operands, since it introduces risk
8082 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8083 ;; for size, but that can (should?) be handled by generic code instead.
8084 (define_split
8085   [(set (match_operand 0 "register_operand")
8086         (and (match_operand 1 "register_operand")
8087              (match_operand 2 "const_int_operand")))
8088    (clobber (reg:CC FLAGS_REG))]
8089    "reload_completed
8090     && QI_REG_P (operands[0])
8091     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8092     && !(~INTVAL (operands[2]) & ~(255 << 8))
8093     && GET_MODE (operands[0]) != QImode"
8094   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8095                    (and:SI (zero_extract:SI (match_dup 1)
8096                                             (const_int 8) (const_int 8))
8097                            (match_dup 2)))
8098               (clobber (reg:CC FLAGS_REG))])]
8100   operands[0] = gen_lowpart (SImode, operands[0]);
8101   operands[1] = gen_lowpart (SImode, operands[1]);
8102   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8105 ;; Since AND can be encoded with sign extended immediate, this is only
8106 ;; profitable when 7th bit is not set.
8107 (define_split
8108   [(set (match_operand 0 "register_operand")
8109         (and (match_operand 1 "general_operand")
8110              (match_operand 2 "const_int_operand")))
8111    (clobber (reg:CC FLAGS_REG))]
8112    "reload_completed
8113     && ANY_QI_REG_P (operands[0])
8114     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8115     && !(~INTVAL (operands[2]) & ~255)
8116     && !(INTVAL (operands[2]) & 128)
8117     && GET_MODE (operands[0]) != QImode"
8118   [(parallel [(set (strict_low_part (match_dup 0))
8119                    (and:QI (match_dup 1)
8120                            (match_dup 2)))
8121               (clobber (reg:CC FLAGS_REG))])]
8123   operands[0] = gen_lowpart (QImode, operands[0]);
8124   operands[1] = gen_lowpart (QImode, operands[1]);
8125   operands[2] = gen_lowpart (QImode, operands[2]);
8128 ;; Logical inclusive and exclusive OR instructions
8130 ;; %%% This used to optimize known byte-wide and operations to memory.
8131 ;; If this is considered useful, it should be done with splitters.
8133 (define_expand "<code><mode>3"
8134   [(set (match_operand:SWIM 0 "nonimmediate_operand")
8135         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8136                      (match_operand:SWIM 2 "<general_operand>")))]
8137   ""
8138   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8140 (define_insn "*<code><mode>_1"
8141   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8142         (any_or:SWI48
8143          (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8144          (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8145    (clobber (reg:CC FLAGS_REG))]
8146   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8147   "@
8148    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8149    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8150    k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8151   [(set_attr "type" "alu,alu,msklog")
8152    (set_attr "mode" "<MODE>")])
8154 (define_insn "*<code>hi_1"
8155   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8156         (any_or:HI
8157          (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8158          (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8159    (clobber (reg:CC FLAGS_REG))]
8160   "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8161   "@
8162   <logic>{w}\t{%2, %0|%0, %2}
8163   <logic>{w}\t{%2, %0|%0, %2}
8164   k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8165   [(set_attr "type" "alu,alu,msklog")
8166    (set_attr "mode" "HI")])
8168 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8169 (define_insn "*<code>qi_1"
8170   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8171         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8172                    (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8173    (clobber (reg:CC FLAGS_REG))]
8174   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8175   "@
8176    <logic>{b}\t{%2, %0|%0, %2}
8177    <logic>{b}\t{%2, %0|%0, %2}
8178    <logic>{l}\t{%k2, %k0|%k0, %k2}
8179    k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8180   [(set_attr "type" "alu,alu,alu,msklog")
8181    (set_attr "mode" "QI,QI,SI,HI")])
8183 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8184 (define_insn "*<code>si_1_zext"
8185   [(set (match_operand:DI 0 "register_operand" "=r")
8186         (zero_extend:DI
8187          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8188                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8189    (clobber (reg:CC FLAGS_REG))]
8190   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8191   "<logic>{l}\t{%2, %k0|%k0, %2}"
8192   [(set_attr "type" "alu")
8193    (set_attr "mode" "SI")])
8195 (define_insn "*<code>si_1_zext_imm"
8196   [(set (match_operand:DI 0 "register_operand" "=r")
8197         (any_or:DI
8198          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8199          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8200    (clobber (reg:CC FLAGS_REG))]
8201   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8202   "<logic>{l}\t{%2, %k0|%k0, %2}"
8203   [(set_attr "type" "alu")
8204    (set_attr "mode" "SI")])
8206 (define_insn "*<code>qi_1_slp"
8207   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8208         (any_or:QI (match_dup 0)
8209                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8210    (clobber (reg:CC FLAGS_REG))]
8211   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8212    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8213   "<logic>{b}\t{%1, %0|%0, %1}"
8214   [(set_attr "type" "alu1")
8215    (set_attr "mode" "QI")])
8217 (define_insn "*<code><mode>_2"
8218   [(set (reg FLAGS_REG)
8219         (compare (any_or:SWI
8220                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8221                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8222                  (const_int 0)))
8223    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8224         (any_or:SWI (match_dup 1) (match_dup 2)))]
8225   "ix86_match_ccmode (insn, CCNOmode)
8226    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8227   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8228   [(set_attr "type" "alu")
8229    (set_attr "mode" "<MODE>")])
8231 (define_insn "kxnor<mode>"
8232   [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8233         (not:SWI12
8234           (xor:SWI12
8235             (match_operand:SWI12 1 "register_operand" "0,k")
8236             (match_operand:SWI12 2 "register_operand" "r,k"))))
8237    (clobber (reg:CC FLAGS_REG))]
8238   "TARGET_AVX512F"
8240   if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8241     return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8242   return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8244   [(set_attr "type" "*,msklog")
8245    (set_attr "prefix" "*,vex")
8246    (set_attr "mode" "<MODE>")])
8248 (define_insn "kxnor<mode>"
8249   [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8250         (not:SWI48x
8251           (xor:SWI48x
8252             (match_operand:SWI48x 1 "register_operand" "0,k")
8253             (match_operand:SWI48x 2 "register_operand" "r,k"))))
8254    (clobber (reg:CC FLAGS_REG))]
8255   "TARGET_AVX512BW"
8256   "@
8257    #
8258    kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8259   [(set_attr "type" "*,msklog")
8260    (set_attr "prefix" "*,vex")
8261    (set_attr "mode" "<MODE>")])
8263 (define_split
8264   [(set (match_operand:SWI1248x 0 "general_reg_operand")
8265         (not:SWI1248x
8266           (xor:SWI1248x
8267             (match_dup 0)
8268             (match_operand:SWI1248x 1 "general_reg_operand"))))
8269    (clobber (reg:CC FLAGS_REG))]
8270   "TARGET_AVX512F && reload_completed"
8271    [(parallel [(set (match_dup 0)
8272                     (xor:HI (match_dup 0)
8273                             (match_dup 1)))
8274                (clobber (reg:CC FLAGS_REG))])
8275     (set (match_dup 0)
8276          (not:HI (match_dup 0)))])
8278 ;;There are kortrest[bdq] but no intrinsics for them.
8279 ;;We probably don't need to implement them.
8280 (define_insn "kortestzhi"
8281   [(set (reg:CCZ FLAGS_REG)
8282         (compare:CCZ
8283           (ior:HI
8284             (match_operand:HI 0 "register_operand" "k")
8285             (match_operand:HI 1 "register_operand" "k"))
8286           (const_int 0)))]
8287   "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8288   "kortestw\t{%1, %0|%0, %1}"
8289   [(set_attr "mode" "HI")
8290    (set_attr "type" "msklog")
8291    (set_attr "prefix" "vex")])
8293 (define_insn "kortestchi"
8294   [(set (reg:CCC FLAGS_REG)
8295         (compare:CCC
8296           (ior:HI
8297             (match_operand:HI 0 "register_operand" "k")
8298             (match_operand:HI 1 "register_operand" "k"))
8299           (const_int -1)))]
8300   "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8301   "kortestw\t{%1, %0|%0, %1}"
8302   [(set_attr "mode" "HI")
8303    (set_attr "type" "msklog")
8304    (set_attr "prefix" "vex")])
8306 (define_insn "kunpckhi"
8307   [(set (match_operand:HI 0 "register_operand" "=k")
8308         (ior:HI
8309           (ashift:HI
8310             (match_operand:HI 1 "register_operand" "k")
8311             (const_int 8))
8312           (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8313   "TARGET_AVX512F"
8314   "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8315   [(set_attr "mode" "HI")
8316    (set_attr "type" "msklog")
8317    (set_attr "prefix" "vex")])
8319 (define_insn "kunpcksi"
8320   [(set (match_operand:SI 0 "register_operand" "=k")
8321         (ior:SI
8322           (ashift:SI
8323             (match_operand:SI 1 "register_operand" "k")
8324             (const_int 16))
8325           (zero_extend:SI (subreg:HI (match_operand:SI 2 "register_operand" "k") 0))))]
8326   "TARGET_AVX512BW"
8327   "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8328   [(set_attr "mode" "SI")])
8330 (define_insn "kunpckdi"
8331   [(set (match_operand:DI 0 "register_operand" "=k")
8332         (ior:DI
8333           (ashift:DI
8334             (match_operand:DI 1 "register_operand" "k")
8335             (const_int 32))
8336           (zero_extend:DI (subreg:SI (match_operand:DI 2 "register_operand" "k") 0))))]
8337   "TARGET_AVX512BW"
8338   "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8339   [(set_attr "mode" "DI")])
8341 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8342 ;; ??? Special case for immediate operand is missing - it is tricky.
8343 (define_insn "*<code>si_2_zext"
8344   [(set (reg FLAGS_REG)
8345         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8346                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8347                  (const_int 0)))
8348    (set (match_operand:DI 0 "register_operand" "=r")
8349         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8350   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8351    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8352   "<logic>{l}\t{%2, %k0|%k0, %2}"
8353   [(set_attr "type" "alu")
8354    (set_attr "mode" "SI")])
8356 (define_insn "*<code>si_2_zext_imm"
8357   [(set (reg FLAGS_REG)
8358         (compare (any_or:SI
8359                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8360                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8361                  (const_int 0)))
8362    (set (match_operand:DI 0 "register_operand" "=r")
8363         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8364   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8365    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8366   "<logic>{l}\t{%2, %k0|%k0, %2}"
8367   [(set_attr "type" "alu")
8368    (set_attr "mode" "SI")])
8370 (define_insn "*<code>qi_2_slp"
8371   [(set (reg FLAGS_REG)
8372         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8373                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8374                  (const_int 0)))
8375    (set (strict_low_part (match_dup 0))
8376         (any_or:QI (match_dup 0) (match_dup 1)))]
8377   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8378    && ix86_match_ccmode (insn, CCNOmode)
8379    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8380   "<logic>{b}\t{%1, %0|%0, %1}"
8381   [(set_attr "type" "alu1")
8382    (set_attr "mode" "QI")])
8384 (define_insn "*<code><mode>_3"
8385   [(set (reg FLAGS_REG)
8386         (compare (any_or:SWI
8387                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8388                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8389                  (const_int 0)))
8390    (clobber (match_scratch:SWI 0 "=<r>"))]
8391   "ix86_match_ccmode (insn, CCNOmode)
8392    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8393   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8394   [(set_attr "type" "alu")
8395    (set_attr "mode" "<MODE>")])
8397 (define_insn "*<code>qi_ext_0"
8398   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8399                          (const_int 8)
8400                          (const_int 8))
8401         (any_or:SI
8402           (zero_extract:SI
8403             (match_operand 1 "ext_register_operand" "0")
8404             (const_int 8)
8405             (const_int 8))
8406           (match_operand 2 "const_int_operand" "n")))
8407    (clobber (reg:CC FLAGS_REG))]
8408   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8409   "<logic>{b}\t{%2, %h0|%h0, %2}"
8410   [(set_attr "type" "alu")
8411    (set_attr "length_immediate" "1")
8412    (set_attr "modrm" "1")
8413    (set_attr "mode" "QI")])
8415 (define_insn "*<code>qi_ext_1"
8416   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8417                          (const_int 8)
8418                          (const_int 8))
8419         (any_or:SI
8420           (zero_extract:SI
8421             (match_operand 1 "ext_register_operand" "0,0")
8422             (const_int 8)
8423             (const_int 8))
8424           (zero_extend:SI
8425             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8426    (clobber (reg:CC FLAGS_REG))]
8427   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8428   "<logic>{b}\t{%2, %h0|%h0, %2}"
8429   [(set_attr "isa" "*,nox64")
8430    (set_attr "type" "alu")
8431    (set_attr "length_immediate" "0")
8432    (set_attr "mode" "QI")])
8434 (define_insn "*<code>qi_ext_2"
8435   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8436                          (const_int 8)
8437                          (const_int 8))
8438         (any_or:SI
8439           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8440                            (const_int 8)
8441                            (const_int 8))
8442           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8443                            (const_int 8)
8444                            (const_int 8))))
8445    (clobber (reg:CC FLAGS_REG))]
8446   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8447   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8448   [(set_attr "type" "alu")
8449    (set_attr "length_immediate" "0")
8450    (set_attr "mode" "QI")])
8452 (define_split
8453   [(set (match_operand 0 "register_operand")
8454         (any_or (match_operand 1 "register_operand")
8455                 (match_operand 2 "const_int_operand")))
8456    (clobber (reg:CC FLAGS_REG))]
8457    "reload_completed
8458     && QI_REG_P (operands[0])
8459     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8460     && !(INTVAL (operands[2]) & ~(255 << 8))
8461     && GET_MODE (operands[0]) != QImode"
8462   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8463                    (any_or:SI (zero_extract:SI (match_dup 1)
8464                                                (const_int 8) (const_int 8))
8465                               (match_dup 2)))
8466               (clobber (reg:CC FLAGS_REG))])]
8468   operands[0] = gen_lowpart (SImode, operands[0]);
8469   operands[1] = gen_lowpart (SImode, operands[1]);
8470   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8473 ;; Since OR can be encoded with sign extended immediate, this is only
8474 ;; profitable when 7th bit is set.
8475 (define_split
8476   [(set (match_operand 0 "register_operand")
8477         (any_or (match_operand 1 "general_operand")
8478                 (match_operand 2 "const_int_operand")))
8479    (clobber (reg:CC FLAGS_REG))]
8480    "reload_completed
8481     && ANY_QI_REG_P (operands[0])
8482     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8483     && !(INTVAL (operands[2]) & ~255)
8484     && (INTVAL (operands[2]) & 128)
8485     && GET_MODE (operands[0]) != QImode"
8486   [(parallel [(set (strict_low_part (match_dup 0))
8487                    (any_or:QI (match_dup 1)
8488                               (match_dup 2)))
8489               (clobber (reg:CC FLAGS_REG))])]
8491   operands[0] = gen_lowpart (QImode, operands[0]);
8492   operands[1] = gen_lowpart (QImode, operands[1]);
8493   operands[2] = gen_lowpart (QImode, operands[2]);
8496 (define_expand "xorqi_cc_ext_1"
8497   [(parallel [
8498      (set (reg:CCNO FLAGS_REG)
8499           (compare:CCNO
8500             (xor:SI
8501               (zero_extract:SI
8502                 (match_operand 1 "ext_register_operand")
8503                 (const_int 8)
8504                 (const_int 8))
8505               (match_operand:QI 2 "const_int_operand"))
8506             (const_int 0)))
8507      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8508                            (const_int 8)
8509                            (const_int 8))
8510           (xor:SI
8511             (zero_extract:SI
8512              (match_dup 1)
8513              (const_int 8)
8514              (const_int 8))
8515             (match_dup 2)))])])
8517 (define_insn "*xorqi_cc_ext_1"
8518   [(set (reg FLAGS_REG)
8519         (compare
8520           (xor:SI
8521             (zero_extract:SI
8522               (match_operand 1 "ext_register_operand" "0,0")
8523               (const_int 8)
8524               (const_int 8))
8525             (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8526           (const_int 0)))
8527    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8528                          (const_int 8)
8529                          (const_int 8))
8530         (xor:SI
8531           (zero_extract:SI
8532            (match_dup 1)
8533            (const_int 8)
8534            (const_int 8))
8535           (match_dup 2)))]
8536   "ix86_match_ccmode (insn, CCNOmode)"
8537   "xor{b}\t{%2, %h0|%h0, %2}"
8538   [(set_attr "isa" "*,nox64")
8539    (set_attr "type" "alu")
8540    (set_attr "modrm" "1")
8541    (set_attr "mode" "QI")])
8543 ;; Negation instructions
8545 (define_expand "neg<mode>2"
8546   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8547         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8548   ""
8549   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8551 (define_insn_and_split "*neg<dwi>2_doubleword"
8552   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8553         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8554    (clobber (reg:CC FLAGS_REG))]
8555   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8556   "#"
8557   "reload_completed"
8558   [(parallel
8559     [(set (reg:CCZ FLAGS_REG)
8560           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8561      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8562    (parallel
8563     [(set (match_dup 2)
8564           (plus:DWIH (match_dup 3)
8565                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8566                                 (const_int 0))))
8567      (clobber (reg:CC FLAGS_REG))])
8568    (parallel
8569     [(set (match_dup 2)
8570           (neg:DWIH (match_dup 2)))
8571      (clobber (reg:CC FLAGS_REG))])]
8572   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8574 (define_insn "*neg<mode>2_1"
8575   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8576         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8577    (clobber (reg:CC FLAGS_REG))]
8578   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8579   "neg{<imodesuffix>}\t%0"
8580   [(set_attr "type" "negnot")
8581    (set_attr "mode" "<MODE>")])
8583 ;; Combine is quite creative about this pattern.
8584 (define_insn "*negsi2_1_zext"
8585   [(set (match_operand:DI 0 "register_operand" "=r")
8586         (lshiftrt:DI
8587           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8588                              (const_int 32)))
8589         (const_int 32)))
8590    (clobber (reg:CC FLAGS_REG))]
8591   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8592   "neg{l}\t%k0"
8593   [(set_attr "type" "negnot")
8594    (set_attr "mode" "SI")])
8596 ;; The problem with neg is that it does not perform (compare x 0),
8597 ;; it really performs (compare 0 x), which leaves us with the zero
8598 ;; flag being the only useful item.
8600 (define_insn "*neg<mode>2_cmpz"
8601   [(set (reg:CCZ FLAGS_REG)
8602         (compare:CCZ
8603           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8604                    (const_int 0)))
8605    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8606         (neg:SWI (match_dup 1)))]
8607   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8608   "neg{<imodesuffix>}\t%0"
8609   [(set_attr "type" "negnot")
8610    (set_attr "mode" "<MODE>")])
8612 (define_insn "*negsi2_cmpz_zext"
8613   [(set (reg:CCZ FLAGS_REG)
8614         (compare:CCZ
8615           (lshiftrt:DI
8616             (neg:DI (ashift:DI
8617                       (match_operand:DI 1 "register_operand" "0")
8618                       (const_int 32)))
8619             (const_int 32))
8620           (const_int 0)))
8621    (set (match_operand:DI 0 "register_operand" "=r")
8622         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8623                                         (const_int 32)))
8624                      (const_int 32)))]
8625   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8626   "neg{l}\t%k0"
8627   [(set_attr "type" "negnot")
8628    (set_attr "mode" "SI")])
8630 ;; Negate with jump on overflow.
8631 (define_expand "negv<mode>3"
8632   [(parallel [(set (reg:CCO FLAGS_REG)
8633                    (ne:CCO (match_operand:SWI 1 "register_operand")
8634                            (match_dup 3)))
8635               (set (match_operand:SWI 0 "register_operand")
8636                    (neg:SWI (match_dup 1)))])
8637    (set (pc) (if_then_else
8638                (eq (reg:CCO FLAGS_REG) (const_int 0))
8639                (label_ref (match_operand 2))
8640                (pc)))]
8641   ""
8643   operands[3]
8644     = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8645                     <MODE>mode);
8648 (define_insn "*negv<mode>3"
8649   [(set (reg:CCO FLAGS_REG)
8650         (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8651                 (match_operand:SWI 2 "const_int_operand")))
8652    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8653         (neg:SWI (match_dup 1)))]
8654   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8655    && mode_signbit_p (<MODE>mode, operands[2])"
8656   "neg{<imodesuffix>}\t%0"
8657   [(set_attr "type" "negnot")
8658    (set_attr "mode" "<MODE>")])
8660 ;; Changing of sign for FP values is doable using integer unit too.
8662 (define_expand "<code><mode>2"
8663   [(set (match_operand:X87MODEF 0 "register_operand")
8664         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8665   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8666   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8668 (define_insn "*absneg<mode>2_mixed"
8669   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8670         (match_operator:MODEF 3 "absneg_operator"
8671           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8672    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8673    (clobber (reg:CC FLAGS_REG))]
8674   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8675   "#")
8677 (define_insn "*absneg<mode>2_sse"
8678   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8679         (match_operator:MODEF 3 "absneg_operator"
8680           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8681    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8682    (clobber (reg:CC FLAGS_REG))]
8683   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8684   "#")
8686 (define_insn "*absneg<mode>2_i387"
8687   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8688         (match_operator:X87MODEF 3 "absneg_operator"
8689           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8690    (use (match_operand 2))
8691    (clobber (reg:CC FLAGS_REG))]
8692   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8693   "#")
8695 (define_expand "<code>tf2"
8696   [(set (match_operand:TF 0 "register_operand")
8697         (absneg:TF (match_operand:TF 1 "register_operand")))]
8698   "TARGET_SSE"
8699   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8701 (define_insn "*absnegtf2_sse"
8702   [(set (match_operand:TF 0 "register_operand" "=x,x")
8703         (match_operator:TF 3 "absneg_operator"
8704           [(match_operand:TF 1 "register_operand" "0,x")]))
8705    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8706    (clobber (reg:CC FLAGS_REG))]
8707   "TARGET_SSE"
8708   "#")
8710 ;; Splitters for fp abs and neg.
8712 (define_split
8713   [(set (match_operand 0 "fp_register_operand")
8714         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8715    (use (match_operand 2))
8716    (clobber (reg:CC FLAGS_REG))]
8717   "reload_completed"
8718   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8720 (define_split
8721   [(set (match_operand 0 "register_operand")
8722         (match_operator 3 "absneg_operator"
8723           [(match_operand 1 "register_operand")]))
8724    (use (match_operand 2 "nonimmediate_operand"))
8725    (clobber (reg:CC FLAGS_REG))]
8726   "reload_completed && SSE_REG_P (operands[0])"
8727   [(set (match_dup 0) (match_dup 3))]
8729   enum machine_mode mode = GET_MODE (operands[0]);
8730   enum machine_mode vmode = GET_MODE (operands[2]);
8731   rtx tmp;
8733   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8734   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8735   if (operands_match_p (operands[0], operands[2]))
8736     {
8737       tmp = operands[1];
8738       operands[1] = operands[2];
8739       operands[2] = tmp;
8740     }
8741   if (GET_CODE (operands[3]) == ABS)
8742     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8743   else
8744     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8745   operands[3] = tmp;
8748 (define_split
8749   [(set (match_operand:SF 0 "register_operand")
8750         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8751    (use (match_operand:V4SF 2))
8752    (clobber (reg:CC FLAGS_REG))]
8753   "reload_completed"
8754   [(parallel [(set (match_dup 0) (match_dup 1))
8755               (clobber (reg:CC FLAGS_REG))])]
8757   rtx tmp;
8758   operands[0] = gen_lowpart (SImode, operands[0]);
8759   if (GET_CODE (operands[1]) == ABS)
8760     {
8761       tmp = gen_int_mode (0x7fffffff, SImode);
8762       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8763     }
8764   else
8765     {
8766       tmp = gen_int_mode (0x80000000, SImode);
8767       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8768     }
8769   operands[1] = tmp;
8772 (define_split
8773   [(set (match_operand:DF 0 "register_operand")
8774         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8775    (use (match_operand 2))
8776    (clobber (reg:CC FLAGS_REG))]
8777   "reload_completed"
8778   [(parallel [(set (match_dup 0) (match_dup 1))
8779               (clobber (reg:CC FLAGS_REG))])]
8781   rtx tmp;
8782   if (TARGET_64BIT)
8783     {
8784       tmp = gen_lowpart (DImode, operands[0]);
8785       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8786       operands[0] = tmp;
8788       if (GET_CODE (operands[1]) == ABS)
8789         tmp = const0_rtx;
8790       else
8791         tmp = gen_rtx_NOT (DImode, tmp);
8792     }
8793   else
8794     {
8795       operands[0] = gen_highpart (SImode, operands[0]);
8796       if (GET_CODE (operands[1]) == ABS)
8797         {
8798           tmp = gen_int_mode (0x7fffffff, SImode);
8799           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8800         }
8801       else
8802         {
8803           tmp = gen_int_mode (0x80000000, SImode);
8804           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8805         }
8806     }
8807   operands[1] = tmp;
8810 (define_split
8811   [(set (match_operand:XF 0 "register_operand")
8812         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8813    (use (match_operand 2))
8814    (clobber (reg:CC FLAGS_REG))]
8815   "reload_completed"
8816   [(parallel [(set (match_dup 0) (match_dup 1))
8817               (clobber (reg:CC FLAGS_REG))])]
8819   rtx tmp;
8820   operands[0] = gen_rtx_REG (SImode,
8821                              true_regnum (operands[0])
8822                              + (TARGET_64BIT ? 1 : 2));
8823   if (GET_CODE (operands[1]) == ABS)
8824     {
8825       tmp = GEN_INT (0x7fff);
8826       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8827     }
8828   else
8829     {
8830       tmp = GEN_INT (0x8000);
8831       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8832     }
8833   operands[1] = tmp;
8836 ;; Conditionalize these after reload. If they match before reload, we
8837 ;; lose the clobber and ability to use integer instructions.
8839 (define_insn "*<code><mode>2_1"
8840   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8841         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8842   "TARGET_80387
8843    && (reload_completed
8844        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8845   "f<absneg_mnemonic>"
8846   [(set_attr "type" "fsgn")
8847    (set_attr "mode" "<MODE>")])
8849 (define_insn "*<code>extendsfdf2"
8850   [(set (match_operand:DF 0 "register_operand" "=f")
8851         (absneg:DF (float_extend:DF
8852                      (match_operand:SF 1 "register_operand" "0"))))]
8853   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8854   "f<absneg_mnemonic>"
8855   [(set_attr "type" "fsgn")
8856    (set_attr "mode" "DF")])
8858 (define_insn "*<code>extendsfxf2"
8859   [(set (match_operand:XF 0 "register_operand" "=f")
8860         (absneg:XF (float_extend:XF
8861                      (match_operand:SF 1 "register_operand" "0"))))]
8862   "TARGET_80387"
8863   "f<absneg_mnemonic>"
8864   [(set_attr "type" "fsgn")
8865    (set_attr "mode" "XF")])
8867 (define_insn "*<code>extenddfxf2"
8868   [(set (match_operand:XF 0 "register_operand" "=f")
8869         (absneg:XF (float_extend:XF
8870                      (match_operand:DF 1 "register_operand" "0"))))]
8871   "TARGET_80387"
8872   "f<absneg_mnemonic>"
8873   [(set_attr "type" "fsgn")
8874    (set_attr "mode" "XF")])
8876 ;; Copysign instructions
8878 (define_mode_iterator CSGNMODE [SF DF TF])
8879 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8881 (define_expand "copysign<mode>3"
8882   [(match_operand:CSGNMODE 0 "register_operand")
8883    (match_operand:CSGNMODE 1 "nonmemory_operand")
8884    (match_operand:CSGNMODE 2 "register_operand")]
8885   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8886    || (TARGET_SSE && (<MODE>mode == TFmode))"
8887   "ix86_expand_copysign (operands); DONE;")
8889 (define_insn_and_split "copysign<mode>3_const"
8890   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8891         (unspec:CSGNMODE
8892           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8893            (match_operand:CSGNMODE 2 "register_operand" "0")
8894            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8895           UNSPEC_COPYSIGN))]
8896   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8897    || (TARGET_SSE && (<MODE>mode == TFmode))"
8898   "#"
8899   "&& reload_completed"
8900   [(const_int 0)]
8901   "ix86_split_copysign_const (operands); DONE;")
8903 (define_insn "copysign<mode>3_var"
8904   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8905         (unspec:CSGNMODE
8906           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8907            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8908            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8909            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8910           UNSPEC_COPYSIGN))
8911    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8912   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8913    || (TARGET_SSE && (<MODE>mode == TFmode))"
8914   "#")
8916 (define_split
8917   [(set (match_operand:CSGNMODE 0 "register_operand")
8918         (unspec:CSGNMODE
8919           [(match_operand:CSGNMODE 2 "register_operand")
8920            (match_operand:CSGNMODE 3 "register_operand")
8921            (match_operand:<CSGNVMODE> 4)
8922            (match_operand:<CSGNVMODE> 5)]
8923           UNSPEC_COPYSIGN))
8924    (clobber (match_scratch:<CSGNVMODE> 1))]
8925   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8926     || (TARGET_SSE && (<MODE>mode == TFmode)))
8927    && reload_completed"
8928   [(const_int 0)]
8929   "ix86_split_copysign_var (operands); DONE;")
8931 ;; One complement instructions
8933 (define_expand "one_cmpl<mode>2"
8934   [(set (match_operand:SWIM 0 "nonimmediate_operand")
8935         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8936   ""
8937   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8939 (define_insn "*one_cmpl<mode>2_1"
8940   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
8941         (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
8942   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8943   "@
8944    not{<imodesuffix>}\t%0
8945    knot<mskmodesuffix>\t{%1, %0|%0, %1}"
8946   [(set_attr "isa" "*,avx512bw")
8947    (set_attr "type" "negnot,msklog")
8948    (set_attr "prefix" "*,vex")
8949    (set_attr "mode" "<MODE>")])
8951 (define_insn "*one_cmplhi2_1"
8952   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
8953         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
8954   "ix86_unary_operator_ok (NOT, HImode, operands)"
8955   "@
8956    not{w}\t%0
8957    knotw\t{%1, %0|%0, %1}"
8958   [(set_attr "isa" "*,avx512f")
8959    (set_attr "type" "negnot,msklog")
8960    (set_attr "prefix" "*,vex")
8961    (set_attr "mode" "HI")])
8963 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8964 (define_insn "*one_cmplqi2_1"
8965   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
8966         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
8967   "ix86_unary_operator_ok (NOT, QImode, operands)"
8969   switch (which_alternative)
8970     {
8971     case 0:
8972       return "not{b}\t%0";
8973     case 1:
8974       return "not{l}\t%k0";
8975     case 2:
8976       if (TARGET_AVX512DQ)
8977         return "knotb\t{%1, %0|%0, %1}";
8978       return "knotw\t{%1, %0|%0, %1}";
8979     default:
8980       gcc_unreachable ();
8981     }
8983   [(set_attr "isa" "*,*,avx512f")
8984    (set_attr "type" "negnot,negnot,msklog")
8985    (set_attr "prefix" "*,*,vex")
8986    (set_attr "mode" "QI,SI,QI")])
8988 ;; ??? Currently never generated - xor is used instead.
8989 (define_insn "*one_cmplsi2_1_zext"
8990   [(set (match_operand:DI 0 "register_operand" "=r")
8991         (zero_extend:DI
8992           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8993   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8994   "not{l}\t%k0"
8995   [(set_attr "type" "negnot")
8996    (set_attr "mode" "SI")])
8998 (define_insn "*one_cmpl<mode>2_2"
8999   [(set (reg FLAGS_REG)
9000         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9001                  (const_int 0)))
9002    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9003         (not:SWI (match_dup 1)))]
9004   "ix86_match_ccmode (insn, CCNOmode)
9005    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9006   "#"
9007   [(set_attr "type" "alu1")
9008    (set_attr "mode" "<MODE>")])
9010 (define_split
9011   [(set (match_operand 0 "flags_reg_operand")
9012         (match_operator 2 "compare_operator"
9013           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9014            (const_int 0)]))
9015    (set (match_operand:SWI 1 "nonimmediate_operand")
9016         (not:SWI (match_dup 3)))]
9017   "ix86_match_ccmode (insn, CCNOmode)"
9018   [(parallel [(set (match_dup 0)
9019                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9020                                     (const_int 0)]))
9021               (set (match_dup 1)
9022                    (xor:SWI (match_dup 3) (const_int -1)))])])
9024 ;; ??? Currently never generated - xor is used instead.
9025 (define_insn "*one_cmplsi2_2_zext"
9026   [(set (reg FLAGS_REG)
9027         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9028                  (const_int 0)))
9029    (set (match_operand:DI 0 "register_operand" "=r")
9030         (zero_extend:DI (not:SI (match_dup 1))))]
9031   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9032    && ix86_unary_operator_ok (NOT, SImode, operands)"
9033   "#"
9034   [(set_attr "type" "alu1")
9035    (set_attr "mode" "SI")])
9037 (define_split
9038   [(set (match_operand 0 "flags_reg_operand")
9039         (match_operator 2 "compare_operator"
9040           [(not:SI (match_operand:SI 3 "register_operand"))
9041            (const_int 0)]))
9042    (set (match_operand:DI 1 "register_operand")
9043         (zero_extend:DI (not:SI (match_dup 3))))]
9044   "ix86_match_ccmode (insn, CCNOmode)"
9045   [(parallel [(set (match_dup 0)
9046                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9047                                     (const_int 0)]))
9048               (set (match_dup 1)
9049                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9051 ;; Shift instructions
9053 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9054 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9055 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9056 ;; from the assembler input.
9058 ;; This instruction shifts the target reg/mem as usual, but instead of
9059 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9060 ;; is a left shift double, bits are taken from the high order bits of
9061 ;; reg, else if the insn is a shift right double, bits are taken from the
9062 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9063 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9065 ;; Since sh[lr]d does not change the `reg' operand, that is done
9066 ;; separately, making all shifts emit pairs of shift double and normal
9067 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9068 ;; support a 63 bit shift, each shift where the count is in a reg expands
9069 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9071 ;; If the shift count is a constant, we need never emit more than one
9072 ;; shift pair, instead using moves and sign extension for counts greater
9073 ;; than 31.
9075 (define_expand "ashl<mode>3"
9076   [(set (match_operand:SDWIM 0 "<shift_operand>")
9077         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9078                       (match_operand:QI 2 "nonmemory_operand")))]
9079   ""
9080   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9082 (define_insn "*ashl<mode>3_doubleword"
9083   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9084         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9085                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9086    (clobber (reg:CC FLAGS_REG))]
9087   ""
9088   "#"
9089   [(set_attr "type" "multi")])
9091 (define_split
9092   [(set (match_operand:DWI 0 "register_operand")
9093         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9094                     (match_operand:QI 2 "nonmemory_operand")))
9095    (clobber (reg:CC FLAGS_REG))]
9096   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9097   [(const_int 0)]
9098   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9100 ;; By default we don't ask for a scratch register, because when DWImode
9101 ;; values are manipulated, registers are already at a premium.  But if
9102 ;; we have one handy, we won't turn it away.
9104 (define_peephole2
9105   [(match_scratch:DWIH 3 "r")
9106    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9107                    (ashift:<DWI>
9108                      (match_operand:<DWI> 1 "nonmemory_operand")
9109                      (match_operand:QI 2 "nonmemory_operand")))
9110               (clobber (reg:CC FLAGS_REG))])
9111    (match_dup 3)]
9112   "TARGET_CMOVE"
9113   [(const_int 0)]
9114   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9116 (define_insn "x86_64_shld"
9117   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9118         (ior:DI (ashift:DI (match_dup 0)
9119                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9120                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9121                   (minus:QI (const_int 64) (match_dup 2)))))
9122    (clobber (reg:CC FLAGS_REG))]
9123   "TARGET_64BIT"
9124   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9125   [(set_attr "type" "ishift")
9126    (set_attr "prefix_0f" "1")
9127    (set_attr "mode" "DI")
9128    (set_attr "athlon_decode" "vector")
9129    (set_attr "amdfam10_decode" "vector")
9130    (set_attr "bdver1_decode" "vector")])
9132 (define_insn "x86_shld"
9133   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9134         (ior:SI (ashift:SI (match_dup 0)
9135                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9136                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9137                   (minus:QI (const_int 32) (match_dup 2)))))
9138    (clobber (reg:CC FLAGS_REG))]
9139   ""
9140   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9141   [(set_attr "type" "ishift")
9142    (set_attr "prefix_0f" "1")
9143    (set_attr "mode" "SI")
9144    (set_attr "pent_pair" "np")
9145    (set_attr "athlon_decode" "vector")
9146    (set_attr "amdfam10_decode" "vector")
9147    (set_attr "bdver1_decode" "vector")])
9149 (define_expand "x86_shift<mode>_adj_1"
9150   [(set (reg:CCZ FLAGS_REG)
9151         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9152                              (match_dup 4))
9153                      (const_int 0)))
9154    (set (match_operand:SWI48 0 "register_operand")
9155         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9156                             (match_operand:SWI48 1 "register_operand")
9157                             (match_dup 0)))
9158    (set (match_dup 1)
9159         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9160                             (match_operand:SWI48 3 "register_operand")
9161                             (match_dup 1)))]
9162   "TARGET_CMOVE"
9163   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9165 (define_expand "x86_shift<mode>_adj_2"
9166   [(use (match_operand:SWI48 0 "register_operand"))
9167    (use (match_operand:SWI48 1 "register_operand"))
9168    (use (match_operand:QI 2 "register_operand"))]
9169   ""
9171   rtx label = gen_label_rtx ();
9172   rtx tmp;
9174   emit_insn (gen_testqi_ccz_1 (operands[2],
9175                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9177   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9178   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9179   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9180                               gen_rtx_LABEL_REF (VOIDmode, label),
9181                               pc_rtx);
9182   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9183   JUMP_LABEL (tmp) = label;
9185   emit_move_insn (operands[0], operands[1]);
9186   ix86_expand_clear (operands[1]);
9188   emit_label (label);
9189   LABEL_NUSES (label) = 1;
9191   DONE;
9194 ;; Avoid useless masking of count operand.
9195 (define_insn "*ashl<mode>3_mask"
9196   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9197         (ashift:SWI48
9198           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9199           (subreg:QI
9200             (and:SI
9201               (match_operand:SI 2 "register_operand" "c")
9202               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9203    (clobber (reg:CC FLAGS_REG))]
9204   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9205    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9206       == GET_MODE_BITSIZE (<MODE>mode)-1"
9208   return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9210   [(set_attr "type" "ishift")
9211    (set_attr "mode" "<MODE>")])
9213 (define_insn "*bmi2_ashl<mode>3_1"
9214   [(set (match_operand:SWI48 0 "register_operand" "=r")
9215         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9216                       (match_operand:SWI48 2 "register_operand" "r")))]
9217   "TARGET_BMI2"
9218   "shlx\t{%2, %1, %0|%0, %1, %2}"
9219   [(set_attr "type" "ishiftx")
9220    (set_attr "mode" "<MODE>")])
9222 (define_insn "*ashl<mode>3_1"
9223   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9224         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9225                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9226    (clobber (reg:CC FLAGS_REG))]
9227   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9229   switch (get_attr_type (insn))
9230     {
9231     case TYPE_LEA:
9232     case TYPE_ISHIFTX:
9233       return "#";
9235     case TYPE_ALU:
9236       gcc_assert (operands[2] == const1_rtx);
9237       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9238       return "add{<imodesuffix>}\t%0, %0";
9240     default:
9241       if (operands[2] == const1_rtx
9242           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9243         return "sal{<imodesuffix>}\t%0";
9244       else
9245         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9246     }
9248   [(set_attr "isa" "*,*,bmi2")
9249    (set (attr "type")
9250      (cond [(eq_attr "alternative" "1")
9251               (const_string "lea")
9252             (eq_attr "alternative" "2")
9253               (const_string "ishiftx")
9254             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9255                       (match_operand 0 "register_operand"))
9256                  (match_operand 2 "const1_operand"))
9257               (const_string "alu")
9258            ]
9259            (const_string "ishift")))
9260    (set (attr "length_immediate")
9261      (if_then_else
9262        (ior (eq_attr "type" "alu")
9263             (and (eq_attr "type" "ishift")
9264                  (and (match_operand 2 "const1_operand")
9265                       (ior (match_test "TARGET_SHIFT1")
9266                            (match_test "optimize_function_for_size_p (cfun)")))))
9267        (const_string "0")
9268        (const_string "*")))
9269    (set_attr "mode" "<MODE>")])
9271 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9272 (define_split
9273   [(set (match_operand:SWI48 0 "register_operand")
9274         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9275                       (match_operand:QI 2 "register_operand")))
9276    (clobber (reg:CC FLAGS_REG))]
9277   "TARGET_BMI2 && reload_completed"
9278   [(set (match_dup 0)
9279         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9280   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9282 (define_insn "*bmi2_ashlsi3_1_zext"
9283   [(set (match_operand:DI 0 "register_operand" "=r")
9284         (zero_extend:DI
9285           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9286                      (match_operand:SI 2 "register_operand" "r"))))]
9287   "TARGET_64BIT && TARGET_BMI2"
9288   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9289   [(set_attr "type" "ishiftx")
9290    (set_attr "mode" "SI")])
9292 (define_insn "*ashlsi3_1_zext"
9293   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9294         (zero_extend:DI
9295           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9296                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9297    (clobber (reg:CC FLAGS_REG))]
9298   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9300   switch (get_attr_type (insn))
9301     {
9302     case TYPE_LEA:
9303     case TYPE_ISHIFTX:
9304       return "#";
9306     case TYPE_ALU:
9307       gcc_assert (operands[2] == const1_rtx);
9308       return "add{l}\t%k0, %k0";
9310     default:
9311       if (operands[2] == const1_rtx
9312           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9313         return "sal{l}\t%k0";
9314       else
9315         return "sal{l}\t{%2, %k0|%k0, %2}";
9316     }
9318   [(set_attr "isa" "*,*,bmi2")
9319    (set (attr "type")
9320      (cond [(eq_attr "alternative" "1")
9321               (const_string "lea")
9322             (eq_attr "alternative" "2")
9323               (const_string "ishiftx")
9324             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9325                  (match_operand 2 "const1_operand"))
9326               (const_string "alu")
9327            ]
9328            (const_string "ishift")))
9329    (set (attr "length_immediate")
9330      (if_then_else
9331        (ior (eq_attr "type" "alu")
9332             (and (eq_attr "type" "ishift")
9333                  (and (match_operand 2 "const1_operand")
9334                       (ior (match_test "TARGET_SHIFT1")
9335                            (match_test "optimize_function_for_size_p (cfun)")))))
9336        (const_string "0")
9337        (const_string "*")))
9338    (set_attr "mode" "SI")])
9340 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9341 (define_split
9342   [(set (match_operand:DI 0 "register_operand")
9343         (zero_extend:DI
9344           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9345                      (match_operand:QI 2 "register_operand"))))
9346    (clobber (reg:CC FLAGS_REG))]
9347   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9348   [(set (match_dup 0)
9349         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9350   "operands[2] = gen_lowpart (SImode, operands[2]);")
9352 (define_insn "*ashlhi3_1"
9353   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9354         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9355                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9356    (clobber (reg:CC FLAGS_REG))]
9357   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9359   switch (get_attr_type (insn))
9360     {
9361     case TYPE_LEA:
9362       return "#";
9364     case TYPE_ALU:
9365       gcc_assert (operands[2] == const1_rtx);
9366       return "add{w}\t%0, %0";
9368     default:
9369       if (operands[2] == const1_rtx
9370           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9371         return "sal{w}\t%0";
9372       else
9373         return "sal{w}\t{%2, %0|%0, %2}";
9374     }
9376   [(set (attr "type")
9377      (cond [(eq_attr "alternative" "1")
9378               (const_string "lea")
9379             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9380                       (match_operand 0 "register_operand"))
9381                  (match_operand 2 "const1_operand"))
9382               (const_string "alu")
9383            ]
9384            (const_string "ishift")))
9385    (set (attr "length_immediate")
9386      (if_then_else
9387        (ior (eq_attr "type" "alu")
9388             (and (eq_attr "type" "ishift")
9389                  (and (match_operand 2 "const1_operand")
9390                       (ior (match_test "TARGET_SHIFT1")
9391                            (match_test "optimize_function_for_size_p (cfun)")))))
9392        (const_string "0")
9393        (const_string "*")))
9394    (set_attr "mode" "HI,SI")])
9396 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9397 (define_insn "*ashlqi3_1"
9398   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9399         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9400                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9401    (clobber (reg:CC FLAGS_REG))]
9402   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9404   switch (get_attr_type (insn))
9405     {
9406     case TYPE_LEA:
9407       return "#";
9409     case TYPE_ALU:
9410       gcc_assert (operands[2] == const1_rtx);
9411       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9412         return "add{l}\t%k0, %k0";
9413       else
9414         return "add{b}\t%0, %0";
9416     default:
9417       if (operands[2] == const1_rtx
9418           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9419         {
9420           if (get_attr_mode (insn) == MODE_SI)
9421             return "sal{l}\t%k0";
9422           else
9423             return "sal{b}\t%0";
9424         }
9425       else
9426         {
9427           if (get_attr_mode (insn) == MODE_SI)
9428             return "sal{l}\t{%2, %k0|%k0, %2}";
9429           else
9430             return "sal{b}\t{%2, %0|%0, %2}";
9431         }
9432     }
9434   [(set (attr "type")
9435      (cond [(eq_attr "alternative" "2")
9436               (const_string "lea")
9437             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9438                       (match_operand 0 "register_operand"))
9439                  (match_operand 2 "const1_operand"))
9440               (const_string "alu")
9441            ]
9442            (const_string "ishift")))
9443    (set (attr "length_immediate")
9444      (if_then_else
9445        (ior (eq_attr "type" "alu")
9446             (and (eq_attr "type" "ishift")
9447                  (and (match_operand 2 "const1_operand")
9448                       (ior (match_test "TARGET_SHIFT1")
9449                            (match_test "optimize_function_for_size_p (cfun)")))))
9450        (const_string "0")
9451        (const_string "*")))
9452    (set_attr "mode" "QI,SI,SI")])
9454 (define_insn "*ashlqi3_1_slp"
9455   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9456         (ashift:QI (match_dup 0)
9457                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9458    (clobber (reg:CC FLAGS_REG))]
9459   "(optimize_function_for_size_p (cfun)
9460     || !TARGET_PARTIAL_FLAG_REG_STALL
9461     || (operands[1] == const1_rtx
9462         && (TARGET_SHIFT1
9463             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9465   switch (get_attr_type (insn))
9466     {
9467     case TYPE_ALU:
9468       gcc_assert (operands[1] == const1_rtx);
9469       return "add{b}\t%0, %0";
9471     default:
9472       if (operands[1] == const1_rtx
9473           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9474         return "sal{b}\t%0";
9475       else
9476         return "sal{b}\t{%1, %0|%0, %1}";
9477     }
9479   [(set (attr "type")
9480      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9481                       (match_operand 0 "register_operand"))
9482                  (match_operand 1 "const1_operand"))
9483               (const_string "alu")
9484            ]
9485            (const_string "ishift1")))
9486    (set (attr "length_immediate")
9487      (if_then_else
9488        (ior (eq_attr "type" "alu")
9489             (and (eq_attr "type" "ishift1")
9490                  (and (match_operand 1 "const1_operand")
9491                       (ior (match_test "TARGET_SHIFT1")
9492                            (match_test "optimize_function_for_size_p (cfun)")))))
9493        (const_string "0")
9494        (const_string "*")))
9495    (set_attr "mode" "QI")])
9497 ;; Convert ashift to the lea pattern to avoid flags dependency.
9498 (define_split
9499   [(set (match_operand 0 "register_operand")
9500         (ashift (match_operand 1 "index_register_operand")
9501                 (match_operand:QI 2 "const_int_operand")))
9502    (clobber (reg:CC FLAGS_REG))]
9503   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9504    && reload_completed
9505    && true_regnum (operands[0]) != true_regnum (operands[1])"
9506   [(const_int 0)]
9508   enum machine_mode mode = GET_MODE (operands[0]);
9509   rtx pat;
9511   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9512     { 
9513       mode = SImode; 
9514       operands[0] = gen_lowpart (mode, operands[0]);
9515       operands[1] = gen_lowpart (mode, operands[1]);
9516     }
9518   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9520   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9522   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9523   DONE;
9526 ;; Convert ashift to the lea pattern to avoid flags dependency.
9527 (define_split
9528   [(set (match_operand:DI 0 "register_operand")
9529         (zero_extend:DI
9530           (ashift:SI (match_operand:SI 1 "index_register_operand")
9531                      (match_operand:QI 2 "const_int_operand"))))
9532    (clobber (reg:CC FLAGS_REG))]
9533   "TARGET_64BIT && reload_completed
9534    && true_regnum (operands[0]) != true_regnum (operands[1])"
9535   [(set (match_dup 0)
9536         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9538   operands[1] = gen_lowpart (SImode, operands[1]);
9539   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9542 ;; This pattern can't accept a variable shift count, since shifts by
9543 ;; zero don't affect the flags.  We assume that shifts by constant
9544 ;; zero are optimized away.
9545 (define_insn "*ashl<mode>3_cmp"
9546   [(set (reg FLAGS_REG)
9547         (compare
9548           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9549                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9550           (const_int 0)))
9551    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9552         (ashift:SWI (match_dup 1) (match_dup 2)))]
9553   "(optimize_function_for_size_p (cfun)
9554     || !TARGET_PARTIAL_FLAG_REG_STALL
9555     || (operands[2] == const1_rtx
9556         && (TARGET_SHIFT1
9557             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9558    && ix86_match_ccmode (insn, CCGOCmode)
9559    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9561   switch (get_attr_type (insn))
9562     {
9563     case TYPE_ALU:
9564       gcc_assert (operands[2] == const1_rtx);
9565       return "add{<imodesuffix>}\t%0, %0";
9567     default:
9568       if (operands[2] == const1_rtx
9569           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9570         return "sal{<imodesuffix>}\t%0";
9571       else
9572         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9573     }
9575   [(set (attr "type")
9576      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9577                       (match_operand 0 "register_operand"))
9578                  (match_operand 2 "const1_operand"))
9579               (const_string "alu")
9580            ]
9581            (const_string "ishift")))
9582    (set (attr "length_immediate")
9583      (if_then_else
9584        (ior (eq_attr "type" "alu")
9585             (and (eq_attr "type" "ishift")
9586                  (and (match_operand 2 "const1_operand")
9587                       (ior (match_test "TARGET_SHIFT1")
9588                            (match_test "optimize_function_for_size_p (cfun)")))))
9589        (const_string "0")
9590        (const_string "*")))
9591    (set_attr "mode" "<MODE>")])
9593 (define_insn "*ashlsi3_cmp_zext"
9594   [(set (reg FLAGS_REG)
9595         (compare
9596           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9597                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9598           (const_int 0)))
9599    (set (match_operand:DI 0 "register_operand" "=r")
9600         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9601   "TARGET_64BIT
9602    && (optimize_function_for_size_p (cfun)
9603        || !TARGET_PARTIAL_FLAG_REG_STALL
9604        || (operands[2] == const1_rtx
9605            && (TARGET_SHIFT1
9606                || TARGET_DOUBLE_WITH_ADD)))
9607    && ix86_match_ccmode (insn, CCGOCmode)
9608    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9610   switch (get_attr_type (insn))
9611     {
9612     case TYPE_ALU:
9613       gcc_assert (operands[2] == const1_rtx);
9614       return "add{l}\t%k0, %k0";
9616     default:
9617       if (operands[2] == const1_rtx
9618           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9619         return "sal{l}\t%k0";
9620       else
9621         return "sal{l}\t{%2, %k0|%k0, %2}";
9622     }
9624   [(set (attr "type")
9625      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9626                  (match_operand 2 "const1_operand"))
9627               (const_string "alu")
9628            ]
9629            (const_string "ishift")))
9630    (set (attr "length_immediate")
9631      (if_then_else
9632        (ior (eq_attr "type" "alu")
9633             (and (eq_attr "type" "ishift")
9634                  (and (match_operand 2 "const1_operand")
9635                       (ior (match_test "TARGET_SHIFT1")
9636                            (match_test "optimize_function_for_size_p (cfun)")))))
9637        (const_string "0")
9638        (const_string "*")))
9639    (set_attr "mode" "SI")])
9641 (define_insn "*ashl<mode>3_cconly"
9642   [(set (reg FLAGS_REG)
9643         (compare
9644           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9645                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9646           (const_int 0)))
9647    (clobber (match_scratch:SWI 0 "=<r>"))]
9648   "(optimize_function_for_size_p (cfun)
9649     || !TARGET_PARTIAL_FLAG_REG_STALL
9650     || (operands[2] == const1_rtx
9651         && (TARGET_SHIFT1
9652             || TARGET_DOUBLE_WITH_ADD)))
9653    && ix86_match_ccmode (insn, CCGOCmode)"
9655   switch (get_attr_type (insn))
9656     {
9657     case TYPE_ALU:
9658       gcc_assert (operands[2] == const1_rtx);
9659       return "add{<imodesuffix>}\t%0, %0";
9661     default:
9662       if (operands[2] == const1_rtx
9663           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9664         return "sal{<imodesuffix>}\t%0";
9665       else
9666         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9667     }
9669   [(set (attr "type")
9670      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9671                       (match_operand 0 "register_operand"))
9672                  (match_operand 2 "const1_operand"))
9673               (const_string "alu")
9674            ]
9675            (const_string "ishift")))
9676    (set (attr "length_immediate")
9677      (if_then_else
9678        (ior (eq_attr "type" "alu")
9679             (and (eq_attr "type" "ishift")
9680                  (and (match_operand 2 "const1_operand")
9681                       (ior (match_test "TARGET_SHIFT1")
9682                            (match_test "optimize_function_for_size_p (cfun)")))))
9683        (const_string "0")
9684        (const_string "*")))
9685    (set_attr "mode" "<MODE>")])
9687 ;; See comment above `ashl<mode>3' about how this works.
9689 (define_expand "<shift_insn><mode>3"
9690   [(set (match_operand:SDWIM 0 "<shift_operand>")
9691         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9692                            (match_operand:QI 2 "nonmemory_operand")))]
9693   ""
9694   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9696 ;; Avoid useless masking of count operand.
9697 (define_insn "*<shift_insn><mode>3_mask"
9698   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9699         (any_shiftrt:SWI48
9700           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9701           (subreg:QI
9702             (and:SI
9703               (match_operand:SI 2 "register_operand" "c")
9704               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9705    (clobber (reg:CC FLAGS_REG))]
9706   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9707    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9708       == GET_MODE_BITSIZE (<MODE>mode)-1"
9710   return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9712   [(set_attr "type" "ishift")
9713    (set_attr "mode" "<MODE>")])
9715 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9716   [(set (match_operand:DWI 0 "register_operand" "=r")
9717         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9718                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9719    (clobber (reg:CC FLAGS_REG))]
9720   ""
9721   "#"
9722   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9723   [(const_int 0)]
9724   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9725   [(set_attr "type" "multi")])
9727 ;; By default we don't ask for a scratch register, because when DWImode
9728 ;; values are manipulated, registers are already at a premium.  But if
9729 ;; we have one handy, we won't turn it away.
9731 (define_peephole2
9732   [(match_scratch:DWIH 3 "r")
9733    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9734                    (any_shiftrt:<DWI>
9735                      (match_operand:<DWI> 1 "register_operand")
9736                      (match_operand:QI 2 "nonmemory_operand")))
9737               (clobber (reg:CC FLAGS_REG))])
9738    (match_dup 3)]
9739   "TARGET_CMOVE"
9740   [(const_int 0)]
9741   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9743 (define_insn "x86_64_shrd"
9744   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9745         (ior:DI (lshiftrt:DI (match_dup 0)
9746                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9747                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9748                   (minus:QI (const_int 64) (match_dup 2)))))
9749    (clobber (reg:CC FLAGS_REG))]
9750   "TARGET_64BIT"
9751   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9752   [(set_attr "type" "ishift")
9753    (set_attr "prefix_0f" "1")
9754    (set_attr "mode" "DI")
9755    (set_attr "athlon_decode" "vector")
9756    (set_attr "amdfam10_decode" "vector")
9757    (set_attr "bdver1_decode" "vector")])
9759 (define_insn "x86_shrd"
9760   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9761         (ior:SI (lshiftrt:SI (match_dup 0)
9762                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9763                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9764                   (minus:QI (const_int 32) (match_dup 2)))))
9765    (clobber (reg:CC FLAGS_REG))]
9766   ""
9767   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9768   [(set_attr "type" "ishift")
9769    (set_attr "prefix_0f" "1")
9770    (set_attr "mode" "SI")
9771    (set_attr "pent_pair" "np")
9772    (set_attr "athlon_decode" "vector")
9773    (set_attr "amdfam10_decode" "vector")
9774    (set_attr "bdver1_decode" "vector")])
9776 (define_insn "ashrdi3_cvt"
9777   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9778         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9779                      (match_operand:QI 2 "const_int_operand")))
9780    (clobber (reg:CC FLAGS_REG))]
9781   "TARGET_64BIT && INTVAL (operands[2]) == 63
9782    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9783    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9784   "@
9785    {cqto|cqo}
9786    sar{q}\t{%2, %0|%0, %2}"
9787   [(set_attr "type" "imovx,ishift")
9788    (set_attr "prefix_0f" "0,*")
9789    (set_attr "length_immediate" "0,*")
9790    (set_attr "modrm" "0,1")
9791    (set_attr "mode" "DI")])
9793 (define_insn "ashrsi3_cvt"
9794   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9795         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9796                      (match_operand:QI 2 "const_int_operand")))
9797    (clobber (reg:CC FLAGS_REG))]
9798   "INTVAL (operands[2]) == 31
9799    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9800    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9801   "@
9802    {cltd|cdq}
9803    sar{l}\t{%2, %0|%0, %2}"
9804   [(set_attr "type" "imovx,ishift")
9805    (set_attr "prefix_0f" "0,*")
9806    (set_attr "length_immediate" "0,*")
9807    (set_attr "modrm" "0,1")
9808    (set_attr "mode" "SI")])
9810 (define_insn "*ashrsi3_cvt_zext"
9811   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9812         (zero_extend:DI
9813           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9814                        (match_operand:QI 2 "const_int_operand"))))
9815    (clobber (reg:CC FLAGS_REG))]
9816   "TARGET_64BIT && INTVAL (operands[2]) == 31
9817    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9818    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9819   "@
9820    {cltd|cdq}
9821    sar{l}\t{%2, %k0|%k0, %2}"
9822   [(set_attr "type" "imovx,ishift")
9823    (set_attr "prefix_0f" "0,*")
9824    (set_attr "length_immediate" "0,*")
9825    (set_attr "modrm" "0,1")
9826    (set_attr "mode" "SI")])
9828 (define_expand "x86_shift<mode>_adj_3"
9829   [(use (match_operand:SWI48 0 "register_operand"))
9830    (use (match_operand:SWI48 1 "register_operand"))
9831    (use (match_operand:QI 2 "register_operand"))]
9832   ""
9834   rtx label = gen_label_rtx ();
9835   rtx tmp;
9837   emit_insn (gen_testqi_ccz_1 (operands[2],
9838                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9840   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9841   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9842   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9843                               gen_rtx_LABEL_REF (VOIDmode, label),
9844                               pc_rtx);
9845   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9846   JUMP_LABEL (tmp) = label;
9848   emit_move_insn (operands[0], operands[1]);
9849   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9850                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9851   emit_label (label);
9852   LABEL_NUSES (label) = 1;
9854   DONE;
9857 (define_insn "*bmi2_<shift_insn><mode>3_1"
9858   [(set (match_operand:SWI48 0 "register_operand" "=r")
9859         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9860                            (match_operand:SWI48 2 "register_operand" "r")))]
9861   "TARGET_BMI2"
9862   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9863   [(set_attr "type" "ishiftx")
9864    (set_attr "mode" "<MODE>")])
9866 (define_insn "*<shift_insn><mode>3_1"
9867   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9868         (any_shiftrt:SWI48
9869           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9870           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9871    (clobber (reg:CC FLAGS_REG))]
9872   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9874   switch (get_attr_type (insn))
9875     {
9876     case TYPE_ISHIFTX:
9877       return "#";
9879     default:
9880       if (operands[2] == const1_rtx
9881           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9882         return "<shift>{<imodesuffix>}\t%0";
9883       else
9884         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9885     }
9887   [(set_attr "isa" "*,bmi2")
9888    (set_attr "type" "ishift,ishiftx")
9889    (set (attr "length_immediate")
9890      (if_then_else
9891        (and (match_operand 2 "const1_operand")
9892             (ior (match_test "TARGET_SHIFT1")
9893                  (match_test "optimize_function_for_size_p (cfun)")))
9894        (const_string "0")
9895        (const_string "*")))
9896    (set_attr "mode" "<MODE>")])
9898 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9899 (define_split
9900   [(set (match_operand:SWI48 0 "register_operand")
9901         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9902                            (match_operand:QI 2 "register_operand")))
9903    (clobber (reg:CC FLAGS_REG))]
9904   "TARGET_BMI2 && reload_completed"
9905   [(set (match_dup 0)
9906         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9907   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9909 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9910   [(set (match_operand:DI 0 "register_operand" "=r")
9911         (zero_extend:DI
9912           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9913                           (match_operand:SI 2 "register_operand" "r"))))]
9914   "TARGET_64BIT && TARGET_BMI2"
9915   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9916   [(set_attr "type" "ishiftx")
9917    (set_attr "mode" "SI")])
9919 (define_insn "*<shift_insn>si3_1_zext"
9920   [(set (match_operand:DI 0 "register_operand" "=r,r")
9921         (zero_extend:DI
9922           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9923                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9924    (clobber (reg:CC FLAGS_REG))]
9925   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9927   switch (get_attr_type (insn))
9928     {
9929     case TYPE_ISHIFTX:
9930       return "#";
9932     default:
9933       if (operands[2] == const1_rtx
9934           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9935         return "<shift>{l}\t%k0";
9936       else
9937         return "<shift>{l}\t{%2, %k0|%k0, %2}";
9938     }
9940   [(set_attr "isa" "*,bmi2")
9941    (set_attr "type" "ishift,ishiftx")
9942    (set (attr "length_immediate")
9943      (if_then_else
9944        (and (match_operand 2 "const1_operand")
9945             (ior (match_test "TARGET_SHIFT1")
9946                  (match_test "optimize_function_for_size_p (cfun)")))
9947        (const_string "0")
9948        (const_string "*")))
9949    (set_attr "mode" "SI")])
9951 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9952 (define_split
9953   [(set (match_operand:DI 0 "register_operand")
9954         (zero_extend:DI
9955           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9956                           (match_operand:QI 2 "register_operand"))))
9957    (clobber (reg:CC FLAGS_REG))]
9958   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9959   [(set (match_dup 0)
9960         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9961   "operands[2] = gen_lowpart (SImode, operands[2]);")
9963 (define_insn "*<shift_insn><mode>3_1"
9964   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9965         (any_shiftrt:SWI12
9966           (match_operand:SWI12 1 "nonimmediate_operand" "0")
9967           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9968    (clobber (reg:CC FLAGS_REG))]
9969   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9971   if (operands[2] == const1_rtx
9972       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9973     return "<shift>{<imodesuffix>}\t%0";
9974   else
9975     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9977   [(set_attr "type" "ishift")
9978    (set (attr "length_immediate")
9979      (if_then_else
9980        (and (match_operand 2 "const1_operand")
9981             (ior (match_test "TARGET_SHIFT1")
9982                  (match_test "optimize_function_for_size_p (cfun)")))
9983        (const_string "0")
9984        (const_string "*")))
9985    (set_attr "mode" "<MODE>")])
9987 (define_insn "*<shift_insn>qi3_1_slp"
9988   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9989         (any_shiftrt:QI (match_dup 0)
9990                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9991    (clobber (reg:CC FLAGS_REG))]
9992   "(optimize_function_for_size_p (cfun)
9993     || !TARGET_PARTIAL_REG_STALL
9994     || (operands[1] == const1_rtx
9995         && TARGET_SHIFT1))"
9997   if (operands[1] == const1_rtx
9998       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9999     return "<shift>{b}\t%0";
10000   else
10001     return "<shift>{b}\t{%1, %0|%0, %1}";
10003   [(set_attr "type" "ishift1")
10004    (set (attr "length_immediate")
10005      (if_then_else
10006        (and (match_operand 1 "const1_operand")
10007             (ior (match_test "TARGET_SHIFT1")
10008                  (match_test "optimize_function_for_size_p (cfun)")))
10009        (const_string "0")
10010        (const_string "*")))
10011    (set_attr "mode" "QI")])
10013 ;; This pattern can't accept a variable shift count, since shifts by
10014 ;; zero don't affect the flags.  We assume that shifts by constant
10015 ;; zero are optimized away.
10016 (define_insn "*<shift_insn><mode>3_cmp"
10017   [(set (reg FLAGS_REG)
10018         (compare
10019           (any_shiftrt:SWI
10020             (match_operand:SWI 1 "nonimmediate_operand" "0")
10021             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10022           (const_int 0)))
10023    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10024         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10025   "(optimize_function_for_size_p (cfun)
10026     || !TARGET_PARTIAL_FLAG_REG_STALL
10027     || (operands[2] == const1_rtx
10028         && TARGET_SHIFT1))
10029    && ix86_match_ccmode (insn, CCGOCmode)
10030    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10032   if (operands[2] == const1_rtx
10033       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10034     return "<shift>{<imodesuffix>}\t%0";
10035   else
10036     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10038   [(set_attr "type" "ishift")
10039    (set (attr "length_immediate")
10040      (if_then_else
10041        (and (match_operand 2 "const1_operand")
10042             (ior (match_test "TARGET_SHIFT1")
10043                  (match_test "optimize_function_for_size_p (cfun)")))
10044        (const_string "0")
10045        (const_string "*")))
10046    (set_attr "mode" "<MODE>")])
10048 (define_insn "*<shift_insn>si3_cmp_zext"
10049   [(set (reg FLAGS_REG)
10050         (compare
10051           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10052                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10053           (const_int 0)))
10054    (set (match_operand:DI 0 "register_operand" "=r")
10055         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10056   "TARGET_64BIT
10057    && (optimize_function_for_size_p (cfun)
10058        || !TARGET_PARTIAL_FLAG_REG_STALL
10059        || (operands[2] == const1_rtx
10060            && TARGET_SHIFT1))
10061    && ix86_match_ccmode (insn, CCGOCmode)
10062    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10064   if (operands[2] == const1_rtx
10065       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10066     return "<shift>{l}\t%k0";
10067   else
10068     return "<shift>{l}\t{%2, %k0|%k0, %2}";
10070   [(set_attr "type" "ishift")
10071    (set (attr "length_immediate")
10072      (if_then_else
10073        (and (match_operand 2 "const1_operand")
10074             (ior (match_test "TARGET_SHIFT1")
10075                  (match_test "optimize_function_for_size_p (cfun)")))
10076        (const_string "0")
10077        (const_string "*")))
10078    (set_attr "mode" "SI")])
10080 (define_insn "*<shift_insn><mode>3_cconly"
10081   [(set (reg FLAGS_REG)
10082         (compare
10083           (any_shiftrt:SWI
10084             (match_operand:SWI 1 "register_operand" "0")
10085             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10086           (const_int 0)))
10087    (clobber (match_scratch:SWI 0 "=<r>"))]
10088   "(optimize_function_for_size_p (cfun)
10089     || !TARGET_PARTIAL_FLAG_REG_STALL
10090     || (operands[2] == const1_rtx
10091         && TARGET_SHIFT1))
10092    && ix86_match_ccmode (insn, CCGOCmode)"
10094   if (operands[2] == const1_rtx
10095       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10096     return "<shift>{<imodesuffix>}\t%0";
10097   else
10098     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10100   [(set_attr "type" "ishift")
10101    (set (attr "length_immediate")
10102      (if_then_else
10103        (and (match_operand 2 "const1_operand")
10104             (ior (match_test "TARGET_SHIFT1")
10105                  (match_test "optimize_function_for_size_p (cfun)")))
10106        (const_string "0")
10107        (const_string "*")))
10108    (set_attr "mode" "<MODE>")])
10110 ;; Rotate instructions
10112 (define_expand "<rotate_insn>ti3"
10113   [(set (match_operand:TI 0 "register_operand")
10114         (any_rotate:TI (match_operand:TI 1 "register_operand")
10115                        (match_operand:QI 2 "nonmemory_operand")))]
10116   "TARGET_64BIT"
10118   if (const_1_to_63_operand (operands[2], VOIDmode))
10119     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10120                 (operands[0], operands[1], operands[2]));
10121   else
10122     FAIL;
10124   DONE;
10127 (define_expand "<rotate_insn>di3"
10128   [(set (match_operand:DI 0 "shiftdi_operand")
10129         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10130                        (match_operand:QI 2 "nonmemory_operand")))]
10131  ""
10133   if (TARGET_64BIT)
10134     ix86_expand_binary_operator (<CODE>, DImode, operands);
10135   else if (const_1_to_31_operand (operands[2], VOIDmode))
10136     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10137                 (operands[0], operands[1], operands[2]));
10138   else
10139     FAIL;
10141   DONE;
10144 (define_expand "<rotate_insn><mode>3"
10145   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10146         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10147                             (match_operand:QI 2 "nonmemory_operand")))]
10148   ""
10149   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10151 ;; Avoid useless masking of count operand.
10152 (define_insn "*<rotate_insn><mode>3_mask"
10153   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10154         (any_rotate:SWI48
10155           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10156           (subreg:QI
10157             (and:SI
10158               (match_operand:SI 2 "register_operand" "c")
10159               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10160    (clobber (reg:CC FLAGS_REG))]
10161   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10162    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10163       == GET_MODE_BITSIZE (<MODE>mode)-1"
10165   return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10167   [(set_attr "type" "rotate")
10168    (set_attr "mode" "<MODE>")])
10170 ;; Implement rotation using two double-precision
10171 ;; shift instructions and a scratch register.
10173 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10174  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10175        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10176                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10177   (clobber (reg:CC FLAGS_REG))
10178   (clobber (match_scratch:DWIH 3 "=&r"))]
10179  ""
10180  "#"
10181  "reload_completed"
10182  [(set (match_dup 3) (match_dup 4))
10183   (parallel
10184    [(set (match_dup 4)
10185          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10186                    (lshiftrt:DWIH (match_dup 5)
10187                                   (minus:QI (match_dup 6) (match_dup 2)))))
10188     (clobber (reg:CC FLAGS_REG))])
10189   (parallel
10190    [(set (match_dup 5)
10191          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10192                    (lshiftrt:DWIH (match_dup 3)
10193                                   (minus:QI (match_dup 6) (match_dup 2)))))
10194     (clobber (reg:CC FLAGS_REG))])]
10196   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10198   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10201 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10202  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10203        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10204                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10205   (clobber (reg:CC FLAGS_REG))
10206   (clobber (match_scratch:DWIH 3 "=&r"))]
10207  ""
10208  "#"
10209  "reload_completed"
10210  [(set (match_dup 3) (match_dup 4))
10211   (parallel
10212    [(set (match_dup 4)
10213          (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10214                    (ashift:DWIH (match_dup 5)
10215                                 (minus:QI (match_dup 6) (match_dup 2)))))
10216     (clobber (reg:CC FLAGS_REG))])
10217   (parallel
10218    [(set (match_dup 5)
10219          (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10220                    (ashift:DWIH (match_dup 3)
10221                                 (minus:QI (match_dup 6) (match_dup 2)))))
10222     (clobber (reg:CC FLAGS_REG))])]
10224   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10226   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10229 (define_insn "*bmi2_rorx<mode>3_1"
10230   [(set (match_operand:SWI48 0 "register_operand" "=r")
10231         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10232                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10233   "TARGET_BMI2"
10234   "rorx\t{%2, %1, %0|%0, %1, %2}"
10235   [(set_attr "type" "rotatex")
10236    (set_attr "mode" "<MODE>")])
10238 (define_insn "*<rotate_insn><mode>3_1"
10239   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10240         (any_rotate:SWI48
10241           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10242           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10243    (clobber (reg:CC FLAGS_REG))]
10244   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10246   switch (get_attr_type (insn))
10247     {
10248     case TYPE_ROTATEX:
10249       return "#";
10251     default:
10252       if (operands[2] == const1_rtx
10253           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10254         return "<rotate>{<imodesuffix>}\t%0";
10255       else
10256         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10257     }
10259   [(set_attr "isa" "*,bmi2")
10260    (set_attr "type" "rotate,rotatex")
10261    (set (attr "length_immediate")
10262      (if_then_else
10263        (and (eq_attr "type" "rotate")
10264             (and (match_operand 2 "const1_operand")
10265                  (ior (match_test "TARGET_SHIFT1")
10266                       (match_test "optimize_function_for_size_p (cfun)"))))
10267        (const_string "0")
10268        (const_string "*")))
10269    (set_attr "mode" "<MODE>")])
10271 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10272 (define_split
10273   [(set (match_operand:SWI48 0 "register_operand")
10274         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10275                       (match_operand:QI 2 "immediate_operand")))
10276    (clobber (reg:CC FLAGS_REG))]
10277   "TARGET_BMI2 && reload_completed"
10278   [(set (match_dup 0)
10279         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10281   operands[2]
10282     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10285 (define_split
10286   [(set (match_operand:SWI48 0 "register_operand")
10287         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10288                         (match_operand:QI 2 "immediate_operand")))
10289    (clobber (reg:CC FLAGS_REG))]
10290   "TARGET_BMI2 && reload_completed"
10291   [(set (match_dup 0)
10292         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10294 (define_insn "*bmi2_rorxsi3_1_zext"
10295   [(set (match_operand:DI 0 "register_operand" "=r")
10296         (zero_extend:DI
10297           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10298                        (match_operand:QI 2 "immediate_operand" "I"))))]
10299   "TARGET_64BIT && TARGET_BMI2"
10300   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10301   [(set_attr "type" "rotatex")
10302    (set_attr "mode" "SI")])
10304 (define_insn "*<rotate_insn>si3_1_zext"
10305   [(set (match_operand:DI 0 "register_operand" "=r,r")
10306         (zero_extend:DI
10307           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10308                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10309    (clobber (reg:CC FLAGS_REG))]
10310   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10312   switch (get_attr_type (insn))
10313     {
10314     case TYPE_ROTATEX:
10315       return "#";
10317     default:
10318       if (operands[2] == const1_rtx
10319           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10320         return "<rotate>{l}\t%k0";
10321       else
10322         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10323     }
10325   [(set_attr "isa" "*,bmi2")
10326    (set_attr "type" "rotate,rotatex")
10327    (set (attr "length_immediate")
10328      (if_then_else
10329        (and (eq_attr "type" "rotate")
10330             (and (match_operand 2 "const1_operand")
10331                  (ior (match_test "TARGET_SHIFT1")
10332                       (match_test "optimize_function_for_size_p (cfun)"))))
10333        (const_string "0")
10334        (const_string "*")))
10335    (set_attr "mode" "SI")])
10337 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10338 (define_split
10339   [(set (match_operand:DI 0 "register_operand")
10340         (zero_extend:DI
10341           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10342                      (match_operand:QI 2 "immediate_operand"))))
10343    (clobber (reg:CC FLAGS_REG))]
10344   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10345   [(set (match_dup 0)
10346         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10348   operands[2]
10349     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10352 (define_split
10353   [(set (match_operand:DI 0 "register_operand")
10354         (zero_extend:DI
10355           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10356                        (match_operand:QI 2 "immediate_operand"))))
10357    (clobber (reg:CC FLAGS_REG))]
10358   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10359   [(set (match_dup 0)
10360         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10362 (define_insn "*<rotate_insn><mode>3_1"
10363   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10364         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10365                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10366    (clobber (reg:CC FLAGS_REG))]
10367   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10369   if (operands[2] == const1_rtx
10370       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10371     return "<rotate>{<imodesuffix>}\t%0";
10372   else
10373     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10375   [(set_attr "type" "rotate")
10376    (set (attr "length_immediate")
10377      (if_then_else
10378        (and (match_operand 2 "const1_operand")
10379             (ior (match_test "TARGET_SHIFT1")
10380                  (match_test "optimize_function_for_size_p (cfun)")))
10381        (const_string "0")
10382        (const_string "*")))
10383    (set_attr "mode" "<MODE>")])
10385 (define_insn "*<rotate_insn>qi3_1_slp"
10386   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10387         (any_rotate:QI (match_dup 0)
10388                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10389    (clobber (reg:CC FLAGS_REG))]
10390   "(optimize_function_for_size_p (cfun)
10391     || !TARGET_PARTIAL_REG_STALL
10392     || (operands[1] == const1_rtx
10393         && TARGET_SHIFT1))"
10395   if (operands[1] == const1_rtx
10396       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10397     return "<rotate>{b}\t%0";
10398   else
10399     return "<rotate>{b}\t{%1, %0|%0, %1}";
10401   [(set_attr "type" "rotate1")
10402    (set (attr "length_immediate")
10403      (if_then_else
10404        (and (match_operand 1 "const1_operand")
10405             (ior (match_test "TARGET_SHIFT1")
10406                  (match_test "optimize_function_for_size_p (cfun)")))
10407        (const_string "0")
10408        (const_string "*")))
10409    (set_attr "mode" "QI")])
10411 (define_split
10412  [(set (match_operand:HI 0 "register_operand")
10413        (any_rotate:HI (match_dup 0) (const_int 8)))
10414   (clobber (reg:CC FLAGS_REG))]
10415  "reload_completed
10416   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10417  [(parallel [(set (strict_low_part (match_dup 0))
10418                   (bswap:HI (match_dup 0)))
10419              (clobber (reg:CC FLAGS_REG))])])
10421 ;; Bit set / bit test instructions
10423 (define_expand "extv"
10424   [(set (match_operand:SI 0 "register_operand")
10425         (sign_extract:SI (match_operand:SI 1 "register_operand")
10426                          (match_operand:SI 2 "const8_operand")
10427                          (match_operand:SI 3 "const8_operand")))]
10428   ""
10430   /* Handle extractions from %ah et al.  */
10431   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10432     FAIL;
10434   /* From mips.md: extract_bit_field doesn't verify that our source
10435      matches the predicate, so check it again here.  */
10436   if (! ext_register_operand (operands[1], VOIDmode))
10437     FAIL;
10440 (define_expand "extzv"
10441   [(set (match_operand:SI 0 "register_operand")
10442         (zero_extract:SI (match_operand 1 "ext_register_operand")
10443                          (match_operand:SI 2 "const8_operand")
10444                          (match_operand:SI 3 "const8_operand")))]
10445   ""
10447   /* Handle extractions from %ah et al.  */
10448   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10449     FAIL;
10451   /* From mips.md: extract_bit_field doesn't verify that our source
10452      matches the predicate, so check it again here.  */
10453   if (! ext_register_operand (operands[1], VOIDmode))
10454     FAIL;
10457 (define_expand "insv"
10458   [(set (zero_extract (match_operand 0 "register_operand")
10459                       (match_operand 1 "const_int_operand")
10460                       (match_operand 2 "const_int_operand"))
10461         (match_operand 3 "register_operand"))]
10462   ""
10464   rtx (*gen_mov_insv_1) (rtx, rtx);
10466   if (ix86_expand_pinsr (operands))
10467     DONE;
10469   /* Handle insertions to %ah et al.  */
10470   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10471     FAIL;
10473   /* From mips.md: insert_bit_field doesn't verify that our source
10474      matches the predicate, so check it again here.  */
10475   if (! ext_register_operand (operands[0], VOIDmode))
10476     FAIL;
10478   gen_mov_insv_1 = (TARGET_64BIT
10479                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10481   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10482   DONE;
10485 ;; %%% bts, btr, btc, bt.
10486 ;; In general these instructions are *slow* when applied to memory,
10487 ;; since they enforce atomic operation.  When applied to registers,
10488 ;; it depends on the cpu implementation.  They're never faster than
10489 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10490 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10491 ;; within the instruction itself, so operating on bits in the high
10492 ;; 32-bits of a register becomes easier.
10494 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10495 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10496 ;; negdf respectively, so they can never be disabled entirely.
10498 (define_insn "*btsq"
10499   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10500                          (const_int 1)
10501                          (match_operand:DI 1 "const_0_to_63_operand"))
10502         (const_int 1))
10503    (clobber (reg:CC FLAGS_REG))]
10504   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10505   "bts{q}\t{%1, %0|%0, %1}"
10506   [(set_attr "type" "alu1")
10507    (set_attr "prefix_0f" "1")
10508    (set_attr "mode" "DI")])
10510 (define_insn "*btrq"
10511   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10512                          (const_int 1)
10513                          (match_operand:DI 1 "const_0_to_63_operand"))
10514         (const_int 0))
10515    (clobber (reg:CC FLAGS_REG))]
10516   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10517   "btr{q}\t{%1, %0|%0, %1}"
10518   [(set_attr "type" "alu1")
10519    (set_attr "prefix_0f" "1")
10520    (set_attr "mode" "DI")])
10522 (define_insn "*btcq"
10523   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10524                          (const_int 1)
10525                          (match_operand:DI 1 "const_0_to_63_operand"))
10526         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10527    (clobber (reg:CC FLAGS_REG))]
10528   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10529   "btc{q}\t{%1, %0|%0, %1}"
10530   [(set_attr "type" "alu1")
10531    (set_attr "prefix_0f" "1")
10532    (set_attr "mode" "DI")])
10534 ;; Allow Nocona to avoid these instructions if a register is available.
10536 (define_peephole2
10537   [(match_scratch:DI 2 "r")
10538    (parallel [(set (zero_extract:DI
10539                      (match_operand:DI 0 "register_operand")
10540                      (const_int 1)
10541                      (match_operand:DI 1 "const_0_to_63_operand"))
10542                    (const_int 1))
10543               (clobber (reg:CC FLAGS_REG))])]
10544   "TARGET_64BIT && !TARGET_USE_BT"
10545   [(const_int 0)]
10547   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10548   rtx op1;
10550   if (HOST_BITS_PER_WIDE_INT >= 64)
10551     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10552   else if (i < HOST_BITS_PER_WIDE_INT)
10553     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10554   else
10555     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10557   op1 = immed_double_const (lo, hi, DImode);
10558   if (i >= 31)
10559     {
10560       emit_move_insn (operands[2], op1);
10561       op1 = operands[2];
10562     }
10564   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10565   DONE;
10568 (define_peephole2
10569   [(match_scratch:DI 2 "r")
10570    (parallel [(set (zero_extract:DI
10571                      (match_operand:DI 0 "register_operand")
10572                      (const_int 1)
10573                      (match_operand:DI 1 "const_0_to_63_operand"))
10574                    (const_int 0))
10575               (clobber (reg:CC FLAGS_REG))])]
10576   "TARGET_64BIT && !TARGET_USE_BT"
10577   [(const_int 0)]
10579   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10580   rtx op1;
10582   if (HOST_BITS_PER_WIDE_INT >= 64)
10583     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10584   else if (i < HOST_BITS_PER_WIDE_INT)
10585     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10586   else
10587     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10589   op1 = immed_double_const (~lo, ~hi, DImode);
10590   if (i >= 32)
10591     {
10592       emit_move_insn (operands[2], op1);
10593       op1 = operands[2];
10594     }
10596   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10597   DONE;
10600 (define_peephole2
10601   [(match_scratch:DI 2 "r")
10602    (parallel [(set (zero_extract:DI
10603                      (match_operand:DI 0 "register_operand")
10604                      (const_int 1)
10605                      (match_operand:DI 1 "const_0_to_63_operand"))
10606               (not:DI (zero_extract:DI
10607                         (match_dup 0) (const_int 1) (match_dup 1))))
10608               (clobber (reg:CC FLAGS_REG))])]
10609   "TARGET_64BIT && !TARGET_USE_BT"
10610   [(const_int 0)]
10612   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10613   rtx op1;
10615   if (HOST_BITS_PER_WIDE_INT >= 64)
10616     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10617   else if (i < HOST_BITS_PER_WIDE_INT)
10618     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10619   else
10620     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10622   op1 = immed_double_const (lo, hi, DImode);
10623   if (i >= 31)
10624     {
10625       emit_move_insn (operands[2], op1);
10626       op1 = operands[2];
10627     }
10629   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10630   DONE;
10633 (define_insn "*bt<mode>"
10634   [(set (reg:CCC FLAGS_REG)
10635         (compare:CCC
10636           (zero_extract:SWI48
10637             (match_operand:SWI48 0 "register_operand" "r")
10638             (const_int 1)
10639             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10640           (const_int 0)))]
10641   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10642   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10643   [(set_attr "type" "alu1")
10644    (set_attr "prefix_0f" "1")
10645    (set_attr "mode" "<MODE>")])
10647 ;; Store-flag instructions.
10649 ;; For all sCOND expanders, also expand the compare or test insn that
10650 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10652 (define_insn_and_split "*setcc_di_1"
10653   [(set (match_operand:DI 0 "register_operand" "=q")
10654         (match_operator:DI 1 "ix86_comparison_operator"
10655           [(reg FLAGS_REG) (const_int 0)]))]
10656   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10657   "#"
10658   "&& reload_completed"
10659   [(set (match_dup 2) (match_dup 1))
10660    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10662   PUT_MODE (operands[1], QImode);
10663   operands[2] = gen_lowpart (QImode, operands[0]);
10666 (define_insn_and_split "*setcc_si_1_and"
10667   [(set (match_operand:SI 0 "register_operand" "=q")
10668         (match_operator:SI 1 "ix86_comparison_operator"
10669           [(reg FLAGS_REG) (const_int 0)]))
10670    (clobber (reg:CC FLAGS_REG))]
10671   "!TARGET_PARTIAL_REG_STALL
10672    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10673   "#"
10674   "&& reload_completed"
10675   [(set (match_dup 2) (match_dup 1))
10676    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10677               (clobber (reg:CC FLAGS_REG))])]
10679   PUT_MODE (operands[1], QImode);
10680   operands[2] = gen_lowpart (QImode, operands[0]);
10683 (define_insn_and_split "*setcc_si_1_movzbl"
10684   [(set (match_operand:SI 0 "register_operand" "=q")
10685         (match_operator:SI 1 "ix86_comparison_operator"
10686           [(reg FLAGS_REG) (const_int 0)]))]
10687   "!TARGET_PARTIAL_REG_STALL
10688    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10689   "#"
10690   "&& reload_completed"
10691   [(set (match_dup 2) (match_dup 1))
10692    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10694   PUT_MODE (operands[1], QImode);
10695   operands[2] = gen_lowpart (QImode, operands[0]);
10698 (define_insn "*setcc_qi"
10699   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10700         (match_operator:QI 1 "ix86_comparison_operator"
10701           [(reg FLAGS_REG) (const_int 0)]))]
10702   ""
10703   "set%C1\t%0"
10704   [(set_attr "type" "setcc")
10705    (set_attr "mode" "QI")])
10707 (define_insn "*setcc_qi_slp"
10708   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10709         (match_operator:QI 1 "ix86_comparison_operator"
10710           [(reg FLAGS_REG) (const_int 0)]))]
10711   ""
10712   "set%C1\t%0"
10713   [(set_attr "type" "setcc")
10714    (set_attr "mode" "QI")])
10716 ;; In general it is not safe to assume too much about CCmode registers,
10717 ;; so simplify-rtx stops when it sees a second one.  Under certain
10718 ;; conditions this is safe on x86, so help combine not create
10720 ;;      seta    %al
10721 ;;      testb   %al, %al
10722 ;;      sete    %al
10724 (define_split
10725   [(set (match_operand:QI 0 "nonimmediate_operand")
10726         (ne:QI (match_operator 1 "ix86_comparison_operator"
10727                  [(reg FLAGS_REG) (const_int 0)])
10728             (const_int 0)))]
10729   ""
10730   [(set (match_dup 0) (match_dup 1))]
10731   "PUT_MODE (operands[1], QImode);")
10733 (define_split
10734   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10735         (ne:QI (match_operator 1 "ix86_comparison_operator"
10736                  [(reg FLAGS_REG) (const_int 0)])
10737             (const_int 0)))]
10738   ""
10739   [(set (match_dup 0) (match_dup 1))]
10740   "PUT_MODE (operands[1], QImode);")
10742 (define_split
10743   [(set (match_operand:QI 0 "nonimmediate_operand")
10744         (eq:QI (match_operator 1 "ix86_comparison_operator"
10745                  [(reg FLAGS_REG) (const_int 0)])
10746             (const_int 0)))]
10747   ""
10748   [(set (match_dup 0) (match_dup 1))]
10750   rtx new_op1 = copy_rtx (operands[1]);
10751   operands[1] = new_op1;
10752   PUT_MODE (new_op1, QImode);
10753   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10754                                              GET_MODE (XEXP (new_op1, 0))));
10756   /* Make sure that (a) the CCmode we have for the flags is strong
10757      enough for the reversed compare or (b) we have a valid FP compare.  */
10758   if (! ix86_comparison_operator (new_op1, VOIDmode))
10759     FAIL;
10762 (define_split
10763   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10764         (eq:QI (match_operator 1 "ix86_comparison_operator"
10765                  [(reg FLAGS_REG) (const_int 0)])
10766             (const_int 0)))]
10767   ""
10768   [(set (match_dup 0) (match_dup 1))]
10770   rtx new_op1 = copy_rtx (operands[1]);
10771   operands[1] = new_op1;
10772   PUT_MODE (new_op1, QImode);
10773   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10774                                              GET_MODE (XEXP (new_op1, 0))));
10776   /* Make sure that (a) the CCmode we have for the flags is strong
10777      enough for the reversed compare or (b) we have a valid FP compare.  */
10778   if (! ix86_comparison_operator (new_op1, VOIDmode))
10779     FAIL;
10782 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10783 ;; subsequent logical operations are used to imitate conditional moves.
10784 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10785 ;; it directly.
10787 (define_insn "setcc_<mode>_sse"
10788   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10789         (match_operator:MODEF 3 "sse_comparison_operator"
10790           [(match_operand:MODEF 1 "register_operand" "0,x")
10791            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10792   "SSE_FLOAT_MODE_P (<MODE>mode)"
10793   "@
10794    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10795    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10796   [(set_attr "isa" "noavx,avx")
10797    (set_attr "type" "ssecmp")
10798    (set_attr "length_immediate" "1")
10799    (set_attr "prefix" "orig,vex")
10800    (set_attr "mode" "<MODE>")])
10802 ;; Basic conditional jump instructions.
10803 ;; We ignore the overflow flag for signed branch instructions.
10805 (define_insn "*jcc_1"
10806   [(set (pc)
10807         (if_then_else (match_operator 1 "ix86_comparison_operator"
10808                                       [(reg FLAGS_REG) (const_int 0)])
10809                       (label_ref (match_operand 0))
10810                       (pc)))]
10811   ""
10812   "%+j%C1\t%l0"
10813   [(set_attr "type" "ibr")
10814    (set_attr "modrm" "0")
10815    (set (attr "length")
10816            (if_then_else (and (ge (minus (match_dup 0) (pc))
10817                                   (const_int -126))
10818                               (lt (minus (match_dup 0) (pc))
10819                                   (const_int 128)))
10820              (const_int 2)
10821              (const_int 6)))])
10823 (define_insn "*jcc_2"
10824   [(set (pc)
10825         (if_then_else (match_operator 1 "ix86_comparison_operator"
10826                                       [(reg FLAGS_REG) (const_int 0)])
10827                       (pc)
10828                       (label_ref (match_operand 0))))]
10829   ""
10830   "%+j%c1\t%l0"
10831   [(set_attr "type" "ibr")
10832    (set_attr "modrm" "0")
10833    (set (attr "length")
10834            (if_then_else (and (ge (minus (match_dup 0) (pc))
10835                                   (const_int -126))
10836                               (lt (minus (match_dup 0) (pc))
10837                                   (const_int 128)))
10838              (const_int 2)
10839              (const_int 6)))])
10841 ;; In general it is not safe to assume too much about CCmode registers,
10842 ;; so simplify-rtx stops when it sees a second one.  Under certain
10843 ;; conditions this is safe on x86, so help combine not create
10845 ;;      seta    %al
10846 ;;      testb   %al, %al
10847 ;;      je      Lfoo
10849 (define_split
10850   [(set (pc)
10851         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10852                                       [(reg FLAGS_REG) (const_int 0)])
10853                           (const_int 0))
10854                       (label_ref (match_operand 1))
10855                       (pc)))]
10856   ""
10857   [(set (pc)
10858         (if_then_else (match_dup 0)
10859                       (label_ref (match_dup 1))
10860                       (pc)))]
10861   "PUT_MODE (operands[0], VOIDmode);")
10863 (define_split
10864   [(set (pc)
10865         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10866                                       [(reg FLAGS_REG) (const_int 0)])
10867                           (const_int 0))
10868                       (label_ref (match_operand 1))
10869                       (pc)))]
10870   ""
10871   [(set (pc)
10872         (if_then_else (match_dup 0)
10873                       (label_ref (match_dup 1))
10874                       (pc)))]
10876   rtx new_op0 = copy_rtx (operands[0]);
10877   operands[0] = new_op0;
10878   PUT_MODE (new_op0, VOIDmode);
10879   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10880                                              GET_MODE (XEXP (new_op0, 0))));
10882   /* Make sure that (a) the CCmode we have for the flags is strong
10883      enough for the reversed compare or (b) we have a valid FP compare.  */
10884   if (! ix86_comparison_operator (new_op0, VOIDmode))
10885     FAIL;
10888 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10889 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10890 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10891 ;; appropriate modulo of the bit offset value.
10893 (define_insn_and_split "*jcc_bt<mode>"
10894   [(set (pc)
10895         (if_then_else (match_operator 0 "bt_comparison_operator"
10896                         [(zero_extract:SWI48
10897                            (match_operand:SWI48 1 "register_operand" "r")
10898                            (const_int 1)
10899                            (zero_extend:SI
10900                              (match_operand:QI 2 "register_operand" "r")))
10901                          (const_int 0)])
10902                       (label_ref (match_operand 3))
10903                       (pc)))
10904    (clobber (reg:CC FLAGS_REG))]
10905   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10906   "#"
10907   "&& 1"
10908   [(set (reg:CCC FLAGS_REG)
10909         (compare:CCC
10910           (zero_extract:SWI48
10911             (match_dup 1)
10912             (const_int 1)
10913             (match_dup 2))
10914           (const_int 0)))
10915    (set (pc)
10916         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10917                       (label_ref (match_dup 3))
10918                       (pc)))]
10920   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10922   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10925 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
10926 ;; zero extended to SImode.
10927 (define_insn_and_split "*jcc_bt<mode>_1"
10928   [(set (pc)
10929         (if_then_else (match_operator 0 "bt_comparison_operator"
10930                         [(zero_extract:SWI48
10931                            (match_operand:SWI48 1 "register_operand" "r")
10932                            (const_int 1)
10933                            (match_operand:SI 2 "register_operand" "r"))
10934                          (const_int 0)])
10935                       (label_ref (match_operand 3))
10936                       (pc)))
10937    (clobber (reg:CC FLAGS_REG))]
10938   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10939   "#"
10940   "&& 1"
10941   [(set (reg:CCC FLAGS_REG)
10942         (compare:CCC
10943           (zero_extract:SWI48
10944             (match_dup 1)
10945             (const_int 1)
10946             (match_dup 2))
10947           (const_int 0)))
10948    (set (pc)
10949         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10950                       (label_ref (match_dup 3))
10951                       (pc)))]
10953   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10955   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10958 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10959 ;; also for DImode, this is what combine produces.
10960 (define_insn_and_split "*jcc_bt<mode>_mask"
10961   [(set (pc)
10962         (if_then_else (match_operator 0 "bt_comparison_operator"
10963                         [(zero_extract:SWI48
10964                            (match_operand:SWI48 1 "register_operand" "r")
10965                            (const_int 1)
10966                            (and:SI
10967                              (match_operand:SI 2 "register_operand" "r")
10968                              (match_operand:SI 3 "const_int_operand" "n")))])
10969                       (label_ref (match_operand 4))
10970                       (pc)))
10971    (clobber (reg:CC FLAGS_REG))]
10972   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10973    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10974       == GET_MODE_BITSIZE (<MODE>mode)-1"
10975   "#"
10976   "&& 1"
10977   [(set (reg:CCC FLAGS_REG)
10978         (compare:CCC
10979           (zero_extract:SWI48
10980             (match_dup 1)
10981             (const_int 1)
10982             (match_dup 2))
10983           (const_int 0)))
10984    (set (pc)
10985         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10986                       (label_ref (match_dup 4))
10987                       (pc)))]
10989   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10991   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10994 (define_insn_and_split "*jcc_btsi_1"
10995   [(set (pc)
10996         (if_then_else (match_operator 0 "bt_comparison_operator"
10997                         [(and:SI
10998                            (lshiftrt:SI
10999                              (match_operand:SI 1 "register_operand" "r")
11000                              (match_operand:QI 2 "register_operand" "r"))
11001                            (const_int 1))
11002                          (const_int 0)])
11003                       (label_ref (match_operand 3))
11004                       (pc)))
11005    (clobber (reg:CC FLAGS_REG))]
11006   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11007   "#"
11008   "&& 1"
11009   [(set (reg:CCC FLAGS_REG)
11010         (compare:CCC
11011           (zero_extract:SI
11012             (match_dup 1)
11013             (const_int 1)
11014             (match_dup 2))
11015           (const_int 0)))
11016    (set (pc)
11017         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11018                       (label_ref (match_dup 3))
11019                       (pc)))]
11021   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11023   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11026 ;; avoid useless masking of bit offset operand
11027 (define_insn_and_split "*jcc_btsi_mask_1"
11028   [(set (pc)
11029         (if_then_else
11030           (match_operator 0 "bt_comparison_operator"
11031             [(and:SI
11032                (lshiftrt:SI
11033                  (match_operand:SI 1 "register_operand" "r")
11034                  (subreg:QI
11035                    (and:SI
11036                      (match_operand:SI 2 "register_operand" "r")
11037                      (match_operand:SI 3 "const_int_operand" "n")) 0))
11038                (const_int 1))
11039              (const_int 0)])
11040           (label_ref (match_operand 4))
11041           (pc)))
11042    (clobber (reg:CC FLAGS_REG))]
11043   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11044    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11045   "#"
11046   "&& 1"
11047   [(set (reg:CCC FLAGS_REG)
11048         (compare:CCC
11049           (zero_extract:SI
11050             (match_dup 1)
11051             (const_int 1)
11052             (match_dup 2))
11053           (const_int 0)))
11054    (set (pc)
11055         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11056                       (label_ref (match_dup 4))
11057                       (pc)))]
11058   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11060 ;; Define combination compare-and-branch fp compare instructions to help
11061 ;; combine.
11063 (define_insn "*jcc<mode>_0_i387"
11064   [(set (pc)
11065         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11066                         [(match_operand:X87MODEF 1 "register_operand" "f")
11067                          (match_operand:X87MODEF 2 "const0_operand")])
11068           (label_ref (match_operand 3))
11069           (pc)))
11070    (clobber (reg:CCFP FPSR_REG))
11071    (clobber (reg:CCFP FLAGS_REG))
11072    (clobber (match_scratch:HI 4 "=a"))]
11073   "TARGET_80387 && !TARGET_CMOVE"
11074   "#")
11076 (define_insn "*jcc<mode>_0_r_i387"
11077   [(set (pc)
11078         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11079                         [(match_operand:X87MODEF 1 "register_operand" "f")
11080                          (match_operand:X87MODEF 2 "const0_operand")])
11081           (pc)
11082           (label_ref (match_operand 3))))
11083    (clobber (reg:CCFP FPSR_REG))
11084    (clobber (reg:CCFP FLAGS_REG))
11085    (clobber (match_scratch:HI 4 "=a"))]
11086   "TARGET_80387 && !TARGET_CMOVE"
11087   "#")
11089 (define_insn "*jccxf_i387"
11090   [(set (pc)
11091         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11092                         [(match_operand:XF 1 "register_operand" "f")
11093                          (match_operand:XF 2 "register_operand" "f")])
11094           (label_ref (match_operand 3))
11095           (pc)))
11096    (clobber (reg:CCFP FPSR_REG))
11097    (clobber (reg:CCFP FLAGS_REG))
11098    (clobber (match_scratch:HI 4 "=a"))]
11099   "TARGET_80387 && !TARGET_CMOVE"
11100   "#")
11102 (define_insn "*jccxf_r_i387"
11103   [(set (pc)
11104         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11105                         [(match_operand:XF 1 "register_operand" "f")
11106                          (match_operand:XF 2 "register_operand" "f")])
11107           (pc)
11108           (label_ref (match_operand 3))))
11109    (clobber (reg:CCFP FPSR_REG))
11110    (clobber (reg:CCFP FLAGS_REG))
11111    (clobber (match_scratch:HI 4 "=a"))]
11112   "TARGET_80387 && !TARGET_CMOVE"
11113   "#")
11115 (define_insn "*jcc<mode>_i387"
11116   [(set (pc)
11117         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11118                         [(match_operand:MODEF 1 "register_operand" "f")
11119                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11120           (label_ref (match_operand 3))
11121           (pc)))
11122    (clobber (reg:CCFP FPSR_REG))
11123    (clobber (reg:CCFP FLAGS_REG))
11124    (clobber (match_scratch:HI 4 "=a"))]
11125   "TARGET_80387 && !TARGET_CMOVE"
11126   "#")
11128 (define_insn "*jcc<mode>_r_i387"
11129   [(set (pc)
11130         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11131                         [(match_operand:MODEF 1 "register_operand" "f")
11132                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11133           (pc)
11134           (label_ref (match_operand 3))))
11135    (clobber (reg:CCFP FPSR_REG))
11136    (clobber (reg:CCFP FLAGS_REG))
11137    (clobber (match_scratch:HI 4 "=a"))]
11138   "TARGET_80387 && !TARGET_CMOVE"
11139   "#")
11141 (define_insn "*jccu<mode>_i387"
11142   [(set (pc)
11143         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11144                         [(match_operand:X87MODEF 1 "register_operand" "f")
11145                          (match_operand:X87MODEF 2 "register_operand" "f")])
11146           (label_ref (match_operand 3))
11147           (pc)))
11148    (clobber (reg:CCFP FPSR_REG))
11149    (clobber (reg:CCFP FLAGS_REG))
11150    (clobber (match_scratch:HI 4 "=a"))]
11151   "TARGET_80387 && !TARGET_CMOVE"
11152   "#")
11154 (define_insn "*jccu<mode>_r_i387"
11155   [(set (pc)
11156         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11157                         [(match_operand:X87MODEF 1 "register_operand" "f")
11158                          (match_operand:X87MODEF 2 "register_operand" "f")])
11159           (pc)
11160           (label_ref (match_operand 3))))
11161    (clobber (reg:CCFP FPSR_REG))
11162    (clobber (reg:CCFP FLAGS_REG))
11163    (clobber (match_scratch:HI 4 "=a"))]
11164   "TARGET_80387 && !TARGET_CMOVE"
11165   "#")
11167 (define_split
11168   [(set (pc)
11169         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11170                         [(match_operand:X87MODEF 1 "register_operand")
11171                          (match_operand:X87MODEF 2 "nonimmediate_operand")])
11172           (match_operand 3)
11173           (match_operand 4)))
11174    (clobber (reg:CCFP FPSR_REG))
11175    (clobber (reg:CCFP FLAGS_REG))]
11176   "TARGET_80387 && !TARGET_CMOVE
11177    && reload_completed"
11178   [(const_int 0)]
11180   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11181                         operands[3], operands[4], NULL_RTX);
11182   DONE;
11185 (define_split
11186   [(set (pc)
11187         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11188                         [(match_operand:X87MODEF 1 "register_operand")
11189                          (match_operand:X87MODEF 2 "general_operand")])
11190           (match_operand 3)
11191           (match_operand 4)))
11192    (clobber (reg:CCFP FPSR_REG))
11193    (clobber (reg:CCFP FLAGS_REG))
11194    (clobber (match_scratch:HI 5))]
11195   "TARGET_80387 && !TARGET_CMOVE
11196    && reload_completed"
11197   [(const_int 0)]
11199   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11200                         operands[3], operands[4], operands[5]);
11201   DONE;
11204 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11205 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11206 ;; with a precedence over other operators and is always put in the first
11207 ;; place. Swap condition and operands to match ficom instruction.
11209 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11210   [(set (pc)
11211         (if_then_else
11212           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11213             [(match_operator:X87MODEF 1 "float_operator"
11214               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11215              (match_operand:X87MODEF 3 "register_operand" "f")])
11216           (label_ref (match_operand 4))
11217           (pc)))
11218    (clobber (reg:CCFP FPSR_REG))
11219    (clobber (reg:CCFP FLAGS_REG))
11220    (clobber (match_scratch:HI 5 "=a"))]
11221   "TARGET_80387 && !TARGET_CMOVE
11222    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11223        || optimize_function_for_size_p (cfun))"
11224   "#")
11226 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11227   [(set (pc)
11228         (if_then_else
11229           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11230             [(match_operator:X87MODEF 1 "float_operator"
11231               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11232              (match_operand:X87MODEF 3 "register_operand" "f")])
11233           (pc)
11234           (label_ref (match_operand 4))))
11235    (clobber (reg:CCFP FPSR_REG))
11236    (clobber (reg:CCFP FLAGS_REG))
11237    (clobber (match_scratch:HI 5 "=a"))]
11238   "TARGET_80387 && !TARGET_CMOVE
11239    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11240        || optimize_function_for_size_p (cfun))"
11241   "#")
11243 (define_split
11244   [(set (pc)
11245         (if_then_else
11246           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11247             [(match_operator:X87MODEF 1 "float_operator"
11248               [(match_operand:SWI24 2 "memory_operand")])
11249              (match_operand:X87MODEF 3 "register_operand")])
11250           (match_operand 4)
11251           (match_operand 5)))
11252    (clobber (reg:CCFP FPSR_REG))
11253    (clobber (reg:CCFP FLAGS_REG))
11254    (clobber (match_scratch:HI 6))]
11255   "TARGET_80387 && !TARGET_CMOVE
11256    && reload_completed"
11257   [(const_int 0)]
11259   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11260                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11261                         operands[4], operands[5], operands[6]);
11262   DONE;
11265 ;; Unconditional and other jump instructions
11267 (define_insn "jump"
11268   [(set (pc)
11269         (label_ref (match_operand 0)))]
11270   ""
11271   "jmp\t%l0"
11272   [(set_attr "type" "ibr")
11273    (set (attr "length")
11274            (if_then_else (and (ge (minus (match_dup 0) (pc))
11275                                   (const_int -126))
11276                               (lt (minus (match_dup 0) (pc))
11277                                   (const_int 128)))
11278              (const_int 2)
11279              (const_int 5)))
11280    (set_attr "modrm" "0")])
11282 (define_expand "indirect_jump"
11283   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11284   ""
11286   if (TARGET_X32)
11287     operands[0] = convert_memory_address (word_mode, operands[0]);
11290 (define_insn "*indirect_jump"
11291   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11292   ""
11293   "jmp\t%A0"
11294   [(set_attr "type" "ibr")
11295    (set_attr "length_immediate" "0")])
11297 (define_expand "tablejump"
11298   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11299               (use (label_ref (match_operand 1)))])]
11300   ""
11302   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11303      relative.  Convert the relative address to an absolute address.  */
11304   if (flag_pic)
11305     {
11306       rtx op0, op1;
11307       enum rtx_code code;
11309       /* We can't use @GOTOFF for text labels on VxWorks;
11310          see gotoff_operand.  */
11311       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11312         {
11313           code = PLUS;
11314           op0 = operands[0];
11315           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11316         }
11317       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11318         {
11319           code = PLUS;
11320           op0 = operands[0];
11321           op1 = pic_offset_table_rtx;
11322         }
11323       else
11324         {
11325           code = MINUS;
11326           op0 = pic_offset_table_rtx;
11327           op1 = operands[0];
11328         }
11330       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11331                                          OPTAB_DIRECT);
11332     }
11334   if (TARGET_X32)
11335     operands[0] = convert_memory_address (word_mode, operands[0]);
11338 (define_insn "*tablejump_1"
11339   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11340    (use (label_ref (match_operand 1)))]
11341   ""
11342   "jmp\t%A0"
11343   [(set_attr "type" "ibr")
11344    (set_attr "length_immediate" "0")])
11346 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11348 (define_peephole2
11349   [(set (reg FLAGS_REG) (match_operand 0))
11350    (set (match_operand:QI 1 "register_operand")
11351         (match_operator:QI 2 "ix86_comparison_operator"
11352           [(reg FLAGS_REG) (const_int 0)]))
11353    (set (match_operand 3 "q_regs_operand")
11354         (zero_extend (match_dup 1)))]
11355   "(peep2_reg_dead_p (3, operands[1])
11356     || operands_match_p (operands[1], operands[3]))
11357    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11358   [(set (match_dup 4) (match_dup 0))
11359    (set (strict_low_part (match_dup 5))
11360         (match_dup 2))]
11362   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11363   operands[5] = gen_lowpart (QImode, operands[3]);
11364   ix86_expand_clear (operands[3]);
11367 (define_peephole2
11368   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11369               (match_operand 4)])
11370    (set (match_operand:QI 1 "register_operand")
11371         (match_operator:QI 2 "ix86_comparison_operator"
11372           [(reg FLAGS_REG) (const_int 0)]))
11373    (set (match_operand 3 "q_regs_operand")
11374         (zero_extend (match_dup 1)))]
11375   "(peep2_reg_dead_p (3, operands[1])
11376     || operands_match_p (operands[1], operands[3]))
11377    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11378   [(parallel [(set (match_dup 5) (match_dup 0))
11379               (match_dup 4)])
11380    (set (strict_low_part (match_dup 6))
11381         (match_dup 2))]
11383   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11384   operands[6] = gen_lowpart (QImode, operands[3]);
11385   ix86_expand_clear (operands[3]);
11388 ;; Similar, but match zero extend with andsi3.
11390 (define_peephole2
11391   [(set (reg FLAGS_REG) (match_operand 0))
11392    (set (match_operand:QI 1 "register_operand")
11393         (match_operator:QI 2 "ix86_comparison_operator"
11394           [(reg FLAGS_REG) (const_int 0)]))
11395    (parallel [(set (match_operand:SI 3 "q_regs_operand")
11396                    (and:SI (match_dup 3) (const_int 255)))
11397               (clobber (reg:CC FLAGS_REG))])]
11398   "REGNO (operands[1]) == REGNO (operands[3])
11399    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11400   [(set (match_dup 4) (match_dup 0))
11401    (set (strict_low_part (match_dup 5))
11402         (match_dup 2))]
11404   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11405   operands[5] = gen_lowpart (QImode, operands[3]);
11406   ix86_expand_clear (operands[3]);
11409 (define_peephole2
11410   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11411               (match_operand 4)])
11412    (set (match_operand:QI 1 "register_operand")
11413         (match_operator:QI 2 "ix86_comparison_operator"
11414           [(reg FLAGS_REG) (const_int 0)]))
11415    (parallel [(set (match_operand 3 "q_regs_operand")
11416                    (zero_extend (match_dup 1)))
11417               (clobber (reg:CC FLAGS_REG))])]
11418   "(peep2_reg_dead_p (3, operands[1])
11419     || operands_match_p (operands[1], operands[3]))
11420    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11421   [(parallel [(set (match_dup 5) (match_dup 0))
11422               (match_dup 4)])
11423    (set (strict_low_part (match_dup 6))
11424         (match_dup 2))]
11426   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11427   operands[6] = gen_lowpart (QImode, operands[3]);
11428   ix86_expand_clear (operands[3]);
11431 ;; Call instructions.
11433 ;; The predicates normally associated with named expanders are not properly
11434 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11435 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11437 ;; P6 processors will jump to the address after the decrement when %esp
11438 ;; is used as a call operand, so they will execute return address as a code.
11439 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11441 ;; Register constraint for call instruction.
11442 (define_mode_attr c [(SI "l") (DI "r")])
11444 ;; Call subroutine returning no value.
11446 (define_expand "call"
11447   [(call (match_operand:QI 0)
11448          (match_operand 1))
11449    (use (match_operand 2))]
11450   ""
11452   ix86_expand_call (NULL, operands[0], operands[1],
11453                     operands[2], NULL, false);
11454   DONE;
11457 (define_expand "sibcall"
11458   [(call (match_operand:QI 0)
11459          (match_operand 1))
11460    (use (match_operand 2))]
11461   ""
11463   ix86_expand_call (NULL, operands[0], operands[1],
11464                     operands[2], NULL, true);
11465   DONE;
11468 (define_insn "*call"
11469   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11470          (match_operand 1))]
11471   "!SIBLING_CALL_P (insn)"
11472   "* return ix86_output_call_insn (insn, operands[0]);"
11473   [(set_attr "type" "call")])
11475 (define_insn "*call_rex64_ms_sysv"
11476   [(match_parallel 2 "call_rex64_ms_sysv_operation"
11477     [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rBwBz"))
11478            (match_operand 1))
11479      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11480   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11481   "* return ix86_output_call_insn (insn, operands[0]);"
11482   [(set_attr "type" "call")])
11484 (define_insn "*sibcall"
11485   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11486          (match_operand 1))]
11487   "SIBLING_CALL_P (insn)"
11488   "* return ix86_output_call_insn (insn, operands[0]);"
11489   [(set_attr "type" "call")])
11491 (define_insn "*sibcall_memory"
11492   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11493          (match_operand 1))
11494    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11495   "!TARGET_X32"
11496   "* return ix86_output_call_insn (insn, operands[0]);"
11497   [(set_attr "type" "call")])
11499 (define_peephole2
11500   [(set (match_operand:W 0 "register_operand")
11501         (match_operand:W 1 "memory_operand"))
11502    (call (mem:QI (match_dup 0))
11503          (match_operand 3))]
11504   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11505    && peep2_reg_dead_p (2, operands[0])"
11506   [(parallel [(call (mem:QI (match_dup 1))
11507                     (match_dup 3))
11508               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11510 (define_peephole2
11511   [(set (match_operand:W 0 "register_operand")
11512         (match_operand:W 1 "memory_operand"))
11513    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11514    (call (mem:QI (match_dup 0))
11515          (match_operand 3))]
11516   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11517    && peep2_reg_dead_p (3, operands[0])"
11518   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11519    (parallel [(call (mem:QI (match_dup 1))
11520                     (match_dup 3))
11521               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11523 (define_expand "call_pop"
11524   [(parallel [(call (match_operand:QI 0)
11525                     (match_operand:SI 1))
11526               (set (reg:SI SP_REG)
11527                    (plus:SI (reg:SI SP_REG)
11528                             (match_operand:SI 3)))])]
11529   "!TARGET_64BIT"
11531   ix86_expand_call (NULL, operands[0], operands[1],
11532                     operands[2], operands[3], false);
11533   DONE;
11536 (define_insn "*call_pop"
11537   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11538          (match_operand 1))
11539    (set (reg:SI SP_REG)
11540         (plus:SI (reg:SI SP_REG)
11541                  (match_operand:SI 2 "immediate_operand" "i")))]
11542   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11543   "* return ix86_output_call_insn (insn, operands[0]);"
11544   [(set_attr "type" "call")])
11546 (define_insn "*sibcall_pop"
11547   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11548          (match_operand 1))
11549    (set (reg:SI SP_REG)
11550         (plus:SI (reg:SI SP_REG)
11551                  (match_operand:SI 2 "immediate_operand" "i")))]
11552   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11553   "* return ix86_output_call_insn (insn, operands[0]);"
11554   [(set_attr "type" "call")])
11556 (define_insn "*sibcall_pop_memory"
11557   [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11558          (match_operand 1))
11559    (set (reg:SI SP_REG)
11560         (plus:SI (reg:SI SP_REG)
11561                  (match_operand:SI 2 "immediate_operand" "i")))
11562    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11563   "!TARGET_64BIT"
11564   "* return ix86_output_call_insn (insn, operands[0]);"
11565   [(set_attr "type" "call")])
11567 (define_peephole2
11568   [(set (match_operand:SI 0 "register_operand")
11569         (match_operand:SI 1 "memory_operand"))
11570    (parallel [(call (mem:QI (match_dup 0))
11571                     (match_operand 3))
11572               (set (reg:SI SP_REG)
11573                    (plus:SI (reg:SI SP_REG)
11574                             (match_operand:SI 4 "immediate_operand")))])]
11575   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11576    && peep2_reg_dead_p (2, operands[0])"
11577   [(parallel [(call (mem:QI (match_dup 1))
11578                     (match_dup 3))
11579               (set (reg:SI SP_REG)
11580                    (plus:SI (reg:SI SP_REG)
11581                             (match_dup 4)))
11582               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11584 (define_peephole2
11585   [(set (match_operand:SI 0 "register_operand")
11586         (match_operand:SI 1 "memory_operand"))
11587    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11588    (parallel [(call (mem:QI (match_dup 0))
11589                     (match_operand 3))
11590               (set (reg:SI SP_REG)
11591                    (plus:SI (reg:SI SP_REG)
11592                             (match_operand:SI 4 "immediate_operand")))])]
11593   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11594    && peep2_reg_dead_p (3, operands[0])"
11595   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11596    (parallel [(call (mem:QI (match_dup 1))
11597                     (match_dup 3))
11598               (set (reg:SI SP_REG)
11599                    (plus:SI (reg:SI SP_REG)
11600                             (match_dup 4)))
11601               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11603 ;; Combining simple memory jump instruction
11605 (define_peephole2
11606   [(set (match_operand:W 0 "register_operand")
11607         (match_operand:W 1 "memory_operand"))
11608    (set (pc) (match_dup 0))]
11609   "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11610   [(set (pc) (match_dup 1))])
11612 ;; Call subroutine, returning value in operand 0
11614 (define_expand "call_value"
11615   [(set (match_operand 0)
11616         (call (match_operand:QI 1)
11617               (match_operand 2)))
11618    (use (match_operand 3))]
11619   ""
11621   ix86_expand_call (operands[0], operands[1], operands[2],
11622                     operands[3], NULL, false);
11623   DONE;
11626 (define_expand "sibcall_value"
11627   [(set (match_operand 0)
11628         (call (match_operand:QI 1)
11629               (match_operand 2)))
11630    (use (match_operand 3))]
11631   ""
11633   ix86_expand_call (operands[0], operands[1], operands[2],
11634                     operands[3], NULL, true);
11635   DONE;
11638 (define_insn "*call_value"
11639   [(set (match_operand 0)
11640         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11641               (match_operand 2)))]
11642   "!SIBLING_CALL_P (insn)"
11643   "* return ix86_output_call_insn (insn, operands[1]);"
11644   [(set_attr "type" "callv")])
11646 (define_insn "*sibcall_value"
11647   [(set (match_operand 0)
11648         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11649               (match_operand 2)))]
11650   "SIBLING_CALL_P (insn)"
11651   "* return ix86_output_call_insn (insn, operands[1]);"
11652   [(set_attr "type" "callv")])
11654 (define_insn "*sibcall_value_memory"
11655   [(set (match_operand 0)
11656         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11657               (match_operand 2)))
11658    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11659   "!TARGET_X32"
11660   "* return ix86_output_call_insn (insn, operands[1]);"
11661   [(set_attr "type" "callv")])
11663 (define_peephole2
11664   [(set (match_operand:W 0 "register_operand")
11665         (match_operand:W 1 "memory_operand"))
11666    (set (match_operand 2)
11667    (call (mem:QI (match_dup 0))
11668                  (match_operand 3)))]
11669   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11670    && peep2_reg_dead_p (2, operands[0])"
11671   [(parallel [(set (match_dup 2)
11672                    (call (mem:QI (match_dup 1))
11673                          (match_dup 3)))
11674               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11676 (define_peephole2
11677   [(set (match_operand:W 0 "register_operand")
11678         (match_operand:W 1 "memory_operand"))
11679    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11680    (set (match_operand 2)
11681         (call (mem:QI (match_dup 0))
11682               (match_operand 3)))]
11683   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11684    && peep2_reg_dead_p (3, operands[0])"
11685   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11686    (parallel [(set (match_dup 2)
11687                    (call (mem:QI (match_dup 1))
11688                          (match_dup 3)))
11689               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11691 (define_insn "*call_value_rex64_ms_sysv"
11692   [(match_parallel 3 "call_rex64_ms_sysv_operation"
11693     [(set (match_operand 0)
11694           (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rBwBz"))
11695                 (match_operand 2)))
11696      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11697  "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11698   "* return ix86_output_call_insn (insn, operands[1]);"
11699   [(set_attr "type" "callv")])
11701 (define_expand "call_value_pop"
11702   [(parallel [(set (match_operand 0)
11703                    (call (match_operand:QI 1)
11704                          (match_operand:SI 2)))
11705               (set (reg:SI SP_REG)
11706                    (plus:SI (reg:SI SP_REG)
11707                             (match_operand:SI 4)))])]
11708   "!TARGET_64BIT"
11710   ix86_expand_call (operands[0], operands[1], operands[2],
11711                     operands[3], operands[4], false);
11712   DONE;
11715 (define_insn "*call_value_pop"
11716   [(set (match_operand 0)
11717         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11718               (match_operand 2)))
11719    (set (reg:SI SP_REG)
11720         (plus:SI (reg:SI SP_REG)
11721                  (match_operand:SI 3 "immediate_operand" "i")))]
11722   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11723   "* return ix86_output_call_insn (insn, operands[1]);"
11724   [(set_attr "type" "callv")])
11726 (define_insn "*sibcall_value_pop"
11727   [(set (match_operand 0)
11728         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11729               (match_operand 2)))
11730    (set (reg:SI SP_REG)
11731         (plus:SI (reg:SI SP_REG)
11732                  (match_operand:SI 3 "immediate_operand" "i")))]
11733   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11734   "* return ix86_output_call_insn (insn, operands[1]);"
11735   [(set_attr "type" "callv")])
11737 (define_insn "*sibcall_value_pop_memory"
11738   [(set (match_operand 0)
11739         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11740               (match_operand 2)))
11741    (set (reg:SI SP_REG)
11742         (plus:SI (reg:SI SP_REG)
11743                  (match_operand:SI 3 "immediate_operand" "i")))
11744    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11745   "!TARGET_64BIT"
11746   "* return ix86_output_call_insn (insn, operands[1]);"
11747   [(set_attr "type" "callv")])
11749 (define_peephole2
11750   [(set (match_operand:SI 0 "register_operand")
11751         (match_operand:SI 1 "memory_operand"))
11752    (parallel [(set (match_operand 2)
11753                    (call (mem:QI (match_dup 0))
11754                          (match_operand 3)))
11755               (set (reg:SI SP_REG)
11756                    (plus:SI (reg:SI SP_REG)
11757                             (match_operand:SI 4 "immediate_operand")))])]
11758   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11759    && peep2_reg_dead_p (2, operands[0])"
11760   [(parallel [(set (match_dup 2)
11761                    (call (mem:QI (match_dup 1))
11762                          (match_dup 3)))
11763               (set (reg:SI SP_REG)
11764                    (plus:SI (reg:SI SP_REG)
11765                             (match_dup 4)))
11766               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11768 (define_peephole2
11769   [(set (match_operand:SI 0 "register_operand")
11770         (match_operand:SI 1 "memory_operand"))
11771    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11772    (parallel [(set (match_operand 2)
11773                    (call (mem:QI (match_dup 0))
11774                          (match_operand 3)))
11775               (set (reg:SI SP_REG)
11776                    (plus:SI (reg:SI SP_REG)
11777                             (match_operand:SI 4 "immediate_operand")))])]
11778   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11779    && peep2_reg_dead_p (3, operands[0])"
11780   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11781    (parallel [(set (match_dup 2)
11782                    (call (mem:QI (match_dup 1))
11783                          (match_dup 3)))
11784               (set (reg:SI SP_REG)
11785                    (plus:SI (reg:SI SP_REG)
11786                             (match_dup 4)))
11787               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11789 ;; Call subroutine returning any type.
11791 (define_expand "untyped_call"
11792   [(parallel [(call (match_operand 0)
11793                     (const_int 0))
11794               (match_operand 1)
11795               (match_operand 2)])]
11796   ""
11798   int i;
11800   /* In order to give reg-stack an easier job in validating two
11801      coprocessor registers as containing a possible return value,
11802      simply pretend the untyped call returns a complex long double
11803      value. 
11805      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11806      and should have the default ABI.  */
11808   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11809                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11810                     operands[0], const0_rtx,
11811                     GEN_INT ((TARGET_64BIT
11812                               ? (ix86_abi == SYSV_ABI
11813                                  ? X86_64_SSE_REGPARM_MAX
11814                                  : X86_64_MS_SSE_REGPARM_MAX)
11815                               : X86_32_SSE_REGPARM_MAX)
11816                              - 1),
11817                     NULL, false);
11819   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11820     {
11821       rtx set = XVECEXP (operands[2], 0, i);
11822       emit_move_insn (SET_DEST (set), SET_SRC (set));
11823     }
11825   /* The optimizer does not know that the call sets the function value
11826      registers we stored in the result block.  We avoid problems by
11827      claiming that all hard registers are used and clobbered at this
11828      point.  */
11829   emit_insn (gen_blockage ());
11831   DONE;
11834 ;; Prologue and epilogue instructions
11836 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11837 ;; all of memory.  This blocks insns from being moved across this point.
11839 (define_insn "blockage"
11840   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11841   ""
11842   ""
11843   [(set_attr "length" "0")])
11845 ;; Do not schedule instructions accessing memory across this point.
11847 (define_expand "memory_blockage"
11848   [(set (match_dup 0)
11849         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11850   ""
11852   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11853   MEM_VOLATILE_P (operands[0]) = 1;
11856 (define_insn "*memory_blockage"
11857   [(set (match_operand:BLK 0)
11858         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11859   ""
11860   ""
11861   [(set_attr "length" "0")])
11863 ;; As USE insns aren't meaningful after reload, this is used instead
11864 ;; to prevent deleting instructions setting registers for PIC code
11865 (define_insn "prologue_use"
11866   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11867   ""
11868   ""
11869   [(set_attr "length" "0")])
11871 ;; Insn emitted into the body of a function to return from a function.
11872 ;; This is only done if the function's epilogue is known to be simple.
11873 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11875 (define_expand "return"
11876   [(simple_return)]
11877   "ix86_can_use_return_insn_p ()"
11879   if (crtl->args.pops_args)
11880     {
11881       rtx popc = GEN_INT (crtl->args.pops_args);
11882       emit_jump_insn (gen_simple_return_pop_internal (popc));
11883       DONE;
11884     }
11887 ;; We need to disable this for TARGET_SEH, as otherwise
11888 ;; shrink-wrapped prologue gets enabled too.  This might exceed
11889 ;; the maximum size of prologue in unwind information.
11891 (define_expand "simple_return"
11892   [(simple_return)]
11893   "!TARGET_SEH"
11895   if (crtl->args.pops_args)
11896     {
11897       rtx popc = GEN_INT (crtl->args.pops_args);
11898       emit_jump_insn (gen_simple_return_pop_internal (popc));
11899       DONE;
11900     }
11903 (define_insn "simple_return_internal"
11904   [(simple_return)]
11905   "reload_completed"
11906   "ret"
11907   [(set_attr "length" "1")
11908    (set_attr "atom_unit" "jeu")
11909    (set_attr "length_immediate" "0")
11910    (set_attr "modrm" "0")])
11912 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11913 ;; instruction Athlon and K8 have.
11915 (define_insn "simple_return_internal_long"
11916   [(simple_return)
11917    (unspec [(const_int 0)] UNSPEC_REP)]
11918   "reload_completed"
11919   "rep%; ret"
11920   [(set_attr "length" "2")
11921    (set_attr "atom_unit" "jeu")
11922    (set_attr "length_immediate" "0")
11923    (set_attr "prefix_rep" "1")
11924    (set_attr "modrm" "0")])
11926 (define_insn "simple_return_pop_internal"
11927   [(simple_return)
11928    (use (match_operand:SI 0 "const_int_operand"))]
11929   "reload_completed"
11930   "ret\t%0"
11931   [(set_attr "length" "3")
11932    (set_attr "atom_unit" "jeu")
11933    (set_attr "length_immediate" "2")
11934    (set_attr "modrm" "0")])
11936 (define_insn "simple_return_indirect_internal"
11937   [(simple_return)
11938    (use (match_operand:SI 0 "register_operand" "r"))]
11939   "reload_completed"
11940   "jmp\t%A0"
11941   [(set_attr "type" "ibr")
11942    (set_attr "length_immediate" "0")])
11944 (define_insn "nop"
11945   [(const_int 0)]
11946   ""
11947   "nop"
11948   [(set_attr "length" "1")
11949    (set_attr "length_immediate" "0")
11950    (set_attr "modrm" "0")])
11952 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11953 (define_insn "nops"
11954   [(unspec_volatile [(match_operand 0 "const_int_operand")]
11955                     UNSPECV_NOPS)]
11956   "reload_completed"
11958   int num = INTVAL (operands[0]);
11960   gcc_assert (IN_RANGE (num, 1, 8));
11962   while (num--)
11963     fputs ("\tnop\n", asm_out_file);
11965   return "";
11967   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11968    (set_attr "length_immediate" "0")
11969    (set_attr "modrm" "0")])
11971 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11972 ;; branch prediction penalty for the third jump in a 16-byte
11973 ;; block on K8.
11975 (define_insn "pad"
11976   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11977   ""
11979 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11980   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11981 #else
11982   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11983      The align insn is used to avoid 3 jump instructions in the row to improve
11984      branch prediction and the benefits hardly outweigh the cost of extra 8
11985      nops on the average inserted by full alignment pseudo operation.  */
11986 #endif
11987   return "";
11989   [(set_attr "length" "16")])
11991 (define_expand "prologue"
11992   [(const_int 0)]
11993   ""
11994   "ix86_expand_prologue (); DONE;")
11996 (define_insn "set_got"
11997   [(set (match_operand:SI 0 "register_operand" "=r")
11998         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11999    (clobber (reg:CC FLAGS_REG))]
12000   "!TARGET_64BIT"
12001   "* return output_set_got (operands[0], NULL_RTX);"
12002   [(set_attr "type" "multi")
12003    (set_attr "length" "12")])
12005 (define_insn "set_got_labelled"
12006   [(set (match_operand:SI 0 "register_operand" "=r")
12007         (unspec:SI [(label_ref (match_operand 1))]
12008          UNSPEC_SET_GOT))
12009    (clobber (reg:CC FLAGS_REG))]
12010   "!TARGET_64BIT"
12011   "* return output_set_got (operands[0], operands[1]);"
12012   [(set_attr "type" "multi")
12013    (set_attr "length" "12")])
12015 (define_insn "set_got_rex64"
12016   [(set (match_operand:DI 0 "register_operand" "=r")
12017         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12018   "TARGET_64BIT"
12019   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12020   [(set_attr "type" "lea")
12021    (set_attr "length_address" "4")
12022    (set_attr "mode" "DI")])
12024 (define_insn "set_rip_rex64"
12025   [(set (match_operand:DI 0 "register_operand" "=r")
12026         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12027   "TARGET_64BIT"
12028   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12029   [(set_attr "type" "lea")
12030    (set_attr "length_address" "4")
12031    (set_attr "mode" "DI")])
12033 (define_insn "set_got_offset_rex64"
12034   [(set (match_operand:DI 0 "register_operand" "=r")
12035         (unspec:DI
12036           [(label_ref (match_operand 1))]
12037           UNSPEC_SET_GOT_OFFSET))]
12038   "TARGET_LP64"
12039   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12040   [(set_attr "type" "imov")
12041    (set_attr "length_immediate" "0")
12042    (set_attr "length_address" "8")
12043    (set_attr "mode" "DI")])
12045 (define_expand "epilogue"
12046   [(const_int 0)]
12047   ""
12048   "ix86_expand_epilogue (1); DONE;")
12050 (define_expand "sibcall_epilogue"
12051   [(const_int 0)]
12052   ""
12053   "ix86_expand_epilogue (0); DONE;")
12055 (define_expand "eh_return"
12056   [(use (match_operand 0 "register_operand"))]
12057   ""
12059   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12061   /* Tricky bit: we write the address of the handler to which we will
12062      be returning into someone else's stack frame, one word below the
12063      stack address we wish to restore.  */
12064   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12065   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12066   tmp = gen_rtx_MEM (Pmode, tmp);
12067   emit_move_insn (tmp, ra);
12069   emit_jump_insn (gen_eh_return_internal ());
12070   emit_barrier ();
12071   DONE;
12074 (define_insn_and_split "eh_return_internal"
12075   [(eh_return)]
12076   ""
12077   "#"
12078   "epilogue_completed"
12079   [(const_int 0)]
12080   "ix86_expand_epilogue (2); DONE;")
12082 (define_insn "leave"
12083   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12084    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12085    (clobber (mem:BLK (scratch)))]
12086   "!TARGET_64BIT"
12087   "leave"
12088   [(set_attr "type" "leave")])
12090 (define_insn "leave_rex64"
12091   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12092    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12093    (clobber (mem:BLK (scratch)))]
12094   "TARGET_64BIT"
12095   "leave"
12096   [(set_attr "type" "leave")])
12098 ;; Handle -fsplit-stack.
12100 (define_expand "split_stack_prologue"
12101   [(const_int 0)]
12102   ""
12104   ix86_expand_split_stack_prologue ();
12105   DONE;
12108 ;; In order to support the call/return predictor, we use a return
12109 ;; instruction which the middle-end doesn't see.
12110 (define_insn "split_stack_return"
12111   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12112                      UNSPECV_SPLIT_STACK_RETURN)]
12113   ""
12115   if (operands[0] == const0_rtx)
12116     return "ret";
12117   else
12118     return "ret\t%0";
12120   [(set_attr "atom_unit" "jeu")
12121    (set_attr "modrm" "0")
12122    (set (attr "length")
12123         (if_then_else (match_operand:SI 0 "const0_operand")
12124                       (const_int 1)
12125                       (const_int 3)))
12126    (set (attr "length_immediate")
12127         (if_then_else (match_operand:SI 0 "const0_operand")
12128                       (const_int 0)
12129                       (const_int 2)))])
12131 ;; If there are operand 0 bytes available on the stack, jump to
12132 ;; operand 1.
12134 (define_expand "split_stack_space_check"
12135   [(set (pc) (if_then_else
12136               (ltu (minus (reg SP_REG)
12137                           (match_operand 0 "register_operand"))
12138                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12139               (label_ref (match_operand 1))
12140               (pc)))]
12141   ""
12143   rtx reg, size, limit;
12145   reg = gen_reg_rtx (Pmode);
12146   size = force_reg (Pmode, operands[0]);
12147   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12148   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12149                           UNSPEC_STACK_CHECK);
12150   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12151   ix86_expand_branch (GEU, reg, limit, operands[1]);
12153   DONE;
12156 ;; Bit manipulation instructions.
12158 (define_expand "ffs<mode>2"
12159   [(set (match_dup 2) (const_int -1))
12160    (parallel [(set (match_dup 3) (match_dup 4))
12161               (set (match_operand:SWI48 0 "register_operand")
12162                    (ctz:SWI48
12163                      (match_operand:SWI48 1 "nonimmediate_operand")))])
12164    (set (match_dup 0) (if_then_else:SWI48
12165                         (eq (match_dup 3) (const_int 0))
12166                         (match_dup 2)
12167                         (match_dup 0)))
12168    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12169               (clobber (reg:CC FLAGS_REG))])]
12170   ""
12172   enum machine_mode flags_mode;
12174   if (<MODE>mode == SImode && !TARGET_CMOVE)
12175     {
12176       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12177       DONE;
12178     }
12180   flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12182   operands[2] = gen_reg_rtx (<MODE>mode);
12183   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12184   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12187 (define_insn_and_split "ffssi2_no_cmove"
12188   [(set (match_operand:SI 0 "register_operand" "=r")
12189         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12190    (clobber (match_scratch:SI 2 "=&q"))
12191    (clobber (reg:CC FLAGS_REG))]
12192   "!TARGET_CMOVE"
12193   "#"
12194   "&& reload_completed"
12195   [(parallel [(set (match_dup 4) (match_dup 5))
12196               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12197    (set (strict_low_part (match_dup 3))
12198         (eq:QI (match_dup 4) (const_int 0)))
12199    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12200               (clobber (reg:CC FLAGS_REG))])
12201    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12202               (clobber (reg:CC FLAGS_REG))])
12203    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12204               (clobber (reg:CC FLAGS_REG))])]
12206   enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12208   operands[3] = gen_lowpart (QImode, operands[2]);
12209   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12210   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12212   ix86_expand_clear (operands[2]);
12215 (define_insn "*tzcnt<mode>_1"
12216   [(set (reg:CCC FLAGS_REG)
12217         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12218                      (const_int 0)))
12219    (set (match_operand:SWI48 0 "register_operand" "=r")
12220         (ctz:SWI48 (match_dup 1)))]
12221   "TARGET_BMI"
12222   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12223   [(set_attr "type" "alu1")
12224    (set_attr "prefix_0f" "1")
12225    (set_attr "prefix_rep" "1")
12226    (set_attr "btver2_decode" "double")
12227    (set_attr "mode" "<MODE>")])
12229 (define_insn "*bsf<mode>_1"
12230   [(set (reg:CCZ FLAGS_REG)
12231         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12232                      (const_int 0)))
12233    (set (match_operand:SWI48 0 "register_operand" "=r")
12234         (ctz:SWI48 (match_dup 1)))]
12235   ""
12236   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12237   [(set_attr "type" "alu1")
12238    (set_attr "prefix_0f" "1")
12239    (set_attr "btver2_decode" "double")
12240    (set_attr "mode" "<MODE>")])
12242 (define_insn "ctz<mode>2"
12243   [(set (match_operand:SWI248 0 "register_operand" "=r")
12244         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12245    (clobber (reg:CC FLAGS_REG))]
12246   ""
12248   if (TARGET_BMI)
12249     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12250   else if (optimize_function_for_size_p (cfun))
12251     ;
12252   else if (TARGET_GENERIC)
12253     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12254     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12256   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12258   [(set_attr "type" "alu1")
12259    (set_attr "prefix_0f" "1")
12260    (set (attr "prefix_rep")
12261      (if_then_else
12262        (ior (match_test "TARGET_BMI")
12263             (and (not (match_test "optimize_function_for_size_p (cfun)"))
12264                  (match_test "TARGET_GENERIC")))
12265        (const_string "1")
12266        (const_string "0")))
12267    (set_attr "mode" "<MODE>")])
12269 (define_expand "clz<mode>2"
12270   [(parallel
12271      [(set (match_operand:SWI248 0 "register_operand")
12272            (minus:SWI248
12273              (match_dup 2)
12274              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12275       (clobber (reg:CC FLAGS_REG))])
12276    (parallel
12277      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12278       (clobber (reg:CC FLAGS_REG))])]
12279   ""
12281   if (TARGET_LZCNT)
12282     {
12283       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12284       DONE;
12285     }
12286   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12289 (define_insn "clz<mode>2_lzcnt"
12290   [(set (match_operand:SWI248 0 "register_operand" "=r")
12291         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12292    (clobber (reg:CC FLAGS_REG))]
12293   "TARGET_LZCNT"
12294   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12295   [(set_attr "prefix_rep" "1")
12296    (set_attr "type" "bitmanip")
12297    (set_attr "mode" "<MODE>")])
12299 ;; BMI instructions.
12300 (define_insn "*bmi_andn_<mode>"
12301   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12302         (and:SWI48
12303           (not:SWI48
12304             (match_operand:SWI48 1 "register_operand" "r,r"))
12305             (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12306    (clobber (reg:CC FLAGS_REG))]
12307   "TARGET_BMI"
12308   "andn\t{%2, %1, %0|%0, %1, %2}"
12309   [(set_attr "type" "bitmanip")
12310    (set_attr "btver2_decode" "direct, double")
12311    (set_attr "mode" "<MODE>")])
12313 (define_insn "bmi_bextr_<mode>"
12314   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12315         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12316                        (match_operand:SWI48 2 "register_operand" "r,r")]
12317                        UNSPEC_BEXTR))
12318    (clobber (reg:CC FLAGS_REG))]
12319   "TARGET_BMI"
12320   "bextr\t{%2, %1, %0|%0, %1, %2}"
12321   [(set_attr "type" "bitmanip")
12322    (set_attr "btver2_decode" "direct, double")
12323    (set_attr "mode" "<MODE>")])
12325 (define_insn "*bmi_blsi_<mode>"
12326   [(set (match_operand:SWI48 0 "register_operand" "=r")
12327         (and:SWI48
12328           (neg:SWI48
12329             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12330           (match_dup 1)))
12331    (clobber (reg:CC FLAGS_REG))]
12332   "TARGET_BMI"
12333   "blsi\t{%1, %0|%0, %1}"
12334   [(set_attr "type" "bitmanip")
12335    (set_attr "btver2_decode" "double")
12336    (set_attr "mode" "<MODE>")])
12338 (define_insn "*bmi_blsmsk_<mode>"
12339   [(set (match_operand:SWI48 0 "register_operand" "=r")
12340         (xor:SWI48
12341           (plus:SWI48
12342             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12343             (const_int -1))
12344           (match_dup 1)))
12345    (clobber (reg:CC FLAGS_REG))]
12346   "TARGET_BMI"
12347   "blsmsk\t{%1, %0|%0, %1}"
12348   [(set_attr "type" "bitmanip")
12349    (set_attr "btver2_decode" "double")
12350    (set_attr "mode" "<MODE>")])
12352 (define_insn "*bmi_blsr_<mode>"
12353   [(set (match_operand:SWI48 0 "register_operand" "=r")
12354         (and:SWI48
12355           (plus:SWI48
12356             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12357             (const_int -1))
12358           (match_dup 1)))
12359    (clobber (reg:CC FLAGS_REG))]
12360    "TARGET_BMI"
12361    "blsr\t{%1, %0|%0, %1}"
12362   [(set_attr "type" "bitmanip")
12363    (set_attr "btver2_decode" "double")
12364    (set_attr "mode" "<MODE>")])
12366 ;; BMI2 instructions.
12367 (define_insn "bmi2_bzhi_<mode>3"
12368   [(set (match_operand:SWI48 0 "register_operand" "=r")
12369         (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12370                                    (match_operand:SWI48 2 "register_operand" "r"))
12371                    (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12372    (clobber (reg:CC FLAGS_REG))]
12373   "TARGET_BMI2"
12374   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12375   [(set_attr "type" "bitmanip")
12376    (set_attr "prefix" "vex")
12377    (set_attr "mode" "<MODE>")])
12379 (define_insn "bmi2_pdep_<mode>3"
12380   [(set (match_operand:SWI48 0 "register_operand" "=r")
12381         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12382                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12383                        UNSPEC_PDEP))]
12384   "TARGET_BMI2"
12385   "pdep\t{%2, %1, %0|%0, %1, %2}"
12386   [(set_attr "type" "bitmanip")
12387    (set_attr "prefix" "vex")
12388    (set_attr "mode" "<MODE>")])
12390 (define_insn "bmi2_pext_<mode>3"
12391   [(set (match_operand:SWI48 0 "register_operand" "=r")
12392         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12393                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12394                        UNSPEC_PEXT))]
12395   "TARGET_BMI2"
12396   "pext\t{%2, %1, %0|%0, %1, %2}"
12397   [(set_attr "type" "bitmanip")
12398    (set_attr "prefix" "vex")
12399    (set_attr "mode" "<MODE>")])
12401 ;; TBM instructions.
12402 (define_insn "tbm_bextri_<mode>"
12403   [(set (match_operand:SWI48 0 "register_operand" "=r")
12404         (zero_extract:SWI48
12405           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12406           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12407           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12408    (clobber (reg:CC FLAGS_REG))]
12409    "TARGET_TBM"
12411   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12412   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12414   [(set_attr "type" "bitmanip")
12415    (set_attr "mode" "<MODE>")])
12417 (define_insn "*tbm_blcfill_<mode>"
12418   [(set (match_operand:SWI48 0 "register_operand" "=r")
12419         (and:SWI48
12420           (plus:SWI48
12421             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12422             (const_int 1))
12423           (match_dup 1)))
12424    (clobber (reg:CC FLAGS_REG))]
12425    "TARGET_TBM"
12426    "blcfill\t{%1, %0|%0, %1}"
12427   [(set_attr "type" "bitmanip")
12428    (set_attr "mode" "<MODE>")])
12430 (define_insn "*tbm_blci_<mode>"
12431   [(set (match_operand:SWI48 0 "register_operand" "=r")
12432         (ior:SWI48
12433           (not:SWI48
12434             (plus:SWI48
12435               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12436               (const_int 1)))
12437           (match_dup 1)))
12438    (clobber (reg:CC FLAGS_REG))]
12439    "TARGET_TBM"
12440    "blci\t{%1, %0|%0, %1}"
12441   [(set_attr "type" "bitmanip")
12442    (set_attr "mode" "<MODE>")])
12444 (define_insn "*tbm_blcic_<mode>"
12445   [(set (match_operand:SWI48 0 "register_operand" "=r")
12446         (and:SWI48
12447           (plus:SWI48
12448             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12449             (const_int 1))
12450           (not:SWI48
12451             (match_dup 1))))
12452    (clobber (reg:CC FLAGS_REG))]
12453    "TARGET_TBM"
12454    "blcic\t{%1, %0|%0, %1}"
12455   [(set_attr "type" "bitmanip")
12456    (set_attr "mode" "<MODE>")])
12458 (define_insn "*tbm_blcmsk_<mode>"
12459   [(set (match_operand:SWI48 0 "register_operand" "=r")
12460         (xor:SWI48
12461           (plus:SWI48
12462             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12463             (const_int 1))
12464           (match_dup 1)))
12465    (clobber (reg:CC FLAGS_REG))]
12466    "TARGET_TBM"
12467    "blcmsk\t{%1, %0|%0, %1}"
12468   [(set_attr "type" "bitmanip")
12469    (set_attr "mode" "<MODE>")])
12471 (define_insn "*tbm_blcs_<mode>"
12472   [(set (match_operand:SWI48 0 "register_operand" "=r")
12473         (ior:SWI48
12474           (plus:SWI48
12475             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12476             (const_int 1))
12477           (match_dup 1)))
12478    (clobber (reg:CC FLAGS_REG))]
12479    "TARGET_TBM"
12480    "blcs\t{%1, %0|%0, %1}"
12481   [(set_attr "type" "bitmanip")
12482    (set_attr "mode" "<MODE>")])
12484 (define_insn "*tbm_blsfill_<mode>"
12485   [(set (match_operand:SWI48 0 "register_operand" "=r")
12486         (ior:SWI48
12487           (plus:SWI48
12488             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12489             (const_int -1))
12490           (match_dup 1)))
12491    (clobber (reg:CC FLAGS_REG))]
12492    "TARGET_TBM"
12493    "blsfill\t{%1, %0|%0, %1}"
12494   [(set_attr "type" "bitmanip")
12495    (set_attr "mode" "<MODE>")])
12497 (define_insn "*tbm_blsic_<mode>"
12498   [(set (match_operand:SWI48 0 "register_operand" "=r")
12499         (ior:SWI48
12500           (plus:SWI48
12501             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12502             (const_int -1))
12503           (not:SWI48
12504             (match_dup 1))))
12505    (clobber (reg:CC FLAGS_REG))]
12506    "TARGET_TBM"
12507    "blsic\t{%1, %0|%0, %1}"
12508   [(set_attr "type" "bitmanip")
12509    (set_attr "mode" "<MODE>")])
12511 (define_insn "*tbm_t1mskc_<mode>"
12512   [(set (match_operand:SWI48 0 "register_operand" "=r")
12513         (ior:SWI48
12514           (plus:SWI48
12515             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12516             (const_int 1))
12517           (not:SWI48
12518             (match_dup 1))))
12519    (clobber (reg:CC FLAGS_REG))]
12520    "TARGET_TBM"
12521    "t1mskc\t{%1, %0|%0, %1}"
12522   [(set_attr "type" "bitmanip")
12523    (set_attr "mode" "<MODE>")])
12525 (define_insn "*tbm_tzmsk_<mode>"
12526   [(set (match_operand:SWI48 0 "register_operand" "=r")
12527         (and:SWI48
12528           (plus:SWI48
12529             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12530             (const_int -1))
12531           (not:SWI48
12532             (match_dup 1))))
12533    (clobber (reg:CC FLAGS_REG))]
12534    "TARGET_TBM"
12535    "tzmsk\t{%1, %0|%0, %1}"
12536   [(set_attr "type" "bitmanip")
12537    (set_attr "mode" "<MODE>")])
12539 (define_insn "bsr_rex64"
12540   [(set (match_operand:DI 0 "register_operand" "=r")
12541         (minus:DI (const_int 63)
12542                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12543    (clobber (reg:CC FLAGS_REG))]
12544   "TARGET_64BIT"
12545   "bsr{q}\t{%1, %0|%0, %1}"
12546   [(set_attr "type" "alu1")
12547    (set_attr "prefix_0f" "1")
12548    (set_attr "mode" "DI")])
12550 (define_insn "bsr"
12551   [(set (match_operand:SI 0 "register_operand" "=r")
12552         (minus:SI (const_int 31)
12553                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12554    (clobber (reg:CC FLAGS_REG))]
12555   ""
12556   "bsr{l}\t{%1, %0|%0, %1}"
12557   [(set_attr "type" "alu1")
12558    (set_attr "prefix_0f" "1")
12559    (set_attr "mode" "SI")])
12561 (define_insn "*bsrhi"
12562   [(set (match_operand:HI 0 "register_operand" "=r")
12563         (minus:HI (const_int 15)
12564                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12565    (clobber (reg:CC FLAGS_REG))]
12566   ""
12567   "bsr{w}\t{%1, %0|%0, %1}"
12568   [(set_attr "type" "alu1")
12569    (set_attr "prefix_0f" "1")
12570    (set_attr "mode" "HI")])
12572 (define_insn "popcount<mode>2"
12573   [(set (match_operand:SWI248 0 "register_operand" "=r")
12574         (popcount:SWI248
12575           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12576    (clobber (reg:CC FLAGS_REG))]
12577   "TARGET_POPCNT"
12579 #if TARGET_MACHO
12580   return "popcnt\t{%1, %0|%0, %1}";
12581 #else
12582   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12583 #endif
12585   [(set_attr "prefix_rep" "1")
12586    (set_attr "type" "bitmanip")
12587    (set_attr "mode" "<MODE>")])
12589 (define_insn "*popcount<mode>2_cmp"
12590   [(set (reg FLAGS_REG)
12591         (compare
12592           (popcount:SWI248
12593             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12594           (const_int 0)))
12595    (set (match_operand:SWI248 0 "register_operand" "=r")
12596         (popcount:SWI248 (match_dup 1)))]
12597   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12599 #if TARGET_MACHO
12600   return "popcnt\t{%1, %0|%0, %1}";
12601 #else
12602   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12603 #endif
12605   [(set_attr "prefix_rep" "1")
12606    (set_attr "type" "bitmanip")
12607    (set_attr "mode" "<MODE>")])
12609 (define_insn "*popcountsi2_cmp_zext"
12610   [(set (reg FLAGS_REG)
12611         (compare
12612           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12613           (const_int 0)))
12614    (set (match_operand:DI 0 "register_operand" "=r")
12615         (zero_extend:DI(popcount:SI (match_dup 1))))]
12616   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12618 #if TARGET_MACHO
12619   return "popcnt\t{%1, %0|%0, %1}";
12620 #else
12621   return "popcnt{l}\t{%1, %0|%0, %1}";
12622 #endif
12624   [(set_attr "prefix_rep" "1")
12625    (set_attr "type" "bitmanip")
12626    (set_attr "mode" "SI")])
12628 (define_expand "bswapdi2"
12629   [(set (match_operand:DI 0 "register_operand")
12630         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12631   "TARGET_64BIT"
12633   if (!TARGET_MOVBE)
12634     operands[1] = force_reg (DImode, operands[1]);
12637 (define_expand "bswapsi2"
12638   [(set (match_operand:SI 0 "register_operand")
12639         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12640   ""
12642   if (TARGET_MOVBE)
12643     ;
12644   else if (TARGET_BSWAP)
12645     operands[1] = force_reg (SImode, operands[1]);
12646   else
12647     {
12648       rtx x = operands[0];
12650       emit_move_insn (x, operands[1]);
12651       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12652       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12653       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12654       DONE;
12655     }
12658 (define_insn "*bswap<mode>2_movbe"
12659   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12660         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12661   "TARGET_MOVBE
12662    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12663   "@
12664     bswap\t%0
12665     movbe\t{%1, %0|%0, %1}
12666     movbe\t{%1, %0|%0, %1}"
12667   [(set_attr "type" "bitmanip,imov,imov")
12668    (set_attr "modrm" "0,1,1")
12669    (set_attr "prefix_0f" "*,1,1")
12670    (set_attr "prefix_extra" "*,1,1")
12671    (set_attr "mode" "<MODE>")])
12673 (define_insn "*bswap<mode>2"
12674   [(set (match_operand:SWI48 0 "register_operand" "=r")
12675         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12676   "TARGET_BSWAP"
12677   "bswap\t%0"
12678   [(set_attr "type" "bitmanip")
12679    (set_attr "modrm" "0")
12680    (set_attr "mode" "<MODE>")])
12682 (define_insn "*bswaphi_lowpart_1"
12683   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12684         (bswap:HI (match_dup 0)))
12685    (clobber (reg:CC FLAGS_REG))]
12686   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12687   "@
12688     xchg{b}\t{%h0, %b0|%b0, %h0}
12689     rol{w}\t{$8, %0|%0, 8}"
12690   [(set_attr "length" "2,4")
12691    (set_attr "mode" "QI,HI")])
12693 (define_insn "bswaphi_lowpart"
12694   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12695         (bswap:HI (match_dup 0)))
12696    (clobber (reg:CC FLAGS_REG))]
12697   ""
12698   "rol{w}\t{$8, %0|%0, 8}"
12699   [(set_attr "length" "4")
12700    (set_attr "mode" "HI")])
12702 (define_expand "paritydi2"
12703   [(set (match_operand:DI 0 "register_operand")
12704         (parity:DI (match_operand:DI 1 "register_operand")))]
12705   "! TARGET_POPCNT"
12707   rtx scratch = gen_reg_rtx (QImode);
12708   rtx cond;
12710   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12711                                 NULL_RTX, operands[1]));
12713   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12714                          gen_rtx_REG (CCmode, FLAGS_REG),
12715                          const0_rtx);
12716   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12718   if (TARGET_64BIT)
12719     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12720   else
12721     {
12722       rtx tmp = gen_reg_rtx (SImode);
12724       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12725       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12726     }
12727   DONE;
12730 (define_expand "paritysi2"
12731   [(set (match_operand:SI 0 "register_operand")
12732         (parity:SI (match_operand:SI 1 "register_operand")))]
12733   "! TARGET_POPCNT"
12735   rtx scratch = gen_reg_rtx (QImode);
12736   rtx cond;
12738   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12740   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12741                          gen_rtx_REG (CCmode, FLAGS_REG),
12742                          const0_rtx);
12743   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12745   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12746   DONE;
12749 (define_insn_and_split "paritydi2_cmp"
12750   [(set (reg:CC FLAGS_REG)
12751         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12752                    UNSPEC_PARITY))
12753    (clobber (match_scratch:DI 0 "=r"))
12754    (clobber (match_scratch:SI 1 "=&r"))
12755    (clobber (match_scratch:HI 2 "=Q"))]
12756   "! TARGET_POPCNT"
12757   "#"
12758   "&& reload_completed"
12759   [(parallel
12760      [(set (match_dup 1)
12761            (xor:SI (match_dup 1) (match_dup 4)))
12762       (clobber (reg:CC FLAGS_REG))])
12763    (parallel
12764      [(set (reg:CC FLAGS_REG)
12765            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12766       (clobber (match_dup 1))
12767       (clobber (match_dup 2))])]
12769   operands[4] = gen_lowpart (SImode, operands[3]);
12771   if (TARGET_64BIT)
12772     {
12773       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12774       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12775     }
12776   else
12777     operands[1] = gen_highpart (SImode, operands[3]);
12780 (define_insn_and_split "paritysi2_cmp"
12781   [(set (reg:CC FLAGS_REG)
12782         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12783                    UNSPEC_PARITY))
12784    (clobber (match_scratch:SI 0 "=r"))
12785    (clobber (match_scratch:HI 1 "=&Q"))]
12786   "! TARGET_POPCNT"
12787   "#"
12788   "&& reload_completed"
12789   [(parallel
12790      [(set (match_dup 1)
12791            (xor:HI (match_dup 1) (match_dup 3)))
12792       (clobber (reg:CC FLAGS_REG))])
12793    (parallel
12794      [(set (reg:CC FLAGS_REG)
12795            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12796       (clobber (match_dup 1))])]
12798   operands[3] = gen_lowpart (HImode, operands[2]);
12800   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12801   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12804 (define_insn "*parityhi2_cmp"
12805   [(set (reg:CC FLAGS_REG)
12806         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12807                    UNSPEC_PARITY))
12808    (clobber (match_scratch:HI 0 "=Q"))]
12809   "! TARGET_POPCNT"
12810   "xor{b}\t{%h0, %b0|%b0, %h0}"
12811   [(set_attr "length" "2")
12812    (set_attr "mode" "HI")])
12815 ;; Thread-local storage patterns for ELF.
12817 ;; Note that these code sequences must appear exactly as shown
12818 ;; in order to allow linker relaxation.
12820 (define_insn "*tls_global_dynamic_32_gnu"
12821   [(set (match_operand:SI 0 "register_operand" "=a")
12822         (unspec:SI
12823          [(match_operand:SI 1 "register_operand" "b")
12824           (match_operand 2 "tls_symbolic_operand")
12825           (match_operand 3 "constant_call_address_operand" "Bz")
12826           (reg:SI SP_REG)]
12827          UNSPEC_TLS_GD))
12828    (clobber (match_scratch:SI 4 "=d"))
12829    (clobber (match_scratch:SI 5 "=c"))
12830    (clobber (reg:CC FLAGS_REG))]
12831   "!TARGET_64BIT && TARGET_GNU_TLS"
12833   output_asm_insn
12834     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12835   if (TARGET_SUN_TLS)
12836 #ifdef HAVE_AS_IX86_TLSGDPLT
12837     return "call\t%a2@tlsgdplt";
12838 #else
12839     return "call\t%p3@plt";
12840 #endif
12841   return "call\t%P3";
12843   [(set_attr "type" "multi")
12844    (set_attr "length" "12")])
12846 (define_expand "tls_global_dynamic_32"
12847   [(parallel
12848     [(set (match_operand:SI 0 "register_operand")
12849           (unspec:SI [(match_operand:SI 2 "register_operand")
12850                       (match_operand 1 "tls_symbolic_operand")
12851                       (match_operand 3 "constant_call_address_operand")
12852                       (reg:SI SP_REG)]
12853                      UNSPEC_TLS_GD))
12854      (clobber (match_scratch:SI 4))
12855      (clobber (match_scratch:SI 5))
12856      (clobber (reg:CC FLAGS_REG))])]
12857   ""
12858   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
12860 (define_insn "*tls_global_dynamic_64_<mode>"
12861   [(set (match_operand:P 0 "register_operand" "=a")
12862         (call:P
12863          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
12864          (match_operand 3)))
12865    (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12866              UNSPEC_TLS_GD)]
12867   "TARGET_64BIT"
12869   if (!TARGET_X32)
12870     fputs (ASM_BYTE "0x66\n", asm_out_file);
12871   output_asm_insn
12872     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12873   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12874   fputs ("\trex64\n", asm_out_file);
12875   if (TARGET_SUN_TLS)
12876     return "call\t%p2@plt";
12877   return "call\t%P2";
12879   [(set_attr "type" "multi")
12880    (set (attr "length")
12881         (symbol_ref "TARGET_X32 ? 15 : 16"))])
12883 (define_insn "*tls_global_dynamic_64_largepic"
12884   [(set (match_operand:DI 0 "register_operand" "=a")
12885         (call:DI
12886          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
12887                           (match_operand:DI 3 "immediate_operand" "i")))
12888          (match_operand 4)))
12889    (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12890              UNSPEC_TLS_GD)]
12891   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12892    && GET_CODE (operands[3]) == CONST
12893    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
12894    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
12896   output_asm_insn
12897     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12898   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
12899   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
12900   return "call\t{*%%rax|rax}";
12902   [(set_attr "type" "multi")
12903    (set_attr "length" "22")])
12905 (define_expand "tls_global_dynamic_64_<mode>"
12906   [(parallel
12907     [(set (match_operand:P 0 "register_operand")
12908           (call:P
12909            (mem:QI (match_operand 2))
12910            (const_int 0)))
12911      (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12912                UNSPEC_TLS_GD)])]
12913   "TARGET_64BIT"
12914   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
12916 (define_insn "*tls_local_dynamic_base_32_gnu"
12917   [(set (match_operand:SI 0 "register_operand" "=a")
12918         (unspec:SI
12919          [(match_operand:SI 1 "register_operand" "b")
12920           (match_operand 2 "constant_call_address_operand" "Bz")
12921           (reg:SI SP_REG)]
12922          UNSPEC_TLS_LD_BASE))
12923    (clobber (match_scratch:SI 3 "=d"))
12924    (clobber (match_scratch:SI 4 "=c"))
12925    (clobber (reg:CC FLAGS_REG))]
12926   "!TARGET_64BIT && TARGET_GNU_TLS"
12928   output_asm_insn
12929     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12930   if (TARGET_SUN_TLS)
12931     {
12932       if (HAVE_AS_IX86_TLSLDMPLT)
12933         return "call\t%&@tlsldmplt";
12934       else
12935         return "call\t%p2@plt";
12936     }
12937   return "call\t%P2";
12939   [(set_attr "type" "multi")
12940    (set_attr "length" "11")])
12942 (define_expand "tls_local_dynamic_base_32"
12943   [(parallel
12944      [(set (match_operand:SI 0 "register_operand")
12945            (unspec:SI
12946             [(match_operand:SI 1 "register_operand")
12947              (match_operand 2 "constant_call_address_operand")
12948              (reg:SI SP_REG)]
12949             UNSPEC_TLS_LD_BASE))
12950       (clobber (match_scratch:SI 3))
12951       (clobber (match_scratch:SI 4))
12952       (clobber (reg:CC FLAGS_REG))])]
12953   ""
12954   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
12956 (define_insn "*tls_local_dynamic_base_64_<mode>"
12957   [(set (match_operand:P 0 "register_operand" "=a")
12958         (call:P
12959          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
12960          (match_operand 2)))
12961    (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12962   "TARGET_64BIT"
12964   output_asm_insn
12965     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12966   if (TARGET_SUN_TLS)
12967     return "call\t%p1@plt";
12968   return "call\t%P1";
12970   [(set_attr "type" "multi")
12971    (set_attr "length" "12")])
12973 (define_insn "*tls_local_dynamic_base_64_largepic"
12974   [(set (match_operand:DI 0 "register_operand" "=a")
12975         (call:DI
12976          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
12977                           (match_operand:DI 2 "immediate_operand" "i")))
12978          (match_operand 3)))
12979    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12980   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12981    && GET_CODE (operands[2]) == CONST
12982    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
12983    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
12985   output_asm_insn
12986     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12987   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
12988   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
12989   return "call\t{*%%rax|rax}";
12991   [(set_attr "type" "multi")
12992    (set_attr "length" "22")])
12994 (define_expand "tls_local_dynamic_base_64_<mode>"
12995   [(parallel
12996      [(set (match_operand:P 0 "register_operand")
12997            (call:P
12998             (mem:QI (match_operand 1))
12999             (const_int 0)))
13000       (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13001   "TARGET_64BIT"
13002   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13004 ;; Local dynamic of a single variable is a lose.  Show combine how
13005 ;; to convert that back to global dynamic.
13007 (define_insn_and_split "*tls_local_dynamic_32_once"
13008   [(set (match_operand:SI 0 "register_operand" "=a")
13009         (plus:SI
13010          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13011                      (match_operand 2 "constant_call_address_operand" "Bz")
13012                      (reg:SI SP_REG)]
13013                     UNSPEC_TLS_LD_BASE)
13014          (const:SI (unspec:SI
13015                     [(match_operand 3 "tls_symbolic_operand")]
13016                     UNSPEC_DTPOFF))))
13017    (clobber (match_scratch:SI 4 "=d"))
13018    (clobber (match_scratch:SI 5 "=c"))
13019    (clobber (reg:CC FLAGS_REG))]
13020   ""
13021   "#"
13022   ""
13023   [(parallel
13024      [(set (match_dup 0)
13025            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13026                        (reg:SI SP_REG)]
13027                       UNSPEC_TLS_GD))
13028       (clobber (match_dup 4))
13029       (clobber (match_dup 5))
13030       (clobber (reg:CC FLAGS_REG))])])
13032 ;; Segment register for the thread base ptr load
13033 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13035 ;; Load and add the thread base pointer from %<tp_seg>:0.
13036 (define_insn "*load_tp_x32"
13037   [(set (match_operand:SI 0 "register_operand" "=r")
13038         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13039   "TARGET_X32"
13040   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13041   [(set_attr "type" "imov")
13042    (set_attr "modrm" "0")
13043    (set_attr "length" "7")
13044    (set_attr "memory" "load")
13045    (set_attr "imm_disp" "false")])
13047 (define_insn "*load_tp_x32_zext"
13048   [(set (match_operand:DI 0 "register_operand" "=r")
13049         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13050   "TARGET_X32"
13051   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13052   [(set_attr "type" "imov")
13053    (set_attr "modrm" "0")
13054    (set_attr "length" "7")
13055    (set_attr "memory" "load")
13056    (set_attr "imm_disp" "false")])
13058 (define_insn "*load_tp_<mode>"
13059   [(set (match_operand:P 0 "register_operand" "=r")
13060         (unspec:P [(const_int 0)] UNSPEC_TP))]
13061   "!TARGET_X32"
13062   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13063   [(set_attr "type" "imov")
13064    (set_attr "modrm" "0")
13065    (set_attr "length" "7")
13066    (set_attr "memory" "load")
13067    (set_attr "imm_disp" "false")])
13069 (define_insn "*add_tp_x32"
13070   [(set (match_operand:SI 0 "register_operand" "=r")
13071         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13072                  (match_operand:SI 1 "register_operand" "0")))
13073    (clobber (reg:CC FLAGS_REG))]
13074   "TARGET_X32"
13075   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13076   [(set_attr "type" "alu")
13077    (set_attr "modrm" "0")
13078    (set_attr "length" "7")
13079    (set_attr "memory" "load")
13080    (set_attr "imm_disp" "false")])
13082 (define_insn "*add_tp_x32_zext"
13083   [(set (match_operand:DI 0 "register_operand" "=r")
13084         (zero_extend:DI
13085           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13086                    (match_operand:SI 1 "register_operand" "0"))))
13087    (clobber (reg:CC FLAGS_REG))]
13088   "TARGET_X32"
13089   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13090   [(set_attr "type" "alu")
13091    (set_attr "modrm" "0")
13092    (set_attr "length" "7")
13093    (set_attr "memory" "load")
13094    (set_attr "imm_disp" "false")])
13096 (define_insn "*add_tp_<mode>"
13097   [(set (match_operand:P 0 "register_operand" "=r")
13098         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13099                 (match_operand:P 1 "register_operand" "0")))
13100    (clobber (reg:CC FLAGS_REG))]
13101   "!TARGET_X32"
13102   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13103   [(set_attr "type" "alu")
13104    (set_attr "modrm" "0")
13105    (set_attr "length" "7")
13106    (set_attr "memory" "load")
13107    (set_attr "imm_disp" "false")])
13109 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13110 ;; %rax as destination of the initial executable code sequence.
13111 (define_insn "tls_initial_exec_64_sun"
13112   [(set (match_operand:DI 0 "register_operand" "=a")
13113         (unspec:DI
13114          [(match_operand 1 "tls_symbolic_operand")]
13115          UNSPEC_TLS_IE_SUN))
13116    (clobber (reg:CC FLAGS_REG))]
13117   "TARGET_64BIT && TARGET_SUN_TLS"
13119   output_asm_insn
13120     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13121   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13123   [(set_attr "type" "multi")])
13125 ;; GNU2 TLS patterns can be split.
13127 (define_expand "tls_dynamic_gnu2_32"
13128   [(set (match_dup 3)
13129         (plus:SI (match_operand:SI 2 "register_operand")
13130                  (const:SI
13131                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13132                              UNSPEC_TLSDESC))))
13133    (parallel
13134     [(set (match_operand:SI 0 "register_operand")
13135           (unspec:SI [(match_dup 1) (match_dup 3)
13136                       (match_dup 2) (reg:SI SP_REG)]
13137                       UNSPEC_TLSDESC))
13138      (clobber (reg:CC FLAGS_REG))])]
13139   "!TARGET_64BIT && TARGET_GNU2_TLS"
13141   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13142   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13145 (define_insn "*tls_dynamic_gnu2_lea_32"
13146   [(set (match_operand:SI 0 "register_operand" "=r")
13147         (plus:SI (match_operand:SI 1 "register_operand" "b")
13148                  (const:SI
13149                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13150                               UNSPEC_TLSDESC))))]
13151   "!TARGET_64BIT && TARGET_GNU2_TLS"
13152   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13153   [(set_attr "type" "lea")
13154    (set_attr "mode" "SI")
13155    (set_attr "length" "6")
13156    (set_attr "length_address" "4")])
13158 (define_insn "*tls_dynamic_gnu2_call_32"
13159   [(set (match_operand:SI 0 "register_operand" "=a")
13160         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13161                     (match_operand:SI 2 "register_operand" "0")
13162                     ;; we have to make sure %ebx still points to the GOT
13163                     (match_operand:SI 3 "register_operand" "b")
13164                     (reg:SI SP_REG)]
13165                    UNSPEC_TLSDESC))
13166    (clobber (reg:CC FLAGS_REG))]
13167   "!TARGET_64BIT && TARGET_GNU2_TLS"
13168   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13169   [(set_attr "type" "call")
13170    (set_attr "length" "2")
13171    (set_attr "length_address" "0")])
13173 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13174   [(set (match_operand:SI 0 "register_operand" "=&a")
13175         (plus:SI
13176          (unspec:SI [(match_operand 3 "tls_modbase_operand")
13177                      (match_operand:SI 4)
13178                      (match_operand:SI 2 "register_operand" "b")
13179                      (reg:SI SP_REG)]
13180                     UNSPEC_TLSDESC)
13181          (const:SI (unspec:SI
13182                     [(match_operand 1 "tls_symbolic_operand")]
13183                     UNSPEC_DTPOFF))))
13184    (clobber (reg:CC FLAGS_REG))]
13185   "!TARGET_64BIT && TARGET_GNU2_TLS"
13186   "#"
13187   ""
13188   [(set (match_dup 0) (match_dup 5))]
13190   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13191   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13194 (define_expand "tls_dynamic_gnu2_64"
13195   [(set (match_dup 2)
13196         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13197                    UNSPEC_TLSDESC))
13198    (parallel
13199     [(set (match_operand:DI 0 "register_operand")
13200           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13201                      UNSPEC_TLSDESC))
13202      (clobber (reg:CC FLAGS_REG))])]
13203   "TARGET_64BIT && TARGET_GNU2_TLS"
13205   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13206   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13209 (define_insn "*tls_dynamic_gnu2_lea_64"
13210   [(set (match_operand:DI 0 "register_operand" "=r")
13211         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13212                    UNSPEC_TLSDESC))]
13213   "TARGET_64BIT && TARGET_GNU2_TLS"
13214   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13215   [(set_attr "type" "lea")
13216    (set_attr "mode" "DI")
13217    (set_attr "length" "7")
13218    (set_attr "length_address" "4")])
13220 (define_insn "*tls_dynamic_gnu2_call_64"
13221   [(set (match_operand:DI 0 "register_operand" "=a")
13222         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13223                     (match_operand:DI 2 "register_operand" "0")
13224                     (reg:DI SP_REG)]
13225                    UNSPEC_TLSDESC))
13226    (clobber (reg:CC FLAGS_REG))]
13227   "TARGET_64BIT && TARGET_GNU2_TLS"
13228   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13229   [(set_attr "type" "call")
13230    (set_attr "length" "2")
13231    (set_attr "length_address" "0")])
13233 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13234   [(set (match_operand:DI 0 "register_operand" "=&a")
13235         (plus:DI
13236          (unspec:DI [(match_operand 2 "tls_modbase_operand")
13237                      (match_operand:DI 3)
13238                      (reg:DI SP_REG)]
13239                     UNSPEC_TLSDESC)
13240          (const:DI (unspec:DI
13241                     [(match_operand 1 "tls_symbolic_operand")]
13242                     UNSPEC_DTPOFF))))
13243    (clobber (reg:CC FLAGS_REG))]
13244   "TARGET_64BIT && TARGET_GNU2_TLS"
13245   "#"
13246   ""
13247   [(set (match_dup 0) (match_dup 4))]
13249   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13250   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13253 ;; These patterns match the binary 387 instructions for addM3, subM3,
13254 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13255 ;; SFmode.  The first is the normal insn, the second the same insn but
13256 ;; with one operand a conversion, and the third the same insn but with
13257 ;; the other operand a conversion.  The conversion may be SFmode or
13258 ;; SImode if the target mode DFmode, but only SImode if the target mode
13259 ;; is SFmode.
13261 ;; Gcc is slightly more smart about handling normal two address instructions
13262 ;; so use special patterns for add and mull.
13264 (define_insn "*fop_<mode>_comm_mixed"
13265   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13266         (match_operator:MODEF 3 "binary_fp_operator"
13267           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13268            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13269   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13270    && COMMUTATIVE_ARITH_P (operands[3])
13271    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13272   "* return output_387_binary_op (insn, operands);"
13273   [(set (attr "type")
13274         (if_then_else (eq_attr "alternative" "1,2")
13275            (if_then_else (match_operand:MODEF 3 "mult_operator")
13276               (const_string "ssemul")
13277               (const_string "sseadd"))
13278            (if_then_else (match_operand:MODEF 3 "mult_operator")
13279               (const_string "fmul")
13280               (const_string "fop"))))
13281    (set_attr "isa" "*,noavx,avx")
13282    (set_attr "prefix" "orig,orig,vex")
13283    (set_attr "mode" "<MODE>")])
13285 (define_insn "*fop_<mode>_comm_sse"
13286   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13287         (match_operator:MODEF 3 "binary_fp_operator"
13288           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13289            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13290   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13291    && COMMUTATIVE_ARITH_P (operands[3])
13292    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13293   "* return output_387_binary_op (insn, operands);"
13294   [(set (attr "type")
13295         (if_then_else (match_operand:MODEF 3 "mult_operator")
13296            (const_string "ssemul")
13297            (const_string "sseadd")))
13298    (set_attr "isa" "noavx,avx")
13299    (set_attr "prefix" "orig,vex")
13300    (set_attr "mode" "<MODE>")])
13302 (define_insn "*fop_<mode>_comm_i387"
13303   [(set (match_operand:MODEF 0 "register_operand" "=f")
13304         (match_operator:MODEF 3 "binary_fp_operator"
13305           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13306            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13307   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13308    && COMMUTATIVE_ARITH_P (operands[3])
13309    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13310   "* return output_387_binary_op (insn, operands);"
13311   [(set (attr "type")
13312         (if_then_else (match_operand:MODEF 3 "mult_operator")
13313            (const_string "fmul")
13314            (const_string "fop")))
13315    (set_attr "mode" "<MODE>")])
13317 (define_insn "*fop_<mode>_1_mixed"
13318   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13319         (match_operator:MODEF 3 "binary_fp_operator"
13320           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13321            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13322   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13323    && !COMMUTATIVE_ARITH_P (operands[3])
13324    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13325   "* return output_387_binary_op (insn, operands);"
13326   [(set (attr "type")
13327         (cond [(and (eq_attr "alternative" "2,3")
13328                     (match_operand:MODEF 3 "mult_operator"))
13329                  (const_string "ssemul")
13330                (and (eq_attr "alternative" "2,3")
13331                     (match_operand:MODEF 3 "div_operator"))
13332                  (const_string "ssediv")
13333                (eq_attr "alternative" "2,3")
13334                  (const_string "sseadd")
13335                (match_operand:MODEF 3 "mult_operator")
13336                  (const_string "fmul")
13337                (match_operand:MODEF 3 "div_operator")
13338                  (const_string "fdiv")
13339               ]
13340               (const_string "fop")))
13341    (set_attr "isa" "*,*,noavx,avx")
13342    (set_attr "prefix" "orig,orig,orig,vex")
13343    (set_attr "mode" "<MODE>")])
13345 (define_insn "*rcpsf2_sse"
13346   [(set (match_operand:SF 0 "register_operand" "=x")
13347         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13348                    UNSPEC_RCP))]
13349   "TARGET_SSE_MATH"
13350   "%vrcpss\t{%1, %d0|%d0, %1}"
13351   [(set_attr "type" "sse")
13352    (set_attr "atom_sse_attr" "rcp")
13353    (set_attr "btver2_sse_attr" "rcp")
13354    (set_attr "prefix" "maybe_vex")
13355    (set_attr "mode" "SF")])
13357 (define_insn "*fop_<mode>_1_sse"
13358   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13359         (match_operator:MODEF 3 "binary_fp_operator"
13360           [(match_operand:MODEF 1 "register_operand" "0,x")
13361            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13362   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13363    && !COMMUTATIVE_ARITH_P (operands[3])"
13364   "* return output_387_binary_op (insn, operands);"
13365   [(set (attr "type")
13366         (cond [(match_operand:MODEF 3 "mult_operator")
13367                  (const_string "ssemul")
13368                (match_operand:MODEF 3 "div_operator")
13369                  (const_string "ssediv")
13370               ]
13371               (const_string "sseadd")))
13372    (set_attr "isa" "noavx,avx")
13373    (set_attr "prefix" "orig,vex")
13374    (set_attr "mode" "<MODE>")])
13376 ;; This pattern is not fully shadowed by the pattern above.
13377 (define_insn "*fop_<mode>_1_i387"
13378   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13379         (match_operator:MODEF 3 "binary_fp_operator"
13380           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13381            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13382   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13383    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13384    && !COMMUTATIVE_ARITH_P (operands[3])
13385    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13386   "* return output_387_binary_op (insn, operands);"
13387   [(set (attr "type")
13388         (cond [(match_operand:MODEF 3 "mult_operator")
13389                  (const_string "fmul")
13390                (match_operand:MODEF 3 "div_operator")
13391                  (const_string "fdiv")
13392               ]
13393               (const_string "fop")))
13394    (set_attr "mode" "<MODE>")])
13396 ;; ??? Add SSE splitters for these!
13397 (define_insn "*fop_<MODEF:mode>_2_i387"
13398   [(set (match_operand:MODEF 0 "register_operand" "=f")
13399         (match_operator:MODEF 3 "binary_fp_operator"
13400           [(float:MODEF
13401              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13402            (match_operand:MODEF 2 "register_operand" "0")]))]
13403   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13404    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13405    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13406        || optimize_function_for_size_p (cfun))"
13407   { return output_387_binary_op (insn, operands); }
13408   [(set (attr "type")
13409         (cond [(match_operand:MODEF 3 "mult_operator")
13410                  (const_string "fmul")
13411                (match_operand:MODEF 3 "div_operator")
13412                  (const_string "fdiv")
13413               ]
13414               (const_string "fop")))
13415    (set_attr "fp_int_src" "true")
13416    (set_attr "mode" "<SWI24:MODE>")])
13418 (define_insn "*fop_<MODEF:mode>_3_i387"
13419   [(set (match_operand:MODEF 0 "register_operand" "=f")
13420         (match_operator:MODEF 3 "binary_fp_operator"
13421           [(match_operand:MODEF 1 "register_operand" "0")
13422            (float:MODEF
13423              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13424   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13425    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13426    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13427        || optimize_function_for_size_p (cfun))"
13428   { return output_387_binary_op (insn, operands); }
13429   [(set (attr "type")
13430         (cond [(match_operand:MODEF 3 "mult_operator")
13431                  (const_string "fmul")
13432                (match_operand:MODEF 3 "div_operator")
13433                  (const_string "fdiv")
13434               ]
13435               (const_string "fop")))
13436    (set_attr "fp_int_src" "true")
13437    (set_attr "mode" "<MODE>")])
13439 (define_insn "*fop_df_4_i387"
13440   [(set (match_operand:DF 0 "register_operand" "=f,f")
13441         (match_operator:DF 3 "binary_fp_operator"
13442            [(float_extend:DF
13443              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13444             (match_operand:DF 2 "register_operand" "0,f")]))]
13445   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13446    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13447    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13448   "* return output_387_binary_op (insn, operands);"
13449   [(set (attr "type")
13450         (cond [(match_operand:DF 3 "mult_operator")
13451                  (const_string "fmul")
13452                (match_operand:DF 3 "div_operator")
13453                  (const_string "fdiv")
13454               ]
13455               (const_string "fop")))
13456    (set_attr "mode" "SF")])
13458 (define_insn "*fop_df_5_i387"
13459   [(set (match_operand:DF 0 "register_operand" "=f,f")
13460         (match_operator:DF 3 "binary_fp_operator"
13461           [(match_operand:DF 1 "register_operand" "0,f")
13462            (float_extend:DF
13463             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13464   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13465    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13466   "* return output_387_binary_op (insn, operands);"
13467   [(set (attr "type")
13468         (cond [(match_operand:DF 3 "mult_operator")
13469                  (const_string "fmul")
13470                (match_operand:DF 3 "div_operator")
13471                  (const_string "fdiv")
13472               ]
13473               (const_string "fop")))
13474    (set_attr "mode" "SF")])
13476 (define_insn "*fop_df_6_i387"
13477   [(set (match_operand:DF 0 "register_operand" "=f,f")
13478         (match_operator:DF 3 "binary_fp_operator"
13479           [(float_extend:DF
13480             (match_operand:SF 1 "register_operand" "0,f"))
13481            (float_extend:DF
13482             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13483   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13484    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13485   "* return output_387_binary_op (insn, operands);"
13486   [(set (attr "type")
13487         (cond [(match_operand:DF 3 "mult_operator")
13488                  (const_string "fmul")
13489                (match_operand:DF 3 "div_operator")
13490                  (const_string "fdiv")
13491               ]
13492               (const_string "fop")))
13493    (set_attr "mode" "SF")])
13495 (define_insn "*fop_xf_comm_i387"
13496   [(set (match_operand:XF 0 "register_operand" "=f")
13497         (match_operator:XF 3 "binary_fp_operator"
13498                         [(match_operand:XF 1 "register_operand" "%0")
13499                          (match_operand:XF 2 "register_operand" "f")]))]
13500   "TARGET_80387
13501    && COMMUTATIVE_ARITH_P (operands[3])"
13502   "* return output_387_binary_op (insn, operands);"
13503   [(set (attr "type")
13504         (if_then_else (match_operand:XF 3 "mult_operator")
13505            (const_string "fmul")
13506            (const_string "fop")))
13507    (set_attr "mode" "XF")])
13509 (define_insn "*fop_xf_1_i387"
13510   [(set (match_operand:XF 0 "register_operand" "=f,f")
13511         (match_operator:XF 3 "binary_fp_operator"
13512                         [(match_operand:XF 1 "register_operand" "0,f")
13513                          (match_operand:XF 2 "register_operand" "f,0")]))]
13514   "TARGET_80387
13515    && !COMMUTATIVE_ARITH_P (operands[3])"
13516   "* return output_387_binary_op (insn, operands);"
13517   [(set (attr "type")
13518         (cond [(match_operand:XF 3 "mult_operator")
13519                  (const_string "fmul")
13520                (match_operand:XF 3 "div_operator")
13521                  (const_string "fdiv")
13522               ]
13523               (const_string "fop")))
13524    (set_attr "mode" "XF")])
13526 (define_insn "*fop_xf_2_i387"
13527   [(set (match_operand:XF 0 "register_operand" "=f")
13528         (match_operator:XF 3 "binary_fp_operator"
13529           [(float:XF
13530              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13531            (match_operand:XF 2 "register_operand" "0")]))]
13532   "TARGET_80387
13533    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13534   { return output_387_binary_op (insn, operands); }
13535   [(set (attr "type")
13536         (cond [(match_operand:XF 3 "mult_operator")
13537                  (const_string "fmul")
13538                (match_operand:XF 3 "div_operator")
13539                  (const_string "fdiv")
13540               ]
13541               (const_string "fop")))
13542    (set_attr "fp_int_src" "true")
13543    (set_attr "mode" "<MODE>")])
13545 (define_insn "*fop_xf_3_i387"
13546   [(set (match_operand:XF 0 "register_operand" "=f")
13547         (match_operator:XF 3 "binary_fp_operator"
13548           [(match_operand:XF 1 "register_operand" "0")
13549            (float:XF
13550              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13551   "TARGET_80387
13552    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13553   { return output_387_binary_op (insn, operands); }
13554   [(set (attr "type")
13555         (cond [(match_operand:XF 3 "mult_operator")
13556                  (const_string "fmul")
13557                (match_operand:XF 3 "div_operator")
13558                  (const_string "fdiv")
13559               ]
13560               (const_string "fop")))
13561    (set_attr "fp_int_src" "true")
13562    (set_attr "mode" "<MODE>")])
13564 (define_insn "*fop_xf_4_i387"
13565   [(set (match_operand:XF 0 "register_operand" "=f,f")
13566         (match_operator:XF 3 "binary_fp_operator"
13567            [(float_extend:XF
13568               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13569             (match_operand:XF 2 "register_operand" "0,f")]))]
13570   "TARGET_80387"
13571   "* return output_387_binary_op (insn, operands);"
13572   [(set (attr "type")
13573         (cond [(match_operand:XF 3 "mult_operator")
13574                  (const_string "fmul")
13575                (match_operand:XF 3 "div_operator")
13576                  (const_string "fdiv")
13577               ]
13578               (const_string "fop")))
13579    (set_attr "mode" "<MODE>")])
13581 (define_insn "*fop_xf_5_i387"
13582   [(set (match_operand:XF 0 "register_operand" "=f,f")
13583         (match_operator:XF 3 "binary_fp_operator"
13584           [(match_operand:XF 1 "register_operand" "0,f")
13585            (float_extend:XF
13586              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13587   "TARGET_80387"
13588   "* return output_387_binary_op (insn, operands);"
13589   [(set (attr "type")
13590         (cond [(match_operand:XF 3 "mult_operator")
13591                  (const_string "fmul")
13592                (match_operand:XF 3 "div_operator")
13593                  (const_string "fdiv")
13594               ]
13595               (const_string "fop")))
13596    (set_attr "mode" "<MODE>")])
13598 (define_insn "*fop_xf_6_i387"
13599   [(set (match_operand:XF 0 "register_operand" "=f,f")
13600         (match_operator:XF 3 "binary_fp_operator"
13601           [(float_extend:XF
13602              (match_operand:MODEF 1 "register_operand" "0,f"))
13603            (float_extend:XF
13604              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13605   "TARGET_80387"
13606   "* return output_387_binary_op (insn, operands);"
13607   [(set (attr "type")
13608         (cond [(match_operand:XF 3 "mult_operator")
13609                  (const_string "fmul")
13610                (match_operand:XF 3 "div_operator")
13611                  (const_string "fdiv")
13612               ]
13613               (const_string "fop")))
13614    (set_attr "mode" "<MODE>")])
13616 ;; FPU special functions.
13618 ;; This pattern implements a no-op XFmode truncation for
13619 ;; all fancy i386 XFmode math functions.
13621 (define_insn "truncxf<mode>2_i387_noop_unspec"
13622   [(set (match_operand:MODEF 0 "register_operand" "=f")
13623         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13624         UNSPEC_TRUNC_NOOP))]
13625   "TARGET_USE_FANCY_MATH_387"
13626   "* return output_387_reg_move (insn, operands);"
13627   [(set_attr "type" "fmov")
13628    (set_attr "mode" "<MODE>")])
13630 (define_insn "sqrtxf2"
13631   [(set (match_operand:XF 0 "register_operand" "=f")
13632         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13633   "TARGET_USE_FANCY_MATH_387"
13634   "fsqrt"
13635   [(set_attr "type" "fpspc")
13636    (set_attr "mode" "XF")
13637    (set_attr "athlon_decode" "direct")
13638    (set_attr "amdfam10_decode" "direct")
13639    (set_attr "bdver1_decode" "direct")])
13641 (define_insn "sqrt_extend<mode>xf2_i387"
13642   [(set (match_operand:XF 0 "register_operand" "=f")
13643         (sqrt:XF
13644           (float_extend:XF
13645             (match_operand:MODEF 1 "register_operand" "0"))))]
13646   "TARGET_USE_FANCY_MATH_387"
13647   "fsqrt"
13648   [(set_attr "type" "fpspc")
13649    (set_attr "mode" "XF")
13650    (set_attr "athlon_decode" "direct")
13651    (set_attr "amdfam10_decode" "direct")
13652    (set_attr "bdver1_decode" "direct")])
13654 (define_insn "*rsqrtsf2_sse"
13655   [(set (match_operand:SF 0 "register_operand" "=x")
13656         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13657                    UNSPEC_RSQRT))]
13658   "TARGET_SSE_MATH"
13659   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13660   [(set_attr "type" "sse")
13661    (set_attr "atom_sse_attr" "rcp")
13662    (set_attr "btver2_sse_attr" "rcp")
13663    (set_attr "prefix" "maybe_vex")
13664    (set_attr "mode" "SF")])
13666 (define_expand "rsqrtsf2"
13667   [(set (match_operand:SF 0 "register_operand")
13668         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13669                    UNSPEC_RSQRT))]
13670   "TARGET_SSE_MATH"
13672   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13673   DONE;
13676 (define_insn "*sqrt<mode>2_sse"
13677   [(set (match_operand:MODEF 0 "register_operand" "=x")
13678         (sqrt:MODEF
13679           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13680   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13681   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13682   [(set_attr "type" "sse")
13683    (set_attr "atom_sse_attr" "sqrt")
13684    (set_attr "btver2_sse_attr" "sqrt")
13685    (set_attr "prefix" "maybe_vex")
13686    (set_attr "mode" "<MODE>")
13687    (set_attr "athlon_decode" "*")
13688    (set_attr "amdfam10_decode" "*")
13689    (set_attr "bdver1_decode" "*")])
13691 (define_expand "sqrt<mode>2"
13692   [(set (match_operand:MODEF 0 "register_operand")
13693         (sqrt:MODEF
13694           (match_operand:MODEF 1 "nonimmediate_operand")))]
13695   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13696    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13698   if (<MODE>mode == SFmode
13699       && TARGET_SSE_MATH
13700       && TARGET_RECIP_SQRT
13701       && !optimize_function_for_size_p (cfun)
13702       && flag_finite_math_only && !flag_trapping_math
13703       && flag_unsafe_math_optimizations)
13704     {
13705       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13706       DONE;
13707     }
13709   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13710     {
13711       rtx op0 = gen_reg_rtx (XFmode);
13712       rtx op1 = force_reg (<MODE>mode, operands[1]);
13714       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13715       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13716       DONE;
13717    }
13720 (define_insn "fpremxf4_i387"
13721   [(set (match_operand:XF 0 "register_operand" "=f")
13722         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13723                     (match_operand:XF 3 "register_operand" "1")]
13724                    UNSPEC_FPREM_F))
13725    (set (match_operand:XF 1 "register_operand" "=u")
13726         (unspec:XF [(match_dup 2) (match_dup 3)]
13727                    UNSPEC_FPREM_U))
13728    (set (reg:CCFP FPSR_REG)
13729         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13730                      UNSPEC_C2_FLAG))]
13731   "TARGET_USE_FANCY_MATH_387"
13732   "fprem"
13733   [(set_attr "type" "fpspc")
13734    (set_attr "mode" "XF")])
13736 (define_expand "fmodxf3"
13737   [(use (match_operand:XF 0 "register_operand"))
13738    (use (match_operand:XF 1 "general_operand"))
13739    (use (match_operand:XF 2 "general_operand"))]
13740   "TARGET_USE_FANCY_MATH_387"
13742   rtx label = gen_label_rtx ();
13744   rtx op1 = gen_reg_rtx (XFmode);
13745   rtx op2 = gen_reg_rtx (XFmode);
13747   emit_move_insn (op2, operands[2]);
13748   emit_move_insn (op1, operands[1]);
13750   emit_label (label);
13751   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13752   ix86_emit_fp_unordered_jump (label);
13753   LABEL_NUSES (label) = 1;
13755   emit_move_insn (operands[0], op1);
13756   DONE;
13759 (define_expand "fmod<mode>3"
13760   [(use (match_operand:MODEF 0 "register_operand"))
13761    (use (match_operand:MODEF 1 "general_operand"))
13762    (use (match_operand:MODEF 2 "general_operand"))]
13763   "TARGET_USE_FANCY_MATH_387"
13765   rtx (*gen_truncxf) (rtx, rtx);
13767   rtx label = gen_label_rtx ();
13769   rtx op1 = gen_reg_rtx (XFmode);
13770   rtx op2 = gen_reg_rtx (XFmode);
13772   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13773   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13775   emit_label (label);
13776   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13777   ix86_emit_fp_unordered_jump (label);
13778   LABEL_NUSES (label) = 1;
13780   /* Truncate the result properly for strict SSE math.  */
13781   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13782       && !TARGET_MIX_SSE_I387)
13783     gen_truncxf = gen_truncxf<mode>2;
13784   else
13785     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13787   emit_insn (gen_truncxf (operands[0], op1));
13788   DONE;
13791 (define_insn "fprem1xf4_i387"
13792   [(set (match_operand:XF 0 "register_operand" "=f")
13793         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13794                     (match_operand:XF 3 "register_operand" "1")]
13795                    UNSPEC_FPREM1_F))
13796    (set (match_operand:XF 1 "register_operand" "=u")
13797         (unspec:XF [(match_dup 2) (match_dup 3)]
13798                    UNSPEC_FPREM1_U))
13799    (set (reg:CCFP FPSR_REG)
13800         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13801                      UNSPEC_C2_FLAG))]
13802   "TARGET_USE_FANCY_MATH_387"
13803   "fprem1"
13804   [(set_attr "type" "fpspc")
13805    (set_attr "mode" "XF")])
13807 (define_expand "remainderxf3"
13808   [(use (match_operand:XF 0 "register_operand"))
13809    (use (match_operand:XF 1 "general_operand"))
13810    (use (match_operand:XF 2 "general_operand"))]
13811   "TARGET_USE_FANCY_MATH_387"
13813   rtx label = gen_label_rtx ();
13815   rtx op1 = gen_reg_rtx (XFmode);
13816   rtx op2 = gen_reg_rtx (XFmode);
13818   emit_move_insn (op2, operands[2]);
13819   emit_move_insn (op1, operands[1]);
13821   emit_label (label);
13822   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13823   ix86_emit_fp_unordered_jump (label);
13824   LABEL_NUSES (label) = 1;
13826   emit_move_insn (operands[0], op1);
13827   DONE;
13830 (define_expand "remainder<mode>3"
13831   [(use (match_operand:MODEF 0 "register_operand"))
13832    (use (match_operand:MODEF 1 "general_operand"))
13833    (use (match_operand:MODEF 2 "general_operand"))]
13834   "TARGET_USE_FANCY_MATH_387"
13836   rtx (*gen_truncxf) (rtx, rtx);
13838   rtx label = gen_label_rtx ();
13840   rtx op1 = gen_reg_rtx (XFmode);
13841   rtx op2 = gen_reg_rtx (XFmode);
13843   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13844   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13846   emit_label (label);
13848   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13849   ix86_emit_fp_unordered_jump (label);
13850   LABEL_NUSES (label) = 1;
13852   /* Truncate the result properly for strict SSE math.  */
13853   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13854       && !TARGET_MIX_SSE_I387)
13855     gen_truncxf = gen_truncxf<mode>2;
13856   else
13857     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13859   emit_insn (gen_truncxf (operands[0], op1));
13860   DONE;
13863 (define_int_iterator SINCOS
13864         [UNSPEC_SIN
13865          UNSPEC_COS])
13867 (define_int_attr sincos
13868         [(UNSPEC_SIN "sin")
13869          (UNSPEC_COS "cos")])
13871 (define_insn "*<sincos>xf2_i387"
13872   [(set (match_operand:XF 0 "register_operand" "=f")
13873         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13874                    SINCOS))]
13875   "TARGET_USE_FANCY_MATH_387
13876    && flag_unsafe_math_optimizations"
13877   "f<sincos>"
13878   [(set_attr "type" "fpspc")
13879    (set_attr "mode" "XF")])
13881 (define_insn "*<sincos>_extend<mode>xf2_i387"
13882   [(set (match_operand:XF 0 "register_operand" "=f")
13883         (unspec:XF [(float_extend:XF
13884                       (match_operand:MODEF 1 "register_operand" "0"))]
13885                    SINCOS))]
13886   "TARGET_USE_FANCY_MATH_387
13887    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13888        || TARGET_MIX_SSE_I387)
13889    && flag_unsafe_math_optimizations"
13890   "f<sincos>"
13891   [(set_attr "type" "fpspc")
13892    (set_attr "mode" "XF")])
13894 ;; When sincos pattern is defined, sin and cos builtin functions will be
13895 ;; expanded to sincos pattern with one of its outputs left unused.
13896 ;; CSE pass will figure out if two sincos patterns can be combined,
13897 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13898 ;; depending on the unused output.
13900 (define_insn "sincosxf3"
13901   [(set (match_operand:XF 0 "register_operand" "=f")
13902         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13903                    UNSPEC_SINCOS_COS))
13904    (set (match_operand:XF 1 "register_operand" "=u")
13905         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13906   "TARGET_USE_FANCY_MATH_387
13907    && flag_unsafe_math_optimizations"
13908   "fsincos"
13909   [(set_attr "type" "fpspc")
13910    (set_attr "mode" "XF")])
13912 (define_split
13913   [(set (match_operand:XF 0 "register_operand")
13914         (unspec:XF [(match_operand:XF 2 "register_operand")]
13915                    UNSPEC_SINCOS_COS))
13916    (set (match_operand:XF 1 "register_operand")
13917         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13918   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13919    && can_create_pseudo_p ()"
13920   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13922 (define_split
13923   [(set (match_operand:XF 0 "register_operand")
13924         (unspec:XF [(match_operand:XF 2 "register_operand")]
13925                    UNSPEC_SINCOS_COS))
13926    (set (match_operand:XF 1 "register_operand")
13927         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13928   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13929    && can_create_pseudo_p ()"
13930   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13932 (define_insn "sincos_extend<mode>xf3_i387"
13933   [(set (match_operand:XF 0 "register_operand" "=f")
13934         (unspec:XF [(float_extend:XF
13935                       (match_operand:MODEF 2 "register_operand" "0"))]
13936                    UNSPEC_SINCOS_COS))
13937    (set (match_operand:XF 1 "register_operand" "=u")
13938         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13939   "TARGET_USE_FANCY_MATH_387
13940    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13941        || TARGET_MIX_SSE_I387)
13942    && flag_unsafe_math_optimizations"
13943   "fsincos"
13944   [(set_attr "type" "fpspc")
13945    (set_attr "mode" "XF")])
13947 (define_split
13948   [(set (match_operand:XF 0 "register_operand")
13949         (unspec:XF [(float_extend:XF
13950                       (match_operand:MODEF 2 "register_operand"))]
13951                    UNSPEC_SINCOS_COS))
13952    (set (match_operand:XF 1 "register_operand")
13953         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13954   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13955    && can_create_pseudo_p ()"
13956   [(set (match_dup 1)
13957         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13959 (define_split
13960   [(set (match_operand:XF 0 "register_operand")
13961         (unspec:XF [(float_extend:XF
13962                       (match_operand:MODEF 2 "register_operand"))]
13963                    UNSPEC_SINCOS_COS))
13964    (set (match_operand:XF 1 "register_operand")
13965         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13966   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13967    && can_create_pseudo_p ()"
13968   [(set (match_dup 0)
13969         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13971 (define_expand "sincos<mode>3"
13972   [(use (match_operand:MODEF 0 "register_operand"))
13973    (use (match_operand:MODEF 1 "register_operand"))
13974    (use (match_operand:MODEF 2 "register_operand"))]
13975   "TARGET_USE_FANCY_MATH_387
13976    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13977        || TARGET_MIX_SSE_I387)
13978    && flag_unsafe_math_optimizations"
13980   rtx op0 = gen_reg_rtx (XFmode);
13981   rtx op1 = gen_reg_rtx (XFmode);
13983   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13984   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13985   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13986   DONE;
13989 (define_insn "fptanxf4_i387"
13990   [(set (match_operand:XF 0 "register_operand" "=f")
13991         (match_operand:XF 3 "const_double_operand" "F"))
13992    (set (match_operand:XF 1 "register_operand" "=u")
13993         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13994                    UNSPEC_TAN))]
13995   "TARGET_USE_FANCY_MATH_387
13996    && flag_unsafe_math_optimizations
13997    && standard_80387_constant_p (operands[3]) == 2"
13998   "fptan"
13999   [(set_attr "type" "fpspc")
14000    (set_attr "mode" "XF")])
14002 (define_insn "fptan_extend<mode>xf4_i387"
14003   [(set (match_operand:MODEF 0 "register_operand" "=f")
14004         (match_operand:MODEF 3 "const_double_operand" "F"))
14005    (set (match_operand:XF 1 "register_operand" "=u")
14006         (unspec:XF [(float_extend:XF
14007                       (match_operand:MODEF 2 "register_operand" "0"))]
14008                    UNSPEC_TAN))]
14009   "TARGET_USE_FANCY_MATH_387
14010    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14011        || TARGET_MIX_SSE_I387)
14012    && flag_unsafe_math_optimizations
14013    && standard_80387_constant_p (operands[3]) == 2"
14014   "fptan"
14015   [(set_attr "type" "fpspc")
14016    (set_attr "mode" "XF")])
14018 (define_expand "tanxf2"
14019   [(use (match_operand:XF 0 "register_operand"))
14020    (use (match_operand:XF 1 "register_operand"))]
14021   "TARGET_USE_FANCY_MATH_387
14022    && flag_unsafe_math_optimizations"
14024   rtx one = gen_reg_rtx (XFmode);
14025   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14027   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14028   DONE;
14031 (define_expand "tan<mode>2"
14032   [(use (match_operand:MODEF 0 "register_operand"))
14033    (use (match_operand:MODEF 1 "register_operand"))]
14034   "TARGET_USE_FANCY_MATH_387
14035    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14036        || TARGET_MIX_SSE_I387)
14037    && flag_unsafe_math_optimizations"
14039   rtx op0 = gen_reg_rtx (XFmode);
14041   rtx one = gen_reg_rtx (<MODE>mode);
14042   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14044   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14045                                              operands[1], op2));
14046   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14047   DONE;
14050 (define_insn "*fpatanxf3_i387"
14051   [(set (match_operand:XF 0 "register_operand" "=f")
14052         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14053                     (match_operand:XF 2 "register_operand" "u")]
14054                    UNSPEC_FPATAN))
14055    (clobber (match_scratch:XF 3 "=2"))]
14056   "TARGET_USE_FANCY_MATH_387
14057    && flag_unsafe_math_optimizations"
14058   "fpatan"
14059   [(set_attr "type" "fpspc")
14060    (set_attr "mode" "XF")])
14062 (define_insn "fpatan_extend<mode>xf3_i387"
14063   [(set (match_operand:XF 0 "register_operand" "=f")
14064         (unspec:XF [(float_extend:XF
14065                       (match_operand:MODEF 1 "register_operand" "0"))
14066                     (float_extend:XF
14067                       (match_operand:MODEF 2 "register_operand" "u"))]
14068                    UNSPEC_FPATAN))
14069    (clobber (match_scratch:XF 3 "=2"))]
14070   "TARGET_USE_FANCY_MATH_387
14071    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14072        || TARGET_MIX_SSE_I387)
14073    && flag_unsafe_math_optimizations"
14074   "fpatan"
14075   [(set_attr "type" "fpspc")
14076    (set_attr "mode" "XF")])
14078 (define_expand "atan2xf3"
14079   [(parallel [(set (match_operand:XF 0 "register_operand")
14080                    (unspec:XF [(match_operand:XF 2 "register_operand")
14081                                (match_operand:XF 1 "register_operand")]
14082                               UNSPEC_FPATAN))
14083               (clobber (match_scratch:XF 3))])]
14084   "TARGET_USE_FANCY_MATH_387
14085    && flag_unsafe_math_optimizations")
14087 (define_expand "atan2<mode>3"
14088   [(use (match_operand:MODEF 0 "register_operand"))
14089    (use (match_operand:MODEF 1 "register_operand"))
14090    (use (match_operand:MODEF 2 "register_operand"))]
14091   "TARGET_USE_FANCY_MATH_387
14092    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14093        || TARGET_MIX_SSE_I387)
14094    && flag_unsafe_math_optimizations"
14096   rtx op0 = gen_reg_rtx (XFmode);
14098   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14099   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14100   DONE;
14103 (define_expand "atanxf2"
14104   [(parallel [(set (match_operand:XF 0 "register_operand")
14105                    (unspec:XF [(match_dup 2)
14106                                (match_operand:XF 1 "register_operand")]
14107                               UNSPEC_FPATAN))
14108               (clobber (match_scratch:XF 3))])]
14109   "TARGET_USE_FANCY_MATH_387
14110    && flag_unsafe_math_optimizations"
14112   operands[2] = gen_reg_rtx (XFmode);
14113   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
14116 (define_expand "atan<mode>2"
14117   [(use (match_operand:MODEF 0 "register_operand"))
14118    (use (match_operand:MODEF 1 "register_operand"))]
14119   "TARGET_USE_FANCY_MATH_387
14120    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14121        || TARGET_MIX_SSE_I387)
14122    && flag_unsafe_math_optimizations"
14124   rtx op0 = gen_reg_rtx (XFmode);
14126   rtx op2 = gen_reg_rtx (<MODE>mode);
14127   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
14129   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14130   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14131   DONE;
14134 (define_expand "asinxf2"
14135   [(set (match_dup 2)
14136         (mult:XF (match_operand:XF 1 "register_operand")
14137                  (match_dup 1)))
14138    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14139    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14140    (parallel [(set (match_operand:XF 0 "register_operand")
14141                    (unspec:XF [(match_dup 5) (match_dup 1)]
14142                               UNSPEC_FPATAN))
14143               (clobber (match_scratch:XF 6))])]
14144   "TARGET_USE_FANCY_MATH_387
14145    && flag_unsafe_math_optimizations"
14147   int i;
14149   if (optimize_insn_for_size_p ())
14150     FAIL;
14152   for (i = 2; i < 6; i++)
14153     operands[i] = gen_reg_rtx (XFmode);
14155   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14158 (define_expand "asin<mode>2"
14159   [(use (match_operand:MODEF 0 "register_operand"))
14160    (use (match_operand:MODEF 1 "general_operand"))]
14161  "TARGET_USE_FANCY_MATH_387
14162    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14163        || TARGET_MIX_SSE_I387)
14164    && flag_unsafe_math_optimizations"
14166   rtx op0 = gen_reg_rtx (XFmode);
14167   rtx op1 = gen_reg_rtx (XFmode);
14169   if (optimize_insn_for_size_p ())
14170     FAIL;
14172   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14173   emit_insn (gen_asinxf2 (op0, op1));
14174   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14175   DONE;
14178 (define_expand "acosxf2"
14179   [(set (match_dup 2)
14180         (mult:XF (match_operand:XF 1 "register_operand")
14181                  (match_dup 1)))
14182    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14183    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14184    (parallel [(set (match_operand:XF 0 "register_operand")
14185                    (unspec:XF [(match_dup 1) (match_dup 5)]
14186                               UNSPEC_FPATAN))
14187               (clobber (match_scratch:XF 6))])]
14188   "TARGET_USE_FANCY_MATH_387
14189    && flag_unsafe_math_optimizations"
14191   int i;
14193   if (optimize_insn_for_size_p ())
14194     FAIL;
14196   for (i = 2; i < 6; i++)
14197     operands[i] = gen_reg_rtx (XFmode);
14199   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14202 (define_expand "acos<mode>2"
14203   [(use (match_operand:MODEF 0 "register_operand"))
14204    (use (match_operand:MODEF 1 "general_operand"))]
14205  "TARGET_USE_FANCY_MATH_387
14206    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14207        || TARGET_MIX_SSE_I387)
14208    && flag_unsafe_math_optimizations"
14210   rtx op0 = gen_reg_rtx (XFmode);
14211   rtx op1 = gen_reg_rtx (XFmode);
14213   if (optimize_insn_for_size_p ())
14214     FAIL;
14216   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14217   emit_insn (gen_acosxf2 (op0, op1));
14218   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14219   DONE;
14222 (define_insn "fyl2xxf3_i387"
14223   [(set (match_operand:XF 0 "register_operand" "=f")
14224         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14225                     (match_operand:XF 2 "register_operand" "u")]
14226                    UNSPEC_FYL2X))
14227    (clobber (match_scratch:XF 3 "=2"))]
14228   "TARGET_USE_FANCY_MATH_387
14229    && flag_unsafe_math_optimizations"
14230   "fyl2x"
14231   [(set_attr "type" "fpspc")
14232    (set_attr "mode" "XF")])
14234 (define_insn "fyl2x_extend<mode>xf3_i387"
14235   [(set (match_operand:XF 0 "register_operand" "=f")
14236         (unspec:XF [(float_extend:XF
14237                       (match_operand:MODEF 1 "register_operand" "0"))
14238                     (match_operand:XF 2 "register_operand" "u")]
14239                    UNSPEC_FYL2X))
14240    (clobber (match_scratch:XF 3 "=2"))]
14241   "TARGET_USE_FANCY_MATH_387
14242    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14243        || TARGET_MIX_SSE_I387)
14244    && flag_unsafe_math_optimizations"
14245   "fyl2x"
14246   [(set_attr "type" "fpspc")
14247    (set_attr "mode" "XF")])
14249 (define_expand "logxf2"
14250   [(parallel [(set (match_operand:XF 0 "register_operand")
14251                    (unspec:XF [(match_operand:XF 1 "register_operand")
14252                                (match_dup 2)] UNSPEC_FYL2X))
14253               (clobber (match_scratch:XF 3))])]
14254   "TARGET_USE_FANCY_MATH_387
14255    && flag_unsafe_math_optimizations"
14257   operands[2] = gen_reg_rtx (XFmode);
14258   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14261 (define_expand "log<mode>2"
14262   [(use (match_operand:MODEF 0 "register_operand"))
14263    (use (match_operand:MODEF 1 "register_operand"))]
14264   "TARGET_USE_FANCY_MATH_387
14265    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14266        || TARGET_MIX_SSE_I387)
14267    && flag_unsafe_math_optimizations"
14269   rtx op0 = gen_reg_rtx (XFmode);
14271   rtx op2 = gen_reg_rtx (XFmode);
14272   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14274   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14275   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14276   DONE;
14279 (define_expand "log10xf2"
14280   [(parallel [(set (match_operand:XF 0 "register_operand")
14281                    (unspec:XF [(match_operand:XF 1 "register_operand")
14282                                (match_dup 2)] UNSPEC_FYL2X))
14283               (clobber (match_scratch:XF 3))])]
14284   "TARGET_USE_FANCY_MATH_387
14285    && flag_unsafe_math_optimizations"
14287   operands[2] = gen_reg_rtx (XFmode);
14288   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14291 (define_expand "log10<mode>2"
14292   [(use (match_operand:MODEF 0 "register_operand"))
14293    (use (match_operand:MODEF 1 "register_operand"))]
14294   "TARGET_USE_FANCY_MATH_387
14295    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14296        || TARGET_MIX_SSE_I387)
14297    && flag_unsafe_math_optimizations"
14299   rtx op0 = gen_reg_rtx (XFmode);
14301   rtx op2 = gen_reg_rtx (XFmode);
14302   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14304   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14305   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14306   DONE;
14309 (define_expand "log2xf2"
14310   [(parallel [(set (match_operand:XF 0 "register_operand")
14311                    (unspec:XF [(match_operand:XF 1 "register_operand")
14312                                (match_dup 2)] UNSPEC_FYL2X))
14313               (clobber (match_scratch:XF 3))])]
14314   "TARGET_USE_FANCY_MATH_387
14315    && flag_unsafe_math_optimizations"
14317   operands[2] = gen_reg_rtx (XFmode);
14318   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14321 (define_expand "log2<mode>2"
14322   [(use (match_operand:MODEF 0 "register_operand"))
14323    (use (match_operand:MODEF 1 "register_operand"))]
14324   "TARGET_USE_FANCY_MATH_387
14325    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14326        || TARGET_MIX_SSE_I387)
14327    && flag_unsafe_math_optimizations"
14329   rtx op0 = gen_reg_rtx (XFmode);
14331   rtx op2 = gen_reg_rtx (XFmode);
14332   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14334   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14335   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14336   DONE;
14339 (define_insn "fyl2xp1xf3_i387"
14340   [(set (match_operand:XF 0 "register_operand" "=f")
14341         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14342                     (match_operand:XF 2 "register_operand" "u")]
14343                    UNSPEC_FYL2XP1))
14344    (clobber (match_scratch:XF 3 "=2"))]
14345   "TARGET_USE_FANCY_MATH_387
14346    && flag_unsafe_math_optimizations"
14347   "fyl2xp1"
14348   [(set_attr "type" "fpspc")
14349    (set_attr "mode" "XF")])
14351 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14352   [(set (match_operand:XF 0 "register_operand" "=f")
14353         (unspec:XF [(float_extend:XF
14354                       (match_operand:MODEF 1 "register_operand" "0"))
14355                     (match_operand:XF 2 "register_operand" "u")]
14356                    UNSPEC_FYL2XP1))
14357    (clobber (match_scratch:XF 3 "=2"))]
14358   "TARGET_USE_FANCY_MATH_387
14359    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14360        || TARGET_MIX_SSE_I387)
14361    && flag_unsafe_math_optimizations"
14362   "fyl2xp1"
14363   [(set_attr "type" "fpspc")
14364    (set_attr "mode" "XF")])
14366 (define_expand "log1pxf2"
14367   [(use (match_operand:XF 0 "register_operand"))
14368    (use (match_operand:XF 1 "register_operand"))]
14369   "TARGET_USE_FANCY_MATH_387
14370    && flag_unsafe_math_optimizations"
14372   if (optimize_insn_for_size_p ())
14373     FAIL;
14375   ix86_emit_i387_log1p (operands[0], operands[1]);
14376   DONE;
14379 (define_expand "log1p<mode>2"
14380   [(use (match_operand:MODEF 0 "register_operand"))
14381    (use (match_operand:MODEF 1 "register_operand"))]
14382   "TARGET_USE_FANCY_MATH_387
14383    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14384        || TARGET_MIX_SSE_I387)
14385    && flag_unsafe_math_optimizations"
14387   rtx op0;
14389   if (optimize_insn_for_size_p ())
14390     FAIL;
14392   op0 = gen_reg_rtx (XFmode);
14394   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14396   ix86_emit_i387_log1p (op0, operands[1]);
14397   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14398   DONE;
14401 (define_insn "fxtractxf3_i387"
14402   [(set (match_operand:XF 0 "register_operand" "=f")
14403         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14404                    UNSPEC_XTRACT_FRACT))
14405    (set (match_operand:XF 1 "register_operand" "=u")
14406         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14407   "TARGET_USE_FANCY_MATH_387
14408    && flag_unsafe_math_optimizations"
14409   "fxtract"
14410   [(set_attr "type" "fpspc")
14411    (set_attr "mode" "XF")])
14413 (define_insn "fxtract_extend<mode>xf3_i387"
14414   [(set (match_operand:XF 0 "register_operand" "=f")
14415         (unspec:XF [(float_extend:XF
14416                       (match_operand:MODEF 2 "register_operand" "0"))]
14417                    UNSPEC_XTRACT_FRACT))
14418    (set (match_operand:XF 1 "register_operand" "=u")
14419         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14420   "TARGET_USE_FANCY_MATH_387
14421    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14422        || TARGET_MIX_SSE_I387)
14423    && flag_unsafe_math_optimizations"
14424   "fxtract"
14425   [(set_attr "type" "fpspc")
14426    (set_attr "mode" "XF")])
14428 (define_expand "logbxf2"
14429   [(parallel [(set (match_dup 2)
14430                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14431                               UNSPEC_XTRACT_FRACT))
14432               (set (match_operand:XF 0 "register_operand")
14433                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14434   "TARGET_USE_FANCY_MATH_387
14435    && flag_unsafe_math_optimizations"
14436   "operands[2] = gen_reg_rtx (XFmode);")
14438 (define_expand "logb<mode>2"
14439   [(use (match_operand:MODEF 0 "register_operand"))
14440    (use (match_operand:MODEF 1 "register_operand"))]
14441   "TARGET_USE_FANCY_MATH_387
14442    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14443        || TARGET_MIX_SSE_I387)
14444    && flag_unsafe_math_optimizations"
14446   rtx op0 = gen_reg_rtx (XFmode);
14447   rtx op1 = gen_reg_rtx (XFmode);
14449   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14450   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14451   DONE;
14454 (define_expand "ilogbxf2"
14455   [(use (match_operand:SI 0 "register_operand"))
14456    (use (match_operand:XF 1 "register_operand"))]
14457   "TARGET_USE_FANCY_MATH_387
14458    && flag_unsafe_math_optimizations"
14460   rtx op0, op1;
14462   if (optimize_insn_for_size_p ())
14463     FAIL;
14465   op0 = gen_reg_rtx (XFmode);
14466   op1 = gen_reg_rtx (XFmode);
14468   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14469   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14470   DONE;
14473 (define_expand "ilogb<mode>2"
14474   [(use (match_operand:SI 0 "register_operand"))
14475    (use (match_operand:MODEF 1 "register_operand"))]
14476   "TARGET_USE_FANCY_MATH_387
14477    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14478        || TARGET_MIX_SSE_I387)
14479    && flag_unsafe_math_optimizations"
14481   rtx op0, op1;
14483   if (optimize_insn_for_size_p ())
14484     FAIL;
14486   op0 = gen_reg_rtx (XFmode);
14487   op1 = gen_reg_rtx (XFmode);
14489   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14490   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14491   DONE;
14494 (define_insn "*f2xm1xf2_i387"
14495   [(set (match_operand:XF 0 "register_operand" "=f")
14496         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14497                    UNSPEC_F2XM1))]
14498   "TARGET_USE_FANCY_MATH_387
14499    && flag_unsafe_math_optimizations"
14500   "f2xm1"
14501   [(set_attr "type" "fpspc")
14502    (set_attr "mode" "XF")])
14504 (define_insn "fscalexf4_i387"
14505   [(set (match_operand:XF 0 "register_operand" "=f")
14506         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14507                     (match_operand:XF 3 "register_operand" "1")]
14508                    UNSPEC_FSCALE_FRACT))
14509    (set (match_operand:XF 1 "register_operand" "=u")
14510         (unspec:XF [(match_dup 2) (match_dup 3)]
14511                    UNSPEC_FSCALE_EXP))]
14512   "TARGET_USE_FANCY_MATH_387
14513    && flag_unsafe_math_optimizations"
14514   "fscale"
14515   [(set_attr "type" "fpspc")
14516    (set_attr "mode" "XF")])
14518 (define_expand "expNcorexf3"
14519   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14520                                (match_operand:XF 2 "register_operand")))
14521    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14522    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14523    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14524    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14525    (parallel [(set (match_operand:XF 0 "register_operand")
14526                    (unspec:XF [(match_dup 8) (match_dup 4)]
14527                               UNSPEC_FSCALE_FRACT))
14528               (set (match_dup 9)
14529                    (unspec:XF [(match_dup 8) (match_dup 4)]
14530                               UNSPEC_FSCALE_EXP))])]
14531   "TARGET_USE_FANCY_MATH_387
14532    && flag_unsafe_math_optimizations"
14534   int i;
14536   if (optimize_insn_for_size_p ())
14537     FAIL;
14539   for (i = 3; i < 10; i++)
14540     operands[i] = gen_reg_rtx (XFmode);
14542   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14545 (define_expand "expxf2"
14546   [(use (match_operand:XF 0 "register_operand"))
14547    (use (match_operand:XF 1 "register_operand"))]
14548   "TARGET_USE_FANCY_MATH_387
14549    && flag_unsafe_math_optimizations"
14551   rtx op2;
14553   if (optimize_insn_for_size_p ())
14554     FAIL;
14556   op2 = gen_reg_rtx (XFmode);
14557   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14559   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14560   DONE;
14563 (define_expand "exp<mode>2"
14564   [(use (match_operand:MODEF 0 "register_operand"))
14565    (use (match_operand:MODEF 1 "general_operand"))]
14566  "TARGET_USE_FANCY_MATH_387
14567    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14568        || TARGET_MIX_SSE_I387)
14569    && flag_unsafe_math_optimizations"
14571   rtx op0, op1;
14573   if (optimize_insn_for_size_p ())
14574     FAIL;
14576   op0 = gen_reg_rtx (XFmode);
14577   op1 = gen_reg_rtx (XFmode);
14579   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14580   emit_insn (gen_expxf2 (op0, op1));
14581   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14582   DONE;
14585 (define_expand "exp10xf2"
14586   [(use (match_operand:XF 0 "register_operand"))
14587    (use (match_operand:XF 1 "register_operand"))]
14588   "TARGET_USE_FANCY_MATH_387
14589    && flag_unsafe_math_optimizations"
14591   rtx op2;
14593   if (optimize_insn_for_size_p ())
14594     FAIL;
14596   op2 = gen_reg_rtx (XFmode);
14597   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14599   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14600   DONE;
14603 (define_expand "exp10<mode>2"
14604   [(use (match_operand:MODEF 0 "register_operand"))
14605    (use (match_operand:MODEF 1 "general_operand"))]
14606  "TARGET_USE_FANCY_MATH_387
14607    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14608        || TARGET_MIX_SSE_I387)
14609    && flag_unsafe_math_optimizations"
14611   rtx op0, op1;
14613   if (optimize_insn_for_size_p ())
14614     FAIL;
14616   op0 = gen_reg_rtx (XFmode);
14617   op1 = gen_reg_rtx (XFmode);
14619   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14620   emit_insn (gen_exp10xf2 (op0, op1));
14621   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14622   DONE;
14625 (define_expand "exp2xf2"
14626   [(use (match_operand:XF 0 "register_operand"))
14627    (use (match_operand:XF 1 "register_operand"))]
14628   "TARGET_USE_FANCY_MATH_387
14629    && flag_unsafe_math_optimizations"
14631   rtx op2;
14633   if (optimize_insn_for_size_p ())
14634     FAIL;
14636   op2 = gen_reg_rtx (XFmode);
14637   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14639   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14640   DONE;
14643 (define_expand "exp2<mode>2"
14644   [(use (match_operand:MODEF 0 "register_operand"))
14645    (use (match_operand:MODEF 1 "general_operand"))]
14646  "TARGET_USE_FANCY_MATH_387
14647    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14648        || TARGET_MIX_SSE_I387)
14649    && flag_unsafe_math_optimizations"
14651   rtx op0, op1;
14653   if (optimize_insn_for_size_p ())
14654     FAIL;
14656   op0 = gen_reg_rtx (XFmode);
14657   op1 = gen_reg_rtx (XFmode);
14659   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14660   emit_insn (gen_exp2xf2 (op0, op1));
14661   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14662   DONE;
14665 (define_expand "expm1xf2"
14666   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14667                                (match_dup 2)))
14668    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14669    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14670    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14671    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14672    (parallel [(set (match_dup 7)
14673                    (unspec:XF [(match_dup 6) (match_dup 4)]
14674                               UNSPEC_FSCALE_FRACT))
14675               (set (match_dup 8)
14676                    (unspec:XF [(match_dup 6) (match_dup 4)]
14677                               UNSPEC_FSCALE_EXP))])
14678    (parallel [(set (match_dup 10)
14679                    (unspec:XF [(match_dup 9) (match_dup 8)]
14680                               UNSPEC_FSCALE_FRACT))
14681               (set (match_dup 11)
14682                    (unspec:XF [(match_dup 9) (match_dup 8)]
14683                               UNSPEC_FSCALE_EXP))])
14684    (set (match_dup 12) (minus:XF (match_dup 10)
14685                                  (float_extend:XF (match_dup 13))))
14686    (set (match_operand:XF 0 "register_operand")
14687         (plus:XF (match_dup 12) (match_dup 7)))]
14688   "TARGET_USE_FANCY_MATH_387
14689    && flag_unsafe_math_optimizations"
14691   int i;
14693   if (optimize_insn_for_size_p ())
14694     FAIL;
14696   for (i = 2; i < 13; i++)
14697     operands[i] = gen_reg_rtx (XFmode);
14699   operands[13]
14700     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14702   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14705 (define_expand "expm1<mode>2"
14706   [(use (match_operand:MODEF 0 "register_operand"))
14707    (use (match_operand:MODEF 1 "general_operand"))]
14708  "TARGET_USE_FANCY_MATH_387
14709    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14710        || TARGET_MIX_SSE_I387)
14711    && flag_unsafe_math_optimizations"
14713   rtx op0, op1;
14715   if (optimize_insn_for_size_p ())
14716     FAIL;
14718   op0 = gen_reg_rtx (XFmode);
14719   op1 = gen_reg_rtx (XFmode);
14721   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14722   emit_insn (gen_expm1xf2 (op0, op1));
14723   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14724   DONE;
14727 (define_expand "ldexpxf3"
14728   [(match_operand:XF 0 "register_operand")
14729    (match_operand:XF 1 "register_operand")
14730    (match_operand:SI 2 "register_operand")]
14731   "TARGET_USE_FANCY_MATH_387
14732    && flag_unsafe_math_optimizations"
14734   rtx tmp1, tmp2;
14735   if (optimize_insn_for_size_p ())
14736     FAIL;
14738   tmp1 = gen_reg_rtx (XFmode);
14739   tmp2 = gen_reg_rtx (XFmode);
14741   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
14742   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
14743                                  operands[1], tmp1));
14744   DONE;
14747 (define_expand "ldexp<mode>3"
14748   [(use (match_operand:MODEF 0 "register_operand"))
14749    (use (match_operand:MODEF 1 "general_operand"))
14750    (use (match_operand:SI 2 "register_operand"))]
14751  "TARGET_USE_FANCY_MATH_387
14752    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14753        || TARGET_MIX_SSE_I387)
14754    && flag_unsafe_math_optimizations"
14756   rtx op0, op1;
14758   if (optimize_insn_for_size_p ())
14759     FAIL;
14761   op0 = gen_reg_rtx (XFmode);
14762   op1 = gen_reg_rtx (XFmode);
14764   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14765   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14766   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14767   DONE;
14770 (define_expand "scalbxf3"
14771   [(parallel [(set (match_operand:XF 0 " register_operand")
14772                    (unspec:XF [(match_operand:XF 1 "register_operand")
14773                                (match_operand:XF 2 "register_operand")]
14774                               UNSPEC_FSCALE_FRACT))
14775               (set (match_dup 3)
14776                    (unspec:XF [(match_dup 1) (match_dup 2)]
14777                               UNSPEC_FSCALE_EXP))])]
14778   "TARGET_USE_FANCY_MATH_387
14779    && flag_unsafe_math_optimizations"
14781   if (optimize_insn_for_size_p ())
14782     FAIL;
14784   operands[3] = gen_reg_rtx (XFmode);
14787 (define_expand "scalb<mode>3"
14788   [(use (match_operand:MODEF 0 "register_operand"))
14789    (use (match_operand:MODEF 1 "general_operand"))
14790    (use (match_operand:MODEF 2 "general_operand"))]
14791  "TARGET_USE_FANCY_MATH_387
14792    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14793        || TARGET_MIX_SSE_I387)
14794    && flag_unsafe_math_optimizations"
14796   rtx op0, op1, op2;
14798   if (optimize_insn_for_size_p ())
14799     FAIL;
14801   op0 = gen_reg_rtx (XFmode);
14802   op1 = gen_reg_rtx (XFmode);
14803   op2 = gen_reg_rtx (XFmode);
14805   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14806   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14807   emit_insn (gen_scalbxf3 (op0, op1, op2));
14808   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14809   DONE;
14812 (define_expand "significandxf2"
14813   [(parallel [(set (match_operand:XF 0 "register_operand")
14814                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14815                               UNSPEC_XTRACT_FRACT))
14816               (set (match_dup 2)
14817                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14818   "TARGET_USE_FANCY_MATH_387
14819    && flag_unsafe_math_optimizations"
14820   "operands[2] = gen_reg_rtx (XFmode);")
14822 (define_expand "significand<mode>2"
14823   [(use (match_operand:MODEF 0 "register_operand"))
14824    (use (match_operand:MODEF 1 "register_operand"))]
14825   "TARGET_USE_FANCY_MATH_387
14826    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14827        || TARGET_MIX_SSE_I387)
14828    && flag_unsafe_math_optimizations"
14830   rtx op0 = gen_reg_rtx (XFmode);
14831   rtx op1 = gen_reg_rtx (XFmode);
14833   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14834   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14835   DONE;
14839 (define_insn "sse4_1_round<mode>2"
14840   [(set (match_operand:MODEF 0 "register_operand" "=x")
14841         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14842                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14843                       UNSPEC_ROUND))]
14844   "TARGET_ROUND"
14845   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14846   [(set_attr "type" "ssecvt")
14847    (set_attr "prefix_extra" "1")
14848    (set_attr "prefix" "maybe_vex")
14849    (set_attr "mode" "<MODE>")])
14851 (define_insn "rintxf2"
14852   [(set (match_operand:XF 0 "register_operand" "=f")
14853         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14854                    UNSPEC_FRNDINT))]
14855   "TARGET_USE_FANCY_MATH_387
14856    && flag_unsafe_math_optimizations"
14857   "frndint"
14858   [(set_attr "type" "fpspc")
14859    (set_attr "mode" "XF")])
14861 (define_expand "rint<mode>2"
14862   [(use (match_operand:MODEF 0 "register_operand"))
14863    (use (match_operand:MODEF 1 "register_operand"))]
14864   "(TARGET_USE_FANCY_MATH_387
14865     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14866         || TARGET_MIX_SSE_I387)
14867     && flag_unsafe_math_optimizations)
14868    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14869        && !flag_trapping_math)"
14871   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14872       && !flag_trapping_math)
14873     {
14874       if (TARGET_ROUND)
14875         emit_insn (gen_sse4_1_round<mode>2
14876                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14877       else if (optimize_insn_for_size_p ())
14878         FAIL;
14879       else
14880         ix86_expand_rint (operands[0], operands[1]);
14881     }
14882   else
14883     {
14884       rtx op0 = gen_reg_rtx (XFmode);
14885       rtx op1 = gen_reg_rtx (XFmode);
14887       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14888       emit_insn (gen_rintxf2 (op0, op1));
14890       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14891     }
14892   DONE;
14895 (define_expand "round<mode>2"
14896   [(match_operand:X87MODEF 0 "register_operand")
14897    (match_operand:X87MODEF 1 "nonimmediate_operand")]
14898   "(TARGET_USE_FANCY_MATH_387
14899     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14900         || TARGET_MIX_SSE_I387)
14901     && flag_unsafe_math_optimizations)
14902    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14903        && !flag_trapping_math && !flag_rounding_math)"
14905   if (optimize_insn_for_size_p ())
14906     FAIL;
14908   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14909       && !flag_trapping_math && !flag_rounding_math)
14910     {
14911       if (TARGET_ROUND)
14912         {
14913           operands[1] = force_reg (<MODE>mode, operands[1]);
14914           ix86_expand_round_sse4 (operands[0], operands[1]);
14915         }
14916       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14917         ix86_expand_round (operands[0], operands[1]);
14918       else
14919         ix86_expand_rounddf_32 (operands[0], operands[1]);
14920     }
14921   else
14922     {
14923       operands[1] = force_reg (<MODE>mode, operands[1]);
14924       ix86_emit_i387_round (operands[0], operands[1]);
14925     }
14926   DONE;
14929 (define_insn_and_split "*fistdi2_1"
14930   [(set (match_operand:DI 0 "nonimmediate_operand")
14931         (unspec:DI [(match_operand:XF 1 "register_operand")]
14932                    UNSPEC_FIST))]
14933   "TARGET_USE_FANCY_MATH_387
14934    && can_create_pseudo_p ()"
14935   "#"
14936   "&& 1"
14937   [(const_int 0)]
14939   if (memory_operand (operands[0], VOIDmode))
14940     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14941   else
14942     {
14943       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14944       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14945                                          operands[2]));
14946     }
14947   DONE;
14949   [(set_attr "type" "fpspc")
14950    (set_attr "mode" "DI")])
14952 (define_insn "fistdi2"
14953   [(set (match_operand:DI 0 "memory_operand" "=m")
14954         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14955                    UNSPEC_FIST))
14956    (clobber (match_scratch:XF 2 "=&1f"))]
14957   "TARGET_USE_FANCY_MATH_387"
14958   "* return output_fix_trunc (insn, operands, false);"
14959   [(set_attr "type" "fpspc")
14960    (set_attr "mode" "DI")])
14962 (define_insn "fistdi2_with_temp"
14963   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14964         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14965                    UNSPEC_FIST))
14966    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14967    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14968   "TARGET_USE_FANCY_MATH_387"
14969   "#"
14970   [(set_attr "type" "fpspc")
14971    (set_attr "mode" "DI")])
14973 (define_split
14974   [(set (match_operand:DI 0 "register_operand")
14975         (unspec:DI [(match_operand:XF 1 "register_operand")]
14976                    UNSPEC_FIST))
14977    (clobber (match_operand:DI 2 "memory_operand"))
14978    (clobber (match_scratch 3))]
14979   "reload_completed"
14980   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14981               (clobber (match_dup 3))])
14982    (set (match_dup 0) (match_dup 2))])
14984 (define_split
14985   [(set (match_operand:DI 0 "memory_operand")
14986         (unspec:DI [(match_operand:XF 1 "register_operand")]
14987                    UNSPEC_FIST))
14988    (clobber (match_operand:DI 2 "memory_operand"))
14989    (clobber (match_scratch 3))]
14990   "reload_completed"
14991   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14992               (clobber (match_dup 3))])])
14994 (define_insn_and_split "*fist<mode>2_1"
14995   [(set (match_operand:SWI24 0 "register_operand")
14996         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14997                       UNSPEC_FIST))]
14998   "TARGET_USE_FANCY_MATH_387
14999    && can_create_pseudo_p ()"
15000   "#"
15001   "&& 1"
15002   [(const_int 0)]
15004   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15005   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15006                                         operands[2]));
15007   DONE;
15009   [(set_attr "type" "fpspc")
15010    (set_attr "mode" "<MODE>")])
15012 (define_insn "fist<mode>2"
15013   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15014         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15015                       UNSPEC_FIST))]
15016   "TARGET_USE_FANCY_MATH_387"
15017   "* return output_fix_trunc (insn, operands, false);"
15018   [(set_attr "type" "fpspc")
15019    (set_attr "mode" "<MODE>")])
15021 (define_insn "fist<mode>2_with_temp"
15022   [(set (match_operand:SWI24 0 "register_operand" "=r")
15023         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15024                       UNSPEC_FIST))
15025    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15026   "TARGET_USE_FANCY_MATH_387"
15027   "#"
15028   [(set_attr "type" "fpspc")
15029    (set_attr "mode" "<MODE>")])
15031 (define_split
15032   [(set (match_operand:SWI24 0 "register_operand")
15033         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15034                       UNSPEC_FIST))
15035    (clobber (match_operand:SWI24 2 "memory_operand"))]
15036   "reload_completed"
15037   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15038    (set (match_dup 0) (match_dup 2))])
15040 (define_split
15041   [(set (match_operand:SWI24 0 "memory_operand")
15042         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15043                       UNSPEC_FIST))
15044    (clobber (match_operand:SWI24 2 "memory_operand"))]
15045   "reload_completed"
15046   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15048 (define_expand "lrintxf<mode>2"
15049   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15050      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15051                      UNSPEC_FIST))]
15052   "TARGET_USE_FANCY_MATH_387")
15054 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15055   [(set (match_operand:SWI48 0 "nonimmediate_operand")
15056      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15057                    UNSPEC_FIX_NOTRUNC))]
15058   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15060 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15061   [(match_operand:SWI248x 0 "nonimmediate_operand")
15062    (match_operand:X87MODEF 1 "register_operand")]
15063   "(TARGET_USE_FANCY_MATH_387
15064     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15065         || TARGET_MIX_SSE_I387)
15066     && flag_unsafe_math_optimizations)
15067    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15068        && <SWI248x:MODE>mode != HImode 
15069        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15070        && !flag_trapping_math && !flag_rounding_math)"
15072   if (optimize_insn_for_size_p ())
15073     FAIL;
15075   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15076       && <SWI248x:MODE>mode != HImode
15077       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15078       && !flag_trapping_math && !flag_rounding_math)
15079     ix86_expand_lround (operands[0], operands[1]);
15080   else
15081     ix86_emit_i387_round (operands[0], operands[1]);
15082   DONE;
15085 (define_int_iterator FRNDINT_ROUNDING
15086         [UNSPEC_FRNDINT_FLOOR
15087          UNSPEC_FRNDINT_CEIL
15088          UNSPEC_FRNDINT_TRUNC])
15090 (define_int_iterator FIST_ROUNDING
15091         [UNSPEC_FIST_FLOOR
15092          UNSPEC_FIST_CEIL])
15094 ;; Base name for define_insn
15095 (define_int_attr rounding_insn
15096         [(UNSPEC_FRNDINT_FLOOR "floor")
15097          (UNSPEC_FRNDINT_CEIL "ceil")
15098          (UNSPEC_FRNDINT_TRUNC "btrunc")
15099          (UNSPEC_FIST_FLOOR "floor")
15100          (UNSPEC_FIST_CEIL "ceil")])
15102 (define_int_attr rounding
15103         [(UNSPEC_FRNDINT_FLOOR "floor")
15104          (UNSPEC_FRNDINT_CEIL "ceil")
15105          (UNSPEC_FRNDINT_TRUNC "trunc")
15106          (UNSPEC_FIST_FLOOR "floor")
15107          (UNSPEC_FIST_CEIL "ceil")])
15109 (define_int_attr ROUNDING
15110         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15111          (UNSPEC_FRNDINT_CEIL "CEIL")
15112          (UNSPEC_FRNDINT_TRUNC "TRUNC")
15113          (UNSPEC_FIST_FLOOR "FLOOR")
15114          (UNSPEC_FIST_CEIL "CEIL")])
15116 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15117 (define_insn_and_split "frndintxf2_<rounding>"
15118   [(set (match_operand:XF 0 "register_operand")
15119         (unspec:XF [(match_operand:XF 1 "register_operand")]
15120                    FRNDINT_ROUNDING))
15121    (clobber (reg:CC FLAGS_REG))]
15122   "TARGET_USE_FANCY_MATH_387
15123    && flag_unsafe_math_optimizations
15124    && can_create_pseudo_p ()"
15125   "#"
15126   "&& 1"
15127   [(const_int 0)]
15129   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15131   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15132   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15134   emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15135                                              operands[2], operands[3]));
15136   DONE;
15138   [(set_attr "type" "frndint")
15139    (set_attr "i387_cw" "<rounding>")
15140    (set_attr "mode" "XF")])
15142 (define_insn "frndintxf2_<rounding>_i387"
15143   [(set (match_operand:XF 0 "register_operand" "=f")
15144         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15145                    FRNDINT_ROUNDING))
15146    (use (match_operand:HI 2 "memory_operand" "m"))
15147    (use (match_operand:HI 3 "memory_operand" "m"))]
15148   "TARGET_USE_FANCY_MATH_387
15149    && flag_unsafe_math_optimizations"
15150   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15151   [(set_attr "type" "frndint")
15152    (set_attr "i387_cw" "<rounding>")
15153    (set_attr "mode" "XF")])
15155 (define_expand "<rounding_insn>xf2"
15156   [(parallel [(set (match_operand:XF 0 "register_operand")
15157                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15158                               FRNDINT_ROUNDING))
15159               (clobber (reg:CC FLAGS_REG))])]
15160   "TARGET_USE_FANCY_MATH_387
15161    && flag_unsafe_math_optimizations
15162    && !optimize_insn_for_size_p ()")
15164 (define_expand "<rounding_insn><mode>2"
15165   [(parallel [(set (match_operand:MODEF 0 "register_operand")
15166                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15167                                  FRNDINT_ROUNDING))
15168               (clobber (reg:CC FLAGS_REG))])]
15169   "(TARGET_USE_FANCY_MATH_387
15170     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15171         || TARGET_MIX_SSE_I387)
15172     && flag_unsafe_math_optimizations)
15173    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15174        && !flag_trapping_math)"
15176   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15177       && !flag_trapping_math)
15178     {
15179       if (TARGET_ROUND)
15180         emit_insn (gen_sse4_1_round<mode>2
15181                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15182       else if (optimize_insn_for_size_p ())
15183         FAIL;
15184       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15185         {
15186           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15187             ix86_expand_floorceil (operands[0], operands[1], true);
15188           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15189             ix86_expand_floorceil (operands[0], operands[1], false);
15190           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15191             ix86_expand_trunc (operands[0], operands[1]);
15192           else
15193             gcc_unreachable ();
15194         }
15195       else
15196         {
15197           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15198             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15199           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15200             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15201           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15202             ix86_expand_truncdf_32 (operands[0], operands[1]);
15203           else
15204             gcc_unreachable ();
15205         }
15206     }
15207   else
15208     {
15209       rtx op0, op1;
15211       if (optimize_insn_for_size_p ())
15212         FAIL;
15214       op0 = gen_reg_rtx (XFmode);
15215       op1 = gen_reg_rtx (XFmode);
15216       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15217       emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15219       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15220     }
15221   DONE;
15224 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15225 (define_insn_and_split "frndintxf2_mask_pm"
15226   [(set (match_operand:XF 0 "register_operand")
15227         (unspec:XF [(match_operand:XF 1 "register_operand")]
15228                    UNSPEC_FRNDINT_MASK_PM))
15229    (clobber (reg:CC FLAGS_REG))]
15230   "TARGET_USE_FANCY_MATH_387
15231    && flag_unsafe_math_optimizations
15232    && can_create_pseudo_p ()"
15233   "#"
15234   "&& 1"
15235   [(const_int 0)]
15237   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15239   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15240   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15242   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15243                                           operands[2], operands[3]));
15244   DONE;
15246   [(set_attr "type" "frndint")
15247    (set_attr "i387_cw" "mask_pm")
15248    (set_attr "mode" "XF")])
15250 (define_insn "frndintxf2_mask_pm_i387"
15251   [(set (match_operand:XF 0 "register_operand" "=f")
15252         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15253                    UNSPEC_FRNDINT_MASK_PM))
15254    (use (match_operand:HI 2 "memory_operand" "m"))
15255    (use (match_operand:HI 3 "memory_operand" "m"))]
15256   "TARGET_USE_FANCY_MATH_387
15257    && flag_unsafe_math_optimizations"
15258   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15259   [(set_attr "type" "frndint")
15260    (set_attr "i387_cw" "mask_pm")
15261    (set_attr "mode" "XF")])
15263 (define_expand "nearbyintxf2"
15264   [(parallel [(set (match_operand:XF 0 "register_operand")
15265                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15266                               UNSPEC_FRNDINT_MASK_PM))
15267               (clobber (reg:CC FLAGS_REG))])]
15268   "TARGET_USE_FANCY_MATH_387
15269    && flag_unsafe_math_optimizations")
15271 (define_expand "nearbyint<mode>2"
15272   [(use (match_operand:MODEF 0 "register_operand"))
15273    (use (match_operand:MODEF 1 "register_operand"))]
15274   "TARGET_USE_FANCY_MATH_387
15275    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15276        || TARGET_MIX_SSE_I387)
15277    && flag_unsafe_math_optimizations"
15279   rtx op0 = gen_reg_rtx (XFmode);
15280   rtx op1 = gen_reg_rtx (XFmode);
15282   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15283   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15285   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15286   DONE;
15289 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15290 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15291   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15292         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15293                         FIST_ROUNDING))
15294    (clobber (reg:CC FLAGS_REG))]
15295   "TARGET_USE_FANCY_MATH_387
15296    && flag_unsafe_math_optimizations
15297    && can_create_pseudo_p ()"
15298   "#"
15299   "&& 1"
15300   [(const_int 0)]
15302   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15304   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15305   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15306   if (memory_operand (operands[0], VOIDmode))
15307     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15308                                            operands[2], operands[3]));
15309   else
15310     {
15311       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15312       emit_insn (gen_fist<mode>2_<rounding>_with_temp
15313                   (operands[0], operands[1], operands[2],
15314                    operands[3], operands[4]));
15315     }
15316   DONE;
15318   [(set_attr "type" "fistp")
15319    (set_attr "i387_cw" "<rounding>")
15320    (set_attr "mode" "<MODE>")])
15322 (define_insn "fistdi2_<rounding>"
15323   [(set (match_operand:DI 0 "memory_operand" "=m")
15324         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15325                    FIST_ROUNDING))
15326    (use (match_operand:HI 2 "memory_operand" "m"))
15327    (use (match_operand:HI 3 "memory_operand" "m"))
15328    (clobber (match_scratch:XF 4 "=&1f"))]
15329   "TARGET_USE_FANCY_MATH_387
15330    && flag_unsafe_math_optimizations"
15331   "* return output_fix_trunc (insn, operands, false);"
15332   [(set_attr "type" "fistp")
15333    (set_attr "i387_cw" "<rounding>")
15334    (set_attr "mode" "DI")])
15336 (define_insn "fistdi2_<rounding>_with_temp"
15337   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15338         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15339                    FIST_ROUNDING))
15340    (use (match_operand:HI 2 "memory_operand" "m,m"))
15341    (use (match_operand:HI 3 "memory_operand" "m,m"))
15342    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15343    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15344   "TARGET_USE_FANCY_MATH_387
15345    && flag_unsafe_math_optimizations"
15346   "#"
15347   [(set_attr "type" "fistp")
15348    (set_attr "i387_cw" "<rounding>")
15349    (set_attr "mode" "DI")])
15351 (define_split
15352   [(set (match_operand:DI 0 "register_operand")
15353         (unspec:DI [(match_operand:XF 1 "register_operand")]
15354                    FIST_ROUNDING))
15355    (use (match_operand:HI 2 "memory_operand"))
15356    (use (match_operand:HI 3 "memory_operand"))
15357    (clobber (match_operand:DI 4 "memory_operand"))
15358    (clobber (match_scratch 5))]
15359   "reload_completed"
15360   [(parallel [(set (match_dup 4)
15361                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15362               (use (match_dup 2))
15363               (use (match_dup 3))
15364               (clobber (match_dup 5))])
15365    (set (match_dup 0) (match_dup 4))])
15367 (define_split
15368   [(set (match_operand:DI 0 "memory_operand")
15369         (unspec:DI [(match_operand:XF 1 "register_operand")]
15370                    FIST_ROUNDING))
15371    (use (match_operand:HI 2 "memory_operand"))
15372    (use (match_operand:HI 3 "memory_operand"))
15373    (clobber (match_operand:DI 4 "memory_operand"))
15374    (clobber (match_scratch 5))]
15375   "reload_completed"
15376   [(parallel [(set (match_dup 0)
15377                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15378               (use (match_dup 2))
15379               (use (match_dup 3))
15380               (clobber (match_dup 5))])])
15382 (define_insn "fist<mode>2_<rounding>"
15383   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15384         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15385                       FIST_ROUNDING))
15386    (use (match_operand:HI 2 "memory_operand" "m"))
15387    (use (match_operand:HI 3 "memory_operand" "m"))]
15388   "TARGET_USE_FANCY_MATH_387
15389    && flag_unsafe_math_optimizations"
15390   "* return output_fix_trunc (insn, operands, false);"
15391   [(set_attr "type" "fistp")
15392    (set_attr "i387_cw" "<rounding>")
15393    (set_attr "mode" "<MODE>")])
15395 (define_insn "fist<mode>2_<rounding>_with_temp"
15396   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15397         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15398                       FIST_ROUNDING))
15399    (use (match_operand:HI 2 "memory_operand" "m,m"))
15400    (use (match_operand:HI 3 "memory_operand" "m,m"))
15401    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15402   "TARGET_USE_FANCY_MATH_387
15403    && flag_unsafe_math_optimizations"
15404   "#"
15405   [(set_attr "type" "fistp")
15406    (set_attr "i387_cw" "<rounding>")
15407    (set_attr "mode" "<MODE>")])
15409 (define_split
15410   [(set (match_operand:SWI24 0 "register_operand")
15411         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15412                       FIST_ROUNDING))
15413    (use (match_operand:HI 2 "memory_operand"))
15414    (use (match_operand:HI 3 "memory_operand"))
15415    (clobber (match_operand:SWI24 4 "memory_operand"))]
15416   "reload_completed"
15417   [(parallel [(set (match_dup 4)
15418                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15419               (use (match_dup 2))
15420               (use (match_dup 3))])
15421    (set (match_dup 0) (match_dup 4))])
15423 (define_split
15424   [(set (match_operand:SWI24 0 "memory_operand")
15425         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15426                       FIST_ROUNDING))
15427    (use (match_operand:HI 2 "memory_operand"))
15428    (use (match_operand:HI 3 "memory_operand"))
15429    (clobber (match_operand:SWI24 4 "memory_operand"))]
15430   "reload_completed"
15431   [(parallel [(set (match_dup 0)
15432                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15433               (use (match_dup 2))
15434               (use (match_dup 3))])])
15436 (define_expand "l<rounding_insn>xf<mode>2"
15437   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15438                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15439                                    FIST_ROUNDING))
15440               (clobber (reg:CC FLAGS_REG))])]
15441   "TARGET_USE_FANCY_MATH_387
15442    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15443    && flag_unsafe_math_optimizations")
15445 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15446   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15447                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15448                                  FIST_ROUNDING))
15449               (clobber (reg:CC FLAGS_REG))])]
15450   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15451    && !flag_trapping_math"
15453   if (TARGET_64BIT && optimize_insn_for_size_p ())
15454     FAIL;
15456   if (ROUND_<ROUNDING> == ROUND_FLOOR)
15457     ix86_expand_lfloorceil (operands[0], operands[1], true);
15458   else if (ROUND_<ROUNDING> == ROUND_CEIL)
15459     ix86_expand_lfloorceil (operands[0], operands[1], false);
15460   else
15461     gcc_unreachable ();
15463   DONE;
15466 (define_insn "fxam<mode>2_i387"
15467   [(set (match_operand:HI 0 "register_operand" "=a")
15468         (unspec:HI
15469           [(match_operand:X87MODEF 1 "register_operand" "f")]
15470           UNSPEC_FXAM))]
15471   "TARGET_USE_FANCY_MATH_387"
15472   "fxam\n\tfnstsw\t%0"
15473   [(set_attr "type" "multi")
15474    (set_attr "length" "4")
15475    (set_attr "unit" "i387")
15476    (set_attr "mode" "<MODE>")])
15478 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15479   [(set (match_operand:HI 0 "register_operand")
15480         (unspec:HI
15481           [(match_operand:MODEF 1 "memory_operand")]
15482           UNSPEC_FXAM_MEM))]
15483   "TARGET_USE_FANCY_MATH_387
15484    && can_create_pseudo_p ()"
15485   "#"
15486   "&& 1"
15487   [(set (match_dup 2)(match_dup 1))
15488    (set (match_dup 0)
15489         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15491   operands[2] = gen_reg_rtx (<MODE>mode);
15493   MEM_VOLATILE_P (operands[1]) = 1;
15495   [(set_attr "type" "multi")
15496    (set_attr "unit" "i387")
15497    (set_attr "mode" "<MODE>")])
15499 (define_expand "isinfxf2"
15500   [(use (match_operand:SI 0 "register_operand"))
15501    (use (match_operand:XF 1 "register_operand"))]
15502   "TARGET_USE_FANCY_MATH_387
15503    && ix86_libc_has_function (function_c99_misc)"
15505   rtx mask = GEN_INT (0x45);
15506   rtx val = GEN_INT (0x05);
15508   rtx cond;
15510   rtx scratch = gen_reg_rtx (HImode);
15511   rtx res = gen_reg_rtx (QImode);
15513   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15515   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15516   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15517   cond = gen_rtx_fmt_ee (EQ, QImode,
15518                          gen_rtx_REG (CCmode, FLAGS_REG),
15519                          const0_rtx);
15520   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15521   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15522   DONE;
15525 (define_expand "isinf<mode>2"
15526   [(use (match_operand:SI 0 "register_operand"))
15527    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15528   "TARGET_USE_FANCY_MATH_387
15529    && ix86_libc_has_function (function_c99_misc)
15530    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15532   rtx mask = GEN_INT (0x45);
15533   rtx val = GEN_INT (0x05);
15535   rtx cond;
15537   rtx scratch = gen_reg_rtx (HImode);
15538   rtx res = gen_reg_rtx (QImode);
15540   /* Remove excess precision by forcing value through memory. */
15541   if (memory_operand (operands[1], VOIDmode))
15542     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15543   else
15544     {
15545       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15547       emit_move_insn (temp, operands[1]);
15548       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15549     }
15551   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15552   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15553   cond = gen_rtx_fmt_ee (EQ, QImode,
15554                          gen_rtx_REG (CCmode, FLAGS_REG),
15555                          const0_rtx);
15556   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15557   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15558   DONE;
15561 (define_expand "signbitxf2"
15562   [(use (match_operand:SI 0 "register_operand"))
15563    (use (match_operand:XF 1 "register_operand"))]
15564   "TARGET_USE_FANCY_MATH_387"
15566   rtx scratch = gen_reg_rtx (HImode);
15568   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15569   emit_insn (gen_andsi3 (operands[0],
15570              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15571   DONE;
15574 (define_insn "movmsk_df"
15575   [(set (match_operand:SI 0 "register_operand" "=r")
15576         (unspec:SI
15577           [(match_operand:DF 1 "register_operand" "x")]
15578           UNSPEC_MOVMSK))]
15579   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15580   "%vmovmskpd\t{%1, %0|%0, %1}"
15581   [(set_attr "type" "ssemov")
15582    (set_attr "prefix" "maybe_vex")
15583    (set_attr "mode" "DF")])
15585 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15586 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15587 (define_expand "signbitdf2"
15588   [(use (match_operand:SI 0 "register_operand"))
15589    (use (match_operand:DF 1 "register_operand"))]
15590   "TARGET_USE_FANCY_MATH_387
15591    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15593   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15594     {
15595       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15596       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15597     }
15598   else
15599     {
15600       rtx scratch = gen_reg_rtx (HImode);
15602       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15603       emit_insn (gen_andsi3 (operands[0],
15604                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15605     }
15606   DONE;
15609 (define_expand "signbitsf2"
15610   [(use (match_operand:SI 0 "register_operand"))
15611    (use (match_operand:SF 1 "register_operand"))]
15612   "TARGET_USE_FANCY_MATH_387
15613    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15615   rtx scratch = gen_reg_rtx (HImode);
15617   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15618   emit_insn (gen_andsi3 (operands[0],
15619              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15620   DONE;
15623 ;; Block operation instructions
15625 (define_insn "cld"
15626   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15627   ""
15628   "cld"
15629   [(set_attr "length" "1")
15630    (set_attr "length_immediate" "0")
15631    (set_attr "modrm" "0")])
15633 (define_expand "movmem<mode>"
15634   [(use (match_operand:BLK 0 "memory_operand"))
15635    (use (match_operand:BLK 1 "memory_operand"))
15636    (use (match_operand:SWI48 2 "nonmemory_operand"))
15637    (use (match_operand:SWI48 3 "const_int_operand"))
15638    (use (match_operand:SI 4 "const_int_operand"))
15639    (use (match_operand:SI 5 "const_int_operand"))
15640    (use (match_operand:SI 6 ""))
15641    (use (match_operand:SI 7 ""))
15642    (use (match_operand:SI 8 ""))]
15643   ""
15645  if (ix86_expand_set_or_movmem (operands[0], operands[1],
15646                                 operands[2], NULL, operands[3],
15647                                 operands[4], operands[5],
15648                                 operands[6], operands[7],
15649                                 operands[8], false))
15650    DONE;
15651  else
15652    FAIL;
15655 ;; Most CPUs don't like single string operations
15656 ;; Handle this case here to simplify previous expander.
15658 (define_expand "strmov"
15659   [(set (match_dup 4) (match_operand 3 "memory_operand"))
15660    (set (match_operand 1 "memory_operand") (match_dup 4))
15661    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15662               (clobber (reg:CC FLAGS_REG))])
15663    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15664               (clobber (reg:CC FLAGS_REG))])]
15665   ""
15667   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15669   /* If .md ever supports :P for Pmode, these can be directly
15670      in the pattern above.  */
15671   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15672   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15674   /* Can't use this if the user has appropriated esi or edi.  */
15675   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15676       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15677     {
15678       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15679                                       operands[2], operands[3],
15680                                       operands[5], operands[6]));
15681       DONE;
15682     }
15684   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15687 (define_expand "strmov_singleop"
15688   [(parallel [(set (match_operand 1 "memory_operand")
15689                    (match_operand 3 "memory_operand"))
15690               (set (match_operand 0 "register_operand")
15691                    (match_operand 4))
15692               (set (match_operand 2 "register_operand")
15693                    (match_operand 5))])]
15694   ""
15695   "ix86_current_function_needs_cld = 1;")
15697 (define_insn "*strmovdi_rex_1"
15698   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15699         (mem:DI (match_operand:P 3 "register_operand" "1")))
15700    (set (match_operand:P 0 "register_operand" "=D")
15701         (plus:P (match_dup 2)
15702                 (const_int 8)))
15703    (set (match_operand:P 1 "register_operand" "=S")
15704         (plus:P (match_dup 3)
15705                 (const_int 8)))]
15706   "TARGET_64BIT
15707    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15708   "%^movsq"
15709   [(set_attr "type" "str")
15710    (set_attr "memory" "both")
15711    (set_attr "mode" "DI")])
15713 (define_insn "*strmovsi_1"
15714   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15715         (mem:SI (match_operand:P 3 "register_operand" "1")))
15716    (set (match_operand:P 0 "register_operand" "=D")
15717         (plus:P (match_dup 2)
15718                 (const_int 4)))
15719    (set (match_operand:P 1 "register_operand" "=S")
15720         (plus:P (match_dup 3)
15721                 (const_int 4)))]
15722   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15723   "%^movs{l|d}"
15724   [(set_attr "type" "str")
15725    (set_attr "memory" "both")
15726    (set_attr "mode" "SI")])
15728 (define_insn "*strmovhi_1"
15729   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15730         (mem:HI (match_operand:P 3 "register_operand" "1")))
15731    (set (match_operand:P 0 "register_operand" "=D")
15732         (plus:P (match_dup 2)
15733                 (const_int 2)))
15734    (set (match_operand:P 1 "register_operand" "=S")
15735         (plus:P (match_dup 3)
15736                 (const_int 2)))]
15737   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15738   "%^movsw"
15739   [(set_attr "type" "str")
15740    (set_attr "memory" "both")
15741    (set_attr "mode" "HI")])
15743 (define_insn "*strmovqi_1"
15744   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15745         (mem:QI (match_operand:P 3 "register_operand" "1")))
15746    (set (match_operand:P 0 "register_operand" "=D")
15747         (plus:P (match_dup 2)
15748                 (const_int 1)))
15749    (set (match_operand:P 1 "register_operand" "=S")
15750         (plus:P (match_dup 3)
15751                 (const_int 1)))]
15752   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15753   "%^movsb"
15754   [(set_attr "type" "str")
15755    (set_attr "memory" "both")
15756    (set (attr "prefix_rex")
15757         (if_then_else
15758           (match_test "<P:MODE>mode == DImode")
15759           (const_string "0")
15760           (const_string "*")))
15761    (set_attr "mode" "QI")])
15763 (define_expand "rep_mov"
15764   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15765               (set (match_operand 0 "register_operand")
15766                    (match_operand 5))
15767               (set (match_operand 2 "register_operand")
15768                    (match_operand 6))
15769               (set (match_operand 1 "memory_operand")
15770                    (match_operand 3 "memory_operand"))
15771               (use (match_dup 4))])]
15772   ""
15773   "ix86_current_function_needs_cld = 1;")
15775 (define_insn "*rep_movdi_rex64"
15776   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15777    (set (match_operand:P 0 "register_operand" "=D")
15778         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15779                           (const_int 3))
15780                 (match_operand:P 3 "register_operand" "0")))
15781    (set (match_operand:P 1 "register_operand" "=S")
15782         (plus:P (ashift:P (match_dup 5) (const_int 3))
15783                 (match_operand:P 4 "register_operand" "1")))
15784    (set (mem:BLK (match_dup 3))
15785         (mem:BLK (match_dup 4)))
15786    (use (match_dup 5))]
15787   "TARGET_64BIT
15788    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15789   "%^rep{%;} movsq"
15790   [(set_attr "type" "str")
15791    (set_attr "prefix_rep" "1")
15792    (set_attr "memory" "both")
15793    (set_attr "mode" "DI")])
15795 (define_insn "*rep_movsi"
15796   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15797    (set (match_operand:P 0 "register_operand" "=D")
15798         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15799                           (const_int 2))
15800                  (match_operand:P 3 "register_operand" "0")))
15801    (set (match_operand:P 1 "register_operand" "=S")
15802         (plus:P (ashift:P (match_dup 5) (const_int 2))
15803                 (match_operand:P 4 "register_operand" "1")))
15804    (set (mem:BLK (match_dup 3))
15805         (mem:BLK (match_dup 4)))
15806    (use (match_dup 5))]
15807   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15808   "%^rep{%;} movs{l|d}"
15809   [(set_attr "type" "str")
15810    (set_attr "prefix_rep" "1")
15811    (set_attr "memory" "both")
15812    (set_attr "mode" "SI")])
15814 (define_insn "*rep_movqi"
15815   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15816    (set (match_operand:P 0 "register_operand" "=D")
15817         (plus:P (match_operand:P 3 "register_operand" "0")
15818                 (match_operand:P 5 "register_operand" "2")))
15819    (set (match_operand:P 1 "register_operand" "=S")
15820         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15821    (set (mem:BLK (match_dup 3))
15822         (mem:BLK (match_dup 4)))
15823    (use (match_dup 5))]
15824   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15825   "%^rep{%;} movsb"
15826   [(set_attr "type" "str")
15827    (set_attr "prefix_rep" "1")
15828    (set_attr "memory" "both")
15829    (set_attr "mode" "QI")])
15831 (define_expand "setmem<mode>"
15832    [(use (match_operand:BLK 0 "memory_operand"))
15833     (use (match_operand:SWI48 1 "nonmemory_operand"))
15834     (use (match_operand:QI 2 "nonmemory_operand"))
15835     (use (match_operand 3 "const_int_operand"))
15836     (use (match_operand:SI 4 "const_int_operand"))
15837     (use (match_operand:SI 5 "const_int_operand"))
15838     (use (match_operand:SI 6 ""))
15839     (use (match_operand:SI 7 ""))
15840     (use (match_operand:SI 8 ""))]
15841   ""
15843  if (ix86_expand_set_or_movmem (operands[0], NULL,
15844                                 operands[1], operands[2],
15845                                 operands[3], operands[4],
15846                                 operands[5], operands[6],
15847                                 operands[7], operands[8], true))
15848    DONE;
15849  else
15850    FAIL;
15853 ;; Most CPUs don't like single string operations
15854 ;; Handle this case here to simplify previous expander.
15856 (define_expand "strset"
15857   [(set (match_operand 1 "memory_operand")
15858         (match_operand 2 "register_operand"))
15859    (parallel [(set (match_operand 0 "register_operand")
15860                    (match_dup 3))
15861               (clobber (reg:CC FLAGS_REG))])]
15862   ""
15864   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15865     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15867   /* If .md ever supports :P for Pmode, this can be directly
15868      in the pattern above.  */
15869   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15870                               GEN_INT (GET_MODE_SIZE (GET_MODE
15871                                                       (operands[2]))));
15872   /* Can't use this if the user has appropriated eax or edi.  */
15873   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15874       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15875     {
15876       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15877                                       operands[3]));
15878       DONE;
15879     }
15882 (define_expand "strset_singleop"
15883   [(parallel [(set (match_operand 1 "memory_operand")
15884                    (match_operand 2 "register_operand"))
15885               (set (match_operand 0 "register_operand")
15886                    (match_operand 3))
15887               (unspec [(const_int 0)] UNSPEC_STOS)])]
15888   ""
15889   "ix86_current_function_needs_cld = 1;")
15891 (define_insn "*strsetdi_rex_1"
15892   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15893         (match_operand:DI 2 "register_operand" "a"))
15894    (set (match_operand:P 0 "register_operand" "=D")
15895         (plus:P (match_dup 1)
15896                 (const_int 8)))
15897    (unspec [(const_int 0)] UNSPEC_STOS)]
15898   "TARGET_64BIT
15899    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15900   "%^stosq"
15901   [(set_attr "type" "str")
15902    (set_attr "memory" "store")
15903    (set_attr "mode" "DI")])
15905 (define_insn "*strsetsi_1"
15906   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15907         (match_operand:SI 2 "register_operand" "a"))
15908    (set (match_operand:P 0 "register_operand" "=D")
15909         (plus:P (match_dup 1)
15910                 (const_int 4)))
15911    (unspec [(const_int 0)] UNSPEC_STOS)]
15912   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15913   "%^stos{l|d}"
15914   [(set_attr "type" "str")
15915    (set_attr "memory" "store")
15916    (set_attr "mode" "SI")])
15918 (define_insn "*strsethi_1"
15919   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15920         (match_operand:HI 2 "register_operand" "a"))
15921    (set (match_operand:P 0 "register_operand" "=D")
15922         (plus:P (match_dup 1)
15923                 (const_int 2)))
15924    (unspec [(const_int 0)] UNSPEC_STOS)]
15925   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15926   "%^stosw"
15927   [(set_attr "type" "str")
15928    (set_attr "memory" "store")
15929    (set_attr "mode" "HI")])
15931 (define_insn "*strsetqi_1"
15932   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15933         (match_operand:QI 2 "register_operand" "a"))
15934    (set (match_operand:P 0 "register_operand" "=D")
15935         (plus:P (match_dup 1)
15936                 (const_int 1)))
15937    (unspec [(const_int 0)] UNSPEC_STOS)]
15938   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15939   "%^stosb"
15940   [(set_attr "type" "str")
15941    (set_attr "memory" "store")
15942    (set (attr "prefix_rex")
15943         (if_then_else
15944           (match_test "<P:MODE>mode == DImode")
15945           (const_string "0")
15946           (const_string "*")))
15947    (set_attr "mode" "QI")])
15949 (define_expand "rep_stos"
15950   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15951               (set (match_operand 0 "register_operand")
15952                    (match_operand 4))
15953               (set (match_operand 2 "memory_operand") (const_int 0))
15954               (use (match_operand 3 "register_operand"))
15955               (use (match_dup 1))])]
15956   ""
15957   "ix86_current_function_needs_cld = 1;")
15959 (define_insn "*rep_stosdi_rex64"
15960   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15961    (set (match_operand:P 0 "register_operand" "=D")
15962         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15963                           (const_int 3))
15964                  (match_operand:P 3 "register_operand" "0")))
15965    (set (mem:BLK (match_dup 3))
15966         (const_int 0))
15967    (use (match_operand:DI 2 "register_operand" "a"))
15968    (use (match_dup 4))]
15969   "TARGET_64BIT
15970    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15971   "%^rep{%;} stosq"
15972   [(set_attr "type" "str")
15973    (set_attr "prefix_rep" "1")
15974    (set_attr "memory" "store")
15975    (set_attr "mode" "DI")])
15977 (define_insn "*rep_stossi"
15978   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15979    (set (match_operand:P 0 "register_operand" "=D")
15980         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15981                           (const_int 2))
15982                  (match_operand:P 3 "register_operand" "0")))
15983    (set (mem:BLK (match_dup 3))
15984         (const_int 0))
15985    (use (match_operand:SI 2 "register_operand" "a"))
15986    (use (match_dup 4))]
15987   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15988   "%^rep{%;} stos{l|d}"
15989   [(set_attr "type" "str")
15990    (set_attr "prefix_rep" "1")
15991    (set_attr "memory" "store")
15992    (set_attr "mode" "SI")])
15994 (define_insn "*rep_stosqi"
15995   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15996    (set (match_operand:P 0 "register_operand" "=D")
15997         (plus:P (match_operand:P 3 "register_operand" "0")
15998                 (match_operand:P 4 "register_operand" "1")))
15999    (set (mem:BLK (match_dup 3))
16000         (const_int 0))
16001    (use (match_operand:QI 2 "register_operand" "a"))
16002    (use (match_dup 4))]
16003   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16004   "%^rep{%;} stosb"
16005   [(set_attr "type" "str")
16006    (set_attr "prefix_rep" "1")
16007    (set_attr "memory" "store")
16008    (set (attr "prefix_rex")
16009         (if_then_else
16010           (match_test "<P:MODE>mode == DImode")
16011           (const_string "0")
16012           (const_string "*")))
16013    (set_attr "mode" "QI")])
16015 (define_expand "cmpstrnsi"
16016   [(set (match_operand:SI 0 "register_operand")
16017         (compare:SI (match_operand:BLK 1 "general_operand")
16018                     (match_operand:BLK 2 "general_operand")))
16019    (use (match_operand 3 "general_operand"))
16020    (use (match_operand 4 "immediate_operand"))]
16021   ""
16023   rtx addr1, addr2, out, outlow, count, countreg, align;
16025   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16026     FAIL;
16028   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16029   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16030     FAIL;
16032   out = operands[0];
16033   if (!REG_P (out))
16034     out = gen_reg_rtx (SImode);
16036   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16037   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16038   if (addr1 != XEXP (operands[1], 0))
16039     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16040   if (addr2 != XEXP (operands[2], 0))
16041     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16043   count = operands[3];
16044   countreg = ix86_zero_extend_to_Pmode (count);
16046   /* %%% Iff we are testing strict equality, we can use known alignment
16047      to good advantage.  This may be possible with combine, particularly
16048      once cc0 is dead.  */
16049   align = operands[4];
16051   if (CONST_INT_P (count))
16052     {
16053       if (INTVAL (count) == 0)
16054         {
16055           emit_move_insn (operands[0], const0_rtx);
16056           DONE;
16057         }
16058       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16059                                      operands[1], operands[2]));
16060     }
16061   else
16062     {
16063       rtx (*gen_cmp) (rtx, rtx);
16065       gen_cmp = (TARGET_64BIT
16066                  ? gen_cmpdi_1 : gen_cmpsi_1);
16068       emit_insn (gen_cmp (countreg, countreg));
16069       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16070                                   operands[1], operands[2]));
16071     }
16073   outlow = gen_lowpart (QImode, out);
16074   emit_insn (gen_cmpintqi (outlow));
16075   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16077   if (operands[0] != out)
16078     emit_move_insn (operands[0], out);
16080   DONE;
16083 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16085 (define_expand "cmpintqi"
16086   [(set (match_dup 1)
16087         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16088    (set (match_dup 2)
16089         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16090    (parallel [(set (match_operand:QI 0 "register_operand")
16091                    (minus:QI (match_dup 1)
16092                              (match_dup 2)))
16093               (clobber (reg:CC FLAGS_REG))])]
16094   ""
16096   operands[1] = gen_reg_rtx (QImode);
16097   operands[2] = gen_reg_rtx (QImode);
16100 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16101 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16103 (define_expand "cmpstrnqi_nz_1"
16104   [(parallel [(set (reg:CC FLAGS_REG)
16105                    (compare:CC (match_operand 4 "memory_operand")
16106                                (match_operand 5 "memory_operand")))
16107               (use (match_operand 2 "register_operand"))
16108               (use (match_operand:SI 3 "immediate_operand"))
16109               (clobber (match_operand 0 "register_operand"))
16110               (clobber (match_operand 1 "register_operand"))
16111               (clobber (match_dup 2))])]
16112   ""
16113   "ix86_current_function_needs_cld = 1;")
16115 (define_insn "*cmpstrnqi_nz_1"
16116   [(set (reg:CC FLAGS_REG)
16117         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16118                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16119    (use (match_operand:P 6 "register_operand" "2"))
16120    (use (match_operand:SI 3 "immediate_operand" "i"))
16121    (clobber (match_operand:P 0 "register_operand" "=S"))
16122    (clobber (match_operand:P 1 "register_operand" "=D"))
16123    (clobber (match_operand:P 2 "register_operand" "=c"))]
16124   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16125   "%^repz{%;} cmpsb"
16126   [(set_attr "type" "str")
16127    (set_attr "mode" "QI")
16128    (set (attr "prefix_rex")
16129         (if_then_else
16130           (match_test "<P:MODE>mode == DImode")
16131           (const_string "0")
16132           (const_string "*")))
16133    (set_attr "prefix_rep" "1")])
16135 ;; The same, but the count is not known to not be zero.
16137 (define_expand "cmpstrnqi_1"
16138   [(parallel [(set (reg:CC FLAGS_REG)
16139                 (if_then_else:CC (ne (match_operand 2 "register_operand")
16140                                      (const_int 0))
16141                   (compare:CC (match_operand 4 "memory_operand")
16142                               (match_operand 5 "memory_operand"))
16143                   (const_int 0)))
16144               (use (match_operand:SI 3 "immediate_operand"))
16145               (use (reg:CC FLAGS_REG))
16146               (clobber (match_operand 0 "register_operand"))
16147               (clobber (match_operand 1 "register_operand"))
16148               (clobber (match_dup 2))])]
16149   ""
16150   "ix86_current_function_needs_cld = 1;")
16152 (define_insn "*cmpstrnqi_1"
16153   [(set (reg:CC FLAGS_REG)
16154         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16155                              (const_int 0))
16156           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16157                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16158           (const_int 0)))
16159    (use (match_operand:SI 3 "immediate_operand" "i"))
16160    (use (reg:CC FLAGS_REG))
16161    (clobber (match_operand:P 0 "register_operand" "=S"))
16162    (clobber (match_operand:P 1 "register_operand" "=D"))
16163    (clobber (match_operand:P 2 "register_operand" "=c"))]
16164   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16165   "%^repz{%;} cmpsb"
16166   [(set_attr "type" "str")
16167    (set_attr "mode" "QI")
16168    (set (attr "prefix_rex")
16169         (if_then_else
16170           (match_test "<P:MODE>mode == DImode")
16171           (const_string "0")
16172           (const_string "*")))
16173    (set_attr "prefix_rep" "1")])
16175 (define_expand "strlen<mode>"
16176   [(set (match_operand:P 0 "register_operand")
16177         (unspec:P [(match_operand:BLK 1 "general_operand")
16178                    (match_operand:QI 2 "immediate_operand")
16179                    (match_operand 3 "immediate_operand")]
16180                   UNSPEC_SCAS))]
16181   ""
16183  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16184    DONE;
16185  else
16186    FAIL;
16189 (define_expand "strlenqi_1"
16190   [(parallel [(set (match_operand 0 "register_operand")
16191                    (match_operand 2))
16192               (clobber (match_operand 1 "register_operand"))
16193               (clobber (reg:CC FLAGS_REG))])]
16194   ""
16195   "ix86_current_function_needs_cld = 1;")
16197 (define_insn "*strlenqi_1"
16198   [(set (match_operand:P 0 "register_operand" "=&c")
16199         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16200                    (match_operand:QI 2 "register_operand" "a")
16201                    (match_operand:P 3 "immediate_operand" "i")
16202                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16203    (clobber (match_operand:P 1 "register_operand" "=D"))
16204    (clobber (reg:CC FLAGS_REG))]
16205   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16206   "%^repnz{%;} scasb"
16207   [(set_attr "type" "str")
16208    (set_attr "mode" "QI")
16209    (set (attr "prefix_rex")
16210         (if_then_else
16211           (match_test "<P:MODE>mode == DImode")
16212           (const_string "0")
16213           (const_string "*")))
16214    (set_attr "prefix_rep" "1")])
16216 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16217 ;; handled in combine, but it is not currently up to the task.
16218 ;; When used for their truth value, the cmpstrn* expanders generate
16219 ;; code like this:
16221 ;;   repz cmpsb
16222 ;;   seta       %al
16223 ;;   setb       %dl
16224 ;;   cmpb       %al, %dl
16225 ;;   jcc        label
16227 ;; The intermediate three instructions are unnecessary.
16229 ;; This one handles cmpstrn*_nz_1...
16230 (define_peephole2
16231   [(parallel[
16232      (set (reg:CC FLAGS_REG)
16233           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16234                       (mem:BLK (match_operand 5 "register_operand"))))
16235      (use (match_operand 6 "register_operand"))
16236      (use (match_operand:SI 3 "immediate_operand"))
16237      (clobber (match_operand 0 "register_operand"))
16238      (clobber (match_operand 1 "register_operand"))
16239      (clobber (match_operand 2 "register_operand"))])
16240    (set (match_operand:QI 7 "register_operand")
16241         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16242    (set (match_operand:QI 8 "register_operand")
16243         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16244    (set (reg FLAGS_REG)
16245         (compare (match_dup 7) (match_dup 8)))
16246   ]
16247   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16248   [(parallel[
16249      (set (reg:CC FLAGS_REG)
16250           (compare:CC (mem:BLK (match_dup 4))
16251                       (mem:BLK (match_dup 5))))
16252      (use (match_dup 6))
16253      (use (match_dup 3))
16254      (clobber (match_dup 0))
16255      (clobber (match_dup 1))
16256      (clobber (match_dup 2))])])
16258 ;; ...and this one handles cmpstrn*_1.
16259 (define_peephole2
16260   [(parallel[
16261      (set (reg:CC FLAGS_REG)
16262           (if_then_else:CC (ne (match_operand 6 "register_operand")
16263                                (const_int 0))
16264             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16265                         (mem:BLK (match_operand 5 "register_operand")))
16266             (const_int 0)))
16267      (use (match_operand:SI 3 "immediate_operand"))
16268      (use (reg:CC FLAGS_REG))
16269      (clobber (match_operand 0 "register_operand"))
16270      (clobber (match_operand 1 "register_operand"))
16271      (clobber (match_operand 2 "register_operand"))])
16272    (set (match_operand:QI 7 "register_operand")
16273         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16274    (set (match_operand:QI 8 "register_operand")
16275         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16276    (set (reg FLAGS_REG)
16277         (compare (match_dup 7) (match_dup 8)))
16278   ]
16279   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16280   [(parallel[
16281      (set (reg:CC FLAGS_REG)
16282           (if_then_else:CC (ne (match_dup 6)
16283                                (const_int 0))
16284             (compare:CC (mem:BLK (match_dup 4))
16285                         (mem:BLK (match_dup 5)))
16286             (const_int 0)))
16287      (use (match_dup 3))
16288      (use (reg:CC FLAGS_REG))
16289      (clobber (match_dup 0))
16290      (clobber (match_dup 1))
16291      (clobber (match_dup 2))])])
16293 ;; Conditional move instructions.
16295 (define_expand "mov<mode>cc"
16296   [(set (match_operand:SWIM 0 "register_operand")
16297         (if_then_else:SWIM (match_operand 1 "comparison_operator")
16298                            (match_operand:SWIM 2 "<general_operand>")
16299                            (match_operand:SWIM 3 "<general_operand>")))]
16300   ""
16301   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16303 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16304 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16305 ;; So just document what we're doing explicitly.
16307 (define_expand "x86_mov<mode>cc_0_m1"
16308   [(parallel
16309     [(set (match_operand:SWI48 0 "register_operand")
16310           (if_then_else:SWI48
16311             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16312              [(match_operand 1 "flags_reg_operand")
16313               (const_int 0)])
16314             (const_int -1)
16315             (const_int 0)))
16316      (clobber (reg:CC FLAGS_REG))])])
16318 (define_insn "*x86_mov<mode>cc_0_m1"
16319   [(set (match_operand:SWI48 0 "register_operand" "=r")
16320         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16321                              [(reg FLAGS_REG) (const_int 0)])
16322           (const_int -1)
16323           (const_int 0)))
16324    (clobber (reg:CC FLAGS_REG))]
16325   ""
16326   "sbb{<imodesuffix>}\t%0, %0"
16327   ; Since we don't have the proper number of operands for an alu insn,
16328   ; fill in all the blanks.
16329   [(set_attr "type" "alu")
16330    (set_attr "use_carry" "1")
16331    (set_attr "pent_pair" "pu")
16332    (set_attr "memory" "none")
16333    (set_attr "imm_disp" "false")
16334    (set_attr "mode" "<MODE>")
16335    (set_attr "length_immediate" "0")])
16337 (define_insn "*x86_mov<mode>cc_0_m1_se"
16338   [(set (match_operand:SWI48 0 "register_operand" "=r")
16339         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16340                              [(reg FLAGS_REG) (const_int 0)])
16341                             (const_int 1)
16342                             (const_int 0)))
16343    (clobber (reg:CC FLAGS_REG))]
16344   ""
16345   "sbb{<imodesuffix>}\t%0, %0"
16346   [(set_attr "type" "alu")
16347    (set_attr "use_carry" "1")
16348    (set_attr "pent_pair" "pu")
16349    (set_attr "memory" "none")
16350    (set_attr "imm_disp" "false")
16351    (set_attr "mode" "<MODE>")
16352    (set_attr "length_immediate" "0")])
16354 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16355   [(set (match_operand:SWI48 0 "register_operand" "=r")
16356         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16357                     [(reg FLAGS_REG) (const_int 0)])))
16358    (clobber (reg:CC FLAGS_REG))]
16359   ""
16360   "sbb{<imodesuffix>}\t%0, %0"
16361   [(set_attr "type" "alu")
16362    (set_attr "use_carry" "1")
16363    (set_attr "pent_pair" "pu")
16364    (set_attr "memory" "none")
16365    (set_attr "imm_disp" "false")
16366    (set_attr "mode" "<MODE>")
16367    (set_attr "length_immediate" "0")])
16369 (define_insn "*mov<mode>cc_noc"
16370   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16371         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16372                                [(reg FLAGS_REG) (const_int 0)])
16373           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16374           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16375   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16376   "@
16377    cmov%O2%C1\t{%2, %0|%0, %2}
16378    cmov%O2%c1\t{%3, %0|%0, %3}"
16379   [(set_attr "type" "icmov")
16380    (set_attr "mode" "<MODE>")])
16382 ;; Don't do conditional moves with memory inputs.  This splitter helps
16383 ;; register starved x86_32 by forcing inputs into registers before reload.
16384 (define_split
16385   [(set (match_operand:SWI248 0 "register_operand")
16386         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16387                                [(reg FLAGS_REG) (const_int 0)])
16388           (match_operand:SWI248 2 "nonimmediate_operand")
16389           (match_operand:SWI248 3 "nonimmediate_operand")))]
16390   "!TARGET_64BIT && TARGET_CMOVE
16391    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16392    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16393    && can_create_pseudo_p ()
16394    && optimize_insn_for_speed_p ()"
16395   [(set (match_dup 0)
16396         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16398   if (MEM_P (operands[2]))
16399     operands[2] = force_reg (<MODE>mode, operands[2]);
16400   if (MEM_P (operands[3]))
16401     operands[3] = force_reg (<MODE>mode, operands[3]);
16404 (define_insn "*movqicc_noc"
16405   [(set (match_operand:QI 0 "register_operand" "=r,r")
16406         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16407                            [(reg FLAGS_REG) (const_int 0)])
16408                       (match_operand:QI 2 "register_operand" "r,0")
16409                       (match_operand:QI 3 "register_operand" "0,r")))]
16410   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16411   "#"
16412   [(set_attr "type" "icmov")
16413    (set_attr "mode" "QI")])
16415 (define_split
16416   [(set (match_operand:SWI12 0 "register_operand")
16417         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16418                               [(reg FLAGS_REG) (const_int 0)])
16419                       (match_operand:SWI12 2 "register_operand")
16420                       (match_operand:SWI12 3 "register_operand")))]
16421   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16422    && reload_completed"
16423   [(set (match_dup 0)
16424         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16426   operands[0] = gen_lowpart (SImode, operands[0]);
16427   operands[2] = gen_lowpart (SImode, operands[2]);
16428   operands[3] = gen_lowpart (SImode, operands[3]);
16431 ;; Don't do conditional moves with memory inputs
16432 (define_peephole2
16433   [(match_scratch:SWI248 2 "r")
16434    (set (match_operand:SWI248 0 "register_operand")
16435         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16436                                [(reg FLAGS_REG) (const_int 0)])
16437           (match_dup 0)
16438           (match_operand:SWI248 3 "memory_operand")))]
16439   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16440    && optimize_insn_for_speed_p ()"
16441   [(set (match_dup 2) (match_dup 3))
16442    (set (match_dup 0)
16443         (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16445 (define_peephole2
16446   [(match_scratch:SWI248 2 "r")
16447    (set (match_operand:SWI248 0 "register_operand")
16448         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16449                                [(reg FLAGS_REG) (const_int 0)])
16450           (match_operand:SWI248 3 "memory_operand")
16451           (match_dup 0)))]
16452   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16453    && optimize_insn_for_speed_p ()"
16454   [(set (match_dup 2) (match_dup 3))
16455    (set (match_dup 0)
16456         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16458 (define_expand "mov<mode>cc"
16459   [(set (match_operand:X87MODEF 0 "register_operand")
16460         (if_then_else:X87MODEF
16461           (match_operand 1 "comparison_operator")
16462           (match_operand:X87MODEF 2 "register_operand")
16463           (match_operand:X87MODEF 3 "register_operand")))]
16464   "(TARGET_80387 && TARGET_CMOVE)
16465    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16466   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16468 (define_insn "*movxfcc_1"
16469   [(set (match_operand:XF 0 "register_operand" "=f,f")
16470         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16471                                 [(reg FLAGS_REG) (const_int 0)])
16472                       (match_operand:XF 2 "register_operand" "f,0")
16473                       (match_operand:XF 3 "register_operand" "0,f")))]
16474   "TARGET_80387 && TARGET_CMOVE"
16475   "@
16476    fcmov%F1\t{%2, %0|%0, %2}
16477    fcmov%f1\t{%3, %0|%0, %3}"
16478   [(set_attr "type" "fcmov")
16479    (set_attr "mode" "XF")])
16481 (define_insn "*movdfcc_1"
16482   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16483         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16484                                 [(reg FLAGS_REG) (const_int 0)])
16485                       (match_operand:DF 2 "nonimmediate_operand"
16486                                                "f ,0,rm,0 ,rm,0")
16487                       (match_operand:DF 3 "nonimmediate_operand"
16488                                                "0 ,f,0 ,rm,0, rm")))]
16489   "TARGET_80387 && TARGET_CMOVE
16490    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16491   "@
16492    fcmov%F1\t{%2, %0|%0, %2}
16493    fcmov%f1\t{%3, %0|%0, %3}
16494    #
16495    #
16496    cmov%O2%C1\t{%2, %0|%0, %2}
16497    cmov%O2%c1\t{%3, %0|%0, %3}"
16498   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16499    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16500    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16502 (define_split
16503   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16504         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16505                                 [(reg FLAGS_REG) (const_int 0)])
16506                       (match_operand:DF 2 "nonimmediate_operand")
16507                       (match_operand:DF 3 "nonimmediate_operand")))]
16508   "!TARGET_64BIT && reload_completed"
16509   [(set (match_dup 2)
16510         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16511    (set (match_dup 3)
16512         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16514   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16515   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16518 (define_insn "*movsfcc_1_387"
16519   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16520         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16521                                 [(reg FLAGS_REG) (const_int 0)])
16522                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16523                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16524   "TARGET_80387 && TARGET_CMOVE
16525    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16526   "@
16527    fcmov%F1\t{%2, %0|%0, %2}
16528    fcmov%f1\t{%3, %0|%0, %3}
16529    cmov%O2%C1\t{%2, %0|%0, %2}
16530    cmov%O2%c1\t{%3, %0|%0, %3}"
16531   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16532    (set_attr "mode" "SF,SF,SI,SI")])
16534 ;; Don't do conditional moves with memory inputs.  This splitter helps
16535 ;; register starved x86_32 by forcing inputs into registers before reload.
16536 (define_split
16537   [(set (match_operand:MODEF 0 "register_operand")
16538         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16539                               [(reg FLAGS_REG) (const_int 0)])
16540           (match_operand:MODEF 2 "nonimmediate_operand")
16541           (match_operand:MODEF 3 "nonimmediate_operand")))]
16542   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16543    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16544    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16545    && can_create_pseudo_p ()
16546    && optimize_insn_for_speed_p ()"
16547   [(set (match_dup 0)
16548         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16550   if (MEM_P (operands[2]))
16551     operands[2] = force_reg (<MODE>mode, operands[2]);
16552   if (MEM_P (operands[3]))
16553     operands[3] = force_reg (<MODE>mode, operands[3]);
16556 ;; Don't do conditional moves with memory inputs
16557 (define_peephole2
16558   [(match_scratch:MODEF 2 "r")
16559    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16560         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16561                               [(reg FLAGS_REG) (const_int 0)])
16562           (match_dup 0)
16563           (match_operand:MODEF 3 "memory_operand")))]
16564   "(<MODE>mode != DFmode || TARGET_64BIT)
16565    && TARGET_80387 && TARGET_CMOVE
16566    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16567    && optimize_insn_for_speed_p ()"
16568   [(set (match_dup 2) (match_dup 3))
16569    (set (match_dup 0)
16570         (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16572 (define_peephole2
16573   [(match_scratch:MODEF 2 "r")
16574    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16575         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16576                               [(reg FLAGS_REG) (const_int 0)])
16577           (match_operand:MODEF 3 "memory_operand")
16578           (match_dup 0)))]
16579   "(<MODE>mode != DFmode || TARGET_64BIT)
16580    && TARGET_80387 && TARGET_CMOVE
16581    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16582    && optimize_insn_for_speed_p ()"
16583   [(set (match_dup 2) (match_dup 3))
16584    (set (match_dup 0)
16585         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16587 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16588 ;; the scalar versions to have only XMM registers as operands.
16590 ;; XOP conditional move
16591 (define_insn "*xop_pcmov_<mode>"
16592   [(set (match_operand:MODEF 0 "register_operand" "=x")
16593         (if_then_else:MODEF
16594           (match_operand:MODEF 1 "register_operand" "x")
16595           (match_operand:MODEF 2 "register_operand" "x")
16596           (match_operand:MODEF 3 "register_operand" "x")))]
16597   "TARGET_XOP"
16598   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16599   [(set_attr "type" "sse4arg")])
16601 ;; These versions of the min/max patterns are intentionally ignorant of
16602 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16603 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16604 ;; are undefined in this condition, we're certain this is correct.
16606 (define_insn "<code><mode>3"
16607   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16608         (smaxmin:MODEF
16609           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16610           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16611   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16612   "@
16613    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16614    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16615   [(set_attr "isa" "noavx,avx")
16616    (set_attr "prefix" "orig,vex")
16617    (set_attr "type" "sseadd")
16618    (set_attr "mode" "<MODE>")])
16620 ;; These versions of the min/max patterns implement exactly the operations
16621 ;;   min = (op1 < op2 ? op1 : op2)
16622 ;;   max = (!(op1 < op2) ? op1 : op2)
16623 ;; Their operands are not commutative, and thus they may be used in the
16624 ;; presence of -0.0 and NaN.
16626 (define_int_iterator IEEE_MAXMIN
16627         [UNSPEC_IEEE_MAX
16628          UNSPEC_IEEE_MIN])
16630 (define_int_attr ieee_maxmin
16631         [(UNSPEC_IEEE_MAX "max")
16632          (UNSPEC_IEEE_MIN "min")])
16634 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16635   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16636         (unspec:MODEF
16637           [(match_operand:MODEF 1 "register_operand" "0,x")
16638            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16639           IEEE_MAXMIN))]
16640   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16641   "@
16642    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16643    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16644   [(set_attr "isa" "noavx,avx")
16645    (set_attr "prefix" "orig,vex")
16646    (set_attr "type" "sseadd")
16647    (set_attr "mode" "<MODE>")])
16649 ;; Make two stack loads independent:
16650 ;;   fld aa              fld aa
16651 ;;   fld %st(0)     ->   fld bb
16652 ;;   fmul bb             fmul %st(1), %st
16654 ;; Actually we only match the last two instructions for simplicity.
16655 (define_peephole2
16656   [(set (match_operand 0 "fp_register_operand")
16657         (match_operand 1 "fp_register_operand"))
16658    (set (match_dup 0)
16659         (match_operator 2 "binary_fp_operator"
16660            [(match_dup 0)
16661             (match_operand 3 "memory_operand")]))]
16662   "REGNO (operands[0]) != REGNO (operands[1])"
16663   [(set (match_dup 0) (match_dup 3))
16664    (set (match_dup 0) (match_dup 4))]
16666   ;; The % modifier is not operational anymore in peephole2's, so we have to
16667   ;; swap the operands manually in the case of addition and multiplication.
16669   rtx op0, op1;
16671   if (COMMUTATIVE_ARITH_P (operands[2]))
16672     op0 = operands[0], op1 = operands[1];
16673   else
16674     op0 = operands[1], op1 = operands[0];
16676   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16677                                 GET_MODE (operands[2]),
16678                                 op0, op1);
16681 ;; Conditional addition patterns
16682 (define_expand "add<mode>cc"
16683   [(match_operand:SWI 0 "register_operand")
16684    (match_operand 1 "ordered_comparison_operator")
16685    (match_operand:SWI 2 "register_operand")
16686    (match_operand:SWI 3 "const_int_operand")]
16687   ""
16688   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16690 ;; Misc patterns (?)
16692 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16693 ;; Otherwise there will be nothing to keep
16695 ;; [(set (reg ebp) (reg esp))]
16696 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16697 ;;  (clobber (eflags)]
16698 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16700 ;; in proper program order.
16702 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16703   [(set (match_operand:P 0 "register_operand" "=r,r")
16704         (plus:P (match_operand:P 1 "register_operand" "0,r")
16705                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16706    (clobber (reg:CC FLAGS_REG))
16707    (clobber (mem:BLK (scratch)))]
16708   ""
16710   switch (get_attr_type (insn))
16711     {
16712     case TYPE_IMOV:
16713       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16715     case TYPE_ALU:
16716       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16717       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16718         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16720       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16722     default:
16723       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16724       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16725     }
16727   [(set (attr "type")
16728         (cond [(and (eq_attr "alternative" "0")
16729                     (not (match_test "TARGET_OPT_AGU")))
16730                  (const_string "alu")
16731                (match_operand:<MODE> 2 "const0_operand")
16732                  (const_string "imov")
16733               ]
16734               (const_string "lea")))
16735    (set (attr "length_immediate")
16736         (cond [(eq_attr "type" "imov")
16737                  (const_string "0")
16738                (and (eq_attr "type" "alu")
16739                     (match_operand 2 "const128_operand"))
16740                  (const_string "1")
16741               ]
16742               (const_string "*")))
16743    (set_attr "mode" "<MODE>")])
16745 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16746   [(set (match_operand:P 0 "register_operand" "=r")
16747         (minus:P (match_operand:P 1 "register_operand" "0")
16748                  (match_operand:P 2 "register_operand" "r")))
16749    (clobber (reg:CC FLAGS_REG))
16750    (clobber (mem:BLK (scratch)))]
16751   ""
16752   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16753   [(set_attr "type" "alu")
16754    (set_attr "mode" "<MODE>")])
16756 (define_insn "allocate_stack_worker_probe_<mode>"
16757   [(set (match_operand:P 0 "register_operand" "=a")
16758         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16759                             UNSPECV_STACK_PROBE))
16760    (clobber (reg:CC FLAGS_REG))]
16761   "ix86_target_stack_probe ()"
16762   "call\t___chkstk_ms"
16763   [(set_attr "type" "multi")
16764    (set_attr "length" "5")])
16766 (define_expand "allocate_stack"
16767   [(match_operand 0 "register_operand")
16768    (match_operand 1 "general_operand")]
16769   "ix86_target_stack_probe ()"
16771   rtx x;
16773 #ifndef CHECK_STACK_LIMIT
16774 #define CHECK_STACK_LIMIT 0
16775 #endif
16777   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16778       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16779     x = operands[1];
16780   else
16781     {
16782       rtx (*insn) (rtx, rtx);
16784       x = copy_to_mode_reg (Pmode, operands[1]);
16786       insn = (TARGET_64BIT
16787               ? gen_allocate_stack_worker_probe_di
16788               : gen_allocate_stack_worker_probe_si);
16790       emit_insn (insn (x, x));
16791     }
16793   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16794                            stack_pointer_rtx, 0, OPTAB_DIRECT);
16796   if (x != stack_pointer_rtx)
16797     emit_move_insn (stack_pointer_rtx, x);
16799   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16800   DONE;
16803 ;; Use IOR for stack probes, this is shorter.
16804 (define_expand "probe_stack"
16805   [(match_operand 0 "memory_operand")]
16806   ""
16808   rtx (*gen_ior3) (rtx, rtx, rtx);
16810   gen_ior3 = (GET_MODE (operands[0]) == DImode
16811               ? gen_iordi3 : gen_iorsi3);
16813   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16814   DONE;
16817 (define_insn "adjust_stack_and_probe<mode>"
16818   [(set (match_operand:P 0 "register_operand" "=r")
16819         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16820                             UNSPECV_PROBE_STACK_RANGE))
16821    (set (reg:P SP_REG)
16822         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16823    (clobber (reg:CC FLAGS_REG))
16824    (clobber (mem:BLK (scratch)))]
16825   ""
16826   "* return output_adjust_stack_and_probe (operands[0]);"
16827   [(set_attr "type" "multi")])
16829 (define_insn "probe_stack_range<mode>"
16830   [(set (match_operand:P 0 "register_operand" "=r")
16831         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16832                             (match_operand:P 2 "const_int_operand" "n")]
16833                             UNSPECV_PROBE_STACK_RANGE))
16834    (clobber (reg:CC FLAGS_REG))]
16835   ""
16836   "* return output_probe_stack_range (operands[0], operands[2]);"
16837   [(set_attr "type" "multi")])
16839 (define_expand "builtin_setjmp_receiver"
16840   [(label_ref (match_operand 0))]
16841   "!TARGET_64BIT && flag_pic"
16843 #if TARGET_MACHO
16844   if (TARGET_MACHO)
16845     {
16846       rtx xops[3];
16847       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16848       rtx label_rtx = gen_label_rtx ();
16849       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16850       xops[0] = xops[1] = picreg;
16851       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16852       ix86_expand_binary_operator (MINUS, SImode, xops);
16853     }
16854   else
16855 #endif
16856     emit_insn (gen_set_got (pic_offset_table_rtx));
16857   DONE;
16860 (define_insn_and_split "nonlocal_goto_receiver"
16861   [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16862   "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16863   "#"
16864   "&& reload_completed"
16865   [(const_int 0)]
16867   if (crtl->uses_pic_offset_table)
16868     {
16869       rtx xops[3];
16870       rtx label_rtx = gen_label_rtx ();
16871       rtx tmp;
16873       /* Get a new pic base.  */
16874       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16875       /* Correct this with the offset from the new to the old.  */
16876       xops[0] = xops[1] = pic_offset_table_rtx;
16877       label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16878       tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16879                             UNSPEC_MACHOPIC_OFFSET);
16880       xops[2] = gen_rtx_CONST (Pmode, tmp);
16881       ix86_expand_binary_operator (MINUS, SImode, xops);
16882     }
16883   else
16884     /* No pic reg restore needed.  */
16885     emit_note (NOTE_INSN_DELETED);
16887   DONE;
16890 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16891 ;; Do not split instructions with mask registers.
16892 (define_split
16893   [(set (match_operand 0 "general_reg_operand")
16894         (match_operator 3 "promotable_binary_operator"
16895            [(match_operand 1 "general_reg_operand")
16896             (match_operand 2 "aligned_operand")]))
16897    (clobber (reg:CC FLAGS_REG))]
16898   "! TARGET_PARTIAL_REG_STALL && reload_completed
16899    && ((GET_MODE (operands[0]) == HImode
16900         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16901             /* ??? next two lines just !satisfies_constraint_K (...) */
16902             || !CONST_INT_P (operands[2])
16903             || satisfies_constraint_K (operands[2])))
16904        || (GET_MODE (operands[0]) == QImode
16905            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16906   [(parallel [(set (match_dup 0)
16907                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16908               (clobber (reg:CC FLAGS_REG))])]
16910   operands[0] = gen_lowpart (SImode, operands[0]);
16911   operands[1] = gen_lowpart (SImode, operands[1]);
16912   if (GET_CODE (operands[3]) != ASHIFT)
16913     operands[2] = gen_lowpart (SImode, operands[2]);
16914   PUT_MODE (operands[3], SImode);
16917 ; Promote the QImode tests, as i386 has encoding of the AND
16918 ; instruction with 32-bit sign-extended immediate and thus the
16919 ; instruction size is unchanged, except in the %eax case for
16920 ; which it is increased by one byte, hence the ! optimize_size.
16921 (define_split
16922   [(set (match_operand 0 "flags_reg_operand")
16923         (match_operator 2 "compare_operator"
16924           [(and (match_operand 3 "aligned_operand")
16925                 (match_operand 4 "const_int_operand"))
16926            (const_int 0)]))
16927    (set (match_operand 1 "register_operand")
16928         (and (match_dup 3) (match_dup 4)))]
16929   "! TARGET_PARTIAL_REG_STALL && reload_completed
16930    && optimize_insn_for_speed_p ()
16931    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16932        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16933    /* Ensure that the operand will remain sign-extended immediate.  */
16934    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16935   [(parallel [(set (match_dup 0)
16936                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16937                                     (const_int 0)]))
16938               (set (match_dup 1)
16939                    (and:SI (match_dup 3) (match_dup 4)))])]
16941   operands[4]
16942     = gen_int_mode (INTVAL (operands[4])
16943                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16944   operands[1] = gen_lowpart (SImode, operands[1]);
16945   operands[3] = gen_lowpart (SImode, operands[3]);
16948 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16949 ; the TEST instruction with 32-bit sign-extended immediate and thus
16950 ; the instruction size would at least double, which is not what we
16951 ; want even with ! optimize_size.
16952 (define_split
16953   [(set (match_operand 0 "flags_reg_operand")
16954         (match_operator 1 "compare_operator"
16955           [(and (match_operand:HI 2 "aligned_operand")
16956                 (match_operand:HI 3 "const_int_operand"))
16957            (const_int 0)]))]
16958   "! TARGET_PARTIAL_REG_STALL && reload_completed
16959    && ! TARGET_FAST_PREFIX
16960    && optimize_insn_for_speed_p ()
16961    /* Ensure that the operand will remain sign-extended immediate.  */
16962    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16963   [(set (match_dup 0)
16964         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16965                          (const_int 0)]))]
16967   operands[3]
16968     = gen_int_mode (INTVAL (operands[3])
16969                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16970   operands[2] = gen_lowpart (SImode, operands[2]);
16973 (define_split
16974   [(set (match_operand 0 "register_operand")
16975         (neg (match_operand 1 "register_operand")))
16976    (clobber (reg:CC FLAGS_REG))]
16977   "! TARGET_PARTIAL_REG_STALL && reload_completed
16978    && (GET_MODE (operands[0]) == HImode
16979        || (GET_MODE (operands[0]) == QImode
16980            && (TARGET_PROMOTE_QImode
16981                || optimize_insn_for_size_p ())))"
16982   [(parallel [(set (match_dup 0)
16983                    (neg:SI (match_dup 1)))
16984               (clobber (reg:CC FLAGS_REG))])]
16986   operands[0] = gen_lowpart (SImode, operands[0]);
16987   operands[1] = gen_lowpart (SImode, operands[1]);
16990 ;; Do not split instructions with mask regs.
16991 (define_split
16992   [(set (match_operand 0 "general_reg_operand")
16993         (not (match_operand 1 "general_reg_operand")))]
16994   "! TARGET_PARTIAL_REG_STALL && reload_completed
16995    && (GET_MODE (operands[0]) == HImode
16996        || (GET_MODE (operands[0]) == QImode
16997            && (TARGET_PROMOTE_QImode
16998                || optimize_insn_for_size_p ())))"
16999   [(set (match_dup 0)
17000         (not:SI (match_dup 1)))]
17002   operands[0] = gen_lowpart (SImode, operands[0]);
17003   operands[1] = gen_lowpart (SImode, operands[1]);
17006 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17007 ;; transform a complex memory operation into two memory to register operations.
17009 ;; Don't push memory operands
17010 (define_peephole2
17011   [(set (match_operand:SWI 0 "push_operand")
17012         (match_operand:SWI 1 "memory_operand"))
17013    (match_scratch:SWI 2 "<r>")]
17014   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17015    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17016   [(set (match_dup 2) (match_dup 1))
17017    (set (match_dup 0) (match_dup 2))])
17019 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17020 ;; SImode pushes.
17021 (define_peephole2
17022   [(set (match_operand:SF 0 "push_operand")
17023         (match_operand:SF 1 "memory_operand"))
17024    (match_scratch:SF 2 "r")]
17025   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17026    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17027   [(set (match_dup 2) (match_dup 1))
17028    (set (match_dup 0) (match_dup 2))])
17030 ;; Don't move an immediate directly to memory when the instruction
17031 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17032 (define_peephole2
17033   [(match_scratch:SWI124 1 "<r>")
17034    (set (match_operand:SWI124 0 "memory_operand")
17035         (const_int 0))]
17036   "optimize_insn_for_speed_p ()
17037    && ((<MODE>mode == HImode
17038        && TARGET_LCP_STALL)
17039        || (!TARGET_USE_MOV0
17040           && TARGET_SPLIT_LONG_MOVES
17041           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17042    && peep2_regno_dead_p (0, FLAGS_REG)"
17043   [(parallel [(set (match_dup 2) (const_int 0))
17044               (clobber (reg:CC FLAGS_REG))])
17045    (set (match_dup 0) (match_dup 1))]
17046   "operands[2] = gen_lowpart (SImode, operands[1]);")
17048 (define_peephole2
17049   [(match_scratch:SWI124 2 "<r>")
17050    (set (match_operand:SWI124 0 "memory_operand")
17051         (match_operand:SWI124 1 "immediate_operand"))]
17052   "optimize_insn_for_speed_p ()
17053    && ((<MODE>mode == HImode
17054        && TARGET_LCP_STALL)
17055        || (TARGET_SPLIT_LONG_MOVES
17056           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17057   [(set (match_dup 2) (match_dup 1))
17058    (set (match_dup 0) (match_dup 2))])
17060 ;; Don't compare memory with zero, load and use a test instead.
17061 (define_peephole2
17062   [(set (match_operand 0 "flags_reg_operand")
17063         (match_operator 1 "compare_operator"
17064           [(match_operand:SI 2 "memory_operand")
17065            (const_int 0)]))
17066    (match_scratch:SI 3 "r")]
17067   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17068   [(set (match_dup 3) (match_dup 2))
17069    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17071 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17072 ;; Don't split NOTs with a displacement operand, because resulting XOR
17073 ;; will not be pairable anyway.
17075 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17076 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17077 ;; so this split helps here as well.
17079 ;; Note: Can't do this as a regular split because we can't get proper
17080 ;; lifetime information then.
17082 (define_peephole2
17083   [(set (match_operand:SWI124 0 "nonimmediate_operand")
17084         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17085   "optimize_insn_for_speed_p ()
17086    && ((TARGET_NOT_UNPAIRABLE
17087         && (!MEM_P (operands[0])
17088             || !memory_displacement_operand (operands[0], <MODE>mode)))
17089        || (TARGET_NOT_VECTORMODE
17090            && long_memory_operand (operands[0], <MODE>mode)))
17091    && peep2_regno_dead_p (0, FLAGS_REG)"
17092   [(parallel [(set (match_dup 0)
17093                    (xor:SWI124 (match_dup 1) (const_int -1)))
17094               (clobber (reg:CC FLAGS_REG))])])
17096 ;; Non pairable "test imm, reg" instructions can be translated to
17097 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17098 ;; byte opcode instead of two, have a short form for byte operands),
17099 ;; so do it for other CPUs as well.  Given that the value was dead,
17100 ;; this should not create any new dependencies.  Pass on the sub-word
17101 ;; versions if we're concerned about partial register stalls.
17103 (define_peephole2
17104   [(set (match_operand 0 "flags_reg_operand")
17105         (match_operator 1 "compare_operator"
17106           [(and:SI (match_operand:SI 2 "register_operand")
17107                    (match_operand:SI 3 "immediate_operand"))
17108            (const_int 0)]))]
17109   "ix86_match_ccmode (insn, CCNOmode)
17110    && (true_regnum (operands[2]) != AX_REG
17111        || satisfies_constraint_K (operands[3]))
17112    && peep2_reg_dead_p (1, operands[2])"
17113   [(parallel
17114      [(set (match_dup 0)
17115            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17116                             (const_int 0)]))
17117       (set (match_dup 2)
17118            (and:SI (match_dup 2) (match_dup 3)))])])
17120 ;; We don't need to handle HImode case, because it will be promoted to SImode
17121 ;; on ! TARGET_PARTIAL_REG_STALL
17123 (define_peephole2
17124   [(set (match_operand 0 "flags_reg_operand")
17125         (match_operator 1 "compare_operator"
17126           [(and:QI (match_operand:QI 2 "register_operand")
17127                    (match_operand:QI 3 "immediate_operand"))
17128            (const_int 0)]))]
17129   "! TARGET_PARTIAL_REG_STALL
17130    && ix86_match_ccmode (insn, CCNOmode)
17131    && true_regnum (operands[2]) != AX_REG
17132    && peep2_reg_dead_p (1, operands[2])"
17133   [(parallel
17134      [(set (match_dup 0)
17135            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17136                             (const_int 0)]))
17137       (set (match_dup 2)
17138            (and:QI (match_dup 2) (match_dup 3)))])])
17140 (define_peephole2
17141   [(set (match_operand 0 "flags_reg_operand")
17142         (match_operator 1 "compare_operator"
17143           [(and:SI
17144              (zero_extract:SI
17145                (match_operand 2 "ext_register_operand")
17146                (const_int 8)
17147                (const_int 8))
17148              (match_operand 3 "const_int_operand"))
17149            (const_int 0)]))]
17150   "! TARGET_PARTIAL_REG_STALL
17151    && ix86_match_ccmode (insn, CCNOmode)
17152    && true_regnum (operands[2]) != AX_REG
17153    && peep2_reg_dead_p (1, operands[2])"
17154   [(parallel [(set (match_dup 0)
17155                    (match_op_dup 1
17156                      [(and:SI
17157                         (zero_extract:SI
17158                           (match_dup 2)
17159                           (const_int 8)
17160                           (const_int 8))
17161                         (match_dup 3))
17162                       (const_int 0)]))
17163               (set (zero_extract:SI (match_dup 2)
17164                                     (const_int 8)
17165                                     (const_int 8))
17166                    (and:SI
17167                      (zero_extract:SI
17168                        (match_dup 2)
17169                        (const_int 8)
17170                        (const_int 8))
17171                      (match_dup 3)))])])
17173 ;; Don't do logical operations with memory inputs.
17174 (define_peephole2
17175   [(match_scratch:SI 2 "r")
17176    (parallel [(set (match_operand:SI 0 "register_operand")
17177                    (match_operator:SI 3 "arith_or_logical_operator"
17178                      [(match_dup 0)
17179                       (match_operand:SI 1 "memory_operand")]))
17180               (clobber (reg:CC FLAGS_REG))])]
17181   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17182   [(set (match_dup 2) (match_dup 1))
17183    (parallel [(set (match_dup 0)
17184                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17185               (clobber (reg:CC FLAGS_REG))])])
17187 (define_peephole2
17188   [(match_scratch:SI 2 "r")
17189    (parallel [(set (match_operand:SI 0 "register_operand")
17190                    (match_operator:SI 3 "arith_or_logical_operator"
17191                      [(match_operand:SI 1 "memory_operand")
17192                       (match_dup 0)]))
17193               (clobber (reg:CC FLAGS_REG))])]
17194   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17195   [(set (match_dup 2) (match_dup 1))
17196    (parallel [(set (match_dup 0)
17197                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17198               (clobber (reg:CC FLAGS_REG))])])
17200 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17201 ;; refers to the destination of the load!
17203 (define_peephole2
17204   [(set (match_operand:SI 0 "register_operand")
17205         (match_operand:SI 1 "register_operand"))
17206    (parallel [(set (match_dup 0)
17207                    (match_operator:SI 3 "commutative_operator"
17208                      [(match_dup 0)
17209                       (match_operand:SI 2 "memory_operand")]))
17210               (clobber (reg:CC FLAGS_REG))])]
17211   "REGNO (operands[0]) != REGNO (operands[1])
17212    && GENERAL_REGNO_P (REGNO (operands[0]))
17213    && GENERAL_REGNO_P (REGNO (operands[1]))"
17214   [(set (match_dup 0) (match_dup 4))
17215    (parallel [(set (match_dup 0)
17216                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17217               (clobber (reg:CC FLAGS_REG))])]
17218   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17220 (define_peephole2
17221   [(set (match_operand 0 "register_operand")
17222         (match_operand 1 "register_operand"))
17223    (set (match_dup 0)
17224                    (match_operator 3 "commutative_operator"
17225                      [(match_dup 0)
17226                       (match_operand 2 "memory_operand")]))]
17227   "REGNO (operands[0]) != REGNO (operands[1])
17228    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17229        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17230   [(set (match_dup 0) (match_dup 2))
17231    (set (match_dup 0)
17232         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17234 ; Don't do logical operations with memory outputs
17236 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17237 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17238 ; the same decoder scheduling characteristics as the original.
17240 (define_peephole2
17241   [(match_scratch:SI 2 "r")
17242    (parallel [(set (match_operand:SI 0 "memory_operand")
17243                    (match_operator:SI 3 "arith_or_logical_operator"
17244                      [(match_dup 0)
17245                       (match_operand:SI 1 "nonmemory_operand")]))
17246               (clobber (reg:CC FLAGS_REG))])]
17247   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17248    /* Do not split stack checking probes.  */
17249    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17250   [(set (match_dup 2) (match_dup 0))
17251    (parallel [(set (match_dup 2)
17252                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17253               (clobber (reg:CC FLAGS_REG))])
17254    (set (match_dup 0) (match_dup 2))])
17256 (define_peephole2
17257   [(match_scratch:SI 2 "r")
17258    (parallel [(set (match_operand:SI 0 "memory_operand")
17259                    (match_operator:SI 3 "arith_or_logical_operator"
17260                      [(match_operand:SI 1 "nonmemory_operand")
17261                       (match_dup 0)]))
17262               (clobber (reg:CC FLAGS_REG))])]
17263   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17264    /* Do not split stack checking probes.  */
17265    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17266   [(set (match_dup 2) (match_dup 0))
17267    (parallel [(set (match_dup 2)
17268                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17269               (clobber (reg:CC FLAGS_REG))])
17270    (set (match_dup 0) (match_dup 2))])
17272 ;; Attempt to use arith or logical operations with memory outputs with
17273 ;; setting of flags.
17274 (define_peephole2
17275   [(set (match_operand:SWI 0 "register_operand")
17276         (match_operand:SWI 1 "memory_operand"))
17277    (parallel [(set (match_dup 0)
17278                    (match_operator:SWI 3 "plusminuslogic_operator"
17279                      [(match_dup 0)
17280                       (match_operand:SWI 2 "<nonmemory_operand>")]))
17281               (clobber (reg:CC FLAGS_REG))])
17282    (set (match_dup 1) (match_dup 0))
17283    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17284   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17285    && peep2_reg_dead_p (4, operands[0])
17286    && !reg_overlap_mentioned_p (operands[0], operands[1])
17287    && !reg_overlap_mentioned_p (operands[0], operands[2])
17288    && (<MODE>mode != QImode
17289        || immediate_operand (operands[2], QImode)
17290        || q_regs_operand (operands[2], QImode))
17291    && ix86_match_ccmode (peep2_next_insn (3),
17292                          (GET_CODE (operands[3]) == PLUS
17293                           || GET_CODE (operands[3]) == MINUS)
17294                          ? CCGOCmode : CCNOmode)"
17295   [(parallel [(set (match_dup 4) (match_dup 5))
17296               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17297                                                   (match_dup 2)]))])]
17299   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17300   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17301                                 copy_rtx (operands[1]),
17302                                 copy_rtx (operands[2]));
17303   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17304                                  operands[5], const0_rtx);
17307 (define_peephole2
17308   [(parallel [(set (match_operand:SWI 0 "register_operand")
17309                    (match_operator:SWI 2 "plusminuslogic_operator"
17310                      [(match_dup 0)
17311                       (match_operand:SWI 1 "memory_operand")]))
17312               (clobber (reg:CC FLAGS_REG))])
17313    (set (match_dup 1) (match_dup 0))
17314    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17315   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17316    && GET_CODE (operands[2]) != MINUS
17317    && peep2_reg_dead_p (3, operands[0])
17318    && !reg_overlap_mentioned_p (operands[0], operands[1])
17319    && ix86_match_ccmode (peep2_next_insn (2),
17320                          GET_CODE (operands[2]) == PLUS
17321                          ? CCGOCmode : CCNOmode)"
17322   [(parallel [(set (match_dup 3) (match_dup 4))
17323               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17324                                                   (match_dup 0)]))])]
17326   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17327   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17328                                 copy_rtx (operands[1]),
17329                                 copy_rtx (operands[0]));
17330   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17331                                  operands[4], const0_rtx);
17334 (define_peephole2
17335   [(set (match_operand:SWI12 0 "register_operand")
17336         (match_operand:SWI12 1 "memory_operand"))
17337    (parallel [(set (match_operand:SI 4 "register_operand")
17338                    (match_operator:SI 3 "plusminuslogic_operator"
17339                      [(match_dup 4)
17340                       (match_operand:SI 2 "nonmemory_operand")]))
17341               (clobber (reg:CC FLAGS_REG))])
17342    (set (match_dup 1) (match_dup 0))
17343    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17344   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17345    && REG_P (operands[0]) && REG_P (operands[4])
17346    && REGNO (operands[0]) == REGNO (operands[4])
17347    && peep2_reg_dead_p (4, operands[0])
17348    && (<MODE>mode != QImode
17349        || immediate_operand (operands[2], SImode)
17350        || q_regs_operand (operands[2], SImode))
17351    && !reg_overlap_mentioned_p (operands[0], operands[1])
17352    && !reg_overlap_mentioned_p (operands[0], operands[2])
17353    && ix86_match_ccmode (peep2_next_insn (3),
17354                          (GET_CODE (operands[3]) == PLUS
17355                           || GET_CODE (operands[3]) == MINUS)
17356                          ? CCGOCmode : CCNOmode)"
17357   [(parallel [(set (match_dup 4) (match_dup 5))
17358               (set (match_dup 1) (match_dup 6))])]
17360   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17361   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17362   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17363                                 copy_rtx (operands[1]), operands[2]);
17364   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17365                                  operands[5], const0_rtx);
17366   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17367                                 copy_rtx (operands[1]),
17368                                 copy_rtx (operands[2]));
17371 ;; Attempt to always use XOR for zeroing registers.
17372 (define_peephole2
17373   [(set (match_operand 0 "register_operand")
17374         (match_operand 1 "const0_operand"))]
17375   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17376    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17377    && GENERAL_REG_P (operands[0])
17378    && peep2_regno_dead_p (0, FLAGS_REG)"
17379   [(parallel [(set (match_dup 0) (const_int 0))
17380               (clobber (reg:CC FLAGS_REG))])]
17381   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17383 (define_peephole2
17384   [(set (strict_low_part (match_operand 0 "register_operand"))
17385         (const_int 0))]
17386   "(GET_MODE (operands[0]) == QImode
17387     || GET_MODE (operands[0]) == HImode)
17388    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17389    && peep2_regno_dead_p (0, FLAGS_REG)"
17390   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17391               (clobber (reg:CC FLAGS_REG))])])
17393 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17394 (define_peephole2
17395   [(set (match_operand:SWI248 0 "register_operand")
17396         (const_int -1))]
17397   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17398    && peep2_regno_dead_p (0, FLAGS_REG)"
17399   [(parallel [(set (match_dup 0) (const_int -1))
17400               (clobber (reg:CC FLAGS_REG))])]
17402   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17403     operands[0] = gen_lowpart (SImode, operands[0]);
17406 ;; Attempt to convert simple lea to add/shift.
17407 ;; These can be created by move expanders.
17408 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17409 ;; relevant lea instructions were already split.
17411 (define_peephole2
17412   [(set (match_operand:SWI48 0 "register_operand")
17413         (plus:SWI48 (match_dup 0)
17414                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
17415   "!TARGET_OPT_AGU
17416    && peep2_regno_dead_p (0, FLAGS_REG)"
17417   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17418               (clobber (reg:CC FLAGS_REG))])])
17420 (define_peephole2
17421   [(set (match_operand:SWI48 0 "register_operand")
17422         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17423                     (match_dup 0)))]
17424   "!TARGET_OPT_AGU
17425    && peep2_regno_dead_p (0, FLAGS_REG)"
17426   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17427               (clobber (reg:CC FLAGS_REG))])])
17429 (define_peephole2
17430   [(set (match_operand:DI 0 "register_operand")
17431         (zero_extend:DI
17432           (plus:SI (match_operand:SI 1 "register_operand")
17433                    (match_operand:SI 2 "nonmemory_operand"))))]
17434   "TARGET_64BIT && !TARGET_OPT_AGU
17435    && REGNO (operands[0]) == REGNO (operands[1])
17436    && peep2_regno_dead_p (0, FLAGS_REG)"
17437   [(parallel [(set (match_dup 0)
17438                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17439               (clobber (reg:CC FLAGS_REG))])])
17441 (define_peephole2
17442   [(set (match_operand:DI 0 "register_operand")
17443         (zero_extend:DI
17444           (plus:SI (match_operand:SI 1 "nonmemory_operand")
17445                    (match_operand:SI 2 "register_operand"))))]
17446   "TARGET_64BIT && !TARGET_OPT_AGU
17447    && REGNO (operands[0]) == REGNO (operands[2])
17448    && peep2_regno_dead_p (0, FLAGS_REG)"
17449   [(parallel [(set (match_dup 0)
17450                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17451               (clobber (reg:CC FLAGS_REG))])])
17453 (define_peephole2
17454   [(set (match_operand:SWI48 0 "register_operand")
17455         (mult:SWI48 (match_dup 0)
17456                     (match_operand:SWI48 1 "const_int_operand")))]
17457   "exact_log2 (INTVAL (operands[1])) >= 0
17458    && peep2_regno_dead_p (0, FLAGS_REG)"
17459   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17460               (clobber (reg:CC FLAGS_REG))])]
17461   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17463 (define_peephole2
17464   [(set (match_operand:DI 0 "register_operand")
17465         (zero_extend:DI
17466           (mult:SI (match_operand:SI 1 "register_operand")
17467                    (match_operand:SI 2 "const_int_operand"))))]
17468   "TARGET_64BIT
17469    && exact_log2 (INTVAL (operands[2])) >= 0
17470    && REGNO (operands[0]) == REGNO (operands[1])
17471    && peep2_regno_dead_p (0, FLAGS_REG)"
17472   [(parallel [(set (match_dup 0)
17473                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17474               (clobber (reg:CC FLAGS_REG))])]
17475   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17477 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17478 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17479 ;; On many CPUs it is also faster, since special hardware to avoid esp
17480 ;; dependencies is present.
17482 ;; While some of these conversions may be done using splitters, we use
17483 ;; peepholes in order to allow combine_stack_adjustments pass to see
17484 ;; nonobfuscated RTL.
17486 ;; Convert prologue esp subtractions to push.
17487 ;; We need register to push.  In order to keep verify_flow_info happy we have
17488 ;; two choices
17489 ;; - use scratch and clobber it in order to avoid dependencies
17490 ;; - use already live register
17491 ;; We can't use the second way right now, since there is no reliable way how to
17492 ;; verify that given register is live.  First choice will also most likely in
17493 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17494 ;; call clobbered registers are dead.  We may want to use base pointer as an
17495 ;; alternative when no register is available later.
17497 (define_peephole2
17498   [(match_scratch:W 1 "r")
17499    (parallel [(set (reg:P SP_REG)
17500                    (plus:P (reg:P SP_REG)
17501                            (match_operand:P 0 "const_int_operand")))
17502               (clobber (reg:CC FLAGS_REG))
17503               (clobber (mem:BLK (scratch)))])]
17504   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17505    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17506   [(clobber (match_dup 1))
17507    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17508               (clobber (mem:BLK (scratch)))])])
17510 (define_peephole2
17511   [(match_scratch:W 1 "r")
17512    (parallel [(set (reg:P SP_REG)
17513                    (plus:P (reg:P SP_REG)
17514                            (match_operand:P 0 "const_int_operand")))
17515               (clobber (reg:CC FLAGS_REG))
17516               (clobber (mem:BLK (scratch)))])]
17517   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17518    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17519   [(clobber (match_dup 1))
17520    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17521    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17522               (clobber (mem:BLK (scratch)))])])
17524 ;; Convert esp subtractions to push.
17525 (define_peephole2
17526   [(match_scratch:W 1 "r")
17527    (parallel [(set (reg:P SP_REG)
17528                    (plus:P (reg:P SP_REG)
17529                            (match_operand:P 0 "const_int_operand")))
17530               (clobber (reg:CC FLAGS_REG))])]
17531   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17532    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17533   [(clobber (match_dup 1))
17534    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17536 (define_peephole2
17537   [(match_scratch:W 1 "r")
17538    (parallel [(set (reg:P SP_REG)
17539                    (plus:P (reg:P SP_REG)
17540                            (match_operand:P 0 "const_int_operand")))
17541               (clobber (reg:CC FLAGS_REG))])]
17542   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17543    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17544   [(clobber (match_dup 1))
17545    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17546    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17548 ;; Convert epilogue deallocator to pop.
17549 (define_peephole2
17550   [(match_scratch:W 1 "r")
17551    (parallel [(set (reg:P SP_REG)
17552                    (plus:P (reg:P SP_REG)
17553                            (match_operand:P 0 "const_int_operand")))
17554               (clobber (reg:CC FLAGS_REG))
17555               (clobber (mem:BLK (scratch)))])]
17556   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17557    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17558   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17559               (clobber (mem:BLK (scratch)))])])
17561 ;; Two pops case is tricky, since pop causes dependency
17562 ;; on destination register.  We use two registers if available.
17563 (define_peephole2
17564   [(match_scratch:W 1 "r")
17565    (match_scratch:W 2 "r")
17566    (parallel [(set (reg:P SP_REG)
17567                    (plus:P (reg:P SP_REG)
17568                            (match_operand:P 0 "const_int_operand")))
17569               (clobber (reg:CC FLAGS_REG))
17570               (clobber (mem:BLK (scratch)))])]
17571   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17572    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17573   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17574               (clobber (mem:BLK (scratch)))])
17575    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17577 (define_peephole2
17578   [(match_scratch:W 1 "r")
17579    (parallel [(set (reg:P SP_REG)
17580                    (plus:P (reg:P SP_REG)
17581                            (match_operand:P 0 "const_int_operand")))
17582               (clobber (reg:CC FLAGS_REG))
17583               (clobber (mem:BLK (scratch)))])]
17584   "optimize_insn_for_size_p ()
17585    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17586   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17587               (clobber (mem:BLK (scratch)))])
17588    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17590 ;; Convert esp additions to pop.
17591 (define_peephole2
17592   [(match_scratch:W 1 "r")
17593    (parallel [(set (reg:P SP_REG)
17594                    (plus:P (reg:P SP_REG)
17595                            (match_operand:P 0 "const_int_operand")))
17596               (clobber (reg:CC FLAGS_REG))])]
17597   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17598   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17600 ;; Two pops case is tricky, since pop causes dependency
17601 ;; on destination register.  We use two registers if available.
17602 (define_peephole2
17603   [(match_scratch:W 1 "r")
17604    (match_scratch:W 2 "r")
17605    (parallel [(set (reg:P SP_REG)
17606                    (plus:P (reg:P SP_REG)
17607                            (match_operand:P 0 "const_int_operand")))
17608               (clobber (reg:CC FLAGS_REG))])]
17609   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17610   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17611    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17613 (define_peephole2
17614   [(match_scratch:W 1 "r")
17615    (parallel [(set (reg:P SP_REG)
17616                    (plus:P (reg:P SP_REG)
17617                            (match_operand:P 0 "const_int_operand")))
17618               (clobber (reg:CC FLAGS_REG))])]
17619   "optimize_insn_for_size_p ()
17620    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17621   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17622    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17624 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17625 ;; required and register dies.  Similarly for 128 to -128.
17626 (define_peephole2
17627   [(set (match_operand 0 "flags_reg_operand")
17628         (match_operator 1 "compare_operator"
17629           [(match_operand 2 "register_operand")
17630            (match_operand 3 "const_int_operand")]))]
17631   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17632      && incdec_operand (operands[3], GET_MODE (operands[3])))
17633     || (!TARGET_FUSE_CMP_AND_BRANCH
17634         && INTVAL (operands[3]) == 128))
17635    && ix86_match_ccmode (insn, CCGCmode)
17636    && peep2_reg_dead_p (1, operands[2])"
17637   [(parallel [(set (match_dup 0)
17638                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17639               (clobber (match_dup 2))])])
17641 ;; Convert imul by three, five and nine into lea
17642 (define_peephole2
17643   [(parallel
17644     [(set (match_operand:SWI48 0 "register_operand")
17645           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17646                       (match_operand:SWI48 2 "const359_operand")))
17647      (clobber (reg:CC FLAGS_REG))])]
17648   "!TARGET_PARTIAL_REG_STALL
17649    || <MODE>mode == SImode
17650    || optimize_function_for_size_p (cfun)"
17651   [(set (match_dup 0)
17652         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17653                     (match_dup 1)))]
17654   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17656 (define_peephole2
17657   [(parallel
17658     [(set (match_operand:SWI48 0 "register_operand")
17659           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17660                       (match_operand:SWI48 2 "const359_operand")))
17661      (clobber (reg:CC FLAGS_REG))])]
17662   "optimize_insn_for_speed_p ()
17663    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17664   [(set (match_dup 0) (match_dup 1))
17665    (set (match_dup 0)
17666         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17667                     (match_dup 0)))]
17668   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17670 ;; imul $32bit_imm, mem, reg is vector decoded, while
17671 ;; imul $32bit_imm, reg, reg is direct decoded.
17672 (define_peephole2
17673   [(match_scratch:SWI48 3 "r")
17674    (parallel [(set (match_operand:SWI48 0 "register_operand")
17675                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17676                                (match_operand:SWI48 2 "immediate_operand")))
17677               (clobber (reg:CC FLAGS_REG))])]
17678   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17679    && !satisfies_constraint_K (operands[2])"
17680   [(set (match_dup 3) (match_dup 1))
17681    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17682               (clobber (reg:CC FLAGS_REG))])])
17684 (define_peephole2
17685   [(match_scratch:SI 3 "r")
17686    (parallel [(set (match_operand:DI 0 "register_operand")
17687                    (zero_extend:DI
17688                      (mult:SI (match_operand:SI 1 "memory_operand")
17689                               (match_operand:SI 2 "immediate_operand"))))
17690               (clobber (reg:CC FLAGS_REG))])]
17691   "TARGET_64BIT
17692    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17693    && !satisfies_constraint_K (operands[2])"
17694   [(set (match_dup 3) (match_dup 1))
17695    (parallel [(set (match_dup 0)
17696                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17697               (clobber (reg:CC FLAGS_REG))])])
17699 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17700 ;; Convert it into imul reg, reg
17701 ;; It would be better to force assembler to encode instruction using long
17702 ;; immediate, but there is apparently no way to do so.
17703 (define_peephole2
17704   [(parallel [(set (match_operand:SWI248 0 "register_operand")
17705                    (mult:SWI248
17706                     (match_operand:SWI248 1 "nonimmediate_operand")
17707                     (match_operand:SWI248 2 "const_int_operand")))
17708               (clobber (reg:CC FLAGS_REG))])
17709    (match_scratch:SWI248 3 "r")]
17710   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17711    && satisfies_constraint_K (operands[2])"
17712   [(set (match_dup 3) (match_dup 2))
17713    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17714               (clobber (reg:CC FLAGS_REG))])]
17716   if (!rtx_equal_p (operands[0], operands[1]))
17717     emit_move_insn (operands[0], operands[1]);
17720 ;; After splitting up read-modify operations, array accesses with memory
17721 ;; operands might end up in form:
17722 ;;  sall    $2, %eax
17723 ;;  movl    4(%esp), %edx
17724 ;;  addl    %edx, %eax
17725 ;; instead of pre-splitting:
17726 ;;  sall    $2, %eax
17727 ;;  addl    4(%esp), %eax
17728 ;; Turn it into:
17729 ;;  movl    4(%esp), %edx
17730 ;;  leal    (%edx,%eax,4), %eax
17732 (define_peephole2
17733   [(match_scratch:W 5 "r")
17734    (parallel [(set (match_operand 0 "register_operand")
17735                    (ashift (match_operand 1 "register_operand")
17736                            (match_operand 2 "const_int_operand")))
17737                (clobber (reg:CC FLAGS_REG))])
17738    (parallel [(set (match_operand 3 "register_operand")
17739                    (plus (match_dup 0)
17740                          (match_operand 4 "x86_64_general_operand")))
17741                    (clobber (reg:CC FLAGS_REG))])]
17742   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17743    /* Validate MODE for lea.  */
17744    && ((!TARGET_PARTIAL_REG_STALL
17745         && (GET_MODE (operands[0]) == QImode
17746             || GET_MODE (operands[0]) == HImode))
17747        || GET_MODE (operands[0]) == SImode
17748        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17749    && (rtx_equal_p (operands[0], operands[3])
17750        || peep2_reg_dead_p (2, operands[0]))
17751    /* We reorder load and the shift.  */
17752    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17753   [(set (match_dup 5) (match_dup 4))
17754    (set (match_dup 0) (match_dup 1))]
17756   enum machine_mode op1mode = GET_MODE (operands[1]);
17757   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17758   int scale = 1 << INTVAL (operands[2]);
17759   rtx index = gen_lowpart (word_mode, operands[1]);
17760   rtx base = gen_lowpart (word_mode, operands[5]);
17761   rtx dest = gen_lowpart (mode, operands[3]);
17763   operands[1] = gen_rtx_PLUS (word_mode, base,
17764                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17765   operands[5] = base;
17766   if (mode != word_mode)
17767     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17768   if (op1mode != word_mode)
17769     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17770   operands[0] = dest;
17773 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17774 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17775 ;; caught for use by garbage collectors and the like.  Using an insn that
17776 ;; maps to SIGILL makes it more likely the program will rightfully die.
17777 ;; Keeping with tradition, "6" is in honor of #UD.
17778 (define_insn "trap"
17779   [(trap_if (const_int 1) (const_int 6))]
17780   ""
17782 #ifdef HAVE_AS_IX86_UD2
17783   return "ud2";
17784 #else
17785   return ASM_SHORT "0x0b0f";
17786 #endif
17788   [(set_attr "length" "2")])
17790 (define_expand "prefetch"
17791   [(prefetch (match_operand 0 "address_operand")
17792              (match_operand:SI 1 "const_int_operand")
17793              (match_operand:SI 2 "const_int_operand"))]
17794   "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
17796   bool write = INTVAL (operands[1]) != 0;
17797   int locality = INTVAL (operands[2]);
17799   gcc_assert (IN_RANGE (locality, 0, 3));
17801   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17802      supported by SSE counterpart or the SSE prefetch is not available
17803      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17804      of locality.  */
17805   if (TARGET_PREFETCHWT1 && write && locality <= 2)
17806     operands[2] = const2_rtx;
17807   else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17808     operands[2] = GEN_INT (3);
17809   else
17810     operands[1] = const0_rtx;
17813 (define_insn "*prefetch_sse"
17814   [(prefetch (match_operand 0 "address_operand" "p")
17815              (const_int 0)
17816              (match_operand:SI 1 "const_int_operand"))]
17817   "TARGET_PREFETCH_SSE"
17819   static const char * const patterns[4] = {
17820    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17821   };
17823   int locality = INTVAL (operands[1]);
17824   gcc_assert (IN_RANGE (locality, 0, 3));
17826   return patterns[locality];
17828   [(set_attr "type" "sse")
17829    (set_attr "atom_sse_attr" "prefetch")
17830    (set (attr "length_address")
17831         (symbol_ref "memory_address_length (operands[0], false)"))
17832    (set_attr "memory" "none")])
17834 (define_insn "*prefetch_3dnow"
17835   [(prefetch (match_operand 0 "address_operand" "p")
17836              (match_operand:SI 1 "const_int_operand" "n")
17837              (const_int 3))]
17838   "TARGET_PRFCHW"
17840   if (INTVAL (operands[1]) == 0)
17841     return "prefetch\t%a0";
17842   else
17843     return "prefetchw\t%a0";
17845   [(set_attr "type" "mmx")
17846    (set (attr "length_address")
17847         (symbol_ref "memory_address_length (operands[0], false)"))
17848    (set_attr "memory" "none")])
17850 (define_insn "*prefetch_prefetchwt1_<mode>"
17851   [(prefetch (match_operand:P 0 "address_operand" "p")
17852              (const_int 1)
17853              (const_int 2))]
17854   "TARGET_PREFETCHWT1"
17855   "prefetchwt1\t%a0";
17856   [(set_attr "type" "sse")
17857    (set (attr "length_address")
17858         (symbol_ref "memory_address_length (operands[0], false)"))
17859    (set_attr "memory" "none")])
17861 (define_expand "stack_protect_set"
17862   [(match_operand 0 "memory_operand")
17863    (match_operand 1 "memory_operand")]
17864   "TARGET_SSP_TLS_GUARD"
17866   rtx (*insn)(rtx, rtx);
17868 #ifdef TARGET_THREAD_SSP_OFFSET
17869   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17870   insn = (TARGET_LP64
17871           ? gen_stack_tls_protect_set_di
17872           : gen_stack_tls_protect_set_si);
17873 #else
17874   insn = (TARGET_LP64
17875           ? gen_stack_protect_set_di
17876           : gen_stack_protect_set_si);
17877 #endif
17879   emit_insn (insn (operands[0], operands[1]));
17880   DONE;
17883 (define_insn "stack_protect_set_<mode>"
17884   [(set (match_operand:PTR 0 "memory_operand" "=m")
17885         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17886                     UNSPEC_SP_SET))
17887    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17888    (clobber (reg:CC FLAGS_REG))]
17889   "TARGET_SSP_TLS_GUARD"
17890   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17891   [(set_attr "type" "multi")])
17893 (define_insn "stack_tls_protect_set_<mode>"
17894   [(set (match_operand:PTR 0 "memory_operand" "=m")
17895         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17896                     UNSPEC_SP_TLS_SET))
17897    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17898    (clobber (reg:CC FLAGS_REG))]
17899   ""
17900   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17901   [(set_attr "type" "multi")])
17903 (define_expand "stack_protect_test"
17904   [(match_operand 0 "memory_operand")
17905    (match_operand 1 "memory_operand")
17906    (match_operand 2)]
17907   "TARGET_SSP_TLS_GUARD"
17909   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17911   rtx (*insn)(rtx, rtx, rtx);
17913 #ifdef TARGET_THREAD_SSP_OFFSET
17914   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17915   insn = (TARGET_LP64
17916           ? gen_stack_tls_protect_test_di
17917           : gen_stack_tls_protect_test_si);
17918 #else
17919   insn = (TARGET_LP64
17920           ? gen_stack_protect_test_di
17921           : gen_stack_protect_test_si);
17922 #endif
17924   emit_insn (insn (flags, operands[0], operands[1]));
17926   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17927                                   flags, const0_rtx, operands[2]));
17928   DONE;
17931 (define_insn "stack_protect_test_<mode>"
17932   [(set (match_operand:CCZ 0 "flags_reg_operand")
17933         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17934                      (match_operand:PTR 2 "memory_operand" "m")]
17935                     UNSPEC_SP_TEST))
17936    (clobber (match_scratch:PTR 3 "=&r"))]
17937   "TARGET_SSP_TLS_GUARD"
17938   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17939   [(set_attr "type" "multi")])
17941 (define_insn "stack_tls_protect_test_<mode>"
17942   [(set (match_operand:CCZ 0 "flags_reg_operand")
17943         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17944                      (match_operand:PTR 2 "const_int_operand" "i")]
17945                     UNSPEC_SP_TLS_TEST))
17946    (clobber (match_scratch:PTR 3 "=r"))]
17947   ""
17948   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17949   [(set_attr "type" "multi")])
17951 (define_insn "sse4_2_crc32<mode>"
17952   [(set (match_operand:SI 0 "register_operand" "=r")
17953         (unspec:SI
17954           [(match_operand:SI 1 "register_operand" "0")
17955            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17956           UNSPEC_CRC32))]
17957   "TARGET_SSE4_2 || TARGET_CRC32"
17958   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17959   [(set_attr "type" "sselog1")
17960    (set_attr "prefix_rep" "1")
17961    (set_attr "prefix_extra" "1")
17962    (set (attr "prefix_data16")
17963      (if_then_else (match_operand:HI 2)
17964        (const_string "1")
17965        (const_string "*")))
17966    (set (attr "prefix_rex")
17967      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17968        (const_string "1")
17969        (const_string "*")))
17970    (set_attr "mode" "SI")])
17972 (define_insn "sse4_2_crc32di"
17973   [(set (match_operand:DI 0 "register_operand" "=r")
17974         (unspec:DI
17975           [(match_operand:DI 1 "register_operand" "0")
17976            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17977           UNSPEC_CRC32))]
17978   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17979   "crc32{q}\t{%2, %0|%0, %2}"
17980   [(set_attr "type" "sselog1")
17981    (set_attr "prefix_rep" "1")
17982    (set_attr "prefix_extra" "1")
17983    (set_attr "mode" "DI")])
17985 (define_insn "rdpmc"
17986   [(set (match_operand:DI 0 "register_operand" "=A")
17987         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17988                             UNSPECV_RDPMC))]
17989   "!TARGET_64BIT"
17990   "rdpmc"
17991   [(set_attr "type" "other")
17992    (set_attr "length" "2")])
17994 (define_insn "rdpmc_rex64"
17995   [(set (match_operand:DI 0 "register_operand" "=a")
17996         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17997                             UNSPECV_RDPMC))
17998    (set (match_operand:DI 1 "register_operand" "=d")
17999         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18000   "TARGET_64BIT"
18001   "rdpmc"
18002   [(set_attr "type" "other")
18003    (set_attr "length" "2")])
18005 (define_insn "rdtsc"
18006   [(set (match_operand:DI 0 "register_operand" "=A")
18007         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18008   "!TARGET_64BIT"
18009   "rdtsc"
18010   [(set_attr "type" "other")
18011    (set_attr "length" "2")])
18013 (define_insn "rdtsc_rex64"
18014   [(set (match_operand:DI 0 "register_operand" "=a")
18015         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18016    (set (match_operand:DI 1 "register_operand" "=d")
18017         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18018   "TARGET_64BIT"
18019   "rdtsc"
18020   [(set_attr "type" "other")
18021    (set_attr "length" "2")])
18023 (define_insn "rdtscp"
18024   [(set (match_operand:DI 0 "register_operand" "=A")
18025         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18026    (set (match_operand:SI 1 "register_operand" "=c")
18027         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18028   "!TARGET_64BIT"
18029   "rdtscp"
18030   [(set_attr "type" "other")
18031    (set_attr "length" "3")])
18033 (define_insn "rdtscp_rex64"
18034   [(set (match_operand:DI 0 "register_operand" "=a")
18035         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18036    (set (match_operand:DI 1 "register_operand" "=d")
18037         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18038    (set (match_operand:SI 2 "register_operand" "=c")
18039         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18040   "TARGET_64BIT"
18041   "rdtscp"
18042   [(set_attr "type" "other")
18043    (set_attr "length" "3")])
18045 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18047 ;; FXSR, XSAVE and XSAVEOPT instructions
18049 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18051 (define_insn "fxsave"
18052   [(set (match_operand:BLK 0 "memory_operand" "=m")
18053         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18054   "TARGET_FXSR"
18055   "fxsave\t%0"
18056   [(set_attr "type" "other")
18057    (set_attr "memory" "store")
18058    (set (attr "length")
18059         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18061 (define_insn "fxsave64"
18062   [(set (match_operand:BLK 0 "memory_operand" "=m")
18063         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18064   "TARGET_64BIT && TARGET_FXSR"
18065   "fxsave64\t%0"
18066   [(set_attr "type" "other")
18067    (set_attr "memory" "store")
18068    (set (attr "length")
18069         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18071 (define_insn "fxrstor"
18072   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18073                     UNSPECV_FXRSTOR)]
18074   "TARGET_FXSR"
18075   "fxrstor\t%0"
18076   [(set_attr "type" "other")
18077    (set_attr "memory" "load")
18078    (set (attr "length")
18079         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18081 (define_insn "fxrstor64"
18082   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18083                     UNSPECV_FXRSTOR64)]
18084   "TARGET_64BIT && TARGET_FXSR"
18085   "fxrstor64\t%0"
18086   [(set_attr "type" "other")
18087    (set_attr "memory" "load")
18088    (set (attr "length")
18089         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18091 (define_int_iterator ANY_XSAVE
18092         [UNSPECV_XSAVE
18093          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18094          (UNSPECV_XSAVEC "TARGET_XSAVEC")
18095          (UNSPECV_XSAVES "TARGET_XSAVES")])
18097 (define_int_iterator ANY_XSAVE64
18098         [UNSPECV_XSAVE64
18099          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18100          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18101          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18103 (define_int_attr xsave
18104         [(UNSPECV_XSAVE "xsave")
18105          (UNSPECV_XSAVE64 "xsave64")
18106          (UNSPECV_XSAVEOPT "xsaveopt")
18107          (UNSPECV_XSAVEOPT64 "xsaveopt64")
18108          (UNSPECV_XSAVEC "xsavec")
18109          (UNSPECV_XSAVEC64 "xsavec64")
18110          (UNSPECV_XSAVES "xsaves")
18111          (UNSPECV_XSAVES64 "xsaves64")])
18113 (define_int_iterator ANY_XRSTOR
18114         [UNSPECV_XRSTOR
18115          (UNSPECV_XRSTORS "TARGET_XSAVES")])
18117 (define_int_iterator ANY_XRSTOR64
18118         [UNSPECV_XRSTOR64
18119          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18121 (define_int_attr xrstor
18122         [(UNSPECV_XRSTOR "xrstor")
18123          (UNSPECV_XRSTOR64 "xrstor")
18124          (UNSPECV_XRSTORS "xrstors")
18125          (UNSPECV_XRSTORS64 "xrstors")])
18127 (define_insn "<xsave>"
18128   [(set (match_operand:BLK 0 "memory_operand" "=m")
18129         (unspec_volatile:BLK
18130          [(match_operand:DI 1 "register_operand" "A")]
18131          ANY_XSAVE))]
18132   "!TARGET_64BIT && TARGET_XSAVE"
18133   "<xsave>\t%0"
18134   [(set_attr "type" "other")
18135    (set_attr "memory" "store")
18136    (set (attr "length")
18137         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18139 (define_insn "<xsave>_rex64"
18140   [(set (match_operand:BLK 0 "memory_operand" "=m")
18141         (unspec_volatile:BLK
18142          [(match_operand:SI 1 "register_operand" "a")
18143           (match_operand:SI 2 "register_operand" "d")]
18144          ANY_XSAVE))]
18145   "TARGET_64BIT && TARGET_XSAVE"
18146   "<xsave>\t%0"
18147   [(set_attr "type" "other")
18148    (set_attr "memory" "store")
18149    (set (attr "length")
18150         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18152 (define_insn "<xsave>"
18153   [(set (match_operand:BLK 0 "memory_operand" "=m")
18154         (unspec_volatile:BLK
18155          [(match_operand:SI 1 "register_operand" "a")
18156           (match_operand:SI 2 "register_operand" "d")]
18157          ANY_XSAVE64))]
18158   "TARGET_64BIT && TARGET_XSAVE"
18159   "<xsave>\t%0"
18160   [(set_attr "type" "other")
18161    (set_attr "memory" "store")
18162    (set (attr "length")
18163         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18165 (define_insn "<xrstor>"
18166    [(unspec_volatile:BLK
18167      [(match_operand:BLK 0 "memory_operand" "m")
18168       (match_operand:DI 1 "register_operand" "A")]
18169      ANY_XRSTOR)]
18170   "!TARGET_64BIT && TARGET_XSAVE"
18171   "<xrstor>\t%0"
18172   [(set_attr "type" "other")
18173    (set_attr "memory" "load")
18174    (set (attr "length")
18175         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18177 (define_insn "<xrstor>_rex64"
18178    [(unspec_volatile:BLK
18179      [(match_operand:BLK 0 "memory_operand" "m")
18180       (match_operand:SI 1 "register_operand" "a")
18181       (match_operand:SI 2 "register_operand" "d")]
18182      ANY_XRSTOR)]
18183   "TARGET_64BIT && TARGET_XSAVE"
18184   "<xrstor>\t%0"
18185   [(set_attr "type" "other")
18186    (set_attr "memory" "load")
18187    (set (attr "length")
18188         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18190 (define_insn "<xrstor>64"
18191    [(unspec_volatile:BLK
18192      [(match_operand:BLK 0 "memory_operand" "m")
18193       (match_operand:SI 1 "register_operand" "a")
18194       (match_operand:SI 2 "register_operand" "d")]
18195      ANY_XRSTOR64)]
18196   "TARGET_64BIT && TARGET_XSAVE"
18197   "<xrstor>64\t%0"
18198   [(set_attr "type" "other")
18199    (set_attr "memory" "load")
18200    (set (attr "length")
18201         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18203 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18205 ;; Floating-point instructions for atomic compound assignments
18207 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18209 ; Clobber all floating-point registers on environment save and restore
18210 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18211 (define_insn "fnstenv"
18212   [(set (match_operand:BLK 0 "memory_operand" "=m")
18213         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18214    (clobber (reg:HI FPCR_REG))
18215    (clobber (reg:XF ST0_REG))
18216    (clobber (reg:XF ST1_REG))
18217    (clobber (reg:XF ST2_REG))
18218    (clobber (reg:XF ST3_REG))
18219    (clobber (reg:XF ST4_REG))
18220    (clobber (reg:XF ST5_REG))
18221    (clobber (reg:XF ST6_REG))
18222    (clobber (reg:XF ST7_REG))]
18223   "TARGET_80387"
18224   "fnstenv\t%0"
18225   [(set_attr "type" "other")
18226    (set_attr "memory" "store")
18227    (set (attr "length")
18228         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18230 (define_insn "fldenv"
18231   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18232                     UNSPECV_FLDENV)
18233    (clobber (reg:CCFP FPSR_REG))
18234    (clobber (reg:HI FPCR_REG))
18235    (clobber (reg:XF ST0_REG))
18236    (clobber (reg:XF ST1_REG))
18237    (clobber (reg:XF ST2_REG))
18238    (clobber (reg:XF ST3_REG))
18239    (clobber (reg:XF ST4_REG))
18240    (clobber (reg:XF ST5_REG))
18241    (clobber (reg:XF ST6_REG))
18242    (clobber (reg:XF ST7_REG))]
18243   "TARGET_80387"
18244   "fldenv\t%0"
18245   [(set_attr "type" "other")
18246    (set_attr "memory" "load")
18247    (set (attr "length")
18248         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18250 (define_insn "fnstsw"
18251   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18252         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18253   "TARGET_80387"
18254   "fnstsw\t%0"
18255   [(set_attr "type" "other,other")
18256    (set_attr "memory" "none,store")
18257    (set (attr "length")
18258         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18260 (define_insn "fnclex"
18261   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18262   "TARGET_80387"
18263   "fnclex"
18264   [(set_attr "type" "other")
18265    (set_attr "memory" "none")
18266    (set_attr "length" "2")])
18268 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18270 ;; LWP instructions
18272 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18274 (define_expand "lwp_llwpcb"
18275   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18276                     UNSPECV_LLWP_INTRINSIC)]
18277   "TARGET_LWP")
18279 (define_insn "*lwp_llwpcb<mode>1"
18280   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18281                     UNSPECV_LLWP_INTRINSIC)]
18282   "TARGET_LWP"
18283   "llwpcb\t%0"
18284   [(set_attr "type" "lwp")
18285    (set_attr "mode" "<MODE>")
18286    (set_attr "length" "5")])
18288 (define_expand "lwp_slwpcb"
18289   [(set (match_operand 0 "register_operand" "=r")
18290         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18291   "TARGET_LWP"
18293   rtx (*insn)(rtx);
18295   insn = (Pmode == DImode
18296           ? gen_lwp_slwpcbdi
18297           : gen_lwp_slwpcbsi);
18299   emit_insn (insn (operands[0]));
18300   DONE;
18303 (define_insn "lwp_slwpcb<mode>"
18304   [(set (match_operand:P 0 "register_operand" "=r")
18305         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18306   "TARGET_LWP"
18307   "slwpcb\t%0"
18308   [(set_attr "type" "lwp")
18309    (set_attr "mode" "<MODE>")
18310    (set_attr "length" "5")])
18312 (define_expand "lwp_lwpval<mode>3"
18313   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18314                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18315                      (match_operand:SI 3 "const_int_operand" "i")]
18316                     UNSPECV_LWPVAL_INTRINSIC)]
18317   "TARGET_LWP"
18318   ;; Avoid unused variable warning.
18319   "(void) operands[0];")
18321 (define_insn "*lwp_lwpval<mode>3_1"
18322   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18323                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18324                      (match_operand:SI 2 "const_int_operand" "i")]
18325                     UNSPECV_LWPVAL_INTRINSIC)]
18326   "TARGET_LWP"
18327   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18328   [(set_attr "type" "lwp")
18329    (set_attr "mode" "<MODE>")
18330    (set (attr "length")
18331         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18333 (define_expand "lwp_lwpins<mode>3"
18334   [(set (reg:CCC FLAGS_REG)
18335         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18336                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18337                               (match_operand:SI 3 "const_int_operand" "i")]
18338                              UNSPECV_LWPINS_INTRINSIC))
18339    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18340         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18341   "TARGET_LWP")
18343 (define_insn "*lwp_lwpins<mode>3_1"
18344   [(set (reg:CCC FLAGS_REG)
18345         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18346                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18347                               (match_operand:SI 2 "const_int_operand" "i")]
18348                              UNSPECV_LWPINS_INTRINSIC))]
18349   "TARGET_LWP"
18350   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18351   [(set_attr "type" "lwp")
18352    (set_attr "mode" "<MODE>")
18353    (set (attr "length")
18354         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18356 (define_int_iterator RDFSGSBASE
18357         [UNSPECV_RDFSBASE
18358          UNSPECV_RDGSBASE])
18360 (define_int_iterator WRFSGSBASE
18361         [UNSPECV_WRFSBASE
18362          UNSPECV_WRGSBASE])
18364 (define_int_attr fsgs
18365         [(UNSPECV_RDFSBASE "fs")
18366          (UNSPECV_RDGSBASE "gs")
18367          (UNSPECV_WRFSBASE "fs")
18368          (UNSPECV_WRGSBASE "gs")])
18370 (define_insn "rd<fsgs>base<mode>"
18371   [(set (match_operand:SWI48 0 "register_operand" "=r")
18372         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18373   "TARGET_64BIT && TARGET_FSGSBASE"
18374   "rd<fsgs>base\t%0"
18375   [(set_attr "type" "other")
18376    (set_attr "prefix_extra" "2")])
18378 (define_insn "wr<fsgs>base<mode>"
18379   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18380                     WRFSGSBASE)]
18381   "TARGET_64BIT && TARGET_FSGSBASE"
18382   "wr<fsgs>base\t%0"
18383   [(set_attr "type" "other")
18384    (set_attr "prefix_extra" "2")])
18386 (define_insn "rdrand<mode>_1"
18387   [(set (match_operand:SWI248 0 "register_operand" "=r")
18388         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18389    (set (reg:CCC FLAGS_REG)
18390         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18391   "TARGET_RDRND"
18392   "rdrand\t%0"
18393   [(set_attr "type" "other")
18394    (set_attr "prefix_extra" "1")])
18396 (define_insn "rdseed<mode>_1"
18397   [(set (match_operand:SWI248 0 "register_operand" "=r")
18398         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18399    (set (reg:CCC FLAGS_REG)
18400         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18401   "TARGET_RDSEED"
18402   "rdseed\t%0"
18403   [(set_attr "type" "other")
18404    (set_attr "prefix_extra" "1")])
18406 (define_expand "pause"
18407   [(set (match_dup 0)
18408         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18409   ""
18411   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18412   MEM_VOLATILE_P (operands[0]) = 1;
18415 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18416 ;; They have the same encoding.
18417 (define_insn "*pause"
18418   [(set (match_operand:BLK 0)
18419         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18420   ""
18421   "rep%; nop"
18422   [(set_attr "length" "2")
18423    (set_attr "memory" "unknown")])
18425 (define_expand "xbegin"
18426   [(set (match_operand:SI 0 "register_operand")
18427         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18428   "TARGET_RTM"
18430   rtx label = gen_label_rtx ();
18432   /* xbegin is emitted as jump_insn, so reload won't be able
18433      to reload its operand.  Force the value into AX hard register.  */
18434   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18435   emit_move_insn (ax_reg, constm1_rtx);
18437   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18439   emit_label (label);
18440   LABEL_NUSES (label) = 1;
18442   emit_move_insn (operands[0], ax_reg);
18444   DONE;
18447 (define_insn "xbegin_1"
18448   [(set (pc)
18449         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18450                           (const_int 0))
18451                       (label_ref (match_operand 1))
18452                       (pc)))
18453    (set (match_operand:SI 0 "register_operand" "+a")
18454         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18455   "TARGET_RTM"
18456   "xbegin\t%l1"
18457   [(set_attr "type" "other")
18458    (set_attr "length" "6")])
18460 (define_insn "xend"
18461   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18462   "TARGET_RTM"
18463   "xend"
18464   [(set_attr "type" "other")
18465    (set_attr "length" "3")])
18467 (define_insn "xabort"
18468   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18469                     UNSPECV_XABORT)]
18470   "TARGET_RTM"
18471   "xabort\t%0"
18472   [(set_attr "type" "other")
18473    (set_attr "length" "3")])
18475 (define_expand "xtest"
18476   [(set (match_operand:QI 0 "register_operand")
18477         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18478   "TARGET_RTM"
18480   emit_insn (gen_xtest_1 ());
18482   ix86_expand_setcc (operands[0], NE,
18483                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18484   DONE;
18487 (define_insn "xtest_1"
18488   [(set (reg:CCZ FLAGS_REG)
18489         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18490   "TARGET_RTM"
18491   "xtest"
18492   [(set_attr "type" "other")
18493    (set_attr "length" "3")])
18495 (define_insn "clflushopt"
18496   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18497                    UNSPECV_CLFLUSHOPT)]
18498   "TARGET_CLFLUSHOPT"
18499   "clflushopt\t%a0"
18500   [(set_attr "type" "sse")
18501    (set_attr "atom_sse_attr" "fence")
18502    (set_attr "memory" "unknown")])
18504 (include "mmx.md")
18505 (include "sse.md")
18506 (include "sync.md")