Disable local dynamic TLS model on Solaris/x86 if as/ld cannot handle it
[official-gcc.git] / gcc / config / i386 / i386.md
blobea1d85f76a5563036a60f4cd081b5600376f010f
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
115   ;; For SSE/MMX support:
116   UNSPEC_FIX_NOTRUNC
117   UNSPEC_MASKMOV
118   UNSPEC_MOVMSK
119   UNSPEC_RCP
120   UNSPEC_RSQRT
121   UNSPEC_PSADBW
123   ;; Generic math support
124   UNSPEC_COPYSIGN
125   UNSPEC_IEEE_MIN       ; not commutative
126   UNSPEC_IEEE_MAX       ; not commutative
128   ;; x87 Floating point
129   UNSPEC_SIN
130   UNSPEC_COS
131   UNSPEC_FPATAN
132   UNSPEC_FYL2X
133   UNSPEC_FYL2XP1
134   UNSPEC_FRNDINT
135   UNSPEC_FIST
136   UNSPEC_F2XM1
137   UNSPEC_TAN
138   UNSPEC_FXAM
140   ;; x87 Rounding
141   UNSPEC_FRNDINT_FLOOR
142   UNSPEC_FRNDINT_CEIL
143   UNSPEC_FRNDINT_TRUNC
144   UNSPEC_FRNDINT_MASK_PM
145   UNSPEC_FIST_FLOOR
146   UNSPEC_FIST_CEIL
148   ;; x87 Double output FP
149   UNSPEC_SINCOS_COS
150   UNSPEC_SINCOS_SIN
151   UNSPEC_XTRACT_FRACT
152   UNSPEC_XTRACT_EXP
153   UNSPEC_FSCALE_FRACT
154   UNSPEC_FSCALE_EXP
155   UNSPEC_FPREM_F
156   UNSPEC_FPREM_U
157   UNSPEC_FPREM1_F
158   UNSPEC_FPREM1_U
160   UNSPEC_C2_FLAG
161   UNSPEC_FXAM_MEM
163   ;; SSP patterns
164   UNSPEC_SP_SET
165   UNSPEC_SP_TEST
166   UNSPEC_SP_TLS_SET
167   UNSPEC_SP_TLS_TEST
169   ;; For ROUND support
170   UNSPEC_ROUND
172   ;; For CRC32 support
173   UNSPEC_CRC32
175   ;; For BMI support
176   UNSPEC_BEXTR
178   ;; For BMI2 support
179   UNSPEC_PDEP
180   UNSPEC_PEXT
182   ;; For AVX512F support
183   UNSPEC_KMOV
186 (define_c_enum "unspecv" [
187   UNSPECV_BLOCKAGE
188   UNSPECV_STACK_PROBE
189   UNSPECV_PROBE_STACK_RANGE
190   UNSPECV_ALIGN
191   UNSPECV_PROLOGUE_USE
192   UNSPECV_SPLIT_STACK_RETURN
193   UNSPECV_CLD
194   UNSPECV_NOPS
195   UNSPECV_RDTSC
196   UNSPECV_RDTSCP
197   UNSPECV_RDPMC
198   UNSPECV_LLWP_INTRINSIC
199   UNSPECV_SLWP_INTRINSIC
200   UNSPECV_LWPVAL_INTRINSIC
201   UNSPECV_LWPINS_INTRINSIC
202   UNSPECV_RDFSBASE
203   UNSPECV_RDGSBASE
204   UNSPECV_WRFSBASE
205   UNSPECV_WRGSBASE
206   UNSPECV_FXSAVE
207   UNSPECV_FXRSTOR
208   UNSPECV_FXSAVE64
209   UNSPECV_FXRSTOR64
210   UNSPECV_XSAVE
211   UNSPECV_XRSTOR
212   UNSPECV_XSAVE64
213   UNSPECV_XRSTOR64
214   UNSPECV_XSAVEOPT
215   UNSPECV_XSAVEOPT64
217   ;; For atomic compound assignments.
218   UNSPECV_FNSTENV
219   UNSPECV_FLDENV
220   UNSPECV_FNSTSW
221   UNSPECV_FNCLEX
223   ;; For RDRAND support
224   UNSPECV_RDRAND
226   ;; For RDSEED support
227   UNSPECV_RDSEED
229   ;; For RTM support
230   UNSPECV_XBEGIN
231   UNSPECV_XEND
232   UNSPECV_XABORT
233   UNSPECV_XTEST
235   UNSPECV_NLGR
238 ;; Constants to represent rounding modes in the ROUND instruction
239 (define_constants
240   [(ROUND_FLOOR                 0x1)
241    (ROUND_CEIL                  0x2)
242    (ROUND_TRUNC                 0x3)
243    (ROUND_MXCSR                 0x4)
244    (ROUND_NO_EXC                0x8)
245   ])
247 ;; Constants to represent AVX512F embeded rounding
248 (define_constants
249   [(ROUND_NEAREST_INT                   0)
250    (ROUND_NEG_INF                       1)
251    (ROUND_POS_INF                       2)
252    (ROUND_ZERO                          3)
253    (NO_ROUND                            4)
254    (ROUND_SAE                           8)
255   ])
257 ;; Constants to represent pcomtrue/pcomfalse variants
258 (define_constants
259   [(PCOM_FALSE                  0)
260    (PCOM_TRUE                   1)
261    (COM_FALSE_S                 2)
262    (COM_FALSE_P                 3)
263    (COM_TRUE_S                  4)
264    (COM_TRUE_P                  5)
265   ])
267 ;; Constants used in the XOP pperm instruction
268 (define_constants
269   [(PPERM_SRC                   0x00)   /* copy source */
270    (PPERM_INVERT                0x20)   /* invert source */
271    (PPERM_REVERSE               0x40)   /* bit reverse source */
272    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
273    (PPERM_ZERO                  0x80)   /* all 0's */
274    (PPERM_ONES                  0xa0)   /* all 1's */
275    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
276    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
277    (PPERM_SRC1                  0x00)   /* use first source byte */
278    (PPERM_SRC2                  0x10)   /* use second source byte */
279    ])
281 ;; Registers by name.
282 (define_constants
283   [(AX_REG                       0)
284    (DX_REG                       1)
285    (CX_REG                       2)
286    (BX_REG                       3)
287    (SI_REG                       4)
288    (DI_REG                       5)
289    (BP_REG                       6)
290    (SP_REG                       7)
291    (ST0_REG                      8)
292    (ST1_REG                      9)
293    (ST2_REG                     10)
294    (ST3_REG                     11)
295    (ST4_REG                     12)
296    (ST5_REG                     13)
297    (ST6_REG                     14)
298    (ST7_REG                     15)
299    (FLAGS_REG                   17)
300    (FPSR_REG                    18)
301    (FPCR_REG                    19)
302    (XMM0_REG                    21)
303    (XMM1_REG                    22)
304    (XMM2_REG                    23)
305    (XMM3_REG                    24)
306    (XMM4_REG                    25)
307    (XMM5_REG                    26)
308    (XMM6_REG                    27)
309    (XMM7_REG                    28)
310    (MM0_REG                     29)
311    (MM1_REG                     30)
312    (MM2_REG                     31)
313    (MM3_REG                     32)
314    (MM4_REG                     33)
315    (MM5_REG                     34)
316    (MM6_REG                     35)
317    (MM7_REG                     36)
318    (R8_REG                      37)
319    (R9_REG                      38)
320    (R10_REG                     39)
321    (R11_REG                     40)
322    (R12_REG                     41)
323    (R13_REG                     42)
324    (R14_REG                     43)
325    (R15_REG                     44)
326    (XMM8_REG                    45)
327    (XMM9_REG                    46)
328    (XMM10_REG                   47)
329    (XMM11_REG                   48)
330    (XMM12_REG                   49)
331    (XMM13_REG                   50)
332    (XMM14_REG                   51)
333    (XMM15_REG                   52)
334    (XMM16_REG                   53)
335    (XMM17_REG                   54)
336    (XMM18_REG                   55)
337    (XMM19_REG                   56)
338    (XMM20_REG                   57)
339    (XMM21_REG                   58)
340    (XMM22_REG                   59)
341    (XMM23_REG                   60)
342    (XMM24_REG                   61)
343    (XMM25_REG                   62)
344    (XMM26_REG                   63)
345    (XMM27_REG                   64)
346    (XMM28_REG                   65)
347    (XMM29_REG                   66)
348    (XMM30_REG                   67)
349    (XMM31_REG                   68)
350    (MASK0_REG                   69)
351    (MASK1_REG                   70)
352    (MASK2_REG                   71)
353    (MASK3_REG                   72)
354    (MASK4_REG                   73)
355    (MASK5_REG                   74)
356    (MASK6_REG                   75)
357    (MASK7_REG                   76)
358   ])
360 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
361 ;; from i386.c.
363 ;; In C guard expressions, put expressions which may be compile-time
364 ;; constants first.  This allows for better optimization.  For
365 ;; example, write "TARGET_64BIT && reload_completed", not
366 ;; "reload_completed && TARGET_64BIT".
369 ;; Processor type.
370 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
371                     atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
372                     btver2"
373   (const (symbol_ref "ix86_schedule")))
375 ;; A basic instruction type.  Refinements due to arguments to be
376 ;; provided in other attributes.
377 (define_attr "type"
378   "other,multi,
379    alu,alu1,negnot,imov,imovx,lea,
380    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
381    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
382    push,pop,call,callv,leave,
383    str,bitmanip,
384    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
385    fxch,fistp,fisttp,frndint,
386    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
387    ssemul,sseimul,ssediv,sselog,sselog1,
388    sseishft,sseishft1,ssecmp,ssecomi,
389    ssecvt,ssecvt1,sseicvt,sseins,
390    sseshuf,sseshuf1,ssemuladd,sse4arg,
391    lwp,mskmov,msklog,
392    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
393   (const_string "other"))
395 ;; Main data type used by the insn
396 (define_attr "mode"
397   "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
398   V2DF,V2SF,V1DF,V8DF"
399   (const_string "unknown"))
401 ;; The CPU unit operations uses.
402 (define_attr "unit" "integer,i387,sse,mmx,unknown"
403   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
404                           fxch,fistp,fisttp,frndint")
405            (const_string "i387")
406          (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
407                           ssemul,sseimul,ssediv,sselog,sselog1,
408                           sseishft,sseishft1,ssecmp,ssecomi,
409                           ssecvt,ssecvt1,sseicvt,sseins,
410                           sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
411            (const_string "sse")
412          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
413            (const_string "mmx")
414          (eq_attr "type" "other")
415            (const_string "unknown")]
416          (const_string "integer")))
418 ;; The minimum required alignment of vector mode memory operands of the SSE
419 ;; (non-VEX/EVEX) instruction in bits, if it is different from
420 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0.  If an instruction has
421 ;; multiple alternatives, this should be conservative maximum of those minimum
422 ;; required alignments.
423 (define_attr "ssememalign" "" (const_int 0))
425 ;; The (bounding maximum) length of an instruction immediate.
426 (define_attr "length_immediate" ""
427   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
428                           bitmanip,imulx,msklog,mskmov")
429            (const_int 0)
430          (eq_attr "unit" "i387,sse,mmx")
431            (const_int 0)
432          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
433                           rotate,rotatex,rotate1,imul,icmp,push,pop")
434            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
435          (eq_attr "type" "imov,test")
436            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
437          (eq_attr "type" "call")
438            (if_then_else (match_operand 0 "constant_call_address_operand")
439              (const_int 4)
440              (const_int 0))
441          (eq_attr "type" "callv")
442            (if_then_else (match_operand 1 "constant_call_address_operand")
443              (const_int 4)
444              (const_int 0))
445          ;; We don't know the size before shorten_branches.  Expect
446          ;; the instruction to fit for better scheduling.
447          (eq_attr "type" "ibr")
448            (const_int 1)
449          ]
450          (symbol_ref "/* Update immediate_length and other attributes! */
451                       gcc_unreachable (),1")))
453 ;; The (bounding maximum) length of an instruction address.
454 (define_attr "length_address" ""
455   (cond [(eq_attr "type" "str,other,multi,fxch")
456            (const_int 0)
457          (and (eq_attr "type" "call")
458               (match_operand 0 "constant_call_address_operand"))
459              (const_int 0)
460          (and (eq_attr "type" "callv")
461               (match_operand 1 "constant_call_address_operand"))
462              (const_int 0)
463          ]
464          (symbol_ref "ix86_attr_length_address_default (insn)")))
466 ;; Set when length prefix is used.
467 (define_attr "prefix_data16" ""
468   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
469            (const_int 0)
470          (eq_attr "mode" "HI")
471            (const_int 1)
472          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
473            (const_int 1)
474         ]
475         (const_int 0)))
477 ;; Set when string REP prefix is used.
478 (define_attr "prefix_rep" ""
479   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
480            (const_int 0)
481          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
482            (const_int 1)
483         ]
484         (const_int 0)))
486 ;; Set when 0f opcode prefix is used.
487 (define_attr "prefix_0f" ""
488   (if_then_else
489     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
490          (eq_attr "unit" "sse,mmx"))
491     (const_int 1)
492     (const_int 0)))
494 ;; Set when REX opcode prefix is used.
495 (define_attr "prefix_rex" ""
496   (cond [(not (match_test "TARGET_64BIT"))
497            (const_int 0)
498          (and (eq_attr "mode" "DI")
499               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
500                    (eq_attr "unit" "!mmx")))
501            (const_int 1)
502          (and (eq_attr "mode" "QI")
503               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
504            (const_int 1)
505          (match_test "x86_extended_reg_mentioned_p (insn)")
506            (const_int 1)
507          (and (eq_attr "type" "imovx")
508               (match_operand:QI 1 "ext_QIreg_operand"))
509            (const_int 1)
510         ]
511         (const_int 0)))
513 ;; There are also additional prefixes in 3DNOW, SSSE3.
514 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
515 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
516 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
517 (define_attr "prefix_extra" ""
518   (cond [(eq_attr "type" "ssemuladd,sse4arg")
519            (const_int 2)
520          (eq_attr "type" "sseiadd1,ssecvt1")
521            (const_int 1)
522         ]
523         (const_int 0)))
525 ;; Prefix used: original, VEX or maybe VEX.
526 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
527   (cond [(eq_attr "mode" "OI,V8SF,V4DF")
528            (const_string "vex")
529          (eq_attr "mode" "XI,V16SF,V8DF")
530            (const_string "evex")
531         ]
532         (const_string "orig")))
534 ;; VEX W bit is used.
535 (define_attr "prefix_vex_w" "" (const_int 0))
537 ;; The length of VEX prefix
538 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
539 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
540 ;; still prefix_0f 1, with prefix_extra 1.
541 (define_attr "length_vex" ""
542   (if_then_else (and (eq_attr "prefix_0f" "1")
543                      (eq_attr "prefix_extra" "0"))
544     (if_then_else (eq_attr "prefix_vex_w" "1")
545       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
546       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
547     (if_then_else (eq_attr "prefix_vex_w" "1")
548       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
549       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
551 ;; 4-bytes evex prefix and 1 byte opcode.
552 (define_attr "length_evex" "" (const_int 5))
554 ;; Set when modrm byte is used.
555 (define_attr "modrm" ""
556   (cond [(eq_attr "type" "str,leave")
557            (const_int 0)
558          (eq_attr "unit" "i387")
559            (const_int 0)
560          (and (eq_attr "type" "incdec")
561               (and (not (match_test "TARGET_64BIT"))
562                    (ior (match_operand:SI 1 "register_operand")
563                         (match_operand:HI 1 "register_operand"))))
564            (const_int 0)
565          (and (eq_attr "type" "push")
566               (not (match_operand 1 "memory_operand")))
567            (const_int 0)
568          (and (eq_attr "type" "pop")
569               (not (match_operand 0 "memory_operand")))
570            (const_int 0)
571          (and (eq_attr "type" "imov")
572               (and (not (eq_attr "mode" "DI"))
573                    (ior (and (match_operand 0 "register_operand")
574                              (match_operand 1 "immediate_operand"))
575                         (ior (and (match_operand 0 "ax_reg_operand")
576                                   (match_operand 1 "memory_displacement_only_operand"))
577                              (and (match_operand 0 "memory_displacement_only_operand")
578                                   (match_operand 1 "ax_reg_operand"))))))
579            (const_int 0)
580          (and (eq_attr "type" "call")
581               (match_operand 0 "constant_call_address_operand"))
582              (const_int 0)
583          (and (eq_attr "type" "callv")
584               (match_operand 1 "constant_call_address_operand"))
585              (const_int 0)
586          (and (eq_attr "type" "alu,alu1,icmp,test")
587               (match_operand 0 "ax_reg_operand"))
588              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
589          ]
590          (const_int 1)))
592 ;; The (bounding maximum) length of an instruction in bytes.
593 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
594 ;; Later we may want to split them and compute proper length as for
595 ;; other insns.
596 (define_attr "length" ""
597   (cond [(eq_attr "type" "other,multi,fistp,frndint")
598            (const_int 16)
599          (eq_attr "type" "fcmp")
600            (const_int 4)
601          (eq_attr "unit" "i387")
602            (plus (const_int 2)
603                  (plus (attr "prefix_data16")
604                        (attr "length_address")))
605          (ior (eq_attr "prefix" "evex")
606               (and (ior (eq_attr "prefix" "maybe_evex")
607                         (eq_attr "prefix" "maybe_vex"))
608                    (match_test "TARGET_AVX512F")))
609            (plus (attr "length_evex")
610                  (plus (attr "length_immediate")
611                        (plus (attr "modrm")
612                              (attr "length_address"))))
613          (ior (eq_attr "prefix" "vex")
614               (and (ior (eq_attr "prefix" "maybe_vex")
615                         (eq_attr "prefix" "maybe_evex"))
616                    (match_test "TARGET_AVX")))
617            (plus (attr "length_vex")
618                  (plus (attr "length_immediate")
619                        (plus (attr "modrm")
620                              (attr "length_address"))))]
621          (plus (plus (attr "modrm")
622                      (plus (attr "prefix_0f")
623                            (plus (attr "prefix_rex")
624                                  (plus (attr "prefix_extra")
625                                        (const_int 1)))))
626                (plus (attr "prefix_rep")
627                      (plus (attr "prefix_data16")
628                            (plus (attr "length_immediate")
629                                  (attr "length_address")))))))
631 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
632 ;; `store' if there is a simple memory reference therein, or `unknown'
633 ;; if the instruction is complex.
635 (define_attr "memory" "none,load,store,both,unknown"
636   (cond [(eq_attr "type" "other,multi,str,lwp")
637            (const_string "unknown")
638          (eq_attr "type" "lea,fcmov,fpspc")
639            (const_string "none")
640          (eq_attr "type" "fistp,leave")
641            (const_string "both")
642          (eq_attr "type" "frndint")
643            (const_string "load")
644          (eq_attr "type" "push")
645            (if_then_else (match_operand 1 "memory_operand")
646              (const_string "both")
647              (const_string "store"))
648          (eq_attr "type" "pop")
649            (if_then_else (match_operand 0 "memory_operand")
650              (const_string "both")
651              (const_string "load"))
652          (eq_attr "type" "setcc")
653            (if_then_else (match_operand 0 "memory_operand")
654              (const_string "store")
655              (const_string "none"))
656          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
657            (if_then_else (ior (match_operand 0 "memory_operand")
658                               (match_operand 1 "memory_operand"))
659              (const_string "load")
660              (const_string "none"))
661          (eq_attr "type" "ibr")
662            (if_then_else (match_operand 0 "memory_operand")
663              (const_string "load")
664              (const_string "none"))
665          (eq_attr "type" "call")
666            (if_then_else (match_operand 0 "constant_call_address_operand")
667              (const_string "none")
668              (const_string "load"))
669          (eq_attr "type" "callv")
670            (if_then_else (match_operand 1 "constant_call_address_operand")
671              (const_string "none")
672              (const_string "load"))
673          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
674               (match_operand 1 "memory_operand"))
675            (const_string "both")
676          (and (match_operand 0 "memory_operand")
677               (match_operand 1 "memory_operand"))
678            (const_string "both")
679          (match_operand 0 "memory_operand")
680            (const_string "store")
681          (match_operand 1 "memory_operand")
682            (const_string "load")
683          (and (eq_attr "type"
684                  "!alu1,negnot,ishift1,
685                    imov,imovx,icmp,test,bitmanip,
686                    fmov,fcmp,fsgn,
687                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
688                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
689                    mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
690               (match_operand 2 "memory_operand"))
691            (const_string "load")
692          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
693               (match_operand 3 "memory_operand"))
694            (const_string "load")
695         ]
696         (const_string "none")))
698 ;; Indicates if an instruction has both an immediate and a displacement.
700 (define_attr "imm_disp" "false,true,unknown"
701   (cond [(eq_attr "type" "other,multi")
702            (const_string "unknown")
703          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
704               (and (match_operand 0 "memory_displacement_operand")
705                    (match_operand 1 "immediate_operand")))
706            (const_string "true")
707          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
708               (and (match_operand 0 "memory_displacement_operand")
709                    (match_operand 2 "immediate_operand")))
710            (const_string "true")
711         ]
712         (const_string "false")))
714 ;; Indicates if an FP operation has an integer source.
716 (define_attr "fp_int_src" "false,true"
717   (const_string "false"))
719 ;; Defines rounding mode of an FP operation.
721 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
722   (const_string "any"))
724 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
725 (define_attr "use_carry" "0,1" (const_string "0"))
727 ;; Define attribute to indicate unaligned ssemov insns
728 (define_attr "movu" "0,1" (const_string "0"))
730 ;; Used to control the "enabled" attribute on a per-instruction basis.
731 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
732                     sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
733                     avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,fma_avx512f"
734   (const_string "base"))
736 (define_attr "enabled" ""
737   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
738          (eq_attr "isa" "x64_sse4")
739            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
740          (eq_attr "isa" "x64_sse4_noavx")
741            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
742          (eq_attr "isa" "x64_avx")
743            (symbol_ref "TARGET_64BIT && TARGET_AVX")
744          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
745          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
746          (eq_attr "isa" "sse2_noavx")
747            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
748          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
749          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
750          (eq_attr "isa" "sse4_noavx")
751            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
752          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
753          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
754          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
755          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
756          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
757          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
758          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
759          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
760          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
761          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
762          (eq_attr "isa" "fma_avx512f")
763            (symbol_ref "TARGET_FMA || TARGET_AVX512F")
764         ]
765         (const_int 1)))
767 ;; Describe a user's asm statement.
768 (define_asm_attributes
769   [(set_attr "length" "128")
770    (set_attr "type" "multi")])
772 (define_code_iterator plusminus [plus minus])
774 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
776 (define_code_iterator multdiv [mult div])
778 ;; Base name for define_insn
779 (define_code_attr plusminus_insn
780   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
781    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
783 ;; Base name for insn mnemonic.
784 (define_code_attr plusminus_mnemonic
785   [(plus "add") (ss_plus "adds") (us_plus "addus")
786    (minus "sub") (ss_minus "subs") (us_minus "subus")])
787 (define_code_attr plusminus_carry_mnemonic
788   [(plus "adc") (minus "sbb")])
789 (define_code_attr multdiv_mnemonic
790   [(mult "mul") (div "div")])
792 ;; Mark commutative operators as such in constraints.
793 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
794                         (minus "") (ss_minus "") (us_minus "")])
796 ;; Mapping of max and min
797 (define_code_iterator maxmin [smax smin umax umin])
799 ;; Mapping of signed max and min
800 (define_code_iterator smaxmin [smax smin])
802 ;; Mapping of unsigned max and min
803 (define_code_iterator umaxmin [umax umin])
805 ;; Base name for integer and FP insn mnemonic
806 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
807                               (umax "maxu") (umin "minu")])
808 (define_code_attr maxmin_float [(smax "max") (smin "min")])
810 ;; Mapping of logic operators
811 (define_code_iterator any_logic [and ior xor])
812 (define_code_iterator any_or [ior xor])
813 (define_code_iterator fpint_logic [and xor])
815 ;; Base name for insn mnemonic.
816 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
818 ;; Mapping of logic-shift operators
819 (define_code_iterator any_lshift [ashift lshiftrt])
821 ;; Mapping of shift-right operators
822 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
824 ;; Mapping of all shift operators
825 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
827 ;; Base name for define_insn
828 (define_code_attr shift_insn
829   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
831 ;; Base name for insn mnemonic.
832 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
833 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
835 ;; Mapping of rotate operators
836 (define_code_iterator any_rotate [rotate rotatert])
838 ;; Base name for define_insn
839 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
841 ;; Base name for insn mnemonic.
842 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
844 ;; Mapping of abs neg operators
845 (define_code_iterator absneg [abs neg])
847 ;; Base name for x87 insn mnemonic.
848 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
850 ;; Used in signed and unsigned widening multiplications.
851 (define_code_iterator any_extend [sign_extend zero_extend])
853 ;; Prefix for insn menmonic.
854 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
856 ;; Prefix for define_insn
857 (define_code_attr u [(sign_extend "") (zero_extend "u")])
858 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
859 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
861 ;; Used in signed and unsigned truncations.
862 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
863 ;; Instruction suffix for truncations.
864 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
866 ;; Used in signed and unsigned fix.
867 (define_code_iterator any_fix [fix unsigned_fix])
868 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
870 ;; All integer modes.
871 (define_mode_iterator SWI1248x [QI HI SI DI])
873 ;; All integer modes without QImode.
874 (define_mode_iterator SWI248x [HI SI DI])
876 ;; All integer modes without QImode and HImode.
877 (define_mode_iterator SWI48x [SI DI])
879 ;; All integer modes without SImode and DImode.
880 (define_mode_iterator SWI12 [QI HI])
882 ;; All integer modes without DImode.
883 (define_mode_iterator SWI124 [QI HI SI])
885 ;; All integer modes without QImode and DImode.
886 (define_mode_iterator SWI24 [HI SI])
888 ;; Single word integer modes.
889 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
891 ;; Single word integer modes without QImode.
892 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
894 ;; Single word integer modes without QImode and HImode.
895 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
897 ;; All math-dependant single and double word integer modes.
898 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
899                              (HI "TARGET_HIMODE_MATH")
900                              SI DI (TI "TARGET_64BIT")])
902 ;; Math-dependant single word integer modes.
903 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
904                             (HI "TARGET_HIMODE_MATH")
905                             SI (DI "TARGET_64BIT")])
907 ;; Math-dependant integer modes without DImode.
908 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
909                                (HI "TARGET_HIMODE_MATH")
910                                SI])
912 ;; Math-dependant single word integer modes without QImode.
913 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
914                                SI (DI "TARGET_64BIT")])
916 ;; Double word integer modes.
917 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
918                            (TI "TARGET_64BIT")])
920 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
921 ;; compile time constant, it is faster to use <MODE_SIZE> than
922 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
923 ;; command line options just use GET_MODE_SIZE macro.
924 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
925                              (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
926                              (V16QI "16") (V32QI "32") (V64QI "64")
927                              (V8HI "16") (V16HI "32") (V32HI "64")
928                              (V4SI "16") (V8SI "32") (V16SI "64")
929                              (V2DI "16") (V4DI "32") (V8DI "64")
930                              (V1TI "16") (V2TI "32") (V4TI "64")
931                              (V2DF "16") (V4DF "32") (V8DF "64")
932                              (V4SF "16") (V8SF "32") (V16SF "64")])
934 ;; Double word integer modes as mode attribute.
935 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
936 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
938 ;; Half mode for double word integer modes.
939 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
940                             (DI "TARGET_64BIT")])
942 ;; Instruction suffix for integer modes.
943 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
945 ;; Pointer size prefix for integer modes (Intel asm dialect)
946 (define_mode_attr iptrsize [(QI "BYTE")
947                             (HI "WORD")
948                             (SI "DWORD")
949                             (DI "QWORD")])
951 ;; Register class for integer modes.
952 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
954 ;; Immediate operand constraint for integer modes.
955 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
957 ;; General operand constraint for word modes.
958 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
960 ;; Immediate operand constraint for double integer modes.
961 (define_mode_attr di [(SI "nF") (DI "e")])
963 ;; Immediate operand constraint for shifts.
964 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
966 ;; General operand predicate for integer modes.
967 (define_mode_attr general_operand
968         [(QI "general_operand")
969          (HI "general_operand")
970          (SI "x86_64_general_operand")
971          (DI "x86_64_general_operand")
972          (TI "x86_64_general_operand")])
974 ;; General sign/zero extend operand predicate for integer modes.
975 (define_mode_attr general_szext_operand
976         [(QI "general_operand")
977          (HI "general_operand")
978          (SI "x86_64_szext_general_operand")
979          (DI "x86_64_szext_general_operand")])
981 ;; Immediate operand predicate for integer modes.
982 (define_mode_attr immediate_operand
983         [(QI "immediate_operand")
984          (HI "immediate_operand")
985          (SI "x86_64_immediate_operand")
986          (DI "x86_64_immediate_operand")])
988 ;; Nonmemory operand predicate for integer modes.
989 (define_mode_attr nonmemory_operand
990         [(QI "nonmemory_operand")
991          (HI "nonmemory_operand")
992          (SI "x86_64_nonmemory_operand")
993          (DI "x86_64_nonmemory_operand")])
995 ;; Operand predicate for shifts.
996 (define_mode_attr shift_operand
997         [(QI "nonimmediate_operand")
998          (HI "nonimmediate_operand")
999          (SI "nonimmediate_operand")
1000          (DI "shiftdi_operand")
1001          (TI "register_operand")])
1003 ;; Operand predicate for shift argument.
1004 (define_mode_attr shift_immediate_operand
1005         [(QI "const_1_to_31_operand")
1006          (HI "const_1_to_31_operand")
1007          (SI "const_1_to_31_operand")
1008          (DI "const_1_to_63_operand")])
1010 ;; Input operand predicate for arithmetic left shifts.
1011 (define_mode_attr ashl_input_operand
1012         [(QI "nonimmediate_operand")
1013          (HI "nonimmediate_operand")
1014          (SI "nonimmediate_operand")
1015          (DI "ashldi_input_operand")
1016          (TI "reg_or_pm1_operand")])
1018 ;; SSE and x87 SFmode and DFmode floating point modes
1019 (define_mode_iterator MODEF [SF DF])
1021 ;; All x87 floating point modes
1022 (define_mode_iterator X87MODEF [SF DF XF])
1024 ;; SSE instruction suffix for various modes
1025 (define_mode_attr ssemodesuffix
1026   [(SF "ss") (DF "sd")
1027    (V16SF "ps") (V8DF "pd")
1028    (V8SF "ps") (V4DF "pd")
1029    (V4SF "ps") (V2DF "pd")
1030    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1031    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1032    (V64QI "b") (V16SI "d") (V8DI "q")])
1034 ;; SSE vector suffix for floating point modes
1035 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1037 ;; SSE vector mode corresponding to a scalar mode
1038 (define_mode_attr ssevecmode
1039   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1040 (define_mode_attr ssevecmodelower
1041   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1043 ;; Instruction suffix for REX 64bit operators.
1044 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1046 ;; This mode iterator allows :P to be used for patterns that operate on
1047 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1048 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1050 ;; This mode iterator allows :W to be used for patterns that operate on
1051 ;; word_mode sized quantities.
1052 (define_mode_iterator W
1053   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1055 ;; This mode iterator allows :PTR to be used for patterns that operate on
1056 ;; ptr_mode sized quantities.
1057 (define_mode_iterator PTR
1058   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1060 ;; Scheduling descriptions
1062 (include "pentium.md")
1063 (include "ppro.md")
1064 (include "k6.md")
1065 (include "athlon.md")
1066 (include "bdver1.md")
1067 (include "bdver3.md")
1068 (include "btver2.md")
1069 (include "geode.md")
1070 (include "atom.md")
1071 (include "slm.md")
1072 (include "core2.md")
1075 ;; Operand and operator predicates and constraints
1077 (include "predicates.md")
1078 (include "constraints.md")
1081 ;; Compare and branch/compare and store instructions.
1083 (define_expand "cbranch<mode>4"
1084   [(set (reg:CC FLAGS_REG)
1085         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1086                     (match_operand:SDWIM 2 "<general_operand>")))
1087    (set (pc) (if_then_else
1088                (match_operator 0 "ordered_comparison_operator"
1089                 [(reg:CC FLAGS_REG) (const_int 0)])
1090                (label_ref (match_operand 3))
1091                (pc)))]
1092   ""
1094   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1095     operands[1] = force_reg (<MODE>mode, operands[1]);
1096   ix86_expand_branch (GET_CODE (operands[0]),
1097                       operands[1], operands[2], operands[3]);
1098   DONE;
1101 (define_expand "cstore<mode>4"
1102   [(set (reg:CC FLAGS_REG)
1103         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1104                     (match_operand:SWIM 3 "<general_operand>")))
1105    (set (match_operand:QI 0 "register_operand")
1106         (match_operator 1 "ordered_comparison_operator"
1107           [(reg:CC FLAGS_REG) (const_int 0)]))]
1108   ""
1110   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1111     operands[2] = force_reg (<MODE>mode, operands[2]);
1112   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1113                      operands[2], operands[3]);
1114   DONE;
1117 (define_expand "cmp<mode>_1"
1118   [(set (reg:CC FLAGS_REG)
1119         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1120                     (match_operand:SWI48 1 "<general_operand>")))])
1122 (define_insn "*cmp<mode>_ccno_1"
1123   [(set (reg FLAGS_REG)
1124         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1125                  (match_operand:SWI 1 "const0_operand")))]
1126   "ix86_match_ccmode (insn, CCNOmode)"
1127   "@
1128    test{<imodesuffix>}\t%0, %0
1129    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1130   [(set_attr "type" "test,icmp")
1131    (set_attr "length_immediate" "0,1")
1132    (set_attr "mode" "<MODE>")])
1134 (define_insn "*cmp<mode>_1"
1135   [(set (reg FLAGS_REG)
1136         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1137                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1138   "ix86_match_ccmode (insn, CCmode)"
1139   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1140   [(set_attr "type" "icmp")
1141    (set_attr "mode" "<MODE>")])
1143 (define_insn "*cmp<mode>_minus_1"
1144   [(set (reg FLAGS_REG)
1145         (compare
1146           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1147                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1148           (const_int 0)))]
1149   "ix86_match_ccmode (insn, CCGOCmode)"
1150   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1151   [(set_attr "type" "icmp")
1152    (set_attr "mode" "<MODE>")])
1154 (define_insn "*cmpqi_ext_1"
1155   [(set (reg FLAGS_REG)
1156         (compare
1157           (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1158           (subreg:QI
1159             (zero_extract:SI
1160               (match_operand 1 "ext_register_operand" "Q,Q")
1161               (const_int 8)
1162               (const_int 8)) 0)))]
1163   "ix86_match_ccmode (insn, CCmode)"
1164   "cmp{b}\t{%h1, %0|%0, %h1}"
1165   [(set_attr "isa" "*,nox64")
1166    (set_attr "type" "icmp")
1167    (set_attr "mode" "QI")])
1169 (define_insn "*cmpqi_ext_2"
1170   [(set (reg FLAGS_REG)
1171         (compare
1172           (subreg:QI
1173             (zero_extract:SI
1174               (match_operand 0 "ext_register_operand" "Q")
1175               (const_int 8)
1176               (const_int 8)) 0)
1177           (match_operand:QI 1 "const0_operand")))]
1178   "ix86_match_ccmode (insn, CCNOmode)"
1179   "test{b}\t%h0, %h0"
1180   [(set_attr "type" "test")
1181    (set_attr "length_immediate" "0")
1182    (set_attr "mode" "QI")])
1184 (define_expand "cmpqi_ext_3"
1185   [(set (reg:CC FLAGS_REG)
1186         (compare:CC
1187           (subreg:QI
1188             (zero_extract:SI
1189               (match_operand 0 "ext_register_operand")
1190               (const_int 8)
1191               (const_int 8)) 0)
1192           (match_operand:QI 1 "const_int_operand")))])
1194 (define_insn "*cmpqi_ext_3"
1195   [(set (reg FLAGS_REG)
1196         (compare
1197           (subreg:QI
1198             (zero_extract:SI
1199               (match_operand 0 "ext_register_operand" "Q,Q")
1200               (const_int 8)
1201               (const_int 8)) 0)
1202           (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1203   "ix86_match_ccmode (insn, CCmode)"
1204   "cmp{b}\t{%1, %h0|%h0, %1}"
1205   [(set_attr "isa" "*,nox64")
1206    (set_attr "type" "icmp")
1207    (set_attr "modrm" "1")
1208    (set_attr "mode" "QI")])
1210 (define_insn "*cmpqi_ext_4"
1211   [(set (reg FLAGS_REG)
1212         (compare
1213           (subreg:QI
1214             (zero_extract:SI
1215               (match_operand 0 "ext_register_operand" "Q")
1216               (const_int 8)
1217               (const_int 8)) 0)
1218           (subreg:QI
1219             (zero_extract:SI
1220               (match_operand 1 "ext_register_operand" "Q")
1221               (const_int 8)
1222               (const_int 8)) 0)))]
1223   "ix86_match_ccmode (insn, CCmode)"
1224   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1225   [(set_attr "type" "icmp")
1226    (set_attr "mode" "QI")])
1228 ;; These implement float point compares.
1229 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1230 ;; which would allow mix and match FP modes on the compares.  Which is what
1231 ;; the old patterns did, but with many more of them.
1233 (define_expand "cbranchxf4"
1234   [(set (reg:CC FLAGS_REG)
1235         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1236                     (match_operand:XF 2 "nonmemory_operand")))
1237    (set (pc) (if_then_else
1238               (match_operator 0 "ix86_fp_comparison_operator"
1239                [(reg:CC FLAGS_REG)
1240                 (const_int 0)])
1241               (label_ref (match_operand 3))
1242               (pc)))]
1243   "TARGET_80387"
1245   ix86_expand_branch (GET_CODE (operands[0]),
1246                       operands[1], operands[2], operands[3]);
1247   DONE;
1250 (define_expand "cstorexf4"
1251   [(set (reg:CC FLAGS_REG)
1252         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1253                     (match_operand:XF 3 "nonmemory_operand")))
1254    (set (match_operand:QI 0 "register_operand")
1255               (match_operator 1 "ix86_fp_comparison_operator"
1256                [(reg:CC FLAGS_REG)
1257                 (const_int 0)]))]
1258   "TARGET_80387"
1260   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1261                      operands[2], operands[3]);
1262   DONE;
1265 (define_expand "cbranch<mode>4"
1266   [(set (reg:CC FLAGS_REG)
1267         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1268                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1269    (set (pc) (if_then_else
1270               (match_operator 0 "ix86_fp_comparison_operator"
1271                [(reg:CC FLAGS_REG)
1272                 (const_int 0)])
1273               (label_ref (match_operand 3))
1274               (pc)))]
1275   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1277   ix86_expand_branch (GET_CODE (operands[0]),
1278                       operands[1], operands[2], operands[3]);
1279   DONE;
1282 (define_expand "cstore<mode>4"
1283   [(set (reg:CC FLAGS_REG)
1284         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1285                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1286    (set (match_operand:QI 0 "register_operand")
1287               (match_operator 1 "ix86_fp_comparison_operator"
1288                [(reg:CC FLAGS_REG)
1289                 (const_int 0)]))]
1290   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1292   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1293                      operands[2], operands[3]);
1294   DONE;
1297 (define_expand "cbranchcc4"
1298   [(set (pc) (if_then_else
1299               (match_operator 0 "comparison_operator"
1300                [(match_operand 1 "flags_reg_operand")
1301                 (match_operand 2 "const0_operand")])
1302               (label_ref (match_operand 3))
1303               (pc)))]
1304   ""
1306   ix86_expand_branch (GET_CODE (operands[0]),
1307                       operands[1], operands[2], operands[3]);
1308   DONE;
1311 (define_expand "cstorecc4"
1312   [(set (match_operand:QI 0 "register_operand")
1313               (match_operator 1 "comparison_operator"
1314                [(match_operand 2 "flags_reg_operand")
1315                 (match_operand 3 "const0_operand")]))]
1316   ""
1318   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1319                      operands[2], operands[3]);
1320   DONE;
1324 ;; FP compares, step 1:
1325 ;; Set the FP condition codes.
1327 ;; CCFPmode     compare with exceptions
1328 ;; CCFPUmode    compare with no exceptions
1330 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1331 ;; used to manage the reg stack popping would not be preserved.
1333 (define_insn "*cmp<mode>_0_i387"
1334   [(set (match_operand:HI 0 "register_operand" "=a")
1335         (unspec:HI
1336           [(compare:CCFP
1337              (match_operand:X87MODEF 1 "register_operand" "f")
1338              (match_operand:X87MODEF 2 "const0_operand"))]
1339         UNSPEC_FNSTSW))]
1340   "TARGET_80387"
1341   "* return output_fp_compare (insn, operands, false, false);"
1342   [(set_attr "type" "multi")
1343    (set_attr "unit" "i387")
1344    (set_attr "mode" "<MODE>")])
1346 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1347   [(set (reg:CCFP FLAGS_REG)
1348         (compare:CCFP
1349           (match_operand:X87MODEF 1 "register_operand" "f")
1350           (match_operand:X87MODEF 2 "const0_operand")))
1351    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1352   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1353   "#"
1354   "&& reload_completed"
1355   [(set (match_dup 0)
1356         (unspec:HI
1357           [(compare:CCFP (match_dup 1)(match_dup 2))]
1358         UNSPEC_FNSTSW))
1359    (set (reg:CC FLAGS_REG)
1360         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1361   ""
1362   [(set_attr "type" "multi")
1363    (set_attr "unit" "i387")
1364    (set_attr "mode" "<MODE>")])
1366 (define_insn "*cmpxf_i387"
1367   [(set (match_operand:HI 0 "register_operand" "=a")
1368         (unspec:HI
1369           [(compare:CCFP
1370              (match_operand:XF 1 "register_operand" "f")
1371              (match_operand:XF 2 "register_operand" "f"))]
1372           UNSPEC_FNSTSW))]
1373   "TARGET_80387"
1374   "* return output_fp_compare (insn, operands, false, false);"
1375   [(set_attr "type" "multi")
1376    (set_attr "unit" "i387")
1377    (set_attr "mode" "XF")])
1379 (define_insn_and_split "*cmpxf_cc_i387"
1380   [(set (reg:CCFP FLAGS_REG)
1381         (compare:CCFP
1382           (match_operand:XF 1 "register_operand" "f")
1383           (match_operand:XF 2 "register_operand" "f")))
1384    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1385   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1386   "#"
1387   "&& reload_completed"
1388   [(set (match_dup 0)
1389         (unspec:HI
1390           [(compare:CCFP (match_dup 1)(match_dup 2))]
1391         UNSPEC_FNSTSW))
1392    (set (reg:CC FLAGS_REG)
1393         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1394   ""
1395   [(set_attr "type" "multi")
1396    (set_attr "unit" "i387")
1397    (set_attr "mode" "XF")])
1399 (define_insn "*cmp<mode>_i387"
1400   [(set (match_operand:HI 0 "register_operand" "=a")
1401         (unspec:HI
1402           [(compare:CCFP
1403              (match_operand:MODEF 1 "register_operand" "f")
1404              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1405           UNSPEC_FNSTSW))]
1406   "TARGET_80387"
1407   "* return output_fp_compare (insn, operands, false, false);"
1408   [(set_attr "type" "multi")
1409    (set_attr "unit" "i387")
1410    (set_attr "mode" "<MODE>")])
1412 (define_insn_and_split "*cmp<mode>_cc_i387"
1413   [(set (reg:CCFP FLAGS_REG)
1414         (compare:CCFP
1415           (match_operand:MODEF 1 "register_operand" "f")
1416           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1417    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1418   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1419   "#"
1420   "&& reload_completed"
1421   [(set (match_dup 0)
1422         (unspec:HI
1423           [(compare:CCFP (match_dup 1)(match_dup 2))]
1424         UNSPEC_FNSTSW))
1425    (set (reg:CC FLAGS_REG)
1426         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1427   ""
1428   [(set_attr "type" "multi")
1429    (set_attr "unit" "i387")
1430    (set_attr "mode" "<MODE>")])
1432 (define_insn "*cmpu<mode>_i387"
1433   [(set (match_operand:HI 0 "register_operand" "=a")
1434         (unspec:HI
1435           [(compare:CCFPU
1436              (match_operand:X87MODEF 1 "register_operand" "f")
1437              (match_operand:X87MODEF 2 "register_operand" "f"))]
1438           UNSPEC_FNSTSW))]
1439   "TARGET_80387"
1440   "* return output_fp_compare (insn, operands, false, true);"
1441   [(set_attr "type" "multi")
1442    (set_attr "unit" "i387")
1443    (set_attr "mode" "<MODE>")])
1445 (define_insn_and_split "*cmpu<mode>_cc_i387"
1446   [(set (reg:CCFPU FLAGS_REG)
1447         (compare:CCFPU
1448           (match_operand:X87MODEF 1 "register_operand" "f")
1449           (match_operand:X87MODEF 2 "register_operand" "f")))
1450    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1451   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1452   "#"
1453   "&& reload_completed"
1454   [(set (match_dup 0)
1455         (unspec:HI
1456           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1457         UNSPEC_FNSTSW))
1458    (set (reg:CC FLAGS_REG)
1459         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1460   ""
1461   [(set_attr "type" "multi")
1462    (set_attr "unit" "i387")
1463    (set_attr "mode" "<MODE>")])
1465 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1466   [(set (match_operand:HI 0 "register_operand" "=a")
1467         (unspec:HI
1468           [(compare:CCFP
1469              (match_operand:X87MODEF 1 "register_operand" "f")
1470              (match_operator:X87MODEF 3 "float_operator"
1471                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1472           UNSPEC_FNSTSW))]
1473   "TARGET_80387
1474    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1475        || optimize_function_for_size_p (cfun))"
1476   "* return output_fp_compare (insn, operands, false, false);"
1477   [(set_attr "type" "multi")
1478    (set_attr "unit" "i387")
1479    (set_attr "fp_int_src" "true")
1480    (set_attr "mode" "<SWI24:MODE>")])
1482 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1483   [(set (reg:CCFP FLAGS_REG)
1484         (compare:CCFP
1485           (match_operand:X87MODEF 1 "register_operand" "f")
1486           (match_operator:X87MODEF 3 "float_operator"
1487             [(match_operand:SWI24 2 "memory_operand" "m")])))
1488    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1489   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1490    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1491        || optimize_function_for_size_p (cfun))"
1492   "#"
1493   "&& reload_completed"
1494   [(set (match_dup 0)
1495         (unspec:HI
1496           [(compare:CCFP
1497              (match_dup 1)
1498              (match_op_dup 3 [(match_dup 2)]))]
1499         UNSPEC_FNSTSW))
1500    (set (reg:CC FLAGS_REG)
1501         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1502   ""
1503   [(set_attr "type" "multi")
1504    (set_attr "unit" "i387")
1505    (set_attr "fp_int_src" "true")
1506    (set_attr "mode" "<SWI24:MODE>")])
1508 ;; FP compares, step 2
1509 ;; Move the fpsw to ax.
1511 (define_insn "x86_fnstsw_1"
1512   [(set (match_operand:HI 0 "register_operand" "=a")
1513         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1514   "TARGET_80387"
1515   "fnstsw\t%0"
1516   [(set (attr "length")
1517         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1518    (set_attr "mode" "SI")
1519    (set_attr "unit" "i387")])
1521 ;; FP compares, step 3
1522 ;; Get ax into flags, general case.
1524 (define_insn "x86_sahf_1"
1525   [(set (reg:CC FLAGS_REG)
1526         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1527                    UNSPEC_SAHF))]
1528   "TARGET_SAHF"
1530 #ifndef HAVE_AS_IX86_SAHF
1531   if (TARGET_64BIT)
1532     return ASM_BYTE "0x9e";
1533   else
1534 #endif
1535   return "sahf";
1537   [(set_attr "length" "1")
1538    (set_attr "athlon_decode" "vector")
1539    (set_attr "amdfam10_decode" "direct")
1540    (set_attr "bdver1_decode" "direct")
1541    (set_attr "mode" "SI")])
1543 ;; Pentium Pro can do steps 1 through 3 in one go.
1544 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1545 ;; (these i387 instructions set flags directly)
1547 (define_mode_iterator FPCMP [CCFP CCFPU])
1548 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1550 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1551   [(set (reg:FPCMP FLAGS_REG)
1552         (compare:FPCMP
1553           (match_operand:MODEF 0 "register_operand" "f,x")
1554           (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1555   "TARGET_MIX_SSE_I387
1556    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1557   "* return output_fp_compare (insn, operands, true,
1558                                <FPCMP:MODE>mode == CCFPUmode);"
1559   [(set_attr "type" "fcmp,ssecomi")
1560    (set_attr "prefix" "orig,maybe_vex")
1561    (set_attr "mode" "<MODEF:MODE>")
1562    (set (attr "prefix_rep")
1563         (if_then_else (eq_attr "type" "ssecomi")
1564                       (const_string "0")
1565                       (const_string "*")))
1566    (set (attr "prefix_data16")
1567         (cond [(eq_attr "type" "fcmp")
1568                  (const_string "*")
1569                (eq_attr "mode" "DF")
1570                  (const_string "1")
1571               ]
1572               (const_string "0")))
1573    (set_attr "athlon_decode" "vector")
1574    (set_attr "amdfam10_decode" "direct")
1575    (set_attr "bdver1_decode" "double")])
1577 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1578   [(set (reg:FPCMP FLAGS_REG)
1579         (compare:FPCMP
1580           (match_operand:MODEF 0 "register_operand" "x")
1581           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1582   "TARGET_SSE_MATH
1583    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1584   "* return output_fp_compare (insn, operands, true,
1585                                <FPCMP:MODE>mode == CCFPUmode);"
1586   [(set_attr "type" "ssecomi")
1587    (set_attr "prefix" "maybe_vex")
1588    (set_attr "mode" "<MODEF:MODE>")
1589    (set_attr "prefix_rep" "0")
1590    (set (attr "prefix_data16")
1591         (if_then_else (eq_attr "mode" "DF")
1592                       (const_string "1")
1593                       (const_string "0")))
1594    (set_attr "athlon_decode" "vector")
1595    (set_attr "amdfam10_decode" "direct")
1596    (set_attr "bdver1_decode" "double")])
1598 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1599   [(set (reg:FPCMP FLAGS_REG)
1600         (compare:FPCMP
1601           (match_operand:X87MODEF 0 "register_operand" "f")
1602           (match_operand:X87MODEF 1 "register_operand" "f")))]
1603   "TARGET_80387 && TARGET_CMOVE
1604    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1605   "* return output_fp_compare (insn, operands, true,
1606                                <FPCMP:MODE>mode == CCFPUmode);"
1607   [(set_attr "type" "fcmp")
1608    (set_attr "mode" "<X87MODEF:MODE>")
1609    (set_attr "athlon_decode" "vector")
1610    (set_attr "amdfam10_decode" "direct")
1611    (set_attr "bdver1_decode" "double")])
1613 ;; Push/pop instructions.
1615 (define_insn "*push<mode>2"
1616   [(set (match_operand:DWI 0 "push_operand" "=<")
1617         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1618   ""
1619   "#"
1620   [(set_attr "type" "multi")
1621    (set_attr "mode" "<MODE>")])
1623 (define_split
1624   [(set (match_operand:TI 0 "push_operand")
1625         (match_operand:TI 1 "general_operand"))]
1626   "TARGET_64BIT && reload_completed
1627    && !SSE_REG_P (operands[1])"
1628   [(const_int 0)]
1629   "ix86_split_long_move (operands); DONE;")
1631 (define_insn "*pushdi2_rex64"
1632   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1633         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1634   "TARGET_64BIT"
1635   "@
1636    push{q}\t%1
1637    #"
1638   [(set_attr "type" "push,multi")
1639    (set_attr "mode" "DI")])
1641 ;; Convert impossible pushes of immediate to existing instructions.
1642 ;; First try to get scratch register and go through it.  In case this
1643 ;; fails, push sign extended lower part first and then overwrite
1644 ;; upper part by 32bit move.
1645 (define_peephole2
1646   [(match_scratch:DI 2 "r")
1647    (set (match_operand:DI 0 "push_operand")
1648         (match_operand:DI 1 "immediate_operand"))]
1649   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1650    && !x86_64_immediate_operand (operands[1], DImode)"
1651   [(set (match_dup 2) (match_dup 1))
1652    (set (match_dup 0) (match_dup 2))])
1654 ;; We need to define this as both peepholer and splitter for case
1655 ;; peephole2 pass is not run.
1656 ;; "&& 1" is needed to keep it from matching the previous pattern.
1657 (define_peephole2
1658   [(set (match_operand:DI 0 "push_operand")
1659         (match_operand:DI 1 "immediate_operand"))]
1660   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1661    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1662   [(set (match_dup 0) (match_dup 1))
1663    (set (match_dup 2) (match_dup 3))]
1665   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1667   operands[1] = gen_lowpart (DImode, operands[2]);
1668   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1669                                                    GEN_INT (4)));
1672 (define_split
1673   [(set (match_operand:DI 0 "push_operand")
1674         (match_operand:DI 1 "immediate_operand"))]
1675   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1676                     ? epilogue_completed : reload_completed)
1677    && !symbolic_operand (operands[1], DImode)
1678    && !x86_64_immediate_operand (operands[1], DImode)"
1679   [(set (match_dup 0) (match_dup 1))
1680    (set (match_dup 2) (match_dup 3))]
1682   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1684   operands[1] = gen_lowpart (DImode, operands[2]);
1685   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1686                                                    GEN_INT (4)));
1689 (define_split
1690   [(set (match_operand:DI 0 "push_operand")
1691         (match_operand:DI 1 "general_operand"))]
1692   "!TARGET_64BIT && reload_completed
1693    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1694   [(const_int 0)]
1695   "ix86_split_long_move (operands); DONE;")
1697 (define_insn "*pushsi2"
1698   [(set (match_operand:SI 0 "push_operand" "=<")
1699         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1700   "!TARGET_64BIT"
1701   "push{l}\t%1"
1702   [(set_attr "type" "push")
1703    (set_attr "mode" "SI")])
1705 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1706 ;; "push a byte/word".  But actually we use pushl, which has the effect
1707 ;; of rounding the amount pushed up to a word.
1709 ;; For TARGET_64BIT we always round up to 8 bytes.
1710 (define_insn "*push<mode>2_rex64"
1711   [(set (match_operand:SWI124 0 "push_operand" "=X")
1712         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1713   "TARGET_64BIT"
1714   "push{q}\t%q1"
1715   [(set_attr "type" "push")
1716    (set_attr "mode" "DI")])
1718 (define_insn "*push<mode>2"
1719   [(set (match_operand:SWI12 0 "push_operand" "=X")
1720         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1721   "!TARGET_64BIT"
1722   "push{l}\t%k1"
1723   [(set_attr "type" "push")
1724    (set_attr "mode" "SI")])
1726 (define_insn "*push<mode>2_prologue"
1727   [(set (match_operand:W 0 "push_operand" "=<")
1728         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1729    (clobber (mem:BLK (scratch)))]
1730   ""
1731   "push{<imodesuffix>}\t%1"
1732   [(set_attr "type" "push")
1733    (set_attr "mode" "<MODE>")])
1735 (define_insn "*pop<mode>1"
1736   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1737         (match_operand:W 1 "pop_operand" ">"))]
1738   ""
1739   "pop{<imodesuffix>}\t%0"
1740   [(set_attr "type" "pop")
1741    (set_attr "mode" "<MODE>")])
1743 (define_insn "*pop<mode>1_epilogue"
1744   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1745         (match_operand:W 1 "pop_operand" ">"))
1746    (clobber (mem:BLK (scratch)))]
1747   ""
1748   "pop{<imodesuffix>}\t%0"
1749   [(set_attr "type" "pop")
1750    (set_attr "mode" "<MODE>")])
1752 (define_insn "*pushfl<mode>2"
1753   [(set (match_operand:W 0 "push_operand" "=<")
1754         (match_operand:W 1 "flags_reg_operand"))]
1755   ""
1756   "pushf{<imodesuffix>}"
1757   [(set_attr "type" "push")
1758    (set_attr "mode" "<MODE>")])
1760 (define_insn "*popfl<mode>1"
1761   [(set (match_operand:W 0 "flags_reg_operand")
1762         (match_operand:W 1 "pop_operand" ">"))]
1763   ""
1764   "popf{<imodesuffix>}"
1765   [(set_attr "type" "pop")
1766    (set_attr "mode" "<MODE>")])
1769 ;; Move instructions.
1771 (define_expand "movxi"
1772   [(set (match_operand:XI 0 "nonimmediate_operand")
1773         (match_operand:XI 1 "general_operand"))]
1774   "TARGET_AVX512F"
1775   "ix86_expand_move (XImode, operands); DONE;")
1777 ;; Reload patterns to support multi-word load/store
1778 ;; with non-offsetable address.
1779 (define_expand "reload_noff_store"
1780   [(parallel [(match_operand 0 "memory_operand" "=m")
1781               (match_operand 1 "register_operand" "r")
1782               (match_operand:DI 2 "register_operand" "=&r")])]
1783   "TARGET_64BIT"
1785   rtx mem = operands[0];
1786   rtx addr = XEXP (mem, 0);
1788   emit_move_insn (operands[2], addr);
1789   mem = replace_equiv_address_nv (mem, operands[2]);
1791   emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1792   DONE;
1795 (define_expand "reload_noff_load"
1796   [(parallel [(match_operand 0 "register_operand" "=r")
1797               (match_operand 1 "memory_operand" "m")
1798               (match_operand:DI 2 "register_operand" "=r")])]
1799   "TARGET_64BIT"
1801   rtx mem = operands[1];
1802   rtx addr = XEXP (mem, 0);
1804   emit_move_insn (operands[2], addr);
1805   mem = replace_equiv_address_nv (mem, operands[2]);
1807   emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1808   DONE;
1811 (define_expand "movoi"
1812   [(set (match_operand:OI 0 "nonimmediate_operand")
1813         (match_operand:OI 1 "general_operand"))]
1814   "TARGET_AVX"
1815   "ix86_expand_move (OImode, operands); DONE;")
1817 (define_expand "movti"
1818   [(set (match_operand:TI 0 "nonimmediate_operand")
1819         (match_operand:TI 1 "nonimmediate_operand"))]
1820   "TARGET_64BIT || TARGET_SSE"
1822   if (TARGET_64BIT)
1823     ix86_expand_move (TImode, operands);
1824   else
1825     ix86_expand_vector_move (TImode, operands);
1826   DONE;
1829 ;; This expands to what emit_move_complex would generate if we didn't
1830 ;; have a movti pattern.  Having this avoids problems with reload on
1831 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1832 ;; to have around all the time.
1833 (define_expand "movcdi"
1834   [(set (match_operand:CDI 0 "nonimmediate_operand")
1835         (match_operand:CDI 1 "general_operand"))]
1836   ""
1838   if (push_operand (operands[0], CDImode))
1839     emit_move_complex_push (CDImode, operands[0], operands[1]);
1840   else
1841     emit_move_complex_parts (operands[0], operands[1]);
1842   DONE;
1845 (define_expand "mov<mode>"
1846   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1847         (match_operand:SWI1248x 1 "general_operand"))]
1848   ""
1849   "ix86_expand_move (<MODE>mode, operands); DONE;")
1851 (define_insn "*mov<mode>_xor"
1852   [(set (match_operand:SWI48 0 "register_operand" "=r")
1853         (match_operand:SWI48 1 "const0_operand"))
1854    (clobber (reg:CC FLAGS_REG))]
1855   "reload_completed"
1856   "xor{l}\t%k0, %k0"
1857   [(set_attr "type" "alu1")
1858    (set_attr "mode" "SI")
1859    (set_attr "length_immediate" "0")])
1861 (define_insn "*mov<mode>_or"
1862   [(set (match_operand:SWI48 0 "register_operand" "=r")
1863         (match_operand:SWI48 1 "const_int_operand"))
1864    (clobber (reg:CC FLAGS_REG))]
1865   "reload_completed
1866    && operands[1] == constm1_rtx"
1867   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1868   [(set_attr "type" "alu1")
1869    (set_attr "mode" "<MODE>")
1870    (set_attr "length_immediate" "1")])
1872 (define_insn "*movxi_internal_avx512f"
1873   [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1874         (match_operand:XI 1 "vector_move_operand"  "C ,xm,x"))]
1875   "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1877   switch (which_alternative)
1878     {
1879     case 0:
1880       return standard_sse_constant_opcode (insn, operands[1]);
1881     case 1:
1882     case 2:
1883       if (misaligned_operand (operands[0], XImode)
1884           || misaligned_operand (operands[1], XImode))
1885         return "vmovdqu32\t{%1, %0|%0, %1}";
1886       else
1887         return "vmovdqa32\t{%1, %0|%0, %1}";
1888     default:
1889       gcc_unreachable ();
1890     }
1892   [(set_attr "type" "sselog1,ssemov,ssemov")
1893    (set_attr "prefix" "evex")
1894    (set_attr "mode" "XI")])
1896 (define_insn "*movoi_internal_avx"
1897   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1898         (match_operand:OI 1 "vector_move_operand"  "C ,xm,x"))]
1899   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1901   switch (get_attr_type (insn))
1902     {
1903     case TYPE_SSELOG1:
1904       return standard_sse_constant_opcode (insn, operands[1]);
1906     case TYPE_SSEMOV:
1907       if (misaligned_operand (operands[0], OImode)
1908           || misaligned_operand (operands[1], OImode))
1909         {
1910           if (get_attr_mode (insn) == MODE_V8SF)
1911             return "vmovups\t{%1, %0|%0, %1}";
1912           else
1913             return "vmovdqu\t{%1, %0|%0, %1}";
1914         }
1915       else
1916         {
1917           if (get_attr_mode (insn) == MODE_V8SF)
1918             return "vmovaps\t{%1, %0|%0, %1}";
1919           else
1920             return "vmovdqa\t{%1, %0|%0, %1}";
1921         }
1923     default:
1924       gcc_unreachable ();
1925     }
1927   [(set_attr "type" "sselog1,ssemov,ssemov")
1928    (set_attr "prefix" "vex")
1929    (set (attr "mode")
1930         (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1931                  (const_string "V8SF")
1932                (and (eq_attr "alternative" "2")
1933                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1934                  (const_string "V8SF")
1935               ]
1936               (const_string "OI")))])
1938 (define_insn "*movti_internal"
1939   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1940         (match_operand:TI 1 "general_operand"      "riFo,re,C,xm,x"))]
1941   "(TARGET_64BIT || TARGET_SSE)
1942    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1944   switch (get_attr_type (insn))
1945     {
1946     case TYPE_MULTI:
1947       return "#";
1949     case TYPE_SSELOG1:
1950       return standard_sse_constant_opcode (insn, operands[1]);
1952     case TYPE_SSEMOV:
1953       /* TDmode values are passed as TImode on the stack.  Moving them
1954          to stack may result in unaligned memory access.  */
1955       if (misaligned_operand (operands[0], TImode)
1956           || misaligned_operand (operands[1], TImode))
1957         {
1958           if (get_attr_mode (insn) == MODE_V4SF)
1959             return "%vmovups\t{%1, %0|%0, %1}";
1960           else
1961             return "%vmovdqu\t{%1, %0|%0, %1}";
1962         }
1963       else
1964         {
1965           if (get_attr_mode (insn) == MODE_V4SF)
1966             return "%vmovaps\t{%1, %0|%0, %1}";
1967           else
1968             return "%vmovdqa\t{%1, %0|%0, %1}";
1969         }
1971     default:
1972       gcc_unreachable ();
1973     }
1975   [(set_attr "isa" "x64,x64,*,*,*")
1976    (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
1977    (set (attr "prefix")
1978      (if_then_else (eq_attr "type" "sselog1,ssemov")
1979        (const_string "maybe_vex")
1980        (const_string "orig")))
1981    (set (attr "mode")
1982         (cond [(eq_attr "alternative" "0,1")
1983                  (const_string "DI")
1984                (ior (not (match_test "TARGET_SSE2"))
1985                     (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1986                  (const_string "V4SF")
1987                (and (eq_attr "alternative" "4")
1988                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1989                  (const_string "V4SF")
1990                (match_test "TARGET_AVX")
1991                  (const_string "TI")
1992                (match_test "optimize_function_for_size_p (cfun)")
1993                  (const_string "V4SF")
1994                ]
1995                (const_string "TI")))])
1997 (define_split
1998   [(set (match_operand:TI 0 "nonimmediate_operand")
1999         (match_operand:TI 1 "general_operand"))]
2000   "reload_completed
2001    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2002   [(const_int 0)]
2003   "ix86_split_long_move (operands); DONE;")
2005 (define_insn "*movdi_internal"
2006   [(set (match_operand:DI 0 "nonimmediate_operand"
2007     "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi")
2008         (match_operand:DI 1 "general_operand"
2009     "riFo,riF,Z,rem,i,re,C ,*y,m  ,*y,*Yn,r   ,C ,*v,m ,*v,*Yj,*v,r   ,*Yj ,*Yn"))]
2010   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2012   switch (get_attr_type (insn))
2013     {
2014     case TYPE_MULTI:
2015       return "#";
2017     case TYPE_MMX:
2018       return "pxor\t%0, %0";
2020     case TYPE_MMXMOV:
2021       /* Handle broken assemblers that require movd instead of movq.  */
2022       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2023           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2024         return "movd\t{%1, %0|%0, %1}";
2025       return "movq\t{%1, %0|%0, %1}";
2027     case TYPE_SSELOG1:
2028       if (GENERAL_REG_P (operands[0]))
2029         return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2031       return standard_sse_constant_opcode (insn, operands[1]);
2033     case TYPE_SSEMOV:
2034       switch (get_attr_mode (insn))
2035         {
2036         case MODE_DI:
2037           /* Handle broken assemblers that require movd instead of movq.  */
2038           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2039               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2040             return "%vmovd\t{%1, %0|%0, %1}";
2041           return "%vmovq\t{%1, %0|%0, %1}";
2042         case MODE_TI:
2043           return "%vmovdqa\t{%1, %0|%0, %1}";
2044         case MODE_XI:
2045           return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2047         case MODE_V2SF:
2048           gcc_assert (!TARGET_AVX);
2049           return "movlps\t{%1, %0|%0, %1}";
2050         case MODE_V4SF:
2051           return "%vmovaps\t{%1, %0|%0, %1}";
2053         default:
2054           gcc_unreachable ();
2055         }
2057     case TYPE_SSECVT:
2058       if (SSE_REG_P (operands[0]))
2059         return "movq2dq\t{%1, %0|%0, %1}";
2060       else
2061         return "movdq2q\t{%1, %0|%0, %1}";
2063     case TYPE_LEA:
2064       return "lea{q}\t{%E1, %0|%0, %E1}";
2066     case TYPE_IMOV:
2067       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2068       if (get_attr_mode (insn) == MODE_SI)
2069         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2070       else if (which_alternative == 4)
2071         return "movabs{q}\t{%1, %0|%0, %1}";
2072       else if (ix86_use_lea_for_mov (insn, operands))
2073         return "lea{q}\t{%E1, %0|%0, %E1}";
2074       else
2075         return "mov{q}\t{%1, %0|%0, %1}";
2077     default:
2078       gcc_unreachable ();
2079     }
2081   [(set (attr "isa")
2082      (cond [(eq_attr "alternative" "0,1")
2083               (const_string "nox64")
2084             (eq_attr "alternative" "2,3,4,5,10,11,16,18")
2085               (const_string "x64")
2086             (eq_attr "alternative" "17")
2087               (const_string "x64_sse4")
2088            ]
2089            (const_string "*")))
2090    (set (attr "type")
2091      (cond [(eq_attr "alternative" "0,1")
2092               (const_string "multi")
2093             (eq_attr "alternative" "6")
2094               (const_string "mmx")
2095             (eq_attr "alternative" "7,8,9,10,11")
2096               (const_string "mmxmov")
2097             (eq_attr "alternative" "12,17")
2098               (const_string "sselog1")
2099             (eq_attr "alternative" "13,14,15,16,18")
2100               (const_string "ssemov")
2101             (eq_attr "alternative" "19,20")
2102               (const_string "ssecvt")
2103             (match_operand 1 "pic_32bit_operand")
2104               (const_string "lea")
2105            ]
2106            (const_string "imov")))
2107    (set (attr "modrm")
2108      (if_then_else
2109        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2110          (const_string "0")
2111          (const_string "*")))
2112    (set (attr "length_immediate")
2113      (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2114               (const_string "8")
2115             (eq_attr "alternative" "17")
2116               (const_string "1")
2117            ]
2118            (const_string "*")))
2119    (set (attr "prefix_rex")
2120      (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2121        (const_string "1")
2122        (const_string "*")))
2123    (set (attr "prefix_extra")
2124      (if_then_else (eq_attr "alternative" "17")
2125        (const_string "1")
2126        (const_string "*")))
2127    (set (attr "prefix")
2128      (if_then_else (eq_attr "type" "sselog1,ssemov")
2129        (const_string "maybe_vex")
2130        (const_string "orig")))
2131    (set (attr "prefix_data16")
2132      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2133        (const_string "1")
2134        (const_string "*")))
2135    (set (attr "mode")
2136      (cond [(eq_attr "alternative" "2")
2137               (const_string "SI")
2138             (eq_attr "alternative" "12,13")
2139               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2140                           (match_operand 1 "ext_sse_reg_operand"))
2141                        (const_string "XI")
2142                      (ior (not (match_test "TARGET_SSE2"))
2143                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2144                        (const_string "V4SF")
2145                      (match_test "TARGET_AVX")
2146                        (const_string "TI")
2147                      (match_test "optimize_function_for_size_p (cfun)")
2148                        (const_string "V4SF")
2149                     ]
2150                     (const_string "TI"))
2152             (and (eq_attr "alternative" "14,15")
2153                  (not (match_test "TARGET_SSE2")))
2154               (const_string "V2SF")
2155             (eq_attr "alternative" "17")
2156               (const_string "TI")
2157            ]
2158            (const_string "DI")))])
2160 (define_split
2161   [(set (match_operand:DI 0 "nonimmediate_operand")
2162         (match_operand:DI 1 "general_operand"))]
2163   "!TARGET_64BIT && reload_completed
2164    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2165    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2166   [(const_int 0)]
2167   "ix86_split_long_move (operands); DONE;")
2169 (define_insn "*movsi_internal"
2170   [(set (match_operand:SI 0 "nonimmediate_operand"
2171                         "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi")
2172         (match_operand:SI 1 "general_operand"
2173                         "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r"))]
2174   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2176   switch (get_attr_type (insn))
2177     {
2178     case TYPE_SSELOG1:
2179       if (GENERAL_REG_P (operands[0]))
2180         return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2182       return standard_sse_constant_opcode (insn, operands[1]);
2184     case TYPE_SSEMOV:
2185       switch (get_attr_mode (insn))
2186         {
2187         case MODE_SI:
2188           return "%vmovd\t{%1, %0|%0, %1}";
2189         case MODE_TI:
2190           return "%vmovdqa\t{%1, %0|%0, %1}";
2191         case MODE_XI:
2192           return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2194         case MODE_V4SF:
2195           return "%vmovaps\t{%1, %0|%0, %1}";
2197         case MODE_SF:
2198           gcc_assert (!TARGET_AVX);
2199           return "movss\t{%1, %0|%0, %1}";
2201         default:
2202           gcc_unreachable ();
2203         }
2205     case TYPE_MMX:
2206       return "pxor\t%0, %0";
2208     case TYPE_MMXMOV:
2209       switch (get_attr_mode (insn))
2210         {
2211         case MODE_DI:
2212           return "movq\t{%1, %0|%0, %1}";
2213         case MODE_SI:
2214           return "movd\t{%1, %0|%0, %1}";
2216         default:
2217           gcc_unreachable ();
2218         }
2220     case TYPE_LEA:
2221       return "lea{l}\t{%E1, %0|%0, %E1}";
2223     case TYPE_IMOV:
2224       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2225       if (ix86_use_lea_for_mov (insn, operands))
2226         return "lea{l}\t{%E1, %0|%0, %E1}";
2227       else
2228         return "mov{l}\t{%1, %0|%0, %1}";
2230     default:
2231       gcc_unreachable ();
2232     }
2234   [(set (attr "isa")
2235      (if_then_else (eq_attr "alternative" "11")
2236        (const_string "sse4")
2237        (const_string "*")))
2238    (set (attr "type")
2239      (cond [(eq_attr "alternative" "2")
2240               (const_string "mmx")
2241             (eq_attr "alternative" "3,4,5")
2242               (const_string "mmxmov")
2243             (eq_attr "alternative" "6,11")
2244               (const_string "sselog1")
2245             (eq_attr "alternative" "7,8,9,10,12")
2246               (const_string "ssemov")
2247             (match_operand 1 "pic_32bit_operand")
2248               (const_string "lea")
2249            ]
2250            (const_string "imov")))
2251    (set (attr "length_immediate")
2252      (if_then_else (eq_attr "alternative" "11")
2253        (const_string "1")
2254        (const_string "*")))
2255    (set (attr "prefix_extra")
2256      (if_then_else (eq_attr "alternative" "11")
2257        (const_string "1")
2258        (const_string "*")))
2259    (set (attr "prefix")
2260      (if_then_else (eq_attr "type" "sselog1,ssemov")
2261        (const_string "maybe_vex")
2262        (const_string "orig")))
2263    (set (attr "prefix_data16")
2264      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2265        (const_string "1")
2266        (const_string "*")))
2267    (set (attr "mode")
2268      (cond [(eq_attr "alternative" "2,3")
2269               (const_string "DI")
2270             (eq_attr "alternative" "6,7")
2271               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2272                           (match_operand 1 "ext_sse_reg_operand"))
2273                        (const_string "XI")
2274                      (ior (not (match_test "TARGET_SSE2"))
2275                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2276                        (const_string "V4SF")
2277                      (match_test "TARGET_AVX")
2278                        (const_string "TI")
2279                      (match_test "optimize_function_for_size_p (cfun)")
2280                        (const_string "V4SF")
2281                     ]
2282                     (const_string "TI"))
2284             (and (eq_attr "alternative" "8,9")
2285                  (not (match_test "TARGET_SSE2")))
2286               (const_string "SF")
2287             (eq_attr "alternative" "11")
2288               (const_string "TI")
2289            ]
2290            (const_string "SI")))])
2292 (define_insn "kmovw"
2293   [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2294         (unspec:HI
2295           [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2296           UNSPEC_KMOV))]
2297   "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2298   "@
2299    kmovw\t{%k1, %0|%0, %k1}
2300    kmovw\t{%1, %0|%0, %1}";
2301   [(set_attr "mode" "HI")
2302    (set_attr "type" "mskmov")
2303    (set_attr "prefix" "vex")])
2306 (define_insn "*movhi_internal"
2307   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2308         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,rm,k,k"))]
2309   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2311   switch (get_attr_type (insn))
2312     {
2313     case TYPE_IMOVX:
2314       /* movzwl is faster than movw on p2 due to partial word stalls,
2315          though not as fast as an aligned movl.  */
2316       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2318     case TYPE_MSKMOV:
2319       switch (which_alternative)
2320         {
2321         case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2322         case 5: return "kmovw\t{%1, %0|%0, %1}";
2323         case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2324         default: gcc_unreachable ();
2325         }
2327     default:
2328       if (get_attr_mode (insn) == MODE_SI)
2329         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2330       else
2331         return "mov{w}\t{%1, %0|%0, %1}";
2332     }
2334   [(set (attr "type")
2335      (cond [(match_test "optimize_function_for_size_p (cfun)")
2336               (const_string "imov")
2337             (and (eq_attr "alternative" "0")
2338                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2339                       (not (match_test "TARGET_HIMODE_MATH"))))
2340               (const_string "imov")
2341             (and (eq_attr "alternative" "1,2")
2342                  (match_operand:HI 1 "aligned_operand"))
2343               (const_string "imov")
2344             (eq_attr "alternative" "4,5,6")
2345               (const_string "mskmov")
2346             (and (match_test "TARGET_MOVX")
2347                  (eq_attr "alternative" "0,2"))
2348               (const_string "imovx")
2349            ]
2350            (const_string "imov")))
2351     (set (attr "prefix")
2352       (if_then_else (eq_attr "alternative" "4,5,6")
2353         (const_string "vex")
2354         (const_string "orig")))
2355     (set (attr "mode")
2356       (cond [(eq_attr "type" "imovx")
2357                (const_string "SI")
2358              (and (eq_attr "alternative" "1,2")
2359                   (match_operand:HI 1 "aligned_operand"))
2360                (const_string "SI")
2361              (and (eq_attr "alternative" "0")
2362                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2363                        (not (match_test "TARGET_HIMODE_MATH"))))
2364                (const_string "SI")
2365             ]
2366             (const_string "HI")))])
2368 ;; Situation is quite tricky about when to choose full sized (SImode) move
2369 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2370 ;; partial register dependency machines (such as AMD Athlon), where QImode
2371 ;; moves issue extra dependency and for partial register stalls machines
2372 ;; that don't use QImode patterns (and QImode move cause stall on the next
2373 ;; instruction).
2375 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2376 ;; register stall machines with, where we use QImode instructions, since
2377 ;; partial register stall can be caused there.  Then we use movzx.
2379 (define_insn "*movqi_internal"
2380   [(set (match_operand:QI 0 "nonimmediate_operand"
2381                         "=q,q ,q ,r,r ,?r,m ,k,k,r")
2382         (match_operand:QI 1 "general_operand"
2383                         "q ,qn,qm,q,rn,qm,qn,r ,k,k"))]
2384   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2386   switch (get_attr_type (insn))
2387     {
2388     case TYPE_IMOVX:
2389       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2390       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2392     case TYPE_MSKMOV:
2393       switch (which_alternative)
2394         {
2395         case 7: return "kmovw\t{%k1, %0|%0, %k1}";
2396         case 8: return "kmovw\t{%1, %0|%0, %1}";
2397         case 9: return "kmovw\t{%1, %k0|%k0, %1}";
2398         default: gcc_unreachable ();
2399         }
2401     default:
2402       if (get_attr_mode (insn) == MODE_SI)
2403         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2404       else
2405         return "mov{b}\t{%1, %0|%0, %1}";
2406     }
2408   [(set (attr "type")
2409      (cond [(and (eq_attr "alternative" "5")
2410                  (not (match_operand:QI 1 "aligned_operand")))
2411               (const_string "imovx")
2412             (match_test "optimize_function_for_size_p (cfun)")
2413               (const_string "imov")
2414             (and (eq_attr "alternative" "3")
2415                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2416                       (not (match_test "TARGET_QIMODE_MATH"))))
2417               (const_string "imov")
2418             (eq_attr "alternative" "3,5")
2419               (const_string "imovx")
2420             (eq_attr "alternative" "7,8,9")
2421               (const_string "mskmov")
2422             (and (match_test "TARGET_MOVX")
2423                  (eq_attr "alternative" "2"))
2424               (const_string "imovx")
2425            ]
2426            (const_string "imov")))
2427    (set (attr "prefix")
2428      (if_then_else (eq_attr "alternative" "7,8,9")
2429        (const_string "vex")
2430        (const_string "orig")))
2431    (set (attr "mode")
2432       (cond [(eq_attr "alternative" "3,4,5")
2433                (const_string "SI")
2434              (eq_attr "alternative" "6")
2435                (const_string "QI")
2436              (eq_attr "type" "imovx")
2437                (const_string "SI")
2438              (and (eq_attr "type" "imov")
2439                   (and (eq_attr "alternative" "0,1")
2440                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2441                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2442                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2443                (const_string "SI")
2444              ;; Avoid partial register stalls when not using QImode arithmetic
2445              (and (eq_attr "type" "imov")
2446                   (and (eq_attr "alternative" "0,1")
2447                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2448                             (not (match_test "TARGET_QIMODE_MATH")))))
2449                (const_string "SI")
2450            ]
2451            (const_string "QI")))])
2453 ;; Stores and loads of ax to arbitrary constant address.
2454 ;; We fake an second form of instruction to force reload to load address
2455 ;; into register when rax is not available
2456 (define_insn "*movabs<mode>_1"
2457   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2458         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2459   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2460   "@
2461    movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2462    mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2463   [(set_attr "type" "imov")
2464    (set_attr "modrm" "0,*")
2465    (set_attr "length_address" "8,0")
2466    (set_attr "length_immediate" "0,*")
2467    (set_attr "memory" "store")
2468    (set_attr "mode" "<MODE>")])
2470 (define_insn "*movabs<mode>_2"
2471   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2472         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2473   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2474   "@
2475    movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2476    mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2477   [(set_attr "type" "imov")
2478    (set_attr "modrm" "0,*")
2479    (set_attr "length_address" "8,0")
2480    (set_attr "length_immediate" "0")
2481    (set_attr "memory" "load")
2482    (set_attr "mode" "<MODE>")])
2484 (define_insn "*swap<mode>"
2485   [(set (match_operand:SWI48 0 "register_operand" "+r")
2486         (match_operand:SWI48 1 "register_operand" "+r"))
2487    (set (match_dup 1)
2488         (match_dup 0))]
2489   ""
2490   "xchg{<imodesuffix>}\t%1, %0"
2491   [(set_attr "type" "imov")
2492    (set_attr "mode" "<MODE>")
2493    (set_attr "pent_pair" "np")
2494    (set_attr "athlon_decode" "vector")
2495    (set_attr "amdfam10_decode" "double")
2496    (set_attr "bdver1_decode" "double")])
2498 (define_insn "*swap<mode>_1"
2499   [(set (match_operand:SWI12 0 "register_operand" "+r")
2500         (match_operand:SWI12 1 "register_operand" "+r"))
2501    (set (match_dup 1)
2502         (match_dup 0))]
2503   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2504   "xchg{l}\t%k1, %k0"
2505   [(set_attr "type" "imov")
2506    (set_attr "mode" "SI")
2507    (set_attr "pent_pair" "np")
2508    (set_attr "athlon_decode" "vector")
2509    (set_attr "amdfam10_decode" "double")
2510    (set_attr "bdver1_decode" "double")])
2512 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2513 ;; is disabled for AMDFAM10
2514 (define_insn "*swap<mode>_2"
2515   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2516         (match_operand:SWI12 1 "register_operand" "+<r>"))
2517    (set (match_dup 1)
2518         (match_dup 0))]
2519   "TARGET_PARTIAL_REG_STALL"
2520   "xchg{<imodesuffix>}\t%1, %0"
2521   [(set_attr "type" "imov")
2522    (set_attr "mode" "<MODE>")
2523    (set_attr "pent_pair" "np")
2524    (set_attr "athlon_decode" "vector")])
2526 (define_expand "movstrict<mode>"
2527   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2528         (match_operand:SWI12 1 "general_operand"))]
2529   ""
2531   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2532     FAIL;
2533   if (GET_CODE (operands[0]) == SUBREG
2534       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2535     FAIL;
2536   /* Don't generate memory->memory moves, go through a register */
2537   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2538     operands[1] = force_reg (<MODE>mode, operands[1]);
2541 (define_insn "*movstrict<mode>_1"
2542   [(set (strict_low_part
2543           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2544         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2545   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2546    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2547   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2548   [(set_attr "type" "imov")
2549    (set_attr "mode" "<MODE>")])
2551 (define_insn "*movstrict<mode>_xor"
2552   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2553         (match_operand:SWI12 1 "const0_operand"))
2554    (clobber (reg:CC FLAGS_REG))]
2555   "reload_completed"
2556   "xor{<imodesuffix>}\t%0, %0"
2557   [(set_attr "type" "alu1")
2558    (set_attr "mode" "<MODE>")
2559    (set_attr "length_immediate" "0")])
2561 (define_insn "*mov<mode>_extv_1"
2562   [(set (match_operand:SWI24 0 "register_operand" "=R")
2563         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2564                             (const_int 8)
2565                             (const_int 8)))]
2566   ""
2567   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2568   [(set_attr "type" "imovx")
2569    (set_attr "mode" "SI")])
2571 (define_insn "*movqi_extv_1"
2572   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2573         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2574                          (const_int 8)
2575                          (const_int 8)))]
2576   ""
2578   switch (get_attr_type (insn))
2579     {
2580     case TYPE_IMOVX:
2581       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2582     default:
2583       return "mov{b}\t{%h1, %0|%0, %h1}";
2584     }
2586   [(set_attr "isa" "*,*,nox64")
2587    (set (attr "type")
2588      (if_then_else (and (match_operand:QI 0 "register_operand")
2589                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2590                              (match_test "TARGET_MOVX")))
2591         (const_string "imovx")
2592         (const_string "imov")))
2593    (set (attr "mode")
2594      (if_then_else (eq_attr "type" "imovx")
2595         (const_string "SI")
2596         (const_string "QI")))])
2598 (define_insn "*mov<mode>_extzv_1"
2599   [(set (match_operand:SWI48 0 "register_operand" "=R")
2600         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2601                             (const_int 8)
2602                             (const_int 8)))]
2603   ""
2604   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2605   [(set_attr "type" "imovx")
2606    (set_attr "mode" "SI")])
2608 (define_insn "*movqi_extzv_2"
2609   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2610         (subreg:QI
2611           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2612                            (const_int 8)
2613                            (const_int 8)) 0))]
2614   ""
2616   switch (get_attr_type (insn))
2617     {
2618     case TYPE_IMOVX:
2619       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2620     default:
2621       return "mov{b}\t{%h1, %0|%0, %h1}";
2622     }
2624   [(set_attr "isa" "*,*,nox64")
2625    (set (attr "type")
2626      (if_then_else (and (match_operand:QI 0 "register_operand")
2627                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2628                              (match_test "TARGET_MOVX")))
2629         (const_string "imovx")
2630         (const_string "imov")))
2631    (set (attr "mode")
2632      (if_then_else (eq_attr "type" "imovx")
2633         (const_string "SI")
2634         (const_string "QI")))])
2636 (define_insn "mov<mode>_insv_1"
2637   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2638                              (const_int 8)
2639                              (const_int 8))
2640         (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2641   ""
2643   if (CONST_INT_P (operands[1]))
2644     operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2645   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2647   [(set_attr "isa" "*,nox64")
2648    (set_attr "type" "imov")
2649    (set_attr "mode" "QI")])
2651 (define_insn "*movqi_insv_2"
2652   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2653                          (const_int 8)
2654                          (const_int 8))
2655         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2656                      (const_int 8)))]
2657   ""
2658   "mov{b}\t{%h1, %h0|%h0, %h1}"
2659   [(set_attr "type" "imov")
2660    (set_attr "mode" "QI")])
2662 ;; Floating point push instructions.
2664 (define_insn "*pushtf"
2665   [(set (match_operand:TF 0 "push_operand" "=<,<")
2666         (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2667   "TARGET_64BIT || TARGET_SSE"
2669   /* This insn should be already split before reg-stack.  */
2670   gcc_unreachable ();
2672   [(set_attr "isa" "*,x64")
2673    (set_attr "type" "multi")
2674    (set_attr "unit" "sse,*")
2675    (set_attr "mode" "TF,DI")])
2677 ;; %%% Kill this when call knows how to work this out.
2678 (define_split
2679   [(set (match_operand:TF 0 "push_operand")
2680         (match_operand:TF 1 "sse_reg_operand"))]
2681   "TARGET_SSE && reload_completed"
2682   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2683    (set (match_dup 0) (match_dup 1))]
2685   /* Preserve memory attributes. */
2686   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2689 (define_insn "*pushxf"
2690   [(set (match_operand:XF 0 "push_operand" "=<,<")
2691         (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2692   ""
2694   /* This insn should be already split before reg-stack.  */
2695   gcc_unreachable ();
2697   [(set_attr "type" "multi")
2698    (set_attr "unit" "i387,*")
2699    (set (attr "mode")
2700         (cond [(eq_attr "alternative" "1")
2701                  (if_then_else (match_test "TARGET_64BIT")
2702                    (const_string "DI")
2703                    (const_string "SI"))
2704               ]
2705               (const_string "XF")))])
2707 ;; %%% Kill this when call knows how to work this out.
2708 (define_split
2709   [(set (match_operand:XF 0 "push_operand")
2710         (match_operand:XF 1 "fp_register_operand"))]
2711   "reload_completed"
2712   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2713    (set (match_dup 0) (match_dup 1))]
2715   operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2716   /* Preserve memory attributes. */
2717   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2720 (define_insn "*pushdf"
2721   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2722         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2723   ""
2725   /* This insn should be already split before reg-stack.  */
2726   gcc_unreachable ();
2728   [(set_attr "isa" "*,nox64,x64,sse2")
2729    (set_attr "type" "multi")
2730    (set_attr "unit" "i387,*,*,sse")
2731    (set_attr "mode" "DF,SI,DI,DF")])
2733 ;; %%% Kill this when call knows how to work this out.
2734 (define_split
2735   [(set (match_operand:DF 0 "push_operand")
2736         (match_operand:DF 1 "any_fp_register_operand"))]
2737   "reload_completed"
2738   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2739    (set (match_dup 0) (match_dup 1))]
2741   /* Preserve memory attributes. */
2742   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2745 (define_insn "*pushsf_rex64"
2746   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2747         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2748   "TARGET_64BIT"
2750   /* Anything else should be already split before reg-stack.  */
2751   gcc_assert (which_alternative == 1);
2752   return "push{q}\t%q1";
2754   [(set_attr "type" "multi,push,multi")
2755    (set_attr "unit" "i387,*,*")
2756    (set_attr "mode" "SF,DI,SF")])
2758 (define_insn "*pushsf"
2759   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2760         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2761   "!TARGET_64BIT"
2763   /* Anything else should be already split before reg-stack.  */
2764   gcc_assert (which_alternative == 1);
2765   return "push{l}\t%1";
2767   [(set_attr "type" "multi,push,multi")
2768    (set_attr "unit" "i387,*,*")
2769    (set_attr "mode" "SF,SI,SF")])
2771 ;; %%% Kill this when call knows how to work this out.
2772 (define_split
2773   [(set (match_operand:SF 0 "push_operand")
2774         (match_operand:SF 1 "any_fp_register_operand"))]
2775   "reload_completed"
2776   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2777    (set (match_dup 0) (match_dup 1))]
2779   rtx op = XEXP (operands[0], 0);
2780   if (GET_CODE (op) == PRE_DEC)
2781     {
2782       gcc_assert (!TARGET_64BIT);
2783       op = GEN_INT (-4);
2784     }
2785   else
2786     {
2787       op = XEXP (XEXP (op, 1), 1);
2788       gcc_assert (CONST_INT_P (op));
2789     }
2790   operands[2] = op;
2791   /* Preserve memory attributes. */
2792   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2795 (define_split
2796   [(set (match_operand:SF 0 "push_operand")
2797         (match_operand:SF 1 "memory_operand"))]
2798   "reload_completed
2799    && (operands[2] = find_constant_src (insn))"
2800   [(set (match_dup 0) (match_dup 2))])
2802 (define_split
2803   [(set (match_operand 0 "push_operand")
2804         (match_operand 1 "general_operand"))]
2805   "reload_completed
2806    && (GET_MODE (operands[0]) == TFmode
2807        || GET_MODE (operands[0]) == XFmode
2808        || GET_MODE (operands[0]) == DFmode)
2809    && !ANY_FP_REG_P (operands[1])"
2810   [(const_int 0)]
2811   "ix86_split_long_move (operands); DONE;")
2813 ;; Floating point move instructions.
2815 (define_expand "movtf"
2816   [(set (match_operand:TF 0 "nonimmediate_operand")
2817         (match_operand:TF 1 "nonimmediate_operand"))]
2818   "TARGET_64BIT || TARGET_SSE"
2819   "ix86_expand_move (TFmode, operands); DONE;")
2821 (define_expand "mov<mode>"
2822   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2823         (match_operand:X87MODEF 1 "general_operand"))]
2824   ""
2825   "ix86_expand_move (<MODE>mode, operands); DONE;")
2827 (define_insn "*movtf_internal"
2828   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2829         (match_operand:TF 1 "general_operand"      "C ,xm,x,*roF,*rC"))]
2830   "(TARGET_64BIT || TARGET_SSE)
2831    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2832    && (!can_create_pseudo_p ()
2833        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2834        || GET_CODE (operands[1]) != CONST_DOUBLE
2835        || (optimize_function_for_size_p (cfun)
2836            && standard_sse_constant_p (operands[1])
2837            && !memory_operand (operands[0], TFmode))
2838        || (!TARGET_MEMORY_MISMATCH_STALL
2839            && memory_operand (operands[0], TFmode)))"
2841   switch (get_attr_type (insn))
2842     {
2843     case TYPE_SSELOG1:
2844       return standard_sse_constant_opcode (insn, operands[1]);
2846     case TYPE_SSEMOV:
2847       /* Handle misaligned load/store since we
2848          don't have movmisaligntf pattern. */
2849       if (misaligned_operand (operands[0], TFmode)
2850           || misaligned_operand (operands[1], TFmode))
2851         {
2852           if (get_attr_mode (insn) == MODE_V4SF)
2853             return "%vmovups\t{%1, %0|%0, %1}";
2854           else
2855             return "%vmovdqu\t{%1, %0|%0, %1}";
2856         }
2857       else
2858         {
2859           if (get_attr_mode (insn) == MODE_V4SF)
2860             return "%vmovaps\t{%1, %0|%0, %1}";
2861           else
2862             return "%vmovdqa\t{%1, %0|%0, %1}";
2863         }
2865     case TYPE_MULTI:
2866         return "#";
2868     default:
2869       gcc_unreachable ();
2870     }
2872   [(set_attr "isa" "*,*,*,x64,x64")
2873    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2874    (set (attr "prefix")
2875      (if_then_else (eq_attr "type" "sselog1,ssemov")
2876        (const_string "maybe_vex")
2877        (const_string "orig")))
2878    (set (attr "mode")
2879         (cond [(eq_attr "alternative" "3,4")
2880                  (const_string "DI")
2881                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2882                  (const_string "V4SF")
2883                (and (eq_attr "alternative" "2")
2884                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2885                  (const_string "V4SF")
2886                (match_test "TARGET_AVX")
2887                  (const_string "TI")
2888                (ior (not (match_test "TARGET_SSE2"))
2889                     (match_test "optimize_function_for_size_p (cfun)"))
2890                  (const_string "V4SF")
2891                ]
2892                (const_string "TI")))])
2894 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2895 (define_insn "*movxf_internal"
2896   [(set (match_operand:XF 0 "nonimmediate_operand"
2897          "=f,m,f,?Yx*r ,!o   ,!o")
2898         (match_operand:XF 1 "general_operand"
2899          "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2900   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2901    && (!can_create_pseudo_p ()
2902        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2903        || GET_CODE (operands[1]) != CONST_DOUBLE
2904        || (optimize_function_for_size_p (cfun)
2905            && standard_80387_constant_p (operands[1]) > 0
2906            && !memory_operand (operands[0], XFmode))
2907        || (!TARGET_MEMORY_MISMATCH_STALL
2908            && memory_operand (operands[0], XFmode)))"
2910   switch (get_attr_type (insn))
2911     {
2912     case TYPE_FMOV:
2913       if (which_alternative == 2)
2914         return standard_80387_constant_opcode (operands[1]);
2915       return output_387_reg_move (insn, operands);
2917     case TYPE_MULTI:
2918       return "#";
2920     default:
2921       gcc_unreachable ();
2922     }
2924   [(set_attr "isa" "*,*,*,*,nox64,x64")
2925    (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
2926    (set (attr "mode")
2927         (cond [(eq_attr "alternative" "3,4,5")
2928                  (if_then_else (match_test "TARGET_64BIT")
2929                    (const_string "DI")
2930                    (const_string "SI"))
2931               ]
2932               (const_string "XF")))])
2934 ;; Possible store forwarding (partial memory) stall in alternative 4.
2935 (define_insn "*movdf_internal"
2936   [(set (match_operand:DF 0 "nonimmediate_operand"
2937     "=Yf*f,m   ,Yf*f,?Yd*r ,!o   ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
2938         (match_operand:DF 1 "general_operand"
2939     "Yf*fm,Yf*f,G   ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
2940   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2941    && (!can_create_pseudo_p ()
2942        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2943        || GET_CODE (operands[1]) != CONST_DOUBLE
2944        || (optimize_function_for_size_p (cfun)
2945            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2946                 && standard_80387_constant_p (operands[1]) > 0)
2947                || (TARGET_SSE2 && TARGET_SSE_MATH
2948                    && standard_sse_constant_p (operands[1])))
2949            && !memory_operand (operands[0], DFmode))
2950        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
2951            && memory_operand (operands[0], DFmode)))"
2953   switch (get_attr_type (insn))
2954     {
2955     case TYPE_FMOV:
2956       if (which_alternative == 2)
2957         return standard_80387_constant_opcode (operands[1]);
2958       return output_387_reg_move (insn, operands);
2960     case TYPE_MULTI:
2961       return "#";
2963     case TYPE_IMOV:
2964       if (get_attr_mode (insn) == MODE_SI)
2965         return "mov{l}\t{%1, %k0|%k0, %1}";
2966       else if (which_alternative == 8)
2967         return "movabs{q}\t{%1, %0|%0, %1}";
2968       else
2969         return "mov{q}\t{%1, %0|%0, %1}";
2971     case TYPE_SSELOG1:
2972       return standard_sse_constant_opcode (insn, operands[1]);
2974     case TYPE_SSEMOV:
2975       switch (get_attr_mode (insn))
2976         {
2977         case MODE_DF:
2978           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2979             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2980           return "%vmovsd\t{%1, %0|%0, %1}";
2982         case MODE_V4SF:
2983           return "%vmovaps\t{%1, %0|%0, %1}";
2984         case MODE_V8DF:
2985           return "vmovapd\t{%g1, %g0|%g0, %g1}";
2986         case MODE_V2DF:
2987           return "%vmovapd\t{%1, %0|%0, %1}";
2989         case MODE_V2SF:
2990           gcc_assert (!TARGET_AVX);
2991           return "movlps\t{%1, %0|%0, %1}";
2992         case MODE_V1DF:
2993           gcc_assert (!TARGET_AVX);
2994           return "movlpd\t{%1, %0|%0, %1}";
2996         case MODE_DI:
2997           /* Handle broken assemblers that require movd instead of movq.  */
2998           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2999               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3000             return "%vmovd\t{%1, %0|%0, %1}";
3001           return "%vmovq\t{%1, %0|%0, %1}";
3003         default:
3004           gcc_unreachable ();
3005         }
3007     default:
3008       gcc_unreachable ();
3009     }
3011   [(set (attr "isa")
3012         (cond [(eq_attr "alternative" "3,4")
3013                  (const_string "nox64")
3014                (eq_attr "alternative" "5,6,7,8,17,18")
3015                  (const_string "x64")
3016                (eq_attr "alternative" "9,10,11,12")
3017                  (const_string "sse2")
3018               ]
3019               (const_string "*")))
3020    (set (attr "type")
3021         (cond [(eq_attr "alternative" "0,1,2")
3022                  (const_string "fmov")
3023                (eq_attr "alternative" "3,4")
3024                  (const_string "multi")
3025                (eq_attr "alternative" "5,6,7,8")
3026                  (const_string "imov")
3027                (eq_attr "alternative" "9,13")
3028                  (const_string "sselog1")
3029               ]
3030               (const_string "ssemov")))
3031    (set (attr "modrm")
3032      (if_then_else (eq_attr "alternative" "8")
3033        (const_string "0")
3034        (const_string "*")))
3035    (set (attr "length_immediate")
3036      (if_then_else (eq_attr "alternative" "8")
3037        (const_string "8")
3038        (const_string "*")))
3039    (set (attr "prefix")
3040      (if_then_else (eq_attr "type" "sselog1,ssemov")
3041        (const_string "maybe_vex")
3042        (const_string "orig")))
3043    (set (attr "prefix_data16")
3044      (if_then_else
3045        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3046             (eq_attr "mode" "V1DF"))
3047        (const_string "1")
3048        (const_string "*")))
3049    (set (attr "mode")
3050         (cond [(eq_attr "alternative" "3,4,7")
3051                  (const_string "SI")
3052                (eq_attr "alternative" "5,6,8,17,18")
3053                  (const_string "DI")
3055                /* xorps is one byte shorter for non-AVX targets.  */
3056                (eq_attr "alternative" "9,13")
3057                  (cond [(not (match_test "TARGET_SSE2"))
3058                           (const_string "V4SF")
3059                         (match_test "TARGET_AVX512F")
3060                           (const_string "XI")
3061                         (match_test "TARGET_AVX")
3062                           (const_string "V2DF")
3063                         (match_test "optimize_function_for_size_p (cfun)")
3064                           (const_string "V4SF")
3065                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3066                           (const_string "TI")
3067                        ]
3068                        (const_string "V2DF"))
3070                /* For architectures resolving dependencies on
3071                   whole SSE registers use movapd to break dependency
3072                   chains, otherwise use short move to avoid extra work.  */
3074                /* movaps is one byte shorter for non-AVX targets.  */
3075                (eq_attr "alternative" "10,14")
3076                  (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3077                              (match_operand 1 "ext_sse_reg_operand"))
3078                           (const_string "V8DF")
3079                         (ior (not (match_test "TARGET_SSE2"))
3080                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3081                           (const_string "V4SF")
3082                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3083                           (const_string "V2DF")
3084                         (match_test "TARGET_AVX")
3085                           (const_string "DF")
3086                         (match_test "optimize_function_for_size_p (cfun)")
3087                           (const_string "V4SF")
3088                        ]
3089                        (const_string "DF"))
3091                /* For architectures resolving dependencies on register
3092                   parts we may avoid extra work to zero out upper part
3093                   of register.  */
3094                (eq_attr "alternative" "11,15")
3095                  (cond [(not (match_test "TARGET_SSE2"))
3096                           (const_string "V2SF")
3097                         (match_test "TARGET_AVX")
3098                           (const_string "DF")
3099                         (match_test "TARGET_SSE_SPLIT_REGS")
3100                           (const_string "V1DF")
3101                        ]
3102                        (const_string "DF"))
3104                (and (eq_attr "alternative" "12,16")
3105                     (not (match_test "TARGET_SSE2")))
3106                  (const_string "V2SF")
3107               ]
3108               (const_string "DF")))])
3110 (define_insn "*movsf_internal"
3111   [(set (match_operand:SF 0 "nonimmediate_operand"
3112           "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3113         (match_operand:SF 1 "general_operand"
3114           "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,Yj,r  ,*y ,m  ,*y,*Yn,r"))]
3115   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3116    && (!can_create_pseudo_p ()
3117        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3118        || GET_CODE (operands[1]) != CONST_DOUBLE
3119        || (optimize_function_for_size_p (cfun)
3120            && ((!TARGET_SSE_MATH
3121                 && standard_80387_constant_p (operands[1]) > 0)
3122                || (TARGET_SSE_MATH
3123                    && standard_sse_constant_p (operands[1]))))
3124        || memory_operand (operands[0], SFmode))"
3126   switch (get_attr_type (insn))
3127     {
3128     case TYPE_FMOV:
3129       if (which_alternative == 2)
3130         return standard_80387_constant_opcode (operands[1]);
3131       return output_387_reg_move (insn, operands);
3133     case TYPE_IMOV:
3134       return "mov{l}\t{%1, %0|%0, %1}";
3136     case TYPE_SSELOG1:
3137       return standard_sse_constant_opcode (insn, operands[1]);
3139     case TYPE_SSEMOV:
3140       switch (get_attr_mode (insn))
3141         {
3142         case MODE_SF:
3143           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3144             return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3145           return "%vmovss\t{%1, %0|%0, %1}";
3147         case MODE_V16SF:
3148           return "vmovaps\t{%g1, %g0|%g0, %g1}";
3149         case MODE_V4SF:
3150           return "%vmovaps\t{%1, %0|%0, %1}";
3152         case MODE_SI:
3153           return "%vmovd\t{%1, %0|%0, %1}";
3155         default:
3156           gcc_unreachable ();
3157         }
3159     case TYPE_MMXMOV:
3160       switch (get_attr_mode (insn))
3161         {
3162         case MODE_DI:
3163           return "movq\t{%1, %0|%0, %1}";
3164         case MODE_SI:
3165           return "movd\t{%1, %0|%0, %1}";
3167         default:
3168           gcc_unreachable ();
3169         }
3171     default:
3172       gcc_unreachable ();
3173     }
3175   [(set (attr "type")
3176         (cond [(eq_attr "alternative" "0,1,2")
3177                  (const_string "fmov")
3178                (eq_attr "alternative" "3,4")
3179                  (const_string "imov")
3180                (eq_attr "alternative" "5")
3181                  (const_string "sselog1")
3182                (eq_attr "alternative" "11,12,13,14,15")
3183                  (const_string "mmxmov")
3184               ]
3185               (const_string "ssemov")))
3186    (set (attr "prefix")
3187      (if_then_else (eq_attr "type" "sselog1,ssemov")
3188        (const_string "maybe_vex")
3189        (const_string "orig")))
3190    (set (attr "prefix_data16")
3191      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3192        (const_string "1")
3193        (const_string "*")))
3194    (set (attr "mode")
3195         (cond [(eq_attr "alternative" "3,4,9,10,13,14,15")
3196                  (const_string "SI")
3197                (eq_attr "alternative" "11")
3198                  (const_string "DI")
3199                (eq_attr "alternative" "5")
3200                  (cond [(not (match_test "TARGET_SSE2"))
3201                           (const_string "V4SF")
3202                         (match_test "TARGET_AVX512F")
3203                           (const_string "V16SF")
3204                         (match_test "TARGET_AVX")
3205                           (const_string "V4SF")
3206                         (match_test "optimize_function_for_size_p (cfun)")
3207                           (const_string "V4SF")
3208                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3209                           (const_string "TI")
3210                        ]
3211                        (const_string "V4SF"))
3213                /* For architectures resolving dependencies on
3214                   whole SSE registers use APS move to break dependency
3215                   chains, otherwise use short move to avoid extra work.
3217                   Do the same for architectures resolving dependencies on
3218                   the parts.  While in DF mode it is better to always handle
3219                   just register parts, the SF mode is different due to lack
3220                   of instructions to load just part of the register.  It is
3221                   better to maintain the whole registers in single format
3222                   to avoid problems on using packed logical operations.  */
3223                (eq_attr "alternative" "6")
3224                  (cond [(ior  (match_operand 0 "ext_sse_reg_operand")
3225                               (match_operand 1 "ext_sse_reg_operand"))
3226                           (const_string "V16SF")
3227                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3228                              (match_test "TARGET_SSE_SPLIT_REGS"))
3229                           (const_string "V4SF")
3230                        ]
3231                        (const_string "SF"))
3232               ]
3233               (const_string "SF")))])
3235 (define_split
3236   [(set (match_operand 0 "any_fp_register_operand")
3237         (match_operand 1 "memory_operand"))]
3238   "reload_completed
3239    && (GET_MODE (operands[0]) == TFmode
3240        || GET_MODE (operands[0]) == XFmode
3241        || GET_MODE (operands[0]) == DFmode
3242        || GET_MODE (operands[0]) == SFmode)
3243    && (operands[2] = find_constant_src (insn))"
3244   [(set (match_dup 0) (match_dup 2))]
3246   rtx c = operands[2];
3247   int r = REGNO (operands[0]);
3249   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3250       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3251     FAIL;
3254 (define_split
3255   [(set (match_operand 0 "any_fp_register_operand")
3256         (float_extend (match_operand 1 "memory_operand")))]
3257   "reload_completed
3258    && (GET_MODE (operands[0]) == TFmode
3259        || GET_MODE (operands[0]) == XFmode
3260        || GET_MODE (operands[0]) == DFmode)
3261    && (operands[2] = find_constant_src (insn))"
3262   [(set (match_dup 0) (match_dup 2))]
3264   rtx c = operands[2];
3265   int r = REGNO (operands[0]);
3267   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3268       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3269     FAIL;
3272 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3273 (define_split
3274   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3275         (match_operand:X87MODEF 1 "immediate_operand"))]
3276   "reload_completed
3277    && (standard_80387_constant_p (operands[1]) == 8
3278        || standard_80387_constant_p (operands[1]) == 9)"
3279   [(set (match_dup 0)(match_dup 1))
3280    (set (match_dup 0)
3281         (neg:X87MODEF (match_dup 0)))]
3283   REAL_VALUE_TYPE r;
3285   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3286   if (real_isnegzero (&r))
3287     operands[1] = CONST0_RTX (<MODE>mode);
3288   else
3289     operands[1] = CONST1_RTX (<MODE>mode);
3292 (define_split
3293   [(set (match_operand 0 "nonimmediate_operand")
3294         (match_operand 1 "general_operand"))]
3295   "reload_completed
3296    && (GET_MODE (operands[0]) == TFmode
3297        || GET_MODE (operands[0]) == XFmode
3298        || GET_MODE (operands[0]) == DFmode)
3299    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3300   [(const_int 0)]
3301   "ix86_split_long_move (operands); DONE;")
3303 (define_insn "swapxf"
3304   [(set (match_operand:XF 0 "register_operand" "+f")
3305         (match_operand:XF 1 "register_operand" "+f"))
3306    (set (match_dup 1)
3307         (match_dup 0))]
3308   "TARGET_80387"
3310   if (STACK_TOP_P (operands[0]))
3311     return "fxch\t%1";
3312   else
3313     return "fxch\t%0";
3315   [(set_attr "type" "fxch")
3316    (set_attr "mode" "XF")])
3318 (define_insn "*swap<mode>"
3319   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3320         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3321    (set (match_dup 1)
3322         (match_dup 0))]
3323   "TARGET_80387 || reload_completed"
3325   if (STACK_TOP_P (operands[0]))
3326     return "fxch\t%1";
3327   else
3328     return "fxch\t%0";
3330   [(set_attr "type" "fxch")
3331    (set_attr "mode" "<MODE>")])
3333 ;; Zero extension instructions
3335 (define_expand "zero_extendsidi2"
3336   [(set (match_operand:DI 0 "nonimmediate_operand")
3337         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3339 (define_insn "*zero_extendsidi2"
3340   [(set (match_operand:DI 0 "nonimmediate_operand"
3341                         "=r,?r,?o,r   ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3342         (zero_extend:DI
3343          (match_operand:SI 1 "x86_64_zext_operand"
3344                         "0 ,rm,r ,rmWz,0,r   ,m   ,*Yj,*x,r   ,m")))]
3345   ""
3347   switch (get_attr_type (insn))
3348     {
3349     case TYPE_IMOVX:
3350       if (ix86_use_lea_for_mov (insn, operands))
3351         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3352       else
3353         return "mov{l}\t{%1, %k0|%k0, %1}";
3355     case TYPE_MULTI:
3356       return "#";
3358     case TYPE_MMXMOV:
3359       return "movd\t{%1, %0|%0, %1}";
3361     case TYPE_SSELOG1:
3362       return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3364     case TYPE_SSEMOV:
3365       if (GENERAL_REG_P (operands[0]))
3366         return "%vmovd\t{%1, %k0|%k0, %1}";
3368       return "%vmovd\t{%1, %0|%0, %1}";
3370     default:
3371       gcc_unreachable ();
3372     }
3374   [(set (attr "isa")
3375      (cond [(eq_attr "alternative" "0,1,2")
3376               (const_string "nox64")
3377             (eq_attr "alternative" "3,7")
3378               (const_string "x64")
3379             (eq_attr "alternative" "8")
3380               (const_string "x64_sse4")
3381             (eq_attr "alternative" "10")
3382               (const_string "sse2")
3383            ]
3384            (const_string "*")))
3385    (set (attr "type")
3386      (cond [(eq_attr "alternative" "0,1,2,4")
3387               (const_string "multi")
3388             (eq_attr "alternative" "5,6")
3389               (const_string "mmxmov")
3390             (eq_attr "alternative" "7,9,10")
3391               (const_string "ssemov")
3392             (eq_attr "alternative" "8")
3393               (const_string "sselog1")
3394            ]
3395            (const_string "imovx")))
3396    (set (attr "prefix_extra")
3397      (if_then_else (eq_attr "alternative" "8")
3398        (const_string "1")
3399        (const_string "*")))
3400    (set (attr "length_immediate")
3401      (if_then_else (eq_attr "alternative" "8")
3402        (const_string "1")
3403        (const_string "*")))
3404    (set (attr "prefix")
3405      (if_then_else (eq_attr "type" "ssemov,sselog1")
3406        (const_string "maybe_vex")
3407        (const_string "orig")))
3408    (set (attr "prefix_0f")
3409      (if_then_else (eq_attr "type" "imovx")
3410        (const_string "0")
3411        (const_string "*")))
3412    (set (attr "mode")
3413      (cond [(eq_attr "alternative" "5,6")
3414               (const_string "DI")
3415             (eq_attr "alternative" "7,8,9")
3416               (const_string "TI")
3417            ]
3418            (const_string "SI")))])
3420 (define_split
3421   [(set (match_operand:DI 0 "memory_operand")
3422         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3423   "reload_completed"
3424   [(set (match_dup 4) (const_int 0))]
3425   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3427 (define_split
3428   [(set (match_operand:DI 0 "register_operand")
3429         (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3430   "!TARGET_64BIT && reload_completed
3431    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3432    && true_regnum (operands[0]) == true_regnum (operands[1])"
3433   [(set (match_dup 4) (const_int 0))]
3434   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3436 (define_split
3437   [(set (match_operand:DI 0 "nonimmediate_operand")
3438         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3439   "!TARGET_64BIT && reload_completed
3440    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3441    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3442   [(set (match_dup 3) (match_dup 1))
3443    (set (match_dup 4) (const_int 0))]
3444   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3446 (define_insn "zero_extend<mode>di2"
3447   [(set (match_operand:DI 0 "register_operand" "=r")
3448         (zero_extend:DI
3449          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3450   "TARGET_64BIT"
3451   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3452   [(set_attr "type" "imovx")
3453    (set_attr "mode" "SI")])
3455 (define_expand "zero_extend<mode>si2"
3456   [(set (match_operand:SI 0 "register_operand")
3457         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3458   ""
3460   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3461     {
3462       operands[1] = force_reg (<MODE>mode, operands[1]);
3463       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3464       DONE;
3465     }
3468 (define_insn_and_split "zero_extend<mode>si2_and"
3469   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3470         (zero_extend:SI
3471           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3472    (clobber (reg:CC FLAGS_REG))]
3473   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3474   "#"
3475   "&& reload_completed"
3476   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3477               (clobber (reg:CC FLAGS_REG))])]
3479   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3480     {
3481       ix86_expand_clear (operands[0]);
3483       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3484       emit_insn (gen_movstrict<mode>
3485                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3486       DONE;
3487     }
3489   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3491   [(set_attr "type" "alu1")
3492    (set_attr "mode" "SI")])
3494 (define_insn "*zero_extend<mode>si2"
3495   [(set (match_operand:SI 0 "register_operand" "=r")
3496         (zero_extend:SI
3497           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3498   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3499   "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3500   [(set_attr "type" "imovx")
3501    (set_attr "mode" "SI")])
3503 (define_expand "zero_extendqihi2"
3504   [(set (match_operand:HI 0 "register_operand")
3505         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3506   ""
3508   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3509     {
3510       operands[1] = force_reg (QImode, operands[1]);
3511       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3512       DONE;
3513     }
3516 (define_insn_and_split "zero_extendqihi2_and"
3517   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3518         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3519    (clobber (reg:CC FLAGS_REG))]
3520   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3521   "#"
3522   "&& reload_completed"
3523   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3524               (clobber (reg:CC FLAGS_REG))])]
3526   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3527     {
3528       ix86_expand_clear (operands[0]);
3530       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3531       emit_insn (gen_movstrictqi
3532                   (gen_lowpart (QImode, operands[0]), operands[1]));
3533       DONE;
3534     }
3536   operands[0] = gen_lowpart (SImode, operands[0]);
3538   [(set_attr "type" "alu1")
3539    (set_attr "mode" "SI")])
3541 ; zero extend to SImode to avoid partial register stalls
3542 (define_insn "*zero_extendqihi2"
3543   [(set (match_operand:HI 0 "register_operand" "=r")
3544         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3545   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3546   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3547   [(set_attr "type" "imovx")
3548    (set_attr "mode" "SI")])
3550 ;; Sign extension instructions
3552 (define_expand "extendsidi2"
3553   [(set (match_operand:DI 0 "register_operand")
3554         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3555   ""
3557   if (!TARGET_64BIT)
3558     {
3559       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3560       DONE;
3561     }
3564 (define_insn "*extendsidi2_rex64"
3565   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3566         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3567   "TARGET_64BIT"
3568   "@
3569    {cltq|cdqe}
3570    movs{lq|x}\t{%1, %0|%0, %1}"
3571   [(set_attr "type" "imovx")
3572    (set_attr "mode" "DI")
3573    (set_attr "prefix_0f" "0")
3574    (set_attr "modrm" "0,1")])
3576 (define_insn "extendsidi2_1"
3577   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3578         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3579    (clobber (reg:CC FLAGS_REG))
3580    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3581   "!TARGET_64BIT"
3582   "#")
3584 ;; Split the memory case.  If the source register doesn't die, it will stay
3585 ;; this way, if it does die, following peephole2s take care of it.
3586 (define_split
3587   [(set (match_operand:DI 0 "memory_operand")
3588         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3589    (clobber (reg:CC FLAGS_REG))
3590    (clobber (match_operand:SI 2 "register_operand"))]
3591   "reload_completed"
3592   [(const_int 0)]
3594   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3596   emit_move_insn (operands[3], operands[1]);
3598   /* Generate a cltd if possible and doing so it profitable.  */
3599   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3600       && true_regnum (operands[1]) == AX_REG
3601       && true_regnum (operands[2]) == DX_REG)
3602     {
3603       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3604     }
3605   else
3606     {
3607       emit_move_insn (operands[2], operands[1]);
3608       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3609     }
3610   emit_move_insn (operands[4], operands[2]);
3611   DONE;
3614 ;; Peepholes for the case where the source register does die, after
3615 ;; being split with the above splitter.
3616 (define_peephole2
3617   [(set (match_operand:SI 0 "memory_operand")
3618         (match_operand:SI 1 "register_operand"))
3619    (set (match_operand:SI 2 "register_operand") (match_dup 1))
3620    (parallel [(set (match_dup 2)
3621                    (ashiftrt:SI (match_dup 2) (const_int 31)))
3622                (clobber (reg:CC FLAGS_REG))])
3623    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3624   "REGNO (operands[1]) != REGNO (operands[2])
3625    && peep2_reg_dead_p (2, operands[1])
3626    && peep2_reg_dead_p (4, operands[2])
3627    && !reg_mentioned_p (operands[2], operands[3])"
3628   [(set (match_dup 0) (match_dup 1))
3629    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3630               (clobber (reg:CC FLAGS_REG))])
3631    (set (match_dup 3) (match_dup 1))])
3633 (define_peephole2
3634   [(set (match_operand:SI 0 "memory_operand")
3635         (match_operand:SI 1 "register_operand"))
3636    (parallel [(set (match_operand:SI 2 "register_operand")
3637                    (ashiftrt:SI (match_dup 1) (const_int 31)))
3638                (clobber (reg:CC FLAGS_REG))])
3639    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3640   "/* cltd is shorter than sarl $31, %eax */
3641    !optimize_function_for_size_p (cfun)
3642    && true_regnum (operands[1]) == AX_REG
3643    && true_regnum (operands[2]) == DX_REG
3644    && peep2_reg_dead_p (2, operands[1])
3645    && peep2_reg_dead_p (3, operands[2])
3646    && !reg_mentioned_p (operands[2], operands[3])"
3647   [(set (match_dup 0) (match_dup 1))
3648    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3649               (clobber (reg:CC FLAGS_REG))])
3650    (set (match_dup 3) (match_dup 1))])
3652 ;; Extend to register case.  Optimize case where source and destination
3653 ;; registers match and cases where we can use cltd.
3654 (define_split
3655   [(set (match_operand:DI 0 "register_operand")
3656         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3657    (clobber (reg:CC FLAGS_REG))
3658    (clobber (match_scratch:SI 2))]
3659   "reload_completed"
3660   [(const_int 0)]
3662   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3664   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3665     emit_move_insn (operands[3], operands[1]);
3667   /* Generate a cltd if possible and doing so it profitable.  */
3668   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3669       && true_regnum (operands[3]) == AX_REG
3670       && true_regnum (operands[4]) == DX_REG)
3671     {
3672       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3673       DONE;
3674     }
3676   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3677     emit_move_insn (operands[4], operands[1]);
3679   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3680   DONE;
3683 (define_insn "extend<mode>di2"
3684   [(set (match_operand:DI 0 "register_operand" "=r")
3685         (sign_extend:DI
3686          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3687   "TARGET_64BIT"
3688   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3689   [(set_attr "type" "imovx")
3690    (set_attr "mode" "DI")])
3692 (define_insn "extendhisi2"
3693   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3694         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3695   ""
3697   switch (get_attr_prefix_0f (insn))
3698     {
3699     case 0:
3700       return "{cwtl|cwde}";
3701     default:
3702       return "movs{wl|x}\t{%1, %0|%0, %1}";
3703     }
3705   [(set_attr "type" "imovx")
3706    (set_attr "mode" "SI")
3707    (set (attr "prefix_0f")
3708      ;; movsx is short decodable while cwtl is vector decoded.
3709      (if_then_else (and (eq_attr "cpu" "!k6")
3710                         (eq_attr "alternative" "0"))
3711         (const_string "0")
3712         (const_string "1")))
3713    (set (attr "modrm")
3714      (if_then_else (eq_attr "prefix_0f" "0")
3715         (const_string "0")
3716         (const_string "1")))])
3718 (define_insn "*extendhisi2_zext"
3719   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3720         (zero_extend:DI
3721          (sign_extend:SI
3722           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3723   "TARGET_64BIT"
3725   switch (get_attr_prefix_0f (insn))
3726     {
3727     case 0:
3728       return "{cwtl|cwde}";
3729     default:
3730       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3731     }
3733   [(set_attr "type" "imovx")
3734    (set_attr "mode" "SI")
3735    (set (attr "prefix_0f")
3736      ;; movsx is short decodable while cwtl is vector decoded.
3737      (if_then_else (and (eq_attr "cpu" "!k6")
3738                         (eq_attr "alternative" "0"))
3739         (const_string "0")
3740         (const_string "1")))
3741    (set (attr "modrm")
3742      (if_then_else (eq_attr "prefix_0f" "0")
3743         (const_string "0")
3744         (const_string "1")))])
3746 (define_insn "extendqisi2"
3747   [(set (match_operand:SI 0 "register_operand" "=r")
3748         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3749   ""
3750   "movs{bl|x}\t{%1, %0|%0, %1}"
3751    [(set_attr "type" "imovx")
3752     (set_attr "mode" "SI")])
3754 (define_insn "*extendqisi2_zext"
3755   [(set (match_operand:DI 0 "register_operand" "=r")
3756         (zero_extend:DI
3757           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3758   "TARGET_64BIT"
3759   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3760    [(set_attr "type" "imovx")
3761     (set_attr "mode" "SI")])
3763 (define_insn "extendqihi2"
3764   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3765         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3766   ""
3768   switch (get_attr_prefix_0f (insn))
3769     {
3770     case 0:
3771       return "{cbtw|cbw}";
3772     default:
3773       return "movs{bw|x}\t{%1, %0|%0, %1}";
3774     }
3776   [(set_attr "type" "imovx")
3777    (set_attr "mode" "HI")
3778    (set (attr "prefix_0f")
3779      ;; movsx is short decodable while cwtl is vector decoded.
3780      (if_then_else (and (eq_attr "cpu" "!k6")
3781                         (eq_attr "alternative" "0"))
3782         (const_string "0")
3783         (const_string "1")))
3784    (set (attr "modrm")
3785      (if_then_else (eq_attr "prefix_0f" "0")
3786         (const_string "0")
3787         (const_string "1")))])
3789 ;; Conversions between float and double.
3791 ;; These are all no-ops in the model used for the 80387.
3792 ;; So just emit moves.
3794 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3795 (define_split
3796   [(set (match_operand:DF 0 "push_operand")
3797         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3798   "reload_completed"
3799   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3800    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3802 (define_split
3803   [(set (match_operand:XF 0 "push_operand")
3804         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3805   "reload_completed"
3806   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3807    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3808   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3810 (define_expand "extendsfdf2"
3811   [(set (match_operand:DF 0 "nonimmediate_operand")
3812         (float_extend:DF (match_operand:SF 1 "general_operand")))]
3813   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3815   /* ??? Needed for compress_float_constant since all fp constants
3816      are TARGET_LEGITIMATE_CONSTANT_P.  */
3817   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3818     {
3819       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3820           && standard_80387_constant_p (operands[1]) > 0)
3821         {
3822           operands[1] = simplify_const_unary_operation
3823             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3824           emit_move_insn_1 (operands[0], operands[1]);
3825           DONE;
3826         }
3827       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3828     }
3831 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3832    cvtss2sd:
3833       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3834       cvtps2pd xmm2,xmm1
3835    We do the conversion post reload to avoid producing of 128bit spills
3836    that might lead to ICE on 32bit target.  The sequence unlikely combine
3837    anyway.  */
3838 (define_split
3839   [(set (match_operand:DF 0 "register_operand")
3840         (float_extend:DF
3841           (match_operand:SF 1 "nonimmediate_operand")))]
3842   "TARGET_USE_VECTOR_FP_CONVERTS
3843    && optimize_insn_for_speed_p ()
3844    && reload_completed && SSE_REG_P (operands[0])"
3845    [(set (match_dup 2)
3846          (float_extend:V2DF
3847            (vec_select:V2SF
3848              (match_dup 3)
3849              (parallel [(const_int 0) (const_int 1)]))))]
3851   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3852   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3853   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3854      Try to avoid move when unpacking can be done in source.  */
3855   if (REG_P (operands[1]))
3856     {
3857       /* If it is unsafe to overwrite upper half of source, we need
3858          to move to destination and unpack there.  */
3859       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3860            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3861           && true_regnum (operands[0]) != true_regnum (operands[1]))
3862         {
3863           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3864           emit_move_insn (tmp, operands[1]);
3865         }
3866       else
3867         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3868       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3869                                              operands[3]));
3870     }
3871   else
3872     emit_insn (gen_vec_setv4sf_0 (operands[3],
3873                                   CONST0_RTX (V4SFmode), operands[1]));
3876 ;; It's more profitable to split and then extend in the same register.
3877 (define_peephole2
3878   [(set (match_operand:DF 0 "register_operand")
3879         (float_extend:DF
3880           (match_operand:SF 1 "memory_operand")))]
3881   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3882    && optimize_insn_for_speed_p ()
3883    && SSE_REG_P (operands[0])"
3884   [(set (match_dup 2) (match_dup 1))
3885    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
3886   "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
3888 (define_insn "*extendsfdf2_mixed"
3889   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3890         (float_extend:DF
3891           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3892   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3894   switch (which_alternative)
3895     {
3896     case 0:
3897     case 1:
3898       return output_387_reg_move (insn, operands);
3900     case 2:
3901       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3903     default:
3904       gcc_unreachable ();
3905     }
3907   [(set_attr "type" "fmov,fmov,ssecvt")
3908    (set_attr "prefix" "orig,orig,maybe_vex")
3909    (set_attr "mode" "SF,XF,DF")])
3911 (define_insn "*extendsfdf2_sse"
3912   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3913         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3914   "TARGET_SSE2 && TARGET_SSE_MATH"
3915   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3916   [(set_attr "type" "ssecvt")
3917    (set_attr "prefix" "maybe_vex")
3918    (set_attr "mode" "DF")])
3920 (define_insn "*extendsfdf2_i387"
3921   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3922         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3923   "TARGET_80387"
3924   "* return output_387_reg_move (insn, operands);"
3925   [(set_attr "type" "fmov")
3926    (set_attr "mode" "SF,XF")])
3928 (define_expand "extend<mode>xf2"
3929   [(set (match_operand:XF 0 "nonimmediate_operand")
3930         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3931   "TARGET_80387"
3933   /* ??? Needed for compress_float_constant since all fp constants
3934      are TARGET_LEGITIMATE_CONSTANT_P.  */
3935   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3936     {
3937       if (standard_80387_constant_p (operands[1]) > 0)
3938         {
3939           operands[1] = simplify_const_unary_operation
3940             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3941           emit_move_insn_1 (operands[0], operands[1]);
3942           DONE;
3943         }
3944       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3945     }
3948 (define_insn "*extend<mode>xf2_i387"
3949   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3950         (float_extend:XF
3951           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3952   "TARGET_80387"
3953   "* return output_387_reg_move (insn, operands);"
3954   [(set_attr "type" "fmov")
3955    (set_attr "mode" "<MODE>,XF")])
3957 ;; %%% This seems bad bad news.
3958 ;; This cannot output into an f-reg because there is no way to be sure
3959 ;; of truncating in that case.  Otherwise this is just like a simple move
3960 ;; insn.  So we pretend we can output to a reg in order to get better
3961 ;; register preferencing, but we really use a stack slot.
3963 ;; Conversion from DFmode to SFmode.
3965 (define_expand "truncdfsf2"
3966   [(set (match_operand:SF 0 "nonimmediate_operand")
3967         (float_truncate:SF
3968           (match_operand:DF 1 "nonimmediate_operand")))]
3969   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3971   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3972     ;
3973   else if (flag_unsafe_math_optimizations)
3974     ;
3975   else
3976     {
3977       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3978       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3979       DONE;
3980     }
3983 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3984    cvtsd2ss:
3985       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3986       cvtpd2ps xmm2,xmm1
3987    We do the conversion post reload to avoid producing of 128bit spills
3988    that might lead to ICE on 32bit target.  The sequence unlikely combine
3989    anyway.  */
3990 (define_split
3991   [(set (match_operand:SF 0 "register_operand")
3992         (float_truncate:SF
3993           (match_operand:DF 1 "nonimmediate_operand")))]
3994   "TARGET_USE_VECTOR_FP_CONVERTS
3995    && optimize_insn_for_speed_p ()
3996    && reload_completed && SSE_REG_P (operands[0])"
3997    [(set (match_dup 2)
3998          (vec_concat:V4SF
3999            (float_truncate:V2SF
4000              (match_dup 4))
4001            (match_dup 3)))]
4003   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4004   operands[3] = CONST0_RTX (V2SFmode);
4005   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4006   /* Use movsd for loading from memory, unpcklpd for registers.
4007      Try to avoid move when unpacking can be done in source, or SSE3
4008      movddup is available.  */
4009   if (REG_P (operands[1]))
4010     {
4011       if (!TARGET_SSE3
4012           && true_regnum (operands[0]) != true_regnum (operands[1])
4013           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4014               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4015         {
4016           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4017           emit_move_insn (tmp, operands[1]);
4018           operands[1] = tmp;
4019         }
4020       else if (!TARGET_SSE3)
4021         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4022       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4023     }
4024   else
4025     emit_insn (gen_sse2_loadlpd (operands[4],
4026                                  CONST0_RTX (V2DFmode), operands[1]));
4029 ;; It's more profitable to split and then extend in the same register.
4030 (define_peephole2
4031   [(set (match_operand:SF 0 "register_operand")
4032         (float_truncate:SF
4033           (match_operand:DF 1 "memory_operand")))]
4034   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4035    && optimize_insn_for_speed_p ()
4036    && SSE_REG_P (operands[0])"
4037   [(set (match_dup 2) (match_dup 1))
4038    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4039   "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4041 (define_expand "truncdfsf2_with_temp"
4042   [(parallel [(set (match_operand:SF 0)
4043                    (float_truncate:SF (match_operand:DF 1)))
4044               (clobber (match_operand:SF 2))])])
4046 (define_insn "*truncdfsf_fast_mixed"
4047   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4048         (float_truncate:SF
4049           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4050   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4052   switch (which_alternative)
4053     {
4054     case 0:
4055       return output_387_reg_move (insn, operands);
4056     case 1:
4057       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4058     default:
4059       gcc_unreachable ();
4060     }
4062   [(set_attr "type" "fmov,ssecvt")
4063    (set_attr "prefix" "orig,maybe_vex")
4064    (set_attr "mode" "SF")])
4066 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4067 ;; because nothing we do here is unsafe.
4068 (define_insn "*truncdfsf_fast_sse"
4069   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4070         (float_truncate:SF
4071           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4072   "TARGET_SSE2 && TARGET_SSE_MATH"
4073   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4074   [(set_attr "type" "ssecvt")
4075    (set_attr "prefix" "maybe_vex")
4076    (set_attr "mode" "SF")])
4078 (define_insn "*truncdfsf_fast_i387"
4079   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4080         (float_truncate:SF
4081           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4082   "TARGET_80387 && flag_unsafe_math_optimizations"
4083   "* return output_387_reg_move (insn, operands);"
4084   [(set_attr "type" "fmov")
4085    (set_attr "mode" "SF")])
4087 (define_insn "*truncdfsf_mixed"
4088   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4089         (float_truncate:SF
4090           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4091    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4092   "TARGET_MIX_SSE_I387"
4094   switch (which_alternative)
4095     {
4096     case 0:
4097       return output_387_reg_move (insn, operands);
4098     case 1:
4099       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4101     default:
4102       return "#";
4103     }
4105   [(set_attr "isa" "*,sse2,*,*,*")
4106    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4107    (set_attr "unit" "*,*,i387,i387,i387")
4108    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4109    (set_attr "mode" "SF")])
4111 (define_insn "*truncdfsf_i387"
4112   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4113         (float_truncate:SF
4114           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4115    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4116   "TARGET_80387"
4118   switch (which_alternative)
4119     {
4120     case 0:
4121       return output_387_reg_move (insn, operands);
4123     default:
4124       return "#";
4125     }
4127   [(set_attr "type" "fmov,multi,multi,multi")
4128    (set_attr "unit" "*,i387,i387,i387")
4129    (set_attr "mode" "SF")])
4131 (define_insn "*truncdfsf2_i387_1"
4132   [(set (match_operand:SF 0 "memory_operand" "=m")
4133         (float_truncate:SF
4134           (match_operand:DF 1 "register_operand" "f")))]
4135   "TARGET_80387
4136    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4137    && !TARGET_MIX_SSE_I387"
4138   "* return output_387_reg_move (insn, operands);"
4139   [(set_attr "type" "fmov")
4140    (set_attr "mode" "SF")])
4142 (define_split
4143   [(set (match_operand:SF 0 "register_operand")
4144         (float_truncate:SF
4145          (match_operand:DF 1 "fp_register_operand")))
4146    (clobber (match_operand 2))]
4147   "reload_completed"
4148   [(set (match_dup 2) (match_dup 1))
4149    (set (match_dup 0) (match_dup 2))]
4150   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4152 ;; Conversion from XFmode to {SF,DF}mode
4154 (define_expand "truncxf<mode>2"
4155   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4156                    (float_truncate:MODEF
4157                      (match_operand:XF 1 "register_operand")))
4158               (clobber (match_dup 2))])]
4159   "TARGET_80387"
4161   if (flag_unsafe_math_optimizations)
4162     {
4163       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4164       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4165       if (reg != operands[0])
4166         emit_move_insn (operands[0], reg);
4167       DONE;
4168     }
4169   else
4170     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4173 (define_insn "*truncxfsf2_mixed"
4174   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4175         (float_truncate:SF
4176           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4177    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4178   "TARGET_80387"
4180   gcc_assert (!which_alternative);
4181   return output_387_reg_move (insn, operands);
4183   [(set_attr "type" "fmov,multi,multi,multi")
4184    (set_attr "unit" "*,i387,i387,i387")
4185    (set_attr "mode" "SF")])
4187 (define_insn "*truncxfdf2_mixed"
4188   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4189         (float_truncate:DF
4190           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4191    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4192   "TARGET_80387"
4194   gcc_assert (!which_alternative);
4195   return output_387_reg_move (insn, operands);
4197   [(set_attr "isa" "*,*,sse2,*")
4198    (set_attr "type" "fmov,multi,multi,multi")
4199    (set_attr "unit" "*,i387,i387,i387")
4200    (set_attr "mode" "DF")])
4202 (define_insn "truncxf<mode>2_i387_noop"
4203   [(set (match_operand:MODEF 0 "register_operand" "=f")
4204         (float_truncate:MODEF
4205           (match_operand:XF 1 "register_operand" "f")))]
4206   "TARGET_80387 && flag_unsafe_math_optimizations"
4207   "* return output_387_reg_move (insn, operands);"
4208   [(set_attr "type" "fmov")
4209    (set_attr "mode" "<MODE>")])
4211 (define_insn "*truncxf<mode>2_i387"
4212   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4213         (float_truncate:MODEF
4214           (match_operand:XF 1 "register_operand" "f")))]
4215   "TARGET_80387"
4216   "* return output_387_reg_move (insn, operands);"
4217   [(set_attr "type" "fmov")
4218    (set_attr "mode" "<MODE>")])
4220 (define_split
4221   [(set (match_operand:MODEF 0 "register_operand")
4222         (float_truncate:MODEF
4223           (match_operand:XF 1 "register_operand")))
4224    (clobber (match_operand:MODEF 2 "memory_operand"))]
4225   "TARGET_80387 && reload_completed"
4226   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4227    (set (match_dup 0) (match_dup 2))])
4229 (define_split
4230   [(set (match_operand:MODEF 0 "memory_operand")
4231         (float_truncate:MODEF
4232           (match_operand:XF 1 "register_operand")))
4233    (clobber (match_operand:MODEF 2 "memory_operand"))]
4234   "TARGET_80387"
4235   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4237 ;; Signed conversion to DImode.
4239 (define_expand "fix_truncxfdi2"
4240   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4241                    (fix:DI (match_operand:XF 1 "register_operand")))
4242               (clobber (reg:CC FLAGS_REG))])]
4243   "TARGET_80387"
4245   if (TARGET_FISTTP)
4246    {
4247      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4248      DONE;
4249    }
4252 (define_expand "fix_trunc<mode>di2"
4253   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4254                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4255               (clobber (reg:CC FLAGS_REG))])]
4256   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4258   if (TARGET_FISTTP
4259       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4260    {
4261      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4262      DONE;
4263    }
4264   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4265    {
4266      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4267      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4268      if (out != operands[0])
4269         emit_move_insn (operands[0], out);
4270      DONE;
4271    }
4274 ;; Signed conversion to SImode.
4276 (define_expand "fix_truncxfsi2"
4277   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4278                    (fix:SI (match_operand:XF 1 "register_operand")))
4279               (clobber (reg:CC FLAGS_REG))])]
4280   "TARGET_80387"
4282   if (TARGET_FISTTP)
4283    {
4284      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4285      DONE;
4286    }
4289 (define_expand "fix_trunc<mode>si2"
4290   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4291                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4292               (clobber (reg:CC FLAGS_REG))])]
4293   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4295   if (TARGET_FISTTP
4296       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4297    {
4298      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4299      DONE;
4300    }
4301   if (SSE_FLOAT_MODE_P (<MODE>mode))
4302    {
4303      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4304      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4305      if (out != operands[0])
4306         emit_move_insn (operands[0], out);
4307      DONE;
4308    }
4311 ;; Signed conversion to HImode.
4313 (define_expand "fix_trunc<mode>hi2"
4314   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4315                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4316               (clobber (reg:CC FLAGS_REG))])]
4317   "TARGET_80387
4318    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4320   if (TARGET_FISTTP)
4321    {
4322      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4323      DONE;
4324    }
4327 ;; Unsigned conversion to SImode.
4329 (define_expand "fixuns_trunc<mode>si2"
4330   [(parallel
4331     [(set (match_operand:SI 0 "register_operand")
4332           (unsigned_fix:SI
4333             (match_operand:MODEF 1 "nonimmediate_operand")))
4334      (use (match_dup 2))
4335      (clobber (match_scratch:<ssevecmode> 3))
4336      (clobber (match_scratch:<ssevecmode> 4))])]
4337   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4339   enum machine_mode mode = <MODE>mode;
4340   enum machine_mode vecmode = <ssevecmode>mode;
4341   REAL_VALUE_TYPE TWO31r;
4342   rtx two31;
4344   if (optimize_insn_for_size_p ())
4345     FAIL;
4347   real_ldexp (&TWO31r, &dconst1, 31);
4348   two31 = const_double_from_real_value (TWO31r, mode);
4349   two31 = ix86_build_const_vector (vecmode, true, two31);
4350   operands[2] = force_reg (vecmode, two31);
4353 (define_insn_and_split "*fixuns_trunc<mode>_1"
4354   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4355         (unsigned_fix:SI
4356           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4357    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4358    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4359    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4360   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4361    && optimize_function_for_speed_p (cfun)"
4362   "#"
4363   "&& reload_completed"
4364   [(const_int 0)]
4366   ix86_split_convert_uns_si_sse (operands);
4367   DONE;
4370 ;; Unsigned conversion to HImode.
4371 ;; Without these patterns, we'll try the unsigned SI conversion which
4372 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4374 (define_expand "fixuns_trunc<mode>hi2"
4375   [(set (match_dup 2)
4376         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4377    (set (match_operand:HI 0 "nonimmediate_operand")
4378         (subreg:HI (match_dup 2) 0))]
4379   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4380   "operands[2] = gen_reg_rtx (SImode);")
4382 ;; When SSE is available, it is always faster to use it!
4383 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4384   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4385         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4386   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4387    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4388   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4389   [(set_attr "type" "sseicvt")
4390    (set_attr "prefix" "maybe_vex")
4391    (set (attr "prefix_rex")
4392         (if_then_else
4393           (match_test "<SWI48:MODE>mode == DImode")
4394           (const_string "1")
4395           (const_string "*")))
4396    (set_attr "mode" "<MODEF:MODE>")
4397    (set_attr "athlon_decode" "double,vector")
4398    (set_attr "amdfam10_decode" "double,double")
4399    (set_attr "bdver1_decode" "double,double")])
4401 ;; Avoid vector decoded forms of the instruction.
4402 (define_peephole2
4403   [(match_scratch:MODEF 2 "x")
4404    (set (match_operand:SWI48 0 "register_operand")
4405         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4406   "TARGET_AVOID_VECTOR_DECODE
4407    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4408    && optimize_insn_for_speed_p ()"
4409   [(set (match_dup 2) (match_dup 1))
4410    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4412 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4413   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4414         (fix:SWI248x (match_operand 1 "register_operand")))]
4415   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4416    && TARGET_FISTTP
4417    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4418          && (TARGET_64BIT || <MODE>mode != DImode))
4419         && TARGET_SSE_MATH)
4420    && can_create_pseudo_p ()"
4421   "#"
4422   "&& 1"
4423   [(const_int 0)]
4425   if (memory_operand (operands[0], VOIDmode))
4426     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4427   else
4428     {
4429       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4430       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4431                                                             operands[1],
4432                                                             operands[2]));
4433     }
4434   DONE;
4436   [(set_attr "type" "fisttp")
4437    (set_attr "mode" "<MODE>")])
4439 (define_insn "fix_trunc<mode>_i387_fisttp"
4440   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4441         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4442    (clobber (match_scratch:XF 2 "=&1f"))]
4443   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4444    && TARGET_FISTTP
4445    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4446          && (TARGET_64BIT || <MODE>mode != DImode))
4447         && TARGET_SSE_MATH)"
4448   "* return output_fix_trunc (insn, operands, true);"
4449   [(set_attr "type" "fisttp")
4450    (set_attr "mode" "<MODE>")])
4452 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4453   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4454         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4455    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4456    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4457   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4458    && TARGET_FISTTP
4459    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4460         && (TARGET_64BIT || <MODE>mode != DImode))
4461         && TARGET_SSE_MATH)"
4462   "#"
4463   [(set_attr "type" "fisttp")
4464    (set_attr "mode" "<MODE>")])
4466 (define_split
4467   [(set (match_operand:SWI248x 0 "register_operand")
4468         (fix:SWI248x (match_operand 1 "register_operand")))
4469    (clobber (match_operand:SWI248x 2 "memory_operand"))
4470    (clobber (match_scratch 3))]
4471   "reload_completed"
4472   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4473               (clobber (match_dup 3))])
4474    (set (match_dup 0) (match_dup 2))])
4476 (define_split
4477   [(set (match_operand:SWI248x 0 "memory_operand")
4478         (fix:SWI248x (match_operand 1 "register_operand")))
4479    (clobber (match_operand:SWI248x 2 "memory_operand"))
4480    (clobber (match_scratch 3))]
4481   "reload_completed"
4482   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4483               (clobber (match_dup 3))])])
4485 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4486 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4487 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4488 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4489 ;; function in i386.c.
4490 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4491   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4492         (fix:SWI248x (match_operand 1 "register_operand")))
4493    (clobber (reg:CC FLAGS_REG))]
4494   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4495    && !TARGET_FISTTP
4496    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4497          && (TARGET_64BIT || <MODE>mode != DImode))
4498    && can_create_pseudo_p ()"
4499   "#"
4500   "&& 1"
4501   [(const_int 0)]
4503   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4505   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4506   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4507   if (memory_operand (operands[0], VOIDmode))
4508     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4509                                          operands[2], operands[3]));
4510   else
4511     {
4512       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4513       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4514                                                      operands[2], operands[3],
4515                                                      operands[4]));
4516     }
4517   DONE;
4519   [(set_attr "type" "fistp")
4520    (set_attr "i387_cw" "trunc")
4521    (set_attr "mode" "<MODE>")])
4523 (define_insn "fix_truncdi_i387"
4524   [(set (match_operand:DI 0 "memory_operand" "=m")
4525         (fix:DI (match_operand 1 "register_operand" "f")))
4526    (use (match_operand:HI 2 "memory_operand" "m"))
4527    (use (match_operand:HI 3 "memory_operand" "m"))
4528    (clobber (match_scratch:XF 4 "=&1f"))]
4529   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4530    && !TARGET_FISTTP
4531    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4532   "* return output_fix_trunc (insn, operands, false);"
4533   [(set_attr "type" "fistp")
4534    (set_attr "i387_cw" "trunc")
4535    (set_attr "mode" "DI")])
4537 (define_insn "fix_truncdi_i387_with_temp"
4538   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4539         (fix:DI (match_operand 1 "register_operand" "f,f")))
4540    (use (match_operand:HI 2 "memory_operand" "m,m"))
4541    (use (match_operand:HI 3 "memory_operand" "m,m"))
4542    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4543    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4544   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4545    && !TARGET_FISTTP
4546    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4547   "#"
4548   [(set_attr "type" "fistp")
4549    (set_attr "i387_cw" "trunc")
4550    (set_attr "mode" "DI")])
4552 (define_split
4553   [(set (match_operand:DI 0 "register_operand")
4554         (fix:DI (match_operand 1 "register_operand")))
4555    (use (match_operand:HI 2 "memory_operand"))
4556    (use (match_operand:HI 3 "memory_operand"))
4557    (clobber (match_operand:DI 4 "memory_operand"))
4558    (clobber (match_scratch 5))]
4559   "reload_completed"
4560   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4561               (use (match_dup 2))
4562               (use (match_dup 3))
4563               (clobber (match_dup 5))])
4564    (set (match_dup 0) (match_dup 4))])
4566 (define_split
4567   [(set (match_operand:DI 0 "memory_operand")
4568         (fix:DI (match_operand 1 "register_operand")))
4569    (use (match_operand:HI 2 "memory_operand"))
4570    (use (match_operand:HI 3 "memory_operand"))
4571    (clobber (match_operand:DI 4 "memory_operand"))
4572    (clobber (match_scratch 5))]
4573   "reload_completed"
4574   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4575               (use (match_dup 2))
4576               (use (match_dup 3))
4577               (clobber (match_dup 5))])])
4579 (define_insn "fix_trunc<mode>_i387"
4580   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4581         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4582    (use (match_operand:HI 2 "memory_operand" "m"))
4583    (use (match_operand:HI 3 "memory_operand" "m"))]
4584   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4585    && !TARGET_FISTTP
4586    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4587   "* return output_fix_trunc (insn, operands, false);"
4588   [(set_attr "type" "fistp")
4589    (set_attr "i387_cw" "trunc")
4590    (set_attr "mode" "<MODE>")])
4592 (define_insn "fix_trunc<mode>_i387_with_temp"
4593   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4594         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4595    (use (match_operand:HI 2 "memory_operand" "m,m"))
4596    (use (match_operand:HI 3 "memory_operand" "m,m"))
4597    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4598   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4599    && !TARGET_FISTTP
4600    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4601   "#"
4602   [(set_attr "type" "fistp")
4603    (set_attr "i387_cw" "trunc")
4604    (set_attr "mode" "<MODE>")])
4606 (define_split
4607   [(set (match_operand:SWI24 0 "register_operand")
4608         (fix:SWI24 (match_operand 1 "register_operand")))
4609    (use (match_operand:HI 2 "memory_operand"))
4610    (use (match_operand:HI 3 "memory_operand"))
4611    (clobber (match_operand:SWI24 4 "memory_operand"))]
4612   "reload_completed"
4613   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4614               (use (match_dup 2))
4615               (use (match_dup 3))])
4616    (set (match_dup 0) (match_dup 4))])
4618 (define_split
4619   [(set (match_operand:SWI24 0 "memory_operand")
4620         (fix:SWI24 (match_operand 1 "register_operand")))
4621    (use (match_operand:HI 2 "memory_operand"))
4622    (use (match_operand:HI 3 "memory_operand"))
4623    (clobber (match_operand:SWI24 4 "memory_operand"))]
4624   "reload_completed"
4625   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4626               (use (match_dup 2))
4627               (use (match_dup 3))])])
4629 (define_insn "x86_fnstcw_1"
4630   [(set (match_operand:HI 0 "memory_operand" "=m")
4631         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4632   "TARGET_80387"
4633   "fnstcw\t%0"
4634   [(set (attr "length")
4635         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4636    (set_attr "mode" "HI")
4637    (set_attr "unit" "i387")
4638    (set_attr "bdver1_decode" "vector")])
4640 (define_insn "x86_fldcw_1"
4641   [(set (reg:HI FPCR_REG)
4642         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4643   "TARGET_80387"
4644   "fldcw\t%0"
4645   [(set (attr "length")
4646         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4647    (set_attr "mode" "HI")
4648    (set_attr "unit" "i387")
4649    (set_attr "athlon_decode" "vector")
4650    (set_attr "amdfam10_decode" "vector")
4651    (set_attr "bdver1_decode" "vector")])
4653 ;; Conversion between fixed point and floating point.
4655 ;; Even though we only accept memory inputs, the backend _really_
4656 ;; wants to be able to do this between registers.
4658 (define_expand "floathi<mode>2"
4659   [(set (match_operand:X87MODEF 0 "register_operand")
4660         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4661   "TARGET_80387
4662    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4663        || TARGET_MIX_SSE_I387)")
4665 ;; Pre-reload splitter to add memory clobber to the pattern.
4666 (define_insn_and_split "*floathi<mode>2_1"
4667   [(set (match_operand:X87MODEF 0 "register_operand")
4668         (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4669   "TARGET_80387
4670    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4671        || TARGET_MIX_SSE_I387)
4672    && can_create_pseudo_p ()"
4673   "#"
4674   "&& 1"
4675   [(parallel [(set (match_dup 0)
4676               (float:X87MODEF (match_dup 1)))
4677    (clobber (match_dup 2))])]
4678   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4680 (define_insn "*floathi<mode>2_i387_with_temp"
4681   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4682         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4683   (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4684   "TARGET_80387
4685    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4686        || TARGET_MIX_SSE_I387)"
4687   "#"
4688   [(set_attr "type" "fmov,multi")
4689    (set_attr "mode" "<MODE>")
4690    (set_attr "unit" "*,i387")
4691    (set_attr "fp_int_src" "true")])
4693 (define_insn "*floathi<mode>2_i387"
4694   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4695         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4696   "TARGET_80387
4697    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4698        || TARGET_MIX_SSE_I387)"
4699   "fild%Z1\t%1"
4700   [(set_attr "type" "fmov")
4701    (set_attr "mode" "<MODE>")
4702    (set_attr "fp_int_src" "true")])
4704 (define_split
4705   [(set (match_operand:X87MODEF 0 "register_operand")
4706         (float:X87MODEF (match_operand:HI 1 "register_operand")))
4707    (clobber (match_operand:HI 2 "memory_operand"))]
4708   "TARGET_80387
4709    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4710        || TARGET_MIX_SSE_I387)
4711    && reload_completed"
4712   [(set (match_dup 2) (match_dup 1))
4713    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4715 (define_split
4716   [(set (match_operand:X87MODEF 0 "register_operand")
4717         (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4718    (clobber (match_operand:HI 2 "memory_operand"))]
4719    "TARGET_80387
4720     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4721         || TARGET_MIX_SSE_I387)
4722     && reload_completed"
4723   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4725 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4726   [(set (match_operand:X87MODEF 0 "register_operand")
4727         (float:X87MODEF
4728           (match_operand:SWI48x 1 "nonimmediate_operand")))]
4729   "TARGET_80387
4730    || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4731        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4733   if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4734         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4735       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4736     {
4737       rtx reg = gen_reg_rtx (XFmode);
4738       rtx (*insn)(rtx, rtx);
4740       emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4742       if (<X87MODEF:MODE>mode == SFmode)
4743         insn = gen_truncxfsf2;
4744       else if (<X87MODEF:MODE>mode == DFmode)
4745         insn = gen_truncxfdf2;
4746       else
4747         gcc_unreachable ();
4749       emit_insn (insn (operands[0], reg));
4750       DONE;
4751     }
4754 ;; Pre-reload splitter to add memory clobber to the pattern.
4755 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4756   [(set (match_operand:X87MODEF 0 "register_operand")
4757         (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4758   "((TARGET_80387
4759      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4760      && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4761            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4762          || TARGET_MIX_SSE_I387))
4763     || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4764         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4765         && ((<SWI48x:MODE>mode == SImode
4766              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4767              && optimize_function_for_speed_p (cfun)
4768              && flag_trapping_math)
4769             || !(TARGET_INTER_UNIT_CONVERSIONS
4770                  || optimize_function_for_size_p (cfun)))))
4771    && can_create_pseudo_p ()"
4772   "#"
4773   "&& 1"
4774   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4775               (clobber (match_dup 2))])]
4777   operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4779   /* Avoid store forwarding (partial memory) stall penalty
4780      by passing DImode value through XMM registers.  */
4781   if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4782       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4783       && optimize_function_for_speed_p (cfun))
4784     {
4785       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4786                                                             operands[1],
4787                                                             operands[2]));
4788       DONE;
4789     }
4792 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4793   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4794         (float:MODEF
4795           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4796    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4797   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4798    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4799   "#"
4800   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4801    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4802    (set_attr "unit" "*,i387,*,*,*")
4803    (set_attr "athlon_decode" "*,*,double,direct,double")
4804    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4805    (set_attr "bdver1_decode" "*,*,double,direct,double")
4806    (set_attr "fp_int_src" "true")])
4808 (define_insn "*floatsi<mode>2_vector_mixed"
4809   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4810         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4811   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4812    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4813   "@
4814    fild%Z1\t%1
4815    #"
4816   [(set_attr "type" "fmov,sseicvt")
4817    (set_attr "mode" "<MODE>,<ssevecmode>")
4818    (set_attr "unit" "i387,*")
4819    (set_attr "athlon_decode" "*,direct")
4820    (set_attr "amdfam10_decode" "*,double")
4821    (set_attr "bdver1_decode" "*,direct")
4822    (set_attr "fp_int_src" "true")])
4824 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_with_temp"
4825   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4826         (float:MODEF
4827           (match_operand:SWI48 1 "nonimmediate_operand" "m,?r,r,m")))
4828    (clobber (match_operand:SWI48 2 "memory_operand" "=X,m,m,X"))]
4829   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4830   "#"
4831   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4832    (set_attr "mode" "<MODEF:MODE>")
4833    (set_attr "unit" "*,i387,*,*")
4834    (set_attr "athlon_decode" "*,*,double,direct")
4835    (set_attr "amdfam10_decode" "*,*,vector,double")
4836    (set_attr "bdver1_decode" "*,*,double,direct")
4837    (set_attr "fp_int_src" "true")])
4839 (define_split
4840   [(set (match_operand:MODEF 0 "register_operand")
4841         (float:MODEF (match_operand:SWI48 1 "register_operand")))
4842    (clobber (match_operand:SWI48 2 "memory_operand"))]
4843   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4844    && TARGET_INTER_UNIT_CONVERSIONS
4845    && reload_completed && SSE_REG_P (operands[0])"
4846   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4848 (define_split
4849   [(set (match_operand:MODEF 0 "register_operand")
4850         (float:MODEF (match_operand:SWI48 1 "register_operand")))
4851    (clobber (match_operand:SWI48 2 "memory_operand"))]
4852   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4853    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4854    && reload_completed && SSE_REG_P (operands[0])"
4855   [(set (match_dup 2) (match_dup 1))
4856    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4858 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_interunit"
4859   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4860         (float:MODEF
4861           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4862   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4863    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4864   "@
4865    fild%Z1\t%1
4866    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4867    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4868   [(set_attr "type" "fmov,sseicvt,sseicvt")
4869    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4870    (set_attr "mode" "<MODEF:MODE>")
4871    (set (attr "prefix_rex")
4872      (if_then_else
4873        (and (eq_attr "prefix" "maybe_vex")
4874             (match_test "<SWI48:MODE>mode == DImode"))
4875        (const_string "1")
4876        (const_string "*")))
4877    (set_attr "unit" "i387,*,*")
4878    (set_attr "athlon_decode" "*,double,direct")
4879    (set_attr "amdfam10_decode" "*,vector,double")
4880    (set_attr "bdver1_decode" "*,double,direct")
4881    (set_attr "fp_int_src" "true")])
4883 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_nointerunit"
4884   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4885         (float:MODEF
4886           (match_operand:SWI48 1 "memory_operand" "m,m")))]
4887   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4888    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4889   "@
4890    fild%Z1\t%1
4891    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4892   [(set_attr "type" "fmov,sseicvt")
4893    (set_attr "prefix" "orig,maybe_vex")
4894    (set_attr "mode" "<MODEF:MODE>")
4895    (set (attr "prefix_rex")
4896      (if_then_else
4897        (and (eq_attr "prefix" "maybe_vex")
4898             (match_test "<SWI48:MODE>mode == DImode"))
4899        (const_string "1")
4900        (const_string "*")))
4901    (set_attr "athlon_decode" "*,direct")
4902    (set_attr "amdfam10_decode" "*,double")
4903    (set_attr "bdver1_decode" "*,direct")
4904    (set_attr "fp_int_src" "true")])
4906 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4907   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4908         (float:MODEF
4909           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4910    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4911   "TARGET_SSE2 && TARGET_SSE_MATH
4912    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4913   "#"
4914   [(set_attr "type" "sseicvt")
4915    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4916    (set_attr "athlon_decode" "double,direct,double")
4917    (set_attr "amdfam10_decode" "vector,double,double")
4918    (set_attr "bdver1_decode" "double,direct,double")
4919    (set_attr "fp_int_src" "true")])
4921 (define_insn "*floatsi<mode>2_vector_sse"
4922   [(set (match_operand:MODEF 0 "register_operand" "=x")
4923         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4924   "TARGET_SSE2 && TARGET_SSE_MATH
4925    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4926   "#"
4927   [(set_attr "type" "sseicvt")
4928    (set_attr "mode" "<MODE>")
4929    (set_attr "athlon_decode" "direct")
4930    (set_attr "amdfam10_decode" "double")
4931    (set_attr "bdver1_decode" "direct")
4932    (set_attr "fp_int_src" "true")])
4934 (define_split
4935   [(set (match_operand:MODEF 0 "register_operand")
4936         (float:MODEF (match_operand:SI 1 "register_operand")))
4937    (clobber (match_operand:SI 2 "memory_operand"))]
4938   "TARGET_SSE2 && TARGET_SSE_MATH
4939    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4940    && reload_completed && SSE_REG_P (operands[0])"
4941   [(const_int 0)]
4943   rtx op1 = operands[1];
4945   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4946                                      <MODE>mode, 0);
4947   if (GET_CODE (op1) == SUBREG)
4948     op1 = SUBREG_REG (op1);
4950   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES_TO_VEC)
4951     {
4952       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4953       emit_insn (gen_sse2_loadld (operands[4],
4954                                   CONST0_RTX (V4SImode), operands[1]));
4955     }
4956   /* We can ignore possible trapping value in the
4957      high part of SSE register for non-trapping math. */
4958   else if (SSE_REG_P (op1) && !flag_trapping_math)
4959     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4960   else
4961     {
4962       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4963       emit_move_insn (operands[2], operands[1]);
4964       emit_insn (gen_sse2_loadld (operands[4],
4965                                   CONST0_RTX (V4SImode), operands[2]));
4966     }
4967   if (<ssevecmode>mode == V4SFmode)
4968     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4969   else
4970     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4971   DONE;
4974 (define_split
4975   [(set (match_operand:MODEF 0 "register_operand")
4976         (float:MODEF (match_operand:SI 1 "memory_operand")))
4977    (clobber (match_operand:SI 2 "memory_operand"))]
4978   "TARGET_SSE2 && TARGET_SSE_MATH
4979    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4980    && reload_completed && SSE_REG_P (operands[0])"
4981   [(const_int 0)]
4983   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4984                                      <MODE>mode, 0);
4985   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4987   emit_insn (gen_sse2_loadld (operands[4],
4988                               CONST0_RTX (V4SImode), operands[1]));
4989   if (<ssevecmode>mode == V4SFmode)
4990     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4991   else
4992     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4993   DONE;
4996 (define_split
4997   [(set (match_operand:MODEF 0 "register_operand")
4998         (float:MODEF (match_operand:SI 1 "register_operand")))]
4999   "TARGET_SSE2 && TARGET_SSE_MATH
5000    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5001    && reload_completed && SSE_REG_P (operands[0])"
5002   [(const_int 0)]
5004   rtx op1 = operands[1];
5006   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5007                                      <MODE>mode, 0);
5008   if (GET_CODE (op1) == SUBREG)
5009     op1 = SUBREG_REG (op1);
5011   if (GENERAL_REG_P (op1))
5012     {
5013       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5014       if (TARGET_INTER_UNIT_MOVES_TO_VEC)
5015         emit_insn (gen_sse2_loadld (operands[4],
5016                                     CONST0_RTX (V4SImode), operands[1]));
5017       else
5018         {
5019           operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5020                                               operands[1]);
5021           emit_insn (gen_sse2_loadld (operands[4],
5022                                       CONST0_RTX (V4SImode), operands[5]));
5023           ix86_free_from_memory (GET_MODE (operands[1]));
5024         }
5025     }
5026   /* We can ignore possible trapping value in the
5027      high part of SSE register for non-trapping math. */
5028   else if (SSE_REG_P (op1) && !flag_trapping_math)
5029     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5030   else
5031     gcc_unreachable ();
5032   if (<ssevecmode>mode == V4SFmode)
5033     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5034   else
5035     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5036   DONE;
5039 (define_split
5040   [(set (match_operand:MODEF 0 "register_operand")
5041         (float:MODEF (match_operand:SI 1 "memory_operand")))]
5042   "TARGET_SSE2 && TARGET_SSE_MATH
5043    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5044    && reload_completed && SSE_REG_P (operands[0])"
5045   [(const_int 0)]
5047   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5048                                      <MODE>mode, 0);
5049   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5051   emit_insn (gen_sse2_loadld (operands[4],
5052                               CONST0_RTX (V4SImode), operands[1]));
5053   if (<ssevecmode>mode == V4SFmode)
5054     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5055   else
5056     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5057   DONE;
5060 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_with_temp"
5061   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5062         (float:MODEF
5063           (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))
5064   (clobber (match_operand:SWI48 2 "memory_operand" "=m,X"))]
5065   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5066   "#"
5067   [(set_attr "type" "sseicvt")
5068    (set_attr "mode" "<MODEF:MODE>")
5069    (set_attr "athlon_decode" "double,direct")
5070    (set_attr "amdfam10_decode" "vector,double")
5071    (set_attr "bdver1_decode" "double,direct")
5072    (set_attr "btver2_decode" "double,double")
5073    (set_attr "fp_int_src" "true")])
5075 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_interunit"
5076   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5077         (float:MODEF
5078           (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))]
5079   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5080    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5081   "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5082   [(set_attr "type" "sseicvt")
5083    (set_attr "prefix" "maybe_vex")
5084    (set_attr "mode" "<MODEF:MODE>")
5085    (set (attr "prefix_rex")
5086      (if_then_else
5087        (and (eq_attr "prefix" "maybe_vex")
5088             (match_test "<SWI48:MODE>mode == DImode"))
5089        (const_string "1")
5090        (const_string "*")))
5091    (set_attr "athlon_decode" "double,direct")
5092    (set_attr "amdfam10_decode" "vector,double")
5093    (set_attr "bdver1_decode" "double,direct")
5094    (set_attr "btver2_decode" "double,double")
5095    (set_attr "fp_int_src" "true")])
5097 (define_split
5098   [(set (match_operand:MODEF 0 "register_operand")
5099         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))
5100    (clobber (match_operand:SWI48 2 "memory_operand"))]
5101   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5102    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5103    && reload_completed && SSE_REG_P (operands[0])"
5104   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5106 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_nointerunit"
5107   [(set (match_operand:MODEF 0 "register_operand" "=x")
5108         (float:MODEF
5109           (match_operand:SWI48 1 "memory_operand" "m")))]
5110   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5111    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5112   "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5113   [(set_attr "type" "sseicvt")
5114    (set_attr "prefix" "maybe_vex")
5115    (set_attr "mode" "<MODEF:MODE>")
5116    (set (attr "prefix_rex")
5117      (if_then_else
5118        (and (eq_attr "prefix" "maybe_vex")
5119             (match_test "<SWI48:MODE>mode == DImode"))
5120        (const_string "1")
5121        (const_string "*")))
5122    (set_attr "athlon_decode" "direct")
5123    (set_attr "amdfam10_decode" "double")
5124    (set_attr "bdver1_decode" "direct")
5125    (set_attr "fp_int_src" "true")])
5127 (define_split
5128   [(set (match_operand:MODEF 0 "register_operand")
5129         (float:MODEF (match_operand:SWI48 1 "register_operand")))
5130    (clobber (match_operand:SWI48 2 "memory_operand"))]
5131   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5132    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5133    && reload_completed && SSE_REG_P (operands[0])"
5134   [(set (match_dup 2) (match_dup 1))
5135    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5137 (define_split
5138   [(set (match_operand:MODEF 0 "register_operand")
5139         (float:MODEF (match_operand:SWI48 1 "memory_operand")))
5140    (clobber (match_operand:SWI48 2 "memory_operand"))]
5141   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5142    && reload_completed && SSE_REG_P (operands[0])"
5143   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5145 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5146   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5147         (float:X87MODEF
5148           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5149   (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5150   "TARGET_80387
5151    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5152   "@
5153    fild%Z1\t%1
5154    #"
5155   [(set_attr "type" "fmov,multi")
5156    (set_attr "mode" "<X87MODEF:MODE>")
5157    (set_attr "unit" "*,i387")
5158    (set_attr "fp_int_src" "true")])
5160 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5161   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5162         (float:X87MODEF
5163           (match_operand:SWI48x 1 "memory_operand" "m")))]
5164   "TARGET_80387
5165    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5166   "fild%Z1\t%1"
5167   [(set_attr "type" "fmov")
5168    (set_attr "mode" "<X87MODEF:MODE>")
5169    (set_attr "fp_int_src" "true")])
5171 (define_split
5172   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5173         (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5174    (clobber (match_operand:SWI48x 2 "memory_operand"))]
5175   "TARGET_80387
5176    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5177    && reload_completed"
5178   [(set (match_dup 2) (match_dup 1))
5179    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5181 (define_split
5182   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5183         (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5184    (clobber (match_operand:SWI48x 2 "memory_operand"))]
5185   "TARGET_80387
5186    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5187    && reload_completed"
5188   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5190 ;; Avoid partial SSE register dependency stalls
5192 (define_split
5193   [(set (match_operand:MODEF 0 "register_operand")
5194         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5195   "TARGET_SSE2 && TARGET_SSE_MATH
5196    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5197    && optimize_function_for_speed_p (cfun)
5198    && reload_completed && SSE_REG_P (operands[0])"
5199   [(set (match_dup 0)
5200         (vec_merge:<ssevecmode>
5201           (vec_duplicate:<ssevecmode>
5202             (float:MODEF (match_dup 1)))
5203           (match_dup 0)
5204           (const_int 1)))]
5206   operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5207                                      <MODE>mode, 0);
5208   emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
5211 (define_split
5212   [(set (match_operand:MODEF 0 "register_operand")
5213         (float:MODEF (match_operand:DI 1 "nonimmediate_operand")))]
5214   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5215    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5216    && optimize_function_for_speed_p (cfun)
5217    && reload_completed && SSE_REG_P (operands[0])"
5218   [(set (match_dup 0)
5219         (vec_merge:<ssevecmode>
5220           (vec_duplicate:<ssevecmode>
5221             (float:MODEF (match_dup 1)))
5222           (match_dup 0)
5223           (const_int 1)))]
5225   operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5226                                      <MODE>mode, 0);
5227   emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
5230 ;; Break partial reg stall for cvtsd2ss.
5232 (define_peephole2
5233   [(set (match_operand:SF 0 "register_operand")
5234         (float_truncate:SF
5235           (match_operand:DF 1 "nonimmediate_operand")))]
5236   "TARGET_SSE2 && TARGET_SSE_MATH
5237    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5238    && optimize_function_for_speed_p (cfun)
5239    && SSE_REG_P (operands[0])
5240    && (!SSE_REG_P (operands[1])
5241        || REGNO (operands[0]) != REGNO (operands[1]))"
5242   [(set (match_dup 0)
5243         (vec_merge:V4SF
5244           (vec_duplicate:V4SF
5245             (float_truncate:V2SF
5246               (match_dup 1)))
5247           (match_dup 0)
5248           (const_int 1)))]
5250   operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
5251                                      SFmode, 0);
5252   operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
5253                                      DFmode, 0);
5254   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5257 ;; Break partial reg stall for cvtss2sd.
5259 (define_peephole2
5260   [(set (match_operand:DF 0 "register_operand")
5261         (float_extend:DF
5262           (match_operand:SF 1 "nonimmediate_operand")))]
5263   "TARGET_SSE2 && TARGET_SSE_MATH
5264    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5265    && optimize_function_for_speed_p (cfun)
5266    && SSE_REG_P (operands[0])
5267    && (!SSE_REG_P (operands[1])
5268        || REGNO (operands[0]) != REGNO (operands[1]))"
5269   [(set (match_dup 0)
5270         (vec_merge:V2DF
5271           (float_extend:V2DF
5272             (vec_select:V2SF
5273               (match_dup 1)
5274               (parallel [(const_int 0) (const_int 1)])))
5275           (match_dup 0)
5276           (const_int 1)))]
5278   operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
5279                                      DFmode, 0);
5280   operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5281                                      SFmode, 0);
5282   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5285 ;; Avoid store forwarding (partial memory) stall penalty
5286 ;; by passing DImode value through XMM registers.  */
5288 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5289   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5290         (float:X87MODEF
5291           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5292    (clobber (match_scratch:V4SI 3 "=X,x"))
5293    (clobber (match_scratch:V4SI 4 "=X,x"))
5294    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5295   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5296    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5297    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5298   "#"
5299   [(set_attr "type" "multi")
5300    (set_attr "mode" "<X87MODEF:MODE>")
5301    (set_attr "unit" "i387")
5302    (set_attr "fp_int_src" "true")])
5304 (define_split
5305   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5306         (float:X87MODEF (match_operand:DI 1 "register_operand")))
5307    (clobber (match_scratch:V4SI 3))
5308    (clobber (match_scratch:V4SI 4))
5309    (clobber (match_operand:DI 2 "memory_operand"))]
5310   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5311    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5312    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5313    && reload_completed"
5314   [(set (match_dup 2) (match_dup 3))
5315    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5317   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5318      Assemble the 64-bit DImode value in an xmm register.  */
5319   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5320                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5321   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5322                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5323   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5324                                          operands[4]));
5326   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5329 (define_split
5330   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5331         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5332    (clobber (match_scratch:V4SI 3))
5333    (clobber (match_scratch:V4SI 4))
5334    (clobber (match_operand:DI 2 "memory_operand"))]
5335   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5336    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5337    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5338    && reload_completed"
5339   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5341 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5342   [(set (match_operand:MODEF 0 "register_operand")
5343         (unsigned_float:MODEF
5344           (match_operand:SWI12 1 "nonimmediate_operand")))]
5345   "!TARGET_64BIT
5346    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5348   operands[1] = convert_to_mode (SImode, operands[1], 1);
5349   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5350   DONE;
5353 ;; Avoid store forwarding (partial memory) stall penalty by extending
5354 ;; SImode value to DImode through XMM register instead of pushing two
5355 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES_TO_VEC
5356 ;; targets benefit from this optimization. Also note that fild
5357 ;; loads from memory only.
5359 (define_insn "*floatunssi<mode>2_1"
5360   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5361         (unsigned_float:X87MODEF
5362           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5363    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5364    (clobber (match_scratch:SI 3 "=X,x"))]
5365   "!TARGET_64BIT
5366    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5367    && TARGET_SSE"
5368   "#"
5369   [(set_attr "type" "multi")
5370    (set_attr "mode" "<MODE>")])
5372 (define_split
5373   [(set (match_operand:X87MODEF 0 "register_operand")
5374         (unsigned_float:X87MODEF
5375           (match_operand:SI 1 "register_operand")))
5376    (clobber (match_operand:DI 2 "memory_operand"))
5377    (clobber (match_scratch:SI 3))]
5378   "!TARGET_64BIT
5379    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5380    && TARGET_SSE
5381    && reload_completed"
5382   [(set (match_dup 2) (match_dup 1))
5383    (set (match_dup 0)
5384         (float:X87MODEF (match_dup 2)))]
5385   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5387 (define_split
5388   [(set (match_operand:X87MODEF 0 "register_operand")
5389         (unsigned_float:X87MODEF
5390           (match_operand:SI 1 "memory_operand")))
5391    (clobber (match_operand:DI 2 "memory_operand"))
5392    (clobber (match_scratch:SI 3))]
5393   "!TARGET_64BIT
5394    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5395    && TARGET_SSE
5396    && reload_completed"
5397   [(set (match_dup 2) (match_dup 3))
5398    (set (match_dup 0)
5399         (float:X87MODEF (match_dup 2)))]
5401   emit_move_insn (operands[3], operands[1]);
5402   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5405 (define_expand "floatunssi<mode>2"
5406   [(parallel
5407      [(set (match_operand:X87MODEF 0 "register_operand")
5408            (unsigned_float:X87MODEF
5409              (match_operand:SI 1 "nonimmediate_operand")))
5410       (clobber (match_dup 2))
5411       (clobber (match_scratch:SI 3))])]
5412   "!TARGET_64BIT
5413    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5414         && TARGET_SSE)
5415        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5417   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5418     {
5419       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5420       DONE;
5421     }
5422   else
5423     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5426 (define_expand "floatunsdisf2"
5427   [(use (match_operand:SF 0 "register_operand"))
5428    (use (match_operand:DI 1 "nonimmediate_operand"))]
5429   "TARGET_64BIT && TARGET_SSE_MATH"
5430   "x86_emit_floatuns (operands); DONE;")
5432 (define_expand "floatunsdidf2"
5433   [(use (match_operand:DF 0 "register_operand"))
5434    (use (match_operand:DI 1 "nonimmediate_operand"))]
5435   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5436    && TARGET_SSE2 && TARGET_SSE_MATH"
5438   if (TARGET_64BIT)
5439     x86_emit_floatuns (operands);
5440   else
5441     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5442   DONE;
5445 ;; Load effective address instructions
5447 (define_insn_and_split "*lea<mode>"
5448   [(set (match_operand:SWI48 0 "register_operand" "=r")
5449         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5450   ""
5452   if (SImode_address_operand (operands[1], VOIDmode))
5453     {
5454       gcc_assert (TARGET_64BIT);
5455       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5456     }
5457   else 
5458     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5460   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5461   [(const_int 0)]
5463   enum machine_mode mode = <MODE>mode;
5464   rtx pat;
5466   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5467      change operands[] array behind our back.  */
5468   pat = PATTERN (curr_insn);
5470   operands[0] = SET_DEST (pat);
5471   operands[1] = SET_SRC (pat);
5473   /* Emit all operations in SImode for zero-extended addresses.  */
5474   if (SImode_address_operand (operands[1], VOIDmode))
5475     mode = SImode;
5477   ix86_split_lea_for_addr (curr_insn, operands, mode);
5479   /* Zero-extend return register to DImode for zero-extended addresses.  */
5480   if (mode != <MODE>mode)
5481     emit_insn (gen_zero_extendsidi2
5482                (operands[0], gen_lowpart (mode, operands[0])));
5484   DONE;
5486   [(set_attr "type" "lea")
5487    (set (attr "mode")
5488      (if_then_else
5489        (match_operand 1 "SImode_address_operand")
5490        (const_string "SI")
5491        (const_string "<MODE>")))])
5493 ;; Add instructions
5495 (define_expand "add<mode>3"
5496   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5497         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5498                     (match_operand:SDWIM 2 "<general_operand>")))]
5499   ""
5500   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5502 (define_insn_and_split "*add<dwi>3_doubleword"
5503   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5504         (plus:<DWI>
5505           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5506           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5507    (clobber (reg:CC FLAGS_REG))]
5508   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5509   "#"
5510   "reload_completed"
5511   [(parallel [(set (reg:CC FLAGS_REG)
5512                    (unspec:CC [(match_dup 1) (match_dup 2)]
5513                               UNSPEC_ADD_CARRY))
5514               (set (match_dup 0)
5515                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5516    (parallel [(set (match_dup 3)
5517                    (plus:DWIH
5518                      (match_dup 4)
5519                      (plus:DWIH
5520                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5521                        (match_dup 5))))
5522               (clobber (reg:CC FLAGS_REG))])]
5523   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5525 (define_insn "*add<mode>3_cc"
5526   [(set (reg:CC FLAGS_REG)
5527         (unspec:CC
5528           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5529            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5530           UNSPEC_ADD_CARRY))
5531    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5532         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5533   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5534   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5535   [(set_attr "type" "alu")
5536    (set_attr "mode" "<MODE>")])
5538 (define_insn "addqi3_cc"
5539   [(set (reg:CC FLAGS_REG)
5540         (unspec:CC
5541           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5542            (match_operand:QI 2 "general_operand" "qn,qm")]
5543           UNSPEC_ADD_CARRY))
5544    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5545         (plus:QI (match_dup 1) (match_dup 2)))]
5546   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5547   "add{b}\t{%2, %0|%0, %2}"
5548   [(set_attr "type" "alu")
5549    (set_attr "mode" "QI")])
5551 (define_insn "*add<mode>_1"
5552   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5553         (plus:SWI48
5554           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5555           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5556    (clobber (reg:CC FLAGS_REG))]
5557   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5559   switch (get_attr_type (insn))
5560     {
5561     case TYPE_LEA:
5562       return "#";
5564     case TYPE_INCDEC:
5565       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5566       if (operands[2] == const1_rtx)
5567         return "inc{<imodesuffix>}\t%0";
5568       else
5569         {
5570           gcc_assert (operands[2] == constm1_rtx);
5571           return "dec{<imodesuffix>}\t%0";
5572         }
5574     default:
5575       /* For most processors, ADD is faster than LEA.  This alternative
5576          was added to use ADD as much as possible.  */
5577       if (which_alternative == 2)
5578         {
5579           rtx tmp;
5580           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5581         }
5582         
5583       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5584       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5585         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5587       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5588     }
5590   [(set (attr "type")
5591      (cond [(eq_attr "alternative" "3")
5592               (const_string "lea")
5593             (match_operand:SWI48 2 "incdec_operand")
5594               (const_string "incdec")
5595            ]
5596            (const_string "alu")))
5597    (set (attr "length_immediate")
5598       (if_then_else
5599         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5600         (const_string "1")
5601         (const_string "*")))
5602    (set_attr "mode" "<MODE>")])
5604 ;; It may seem that nonimmediate operand is proper one for operand 1.
5605 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5606 ;; we take care in ix86_binary_operator_ok to not allow two memory
5607 ;; operands so proper swapping will be done in reload.  This allow
5608 ;; patterns constructed from addsi_1 to match.
5610 (define_insn "addsi_1_zext"
5611   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5612         (zero_extend:DI
5613           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5614                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5615    (clobber (reg:CC FLAGS_REG))]
5616   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5618   switch (get_attr_type (insn))
5619     {
5620     case TYPE_LEA:
5621       return "#";
5623     case TYPE_INCDEC:
5624       if (operands[2] == const1_rtx)
5625         return "inc{l}\t%k0";
5626       else
5627         {
5628           gcc_assert (operands[2] == constm1_rtx);
5629           return "dec{l}\t%k0";
5630         }
5632     default:
5633       /* For most processors, ADD is faster than LEA.  This alternative
5634          was added to use ADD as much as possible.  */
5635       if (which_alternative == 1)
5636         {
5637           rtx tmp;
5638           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5639         }
5641       if (x86_maybe_negate_const_int (&operands[2], SImode))
5642         return "sub{l}\t{%2, %k0|%k0, %2}";
5644       return "add{l}\t{%2, %k0|%k0, %2}";
5645     }
5647   [(set (attr "type")
5648      (cond [(eq_attr "alternative" "2")
5649               (const_string "lea")
5650             (match_operand:SI 2 "incdec_operand")
5651               (const_string "incdec")
5652            ]
5653            (const_string "alu")))
5654    (set (attr "length_immediate")
5655       (if_then_else
5656         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5657         (const_string "1")
5658         (const_string "*")))
5659    (set_attr "mode" "SI")])
5661 (define_insn "*addhi_1"
5662   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5663         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5664                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5665    (clobber (reg:CC FLAGS_REG))]
5666   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5668   switch (get_attr_type (insn))
5669     {
5670     case TYPE_LEA:
5671       return "#";
5673     case TYPE_INCDEC:
5674       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5675       if (operands[2] == const1_rtx)
5676         return "inc{w}\t%0";
5677       else
5678         {
5679           gcc_assert (operands[2] == constm1_rtx);
5680           return "dec{w}\t%0";
5681         }
5683     default:
5684       /* For most processors, ADD is faster than LEA.  This alternative
5685          was added to use ADD as much as possible.  */
5686       if (which_alternative == 2)
5687         {
5688           rtx tmp;
5689           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5690         }
5692       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5693       if (x86_maybe_negate_const_int (&operands[2], HImode))
5694         return "sub{w}\t{%2, %0|%0, %2}";
5696       return "add{w}\t{%2, %0|%0, %2}";
5697     }
5699   [(set (attr "type")
5700      (cond [(eq_attr "alternative" "3")
5701               (const_string "lea")
5702             (match_operand:HI 2 "incdec_operand")
5703               (const_string "incdec")
5704            ]
5705            (const_string "alu")))
5706    (set (attr "length_immediate")
5707       (if_then_else
5708         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5709         (const_string "1")
5710         (const_string "*")))
5711    (set_attr "mode" "HI,HI,HI,SI")])
5713 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5714 (define_insn "*addqi_1"
5715   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5716         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5717                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5718    (clobber (reg:CC FLAGS_REG))]
5719   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5721   bool widen = (which_alternative == 3 || which_alternative == 4);
5723   switch (get_attr_type (insn))
5724     {
5725     case TYPE_LEA:
5726       return "#";
5728     case TYPE_INCDEC:
5729       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5730       if (operands[2] == const1_rtx)
5731         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5732       else
5733         {
5734           gcc_assert (operands[2] == constm1_rtx);
5735           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5736         }
5738     default:
5739       /* For most processors, ADD is faster than LEA.  These alternatives
5740          were added to use ADD as much as possible.  */
5741       if (which_alternative == 2 || which_alternative == 4)
5742         {
5743           rtx tmp;
5744           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5745         }
5747       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5748       if (x86_maybe_negate_const_int (&operands[2], QImode))
5749         {
5750           if (widen)
5751             return "sub{l}\t{%2, %k0|%k0, %2}";
5752           else
5753             return "sub{b}\t{%2, %0|%0, %2}";
5754         }
5755       if (widen)
5756         return "add{l}\t{%k2, %k0|%k0, %k2}";
5757       else
5758         return "add{b}\t{%2, %0|%0, %2}";
5759     }
5761   [(set (attr "type")
5762      (cond [(eq_attr "alternative" "5")
5763               (const_string "lea")
5764             (match_operand:QI 2 "incdec_operand")
5765               (const_string "incdec")
5766            ]
5767            (const_string "alu")))
5768    (set (attr "length_immediate")
5769       (if_then_else
5770         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5771         (const_string "1")
5772         (const_string "*")))
5773    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5775 (define_insn "*addqi_1_slp"
5776   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5777         (plus:QI (match_dup 0)
5778                  (match_operand:QI 1 "general_operand" "qn,qm")))
5779    (clobber (reg:CC FLAGS_REG))]
5780   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5781    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5783   switch (get_attr_type (insn))
5784     {
5785     case TYPE_INCDEC:
5786       if (operands[1] == const1_rtx)
5787         return "inc{b}\t%0";
5788       else
5789         {
5790           gcc_assert (operands[1] == constm1_rtx);
5791           return "dec{b}\t%0";
5792         }
5794     default:
5795       if (x86_maybe_negate_const_int (&operands[1], QImode))
5796         return "sub{b}\t{%1, %0|%0, %1}";
5798       return "add{b}\t{%1, %0|%0, %1}";
5799     }
5801   [(set (attr "type")
5802      (if_then_else (match_operand:QI 1 "incdec_operand")
5803         (const_string "incdec")
5804         (const_string "alu1")))
5805    (set (attr "memory")
5806      (if_then_else (match_operand 1 "memory_operand")
5807         (const_string "load")
5808         (const_string "none")))
5809    (set_attr "mode" "QI")])
5811 ;; Split non destructive adds if we cannot use lea.
5812 (define_split
5813   [(set (match_operand:SWI48 0 "register_operand")
5814         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5815                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5816    (clobber (reg:CC FLAGS_REG))]
5817   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5818   [(set (match_dup 0) (match_dup 1))
5819    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5820               (clobber (reg:CC FLAGS_REG))])])
5822 ;; Convert add to the lea pattern to avoid flags dependency.
5823 (define_split
5824   [(set (match_operand:SWI 0 "register_operand")
5825         (plus:SWI (match_operand:SWI 1 "register_operand")
5826                   (match_operand:SWI 2 "<nonmemory_operand>")))
5827    (clobber (reg:CC FLAGS_REG))]
5828   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5829   [(const_int 0)]
5831   enum machine_mode mode = <MODE>mode;
5832   rtx pat;
5834   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5835     { 
5836       mode = SImode; 
5837       operands[0] = gen_lowpart (mode, operands[0]);
5838       operands[1] = gen_lowpart (mode, operands[1]);
5839       operands[2] = gen_lowpart (mode, operands[2]);
5840     }
5842   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5844   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5845   DONE;
5848 ;; Split non destructive adds if we cannot use lea.
5849 (define_split
5850   [(set (match_operand:DI 0 "register_operand")
5851         (zero_extend:DI
5852           (plus:SI (match_operand:SI 1 "register_operand")
5853                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5854    (clobber (reg:CC FLAGS_REG))]
5855   "TARGET_64BIT
5856    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5857   [(set (match_dup 3) (match_dup 1))
5858    (parallel [(set (match_dup 0)
5859                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5860               (clobber (reg:CC FLAGS_REG))])]
5861   "operands[3] = gen_lowpart (SImode, operands[0]);")
5863 ;; Convert add to the lea pattern to avoid flags dependency.
5864 (define_split
5865   [(set (match_operand:DI 0 "register_operand")
5866         (zero_extend:DI
5867           (plus:SI (match_operand:SI 1 "register_operand")
5868                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5869    (clobber (reg:CC FLAGS_REG))]
5870   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5871   [(set (match_dup 0)
5872         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5874 (define_insn "*add<mode>_2"
5875   [(set (reg FLAGS_REG)
5876         (compare
5877           (plus:SWI
5878             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5879             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5880           (const_int 0)))
5881    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5882         (plus:SWI (match_dup 1) (match_dup 2)))]
5883   "ix86_match_ccmode (insn, CCGOCmode)
5884    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5886   switch (get_attr_type (insn))
5887     {
5888     case TYPE_INCDEC:
5889       if (operands[2] == const1_rtx)
5890         return "inc{<imodesuffix>}\t%0";
5891       else
5892         {
5893           gcc_assert (operands[2] == constm1_rtx);
5894           return "dec{<imodesuffix>}\t%0";
5895         }
5897     default:
5898       if (which_alternative == 2)
5899         {
5900           rtx tmp;
5901           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5902         }
5903         
5904       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5905       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5906         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5908       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5909     }
5911   [(set (attr "type")
5912      (if_then_else (match_operand:SWI 2 "incdec_operand")
5913         (const_string "incdec")
5914         (const_string "alu")))
5915    (set (attr "length_immediate")
5916       (if_then_else
5917         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5918         (const_string "1")
5919         (const_string "*")))
5920    (set_attr "mode" "<MODE>")])
5922 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5923 (define_insn "*addsi_2_zext"
5924   [(set (reg FLAGS_REG)
5925         (compare
5926           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5927                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5928           (const_int 0)))
5929    (set (match_operand:DI 0 "register_operand" "=r,r")
5930         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5931   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5932    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5934   switch (get_attr_type (insn))
5935     {
5936     case TYPE_INCDEC:
5937       if (operands[2] == const1_rtx)
5938         return "inc{l}\t%k0";
5939       else
5940         {
5941           gcc_assert (operands[2] == constm1_rtx);
5942           return "dec{l}\t%k0";
5943         }
5945     default:
5946       if (which_alternative == 1)
5947         {
5948           rtx tmp;
5949           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5950         }
5952       if (x86_maybe_negate_const_int (&operands[2], SImode))
5953         return "sub{l}\t{%2, %k0|%k0, %2}";
5955       return "add{l}\t{%2, %k0|%k0, %2}";
5956     }
5958   [(set (attr "type")
5959      (if_then_else (match_operand:SI 2 "incdec_operand")
5960         (const_string "incdec")
5961         (const_string "alu")))
5962    (set (attr "length_immediate")
5963       (if_then_else
5964         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5965         (const_string "1")
5966         (const_string "*")))
5967    (set_attr "mode" "SI")])
5969 (define_insn "*add<mode>_3"
5970   [(set (reg FLAGS_REG)
5971         (compare
5972           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5973           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5974    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5975   "ix86_match_ccmode (insn, CCZmode)
5976    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5978   switch (get_attr_type (insn))
5979     {
5980     case TYPE_INCDEC:
5981       if (operands[2] == const1_rtx)
5982         return "inc{<imodesuffix>}\t%0";
5983       else
5984         {
5985           gcc_assert (operands[2] == constm1_rtx);
5986           return "dec{<imodesuffix>}\t%0";
5987         }
5989     default:
5990       if (which_alternative == 1)
5991         {
5992           rtx tmp;
5993           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5994         }
5996       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5997       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5998         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6000       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6001     }
6003   [(set (attr "type")
6004      (if_then_else (match_operand:SWI 2 "incdec_operand")
6005         (const_string "incdec")
6006         (const_string "alu")))
6007    (set (attr "length_immediate")
6008       (if_then_else
6009         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6010         (const_string "1")
6011         (const_string "*")))
6012    (set_attr "mode" "<MODE>")])
6014 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6015 (define_insn "*addsi_3_zext"
6016   [(set (reg FLAGS_REG)
6017         (compare
6018           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6019           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6020    (set (match_operand:DI 0 "register_operand" "=r,r")
6021         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6022   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6023    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6025   switch (get_attr_type (insn))
6026     {
6027     case TYPE_INCDEC:
6028       if (operands[2] == const1_rtx)
6029         return "inc{l}\t%k0";
6030       else
6031         {
6032           gcc_assert (operands[2] == constm1_rtx);
6033           return "dec{l}\t%k0";
6034         }
6036     default:
6037       if (which_alternative == 1)
6038         {
6039           rtx tmp;
6040           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6041         }
6043       if (x86_maybe_negate_const_int (&operands[2], SImode))
6044         return "sub{l}\t{%2, %k0|%k0, %2}";
6046       return "add{l}\t{%2, %k0|%k0, %2}";
6047     }
6049   [(set (attr "type")
6050      (if_then_else (match_operand:SI 2 "incdec_operand")
6051         (const_string "incdec")
6052         (const_string "alu")))
6053    (set (attr "length_immediate")
6054       (if_then_else
6055         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6056         (const_string "1")
6057         (const_string "*")))
6058    (set_attr "mode" "SI")])
6060 ; For comparisons against 1, -1 and 128, we may generate better code
6061 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6062 ; is matched then.  We can't accept general immediate, because for
6063 ; case of overflows,  the result is messed up.
6064 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6065 ; only for comparisons not depending on it.
6067 (define_insn "*adddi_4"
6068   [(set (reg FLAGS_REG)
6069         (compare
6070           (match_operand:DI 1 "nonimmediate_operand" "0")
6071           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6072    (clobber (match_scratch:DI 0 "=rm"))]
6073   "TARGET_64BIT
6074    && ix86_match_ccmode (insn, CCGCmode)"
6076   switch (get_attr_type (insn))
6077     {
6078     case TYPE_INCDEC:
6079       if (operands[2] == constm1_rtx)
6080         return "inc{q}\t%0";
6081       else
6082         {
6083           gcc_assert (operands[2] == const1_rtx);
6084           return "dec{q}\t%0";
6085         }
6087     default:
6088       if (x86_maybe_negate_const_int (&operands[2], DImode))
6089         return "add{q}\t{%2, %0|%0, %2}";
6091       return "sub{q}\t{%2, %0|%0, %2}";
6092     }
6094   [(set (attr "type")
6095      (if_then_else (match_operand:DI 2 "incdec_operand")
6096         (const_string "incdec")
6097         (const_string "alu")))
6098    (set (attr "length_immediate")
6099       (if_then_else
6100         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6101         (const_string "1")
6102         (const_string "*")))
6103    (set_attr "mode" "DI")])
6105 ; For comparisons against 1, -1 and 128, we may generate better code
6106 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6107 ; is matched then.  We can't accept general immediate, because for
6108 ; case of overflows,  the result is messed up.
6109 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6110 ; only for comparisons not depending on it.
6112 (define_insn "*add<mode>_4"
6113   [(set (reg FLAGS_REG)
6114         (compare
6115           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6116           (match_operand:SWI124 2 "const_int_operand" "n")))
6117    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6118   "ix86_match_ccmode (insn, CCGCmode)"
6120   switch (get_attr_type (insn))
6121     {
6122     case TYPE_INCDEC:
6123       if (operands[2] == constm1_rtx)
6124         return "inc{<imodesuffix>}\t%0";
6125       else
6126         {
6127           gcc_assert (operands[2] == const1_rtx);
6128           return "dec{<imodesuffix>}\t%0";
6129         }
6131     default:
6132       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6133         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6135       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6136     }
6138   [(set (attr "type")
6139      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6140         (const_string "incdec")
6141         (const_string "alu")))
6142    (set (attr "length_immediate")
6143       (if_then_else
6144         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6145         (const_string "1")
6146         (const_string "*")))
6147    (set_attr "mode" "<MODE>")])
6149 (define_insn "*add<mode>_5"
6150   [(set (reg FLAGS_REG)
6151         (compare
6152           (plus:SWI
6153             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6154             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6155           (const_int 0)))
6156    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6157   "ix86_match_ccmode (insn, CCGOCmode)
6158    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6160   switch (get_attr_type (insn))
6161     {
6162     case TYPE_INCDEC:
6163       if (operands[2] == const1_rtx)
6164         return "inc{<imodesuffix>}\t%0";
6165       else
6166         {
6167           gcc_assert (operands[2] == constm1_rtx);
6168           return "dec{<imodesuffix>}\t%0";
6169         }
6171     default:
6172       if (which_alternative == 1)
6173         {
6174           rtx tmp;
6175           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6176         }
6178       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6179       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6180         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6182       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6183     }
6185   [(set (attr "type")
6186      (if_then_else (match_operand:SWI 2 "incdec_operand")
6187         (const_string "incdec")
6188         (const_string "alu")))
6189    (set (attr "length_immediate")
6190       (if_then_else
6191         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6192         (const_string "1")
6193         (const_string "*")))
6194    (set_attr "mode" "<MODE>")])
6196 (define_insn "addqi_ext_1"
6197   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
6198                          (const_int 8)
6199                          (const_int 8))
6200         (plus:SI
6201           (zero_extract:SI
6202             (match_operand 1 "ext_register_operand" "0,0")
6203             (const_int 8)
6204             (const_int 8))
6205           (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
6206    (clobber (reg:CC FLAGS_REG))]
6207   ""
6209   switch (get_attr_type (insn))
6210     {
6211     case TYPE_INCDEC:
6212       if (operands[2] == const1_rtx)
6213         return "inc{b}\t%h0";
6214       else
6215         {
6216           gcc_assert (operands[2] == constm1_rtx);
6217           return "dec{b}\t%h0";
6218         }
6220     default:
6221       return "add{b}\t{%2, %h0|%h0, %2}";
6222     }
6224   [(set_attr "isa" "*,nox64")
6225    (set (attr "type")
6226      (if_then_else (match_operand:QI 2 "incdec_operand")
6227         (const_string "incdec")
6228         (const_string "alu")))
6229    (set_attr "modrm" "1")
6230    (set_attr "mode" "QI")])
6232 (define_insn "*addqi_ext_2"
6233   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6234                          (const_int 8)
6235                          (const_int 8))
6236         (plus:SI
6237           (zero_extract:SI
6238             (match_operand 1 "ext_register_operand" "%0")
6239             (const_int 8)
6240             (const_int 8))
6241           (zero_extract:SI
6242             (match_operand 2 "ext_register_operand" "Q")
6243             (const_int 8)
6244             (const_int 8))))
6245    (clobber (reg:CC FLAGS_REG))]
6246   ""
6247   "add{b}\t{%h2, %h0|%h0, %h2}"
6248   [(set_attr "type" "alu")
6249    (set_attr "mode" "QI")])
6251 ;; Add with jump on overflow.
6252 (define_expand "addv<mode>4"
6253   [(parallel [(set (reg:CCO FLAGS_REG)
6254                    (eq:CCO (plus:<DWI>
6255                               (sign_extend:<DWI>
6256                                  (match_operand:SWI 1 "nonimmediate_operand"))
6257                               (sign_extend:<DWI>
6258                                  (match_operand:SWI 2 "<general_operand>")))
6259                            (sign_extend:<DWI>
6260                               (plus:SWI (match_dup 1) (match_dup 2)))))
6261               (set (match_operand:SWI 0 "register_operand")
6262                    (plus:SWI (match_dup 1) (match_dup 2)))])
6263    (set (pc) (if_then_else
6264                (eq (reg:CCO FLAGS_REG) (const_int 0))
6265                (label_ref (match_operand 3))
6266                (pc)))]
6267   ""
6268   "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6270 (define_insn "*addv<mode>4"
6271   [(set (reg:CCO FLAGS_REG)
6272         (eq:CCO (plus:<DWI>
6273                    (sign_extend:<DWI>
6274                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6275                    (sign_extend:<DWI>
6276                       (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>")))
6277                 (sign_extend:<DWI>
6278                    (plus:SWI (match_dup 1) (match_dup 2)))))
6279    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6280         (plus:SWI (match_dup 1) (match_dup 2)))]
6281   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6282   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6283   [(set_attr "type" "alu")
6284    (set_attr "mode" "<MODE>")])
6286 ;; The lea patterns for modes less than 32 bits need to be matched by
6287 ;; several insns converted to real lea by splitters.
6289 (define_insn_and_split "*lea_general_1"
6290   [(set (match_operand 0 "register_operand" "=r")
6291         (plus (plus (match_operand 1 "index_register_operand" "l")
6292                     (match_operand 2 "register_operand" "r"))
6293               (match_operand 3 "immediate_operand" "i")))]
6294   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6295    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6296    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6297    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6298    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6299        || GET_MODE (operands[3]) == VOIDmode)"
6300   "#"
6301   "&& reload_completed"
6302   [(const_int 0)]
6304   enum machine_mode mode = SImode;
6305   rtx pat;
6307   operands[0] = gen_lowpart (mode, operands[0]);
6308   operands[1] = gen_lowpart (mode, operands[1]);
6309   operands[2] = gen_lowpart (mode, operands[2]);
6310   operands[3] = gen_lowpart (mode, operands[3]);
6312   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6313                       operands[3]);
6315   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6316   DONE;
6318   [(set_attr "type" "lea")
6319    (set_attr "mode" "SI")])
6321 (define_insn_and_split "*lea_general_2"
6322   [(set (match_operand 0 "register_operand" "=r")
6323         (plus (mult (match_operand 1 "index_register_operand" "l")
6324                     (match_operand 2 "const248_operand" "n"))
6325               (match_operand 3 "nonmemory_operand" "ri")))]
6326   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6327    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6328    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6329    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6330        || GET_MODE (operands[3]) == VOIDmode)"
6331   "#"
6332   "&& reload_completed"
6333   [(const_int 0)]
6335   enum machine_mode mode = SImode;
6336   rtx pat;
6338   operands[0] = gen_lowpart (mode, operands[0]);
6339   operands[1] = gen_lowpart (mode, operands[1]);
6340   operands[3] = gen_lowpart (mode, operands[3]);
6342   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6343                       operands[3]);
6345   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6346   DONE;
6348   [(set_attr "type" "lea")
6349    (set_attr "mode" "SI")])
6351 (define_insn_and_split "*lea_general_3"
6352   [(set (match_operand 0 "register_operand" "=r")
6353         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6354                           (match_operand 2 "const248_operand" "n"))
6355                     (match_operand 3 "register_operand" "r"))
6356               (match_operand 4 "immediate_operand" "i")))]
6357   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6358    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6359    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6360    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6361   "#"
6362   "&& reload_completed"
6363   [(const_int 0)]
6365   enum machine_mode mode = SImode;
6366   rtx pat;
6368   operands[0] = gen_lowpart (mode, operands[0]);
6369   operands[1] = gen_lowpart (mode, operands[1]);
6370   operands[3] = gen_lowpart (mode, operands[3]);
6371   operands[4] = gen_lowpart (mode, operands[4]);
6373   pat = gen_rtx_PLUS (mode,
6374                       gen_rtx_PLUS (mode,
6375                                     gen_rtx_MULT (mode, operands[1],
6376                                                         operands[2]),
6377                                     operands[3]),
6378                       operands[4]);
6380   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6381   DONE;
6383   [(set_attr "type" "lea")
6384    (set_attr "mode" "SI")])
6386 (define_insn_and_split "*lea_general_4"
6387   [(set (match_operand 0 "register_operand" "=r")
6388         (any_or (ashift
6389                   (match_operand 1 "index_register_operand" "l")
6390                   (match_operand 2 "const_int_operand" "n"))
6391                 (match_operand 3 "const_int_operand" "n")))]
6392   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6393       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6394     || GET_MODE (operands[0]) == SImode
6395     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6396    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6397    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6398    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6399        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6400   "#"
6401   "&& reload_completed"
6402   [(const_int 0)]
6404   enum machine_mode mode = GET_MODE (operands[0]);
6405   rtx pat;
6407   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6408     { 
6409       mode = SImode; 
6410       operands[0] = gen_lowpart (mode, operands[0]);
6411       operands[1] = gen_lowpart (mode, operands[1]);
6412     }
6414   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6416   pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6417                        INTVAL (operands[3]));
6419   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6420   DONE;
6422   [(set_attr "type" "lea")
6423    (set (attr "mode")
6424       (if_then_else (match_operand:DI 0)
6425         (const_string "DI")
6426         (const_string "SI")))])
6428 ;; Subtract instructions
6430 (define_expand "sub<mode>3"
6431   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6432         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6433                      (match_operand:SDWIM 2 "<general_operand>")))]
6434   ""
6435   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6437 (define_insn_and_split "*sub<dwi>3_doubleword"
6438   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6439         (minus:<DWI>
6440           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6441           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6442    (clobber (reg:CC FLAGS_REG))]
6443   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6444   "#"
6445   "reload_completed"
6446   [(parallel [(set (reg:CC FLAGS_REG)
6447                    (compare:CC (match_dup 1) (match_dup 2)))
6448               (set (match_dup 0)
6449                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6450    (parallel [(set (match_dup 3)
6451                    (minus:DWIH
6452                      (match_dup 4)
6453                      (plus:DWIH
6454                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6455                        (match_dup 5))))
6456               (clobber (reg:CC FLAGS_REG))])]
6457   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6459 (define_insn "*sub<mode>_1"
6460   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6461         (minus:SWI
6462           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6463           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6464    (clobber (reg:CC FLAGS_REG))]
6465   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6466   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6467   [(set_attr "type" "alu")
6468    (set_attr "mode" "<MODE>")])
6470 (define_insn "*subsi_1_zext"
6471   [(set (match_operand:DI 0 "register_operand" "=r")
6472         (zero_extend:DI
6473           (minus:SI (match_operand:SI 1 "register_operand" "0")
6474                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6475    (clobber (reg:CC FLAGS_REG))]
6476   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6477   "sub{l}\t{%2, %k0|%k0, %2}"
6478   [(set_attr "type" "alu")
6479    (set_attr "mode" "SI")])
6481 (define_insn "*subqi_1_slp"
6482   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6483         (minus:QI (match_dup 0)
6484                   (match_operand:QI 1 "general_operand" "qn,qm")))
6485    (clobber (reg:CC FLAGS_REG))]
6486   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6487    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6488   "sub{b}\t{%1, %0|%0, %1}"
6489   [(set_attr "type" "alu1")
6490    (set_attr "mode" "QI")])
6492 (define_insn "*sub<mode>_2"
6493   [(set (reg FLAGS_REG)
6494         (compare
6495           (minus:SWI
6496             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6497             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6498           (const_int 0)))
6499    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6500         (minus:SWI (match_dup 1) (match_dup 2)))]
6501   "ix86_match_ccmode (insn, CCGOCmode)
6502    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6503   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6504   [(set_attr "type" "alu")
6505    (set_attr "mode" "<MODE>")])
6507 (define_insn "*subsi_2_zext"
6508   [(set (reg FLAGS_REG)
6509         (compare
6510           (minus:SI (match_operand:SI 1 "register_operand" "0")
6511                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6512           (const_int 0)))
6513    (set (match_operand:DI 0 "register_operand" "=r")
6514         (zero_extend:DI
6515           (minus:SI (match_dup 1)
6516                     (match_dup 2))))]
6517   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6518    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6519   "sub{l}\t{%2, %k0|%k0, %2}"
6520   [(set_attr "type" "alu")
6521    (set_attr "mode" "SI")])
6523 ;; Subtract with jump on overflow.
6524 (define_expand "subv<mode>4"
6525   [(parallel [(set (reg:CCO FLAGS_REG)
6526                    (eq:CCO (minus:<DWI>
6527                               (sign_extend:<DWI>
6528                                  (match_operand:SWI 1 "nonimmediate_operand"))
6529                               (sign_extend:<DWI>
6530                                  (match_operand:SWI 2 "<general_operand>")))
6531                            (sign_extend:<DWI>
6532                               (minus:SWI (match_dup 1) (match_dup 2)))))
6533               (set (match_operand:SWI 0 "register_operand")
6534                    (minus:SWI (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   ""
6540   "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6542 (define_insn "*subv<mode>4"
6543   [(set (reg:CCO FLAGS_REG)
6544         (eq:CCO (minus:<DWI>
6545                    (sign_extend:<DWI>
6546                       (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6547                    (sign_extend:<DWI>
6548                       (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6549                 (sign_extend:<DWI>
6550                    (minus:SWI (match_dup 1) (match_dup 2)))))
6551    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6552         (minus:SWI (match_dup 1) (match_dup 2)))]
6553   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6554   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6555   [(set_attr "type" "alu")
6556    (set_attr "mode" "<MODE>")])
6558 (define_insn "*sub<mode>_3"
6559   [(set (reg FLAGS_REG)
6560         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6561                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6562    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6563         (minus:SWI (match_dup 1) (match_dup 2)))]
6564   "ix86_match_ccmode (insn, CCmode)
6565    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6566   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6567   [(set_attr "type" "alu")
6568    (set_attr "mode" "<MODE>")])
6570 (define_insn "*subsi_3_zext"
6571   [(set (reg FLAGS_REG)
6572         (compare (match_operand:SI 1 "register_operand" "0")
6573                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6574    (set (match_operand:DI 0 "register_operand" "=r")
6575         (zero_extend:DI
6576           (minus:SI (match_dup 1)
6577                     (match_dup 2))))]
6578   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6579    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6580   "sub{l}\t{%2, %1|%1, %2}"
6581   [(set_attr "type" "alu")
6582    (set_attr "mode" "SI")])
6584 ;; Add with carry and subtract with borrow
6586 (define_expand "<plusminus_insn><mode>3_carry"
6587   [(parallel
6588     [(set (match_operand:SWI 0 "nonimmediate_operand")
6589           (plusminus:SWI
6590             (match_operand:SWI 1 "nonimmediate_operand")
6591             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6592                        [(match_operand 3 "flags_reg_operand")
6593                         (const_int 0)])
6594                       (match_operand:SWI 2 "<general_operand>"))))
6595      (clobber (reg:CC FLAGS_REG))])]
6596   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6598 (define_insn "*<plusminus_insn><mode>3_carry"
6599   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6600         (plusminus:SWI
6601           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6602           (plus:SWI
6603             (match_operator 3 "ix86_carry_flag_operator"
6604              [(reg FLAGS_REG) (const_int 0)])
6605             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6606    (clobber (reg:CC FLAGS_REG))]
6607   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6608   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6609   [(set_attr "type" "alu")
6610    (set_attr "use_carry" "1")
6611    (set_attr "pent_pair" "pu")
6612    (set_attr "mode" "<MODE>")])
6614 (define_insn "*addsi3_carry_zext"
6615   [(set (match_operand:DI 0 "register_operand" "=r")
6616         (zero_extend:DI
6617           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6618                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6619                              [(reg FLAGS_REG) (const_int 0)])
6620                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6621    (clobber (reg:CC FLAGS_REG))]
6622   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6623   "adc{l}\t{%2, %k0|%k0, %2}"
6624   [(set_attr "type" "alu")
6625    (set_attr "use_carry" "1")
6626    (set_attr "pent_pair" "pu")
6627    (set_attr "mode" "SI")])
6629 (define_insn "*subsi3_carry_zext"
6630   [(set (match_operand:DI 0 "register_operand" "=r")
6631         (zero_extend:DI
6632           (minus:SI (match_operand:SI 1 "register_operand" "0")
6633                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6634                               [(reg FLAGS_REG) (const_int 0)])
6635                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6636    (clobber (reg:CC FLAGS_REG))]
6637   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6638   "sbb{l}\t{%2, %k0|%k0, %2}"
6639   [(set_attr "type" "alu")
6640    (set_attr "pent_pair" "pu")
6641    (set_attr "mode" "SI")])
6643 ;; ADCX instruction
6645 (define_insn "adcx<mode>3"
6646   [(set (reg:CCC FLAGS_REG)
6647         (compare:CCC
6648           (plus:SWI48
6649             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6650             (plus:SWI48
6651               (match_operator 4 "ix86_carry_flag_operator"
6652                [(match_operand 3 "flags_reg_operand") (const_int 0)])
6653               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6654           (const_int 0)))
6655    (set (match_operand:SWI48 0 "register_operand" "=r")
6656         (plus:SWI48 (match_dup 1)
6657                     (plus:SWI48 (match_op_dup 4
6658                                  [(match_dup 3) (const_int 0)])
6659                                 (match_dup 2))))]
6660   "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6661   "adcx\t{%2, %0|%0, %2}"
6662   [(set_attr "type" "alu")
6663    (set_attr "use_carry" "1")
6664    (set_attr "mode" "<MODE>")])
6666 ;; Overflow setting add instructions
6668 (define_insn "*add<mode>3_cconly_overflow"
6669   [(set (reg:CCC FLAGS_REG)
6670         (compare:CCC
6671           (plus:SWI
6672             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6673             (match_operand:SWI 2 "<general_operand>" "<g>"))
6674           (match_dup 1)))
6675    (clobber (match_scratch:SWI 0 "=<r>"))]
6676   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6677   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6678   [(set_attr "type" "alu")
6679    (set_attr "mode" "<MODE>")])
6681 (define_insn "*add<mode>3_cc_overflow"
6682   [(set (reg:CCC FLAGS_REG)
6683         (compare:CCC
6684             (plus:SWI
6685                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6686                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6687             (match_dup 1)))
6688    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6689         (plus:SWI (match_dup 1) (match_dup 2)))]
6690   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6691   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6692   [(set_attr "type" "alu")
6693    (set_attr "mode" "<MODE>")])
6695 (define_insn "*addsi3_zext_cc_overflow"
6696   [(set (reg:CCC FLAGS_REG)
6697         (compare:CCC
6698           (plus:SI
6699             (match_operand:SI 1 "nonimmediate_operand" "%0")
6700             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6701           (match_dup 1)))
6702    (set (match_operand:DI 0 "register_operand" "=r")
6703         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6704   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6705   "add{l}\t{%2, %k0|%k0, %2}"
6706   [(set_attr "type" "alu")
6707    (set_attr "mode" "SI")])
6709 ;; The patterns that match these are at the end of this file.
6711 (define_expand "<plusminus_insn>xf3"
6712   [(set (match_operand:XF 0 "register_operand")
6713         (plusminus:XF
6714           (match_operand:XF 1 "register_operand")
6715           (match_operand:XF 2 "register_operand")))]
6716   "TARGET_80387")
6718 (define_expand "<plusminus_insn><mode>3"
6719   [(set (match_operand:MODEF 0 "register_operand")
6720         (plusminus:MODEF
6721           (match_operand:MODEF 1 "register_operand")
6722           (match_operand:MODEF 2 "nonimmediate_operand")))]
6723   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6724     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6726 ;; Multiply instructions
6728 (define_expand "mul<mode>3"
6729   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6730                    (mult:SWIM248
6731                      (match_operand:SWIM248 1 "register_operand")
6732                      (match_operand:SWIM248 2 "<general_operand>")))
6733               (clobber (reg:CC FLAGS_REG))])])
6735 (define_expand "mulqi3"
6736   [(parallel [(set (match_operand:QI 0 "register_operand")
6737                    (mult:QI
6738                      (match_operand:QI 1 "register_operand")
6739                      (match_operand:QI 2 "nonimmediate_operand")))
6740               (clobber (reg:CC FLAGS_REG))])]
6741   "TARGET_QIMODE_MATH")
6743 ;; On AMDFAM10
6744 ;; IMUL reg32/64, reg32/64, imm8        Direct
6745 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6746 ;; IMUL reg32/64, reg32/64, imm32       Direct
6747 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6748 ;; IMUL reg32/64, reg32/64              Direct
6749 ;; IMUL reg32/64, mem32/64              Direct
6751 ;; On BDVER1, all above IMULs use DirectPath
6753 (define_insn "*mul<mode>3_1"
6754   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6755         (mult:SWI48
6756           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6757           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6758    (clobber (reg:CC FLAGS_REG))]
6759   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6760   "@
6761    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6762    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6763    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6764   [(set_attr "type" "imul")
6765    (set_attr "prefix_0f" "0,0,1")
6766    (set (attr "athlon_decode")
6767         (cond [(eq_attr "cpu" "athlon")
6768                   (const_string "vector")
6769                (eq_attr "alternative" "1")
6770                   (const_string "vector")
6771                (and (eq_attr "alternative" "2")
6772                     (match_operand 1 "memory_operand"))
6773                   (const_string "vector")]
6774               (const_string "direct")))
6775    (set (attr "amdfam10_decode")
6776         (cond [(and (eq_attr "alternative" "0,1")
6777                     (match_operand 1 "memory_operand"))
6778                   (const_string "vector")]
6779               (const_string "direct")))
6780    (set_attr "bdver1_decode" "direct")
6781    (set_attr "mode" "<MODE>")])
6783 (define_insn "*mulsi3_1_zext"
6784   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6785         (zero_extend:DI
6786           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6787                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6788    (clobber (reg:CC FLAGS_REG))]
6789   "TARGET_64BIT
6790    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6791   "@
6792    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6793    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6794    imul{l}\t{%2, %k0|%k0, %2}"
6795   [(set_attr "type" "imul")
6796    (set_attr "prefix_0f" "0,0,1")
6797    (set (attr "athlon_decode")
6798         (cond [(eq_attr "cpu" "athlon")
6799                   (const_string "vector")
6800                (eq_attr "alternative" "1")
6801                   (const_string "vector")
6802                (and (eq_attr "alternative" "2")
6803                     (match_operand 1 "memory_operand"))
6804                   (const_string "vector")]
6805               (const_string "direct")))
6806    (set (attr "amdfam10_decode")
6807         (cond [(and (eq_attr "alternative" "0,1")
6808                     (match_operand 1 "memory_operand"))
6809                   (const_string "vector")]
6810               (const_string "direct")))
6811    (set_attr "bdver1_decode" "direct")
6812    (set_attr "mode" "SI")])
6814 ;; On AMDFAM10
6815 ;; IMUL reg16, reg16, imm8      VectorPath
6816 ;; IMUL reg16, mem16, imm8      VectorPath
6817 ;; IMUL reg16, reg16, imm16     VectorPath
6818 ;; IMUL reg16, mem16, imm16     VectorPath
6819 ;; IMUL reg16, reg16            Direct
6820 ;; IMUL reg16, mem16            Direct
6822 ;; On BDVER1, all HI MULs use DoublePath
6824 (define_insn "*mulhi3_1"
6825   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6826         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6827                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6828    (clobber (reg:CC FLAGS_REG))]
6829   "TARGET_HIMODE_MATH
6830    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6831   "@
6832    imul{w}\t{%2, %1, %0|%0, %1, %2}
6833    imul{w}\t{%2, %1, %0|%0, %1, %2}
6834    imul{w}\t{%2, %0|%0, %2}"
6835   [(set_attr "type" "imul")
6836    (set_attr "prefix_0f" "0,0,1")
6837    (set (attr "athlon_decode")
6838         (cond [(eq_attr "cpu" "athlon")
6839                   (const_string "vector")
6840                (eq_attr "alternative" "1,2")
6841                   (const_string "vector")]
6842               (const_string "direct")))
6843    (set (attr "amdfam10_decode")
6844         (cond [(eq_attr "alternative" "0,1")
6845                   (const_string "vector")]
6846               (const_string "direct")))
6847    (set_attr "bdver1_decode" "double")
6848    (set_attr "mode" "HI")])
6850 ;;On AMDFAM10 and BDVER1
6851 ;; MUL reg8     Direct
6852 ;; MUL mem8     Direct
6854 (define_insn "*mulqi3_1"
6855   [(set (match_operand:QI 0 "register_operand" "=a")
6856         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6857                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6858    (clobber (reg:CC FLAGS_REG))]
6859   "TARGET_QIMODE_MATH
6860    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6861   "mul{b}\t%2"
6862   [(set_attr "type" "imul")
6863    (set_attr "length_immediate" "0")
6864    (set (attr "athlon_decode")
6865      (if_then_else (eq_attr "cpu" "athlon")
6866         (const_string "vector")
6867         (const_string "direct")))
6868    (set_attr "amdfam10_decode" "direct")
6869    (set_attr "bdver1_decode" "direct")
6870    (set_attr "mode" "QI")])
6872 ;; Multiply with jump on overflow.
6873 (define_expand "mulv<mode>4"
6874   [(parallel [(set (reg:CCO FLAGS_REG)
6875                    (eq:CCO (mult:<DWI>
6876                               (sign_extend:<DWI>
6877                                  (match_operand:SWI48 1 "register_operand"))
6878                               (sign_extend:<DWI>
6879                                  (match_operand:SWI48 2 "<general_operand>")))
6880                            (sign_extend:<DWI>
6881                               (mult:SWI48 (match_dup 1) (match_dup 2)))))
6882               (set (match_operand:SWI48 0 "register_operand")
6883                    (mult:SWI48 (match_dup 1) (match_dup 2)))])
6884    (set (pc) (if_then_else
6885                (eq (reg:CCO FLAGS_REG) (const_int 0))
6886                (label_ref (match_operand 3))
6887                (pc)))])
6889 (define_insn "*mulv<mode>4"
6890   [(set (reg:CCO FLAGS_REG)
6891         (eq:CCO (mult:<DWI>
6892                    (sign_extend:<DWI>
6893                       (match_operand:SWI 1 "nonimmediate_operand" "%rm,rm,0"))
6894                    (sign_extend:<DWI>
6895                       (match_operand:SWI 2 "<general_operand>" "K,<i>,mr")))
6896                 (sign_extend:<DWI>
6897                    (mult:SWI (match_dup 1) (match_dup 2)))))
6898    (set (match_operand:SWI 0 "register_operand" "=r,r,r")
6899         (mult:SWI (match_dup 1) (match_dup 2)))]
6900   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6901   "@
6902    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6903    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6904    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6905   [(set_attr "type" "imul")
6906    (set_attr "prefix_0f" "0,0,1")
6907    (set (attr "athlon_decode")
6908         (cond [(eq_attr "cpu" "athlon")
6909                   (const_string "vector")
6910                (eq_attr "alternative" "1")
6911                   (const_string "vector")
6912                (and (eq_attr "alternative" "2")
6913                     (match_operand 1 "memory_operand"))
6914                   (const_string "vector")]
6915               (const_string "direct")))
6916    (set (attr "amdfam10_decode")
6917         (cond [(and (eq_attr "alternative" "0,1")
6918                     (match_operand 1 "memory_operand"))
6919                   (const_string "vector")]
6920               (const_string "direct")))
6921    (set_attr "bdver1_decode" "direct")
6922    (set_attr "mode" "<MODE>")])
6924 (define_expand "<u>mul<mode><dwi>3"
6925   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6926                    (mult:<DWI>
6927                      (any_extend:<DWI>
6928                        (match_operand:DWIH 1 "nonimmediate_operand"))
6929                      (any_extend:<DWI>
6930                        (match_operand:DWIH 2 "register_operand"))))
6931               (clobber (reg:CC FLAGS_REG))])])
6933 (define_expand "<u>mulqihi3"
6934   [(parallel [(set (match_operand:HI 0 "register_operand")
6935                    (mult:HI
6936                      (any_extend:HI
6937                        (match_operand:QI 1 "nonimmediate_operand"))
6938                      (any_extend:HI
6939                        (match_operand:QI 2 "register_operand"))))
6940               (clobber (reg:CC FLAGS_REG))])]
6941   "TARGET_QIMODE_MATH")
6943 (define_insn "*bmi2_umulditi3_1"
6944   [(set (match_operand:DI 0 "register_operand" "=r")
6945         (mult:DI
6946           (match_operand:DI 2 "nonimmediate_operand" "%d")
6947           (match_operand:DI 3 "nonimmediate_operand" "rm")))
6948    (set (match_operand:DI 1 "register_operand" "=r")
6949         (truncate:DI
6950           (lshiftrt:TI
6951             (mult:TI (zero_extend:TI (match_dup 2))
6952                      (zero_extend:TI (match_dup 3)))
6953             (const_int 64))))]
6954   "TARGET_64BIT && TARGET_BMI2
6955    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6956   "mulx\t{%3, %0, %1|%1, %0, %3}"
6957   [(set_attr "type" "imulx")
6958    (set_attr "prefix" "vex")
6959    (set_attr "mode" "DI")])
6961 (define_insn "*bmi2_umulsidi3_1"
6962   [(set (match_operand:SI 0 "register_operand" "=r")
6963         (mult:SI
6964           (match_operand:SI 2 "nonimmediate_operand" "%d")
6965           (match_operand:SI 3 "nonimmediate_operand" "rm")))
6966    (set (match_operand:SI 1 "register_operand" "=r")
6967         (truncate:SI
6968           (lshiftrt:DI
6969             (mult:DI (zero_extend:DI (match_dup 2))
6970                      (zero_extend:DI (match_dup 3)))
6971             (const_int 32))))]
6972   "!TARGET_64BIT && TARGET_BMI2
6973    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6974   "mulx\t{%3, %0, %1|%1, %0, %3}"
6975   [(set_attr "type" "imulx")
6976    (set_attr "prefix" "vex")
6977    (set_attr "mode" "SI")])
6979 (define_insn "*umul<mode><dwi>3_1"
6980   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6981         (mult:<DWI>
6982           (zero_extend:<DWI>
6983             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6984           (zero_extend:<DWI>
6985             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6986    (clobber (reg:CC FLAGS_REG))]
6987   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6988   "@
6989    #
6990    mul{<imodesuffix>}\t%2"
6991   [(set_attr "isa" "bmi2,*")
6992    (set_attr "type" "imulx,imul")
6993    (set_attr "length_immediate" "*,0")
6994    (set (attr "athlon_decode")
6995         (cond [(eq_attr "alternative" "1")
6996                  (if_then_else (eq_attr "cpu" "athlon")
6997                    (const_string "vector")
6998                    (const_string "double"))]
6999               (const_string "*")))
7000    (set_attr "amdfam10_decode" "*,double")
7001    (set_attr "bdver1_decode" "*,direct")
7002    (set_attr "prefix" "vex,orig")
7003    (set_attr "mode" "<MODE>")])
7005 ;; Convert mul to the mulx pattern to avoid flags dependency.
7006 (define_split
7007  [(set (match_operand:<DWI> 0 "register_operand")
7008        (mult:<DWI>
7009          (zero_extend:<DWI>
7010            (match_operand:DWIH 1 "register_operand"))
7011          (zero_extend:<DWI>
7012            (match_operand:DWIH 2 "nonimmediate_operand"))))
7013   (clobber (reg:CC FLAGS_REG))]
7014  "TARGET_BMI2 && reload_completed
7015   && true_regnum (operands[1]) == DX_REG"
7016   [(parallel [(set (match_dup 3)
7017                    (mult:DWIH (match_dup 1) (match_dup 2)))
7018               (set (match_dup 4)
7019                    (truncate:DWIH
7020                      (lshiftrt:<DWI>
7021                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7022                                    (zero_extend:<DWI> (match_dup 2)))
7023                        (match_dup 5))))])]
7025   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7027   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
7030 (define_insn "*mul<mode><dwi>3_1"
7031   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7032         (mult:<DWI>
7033           (sign_extend:<DWI>
7034             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7035           (sign_extend:<DWI>
7036             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7037    (clobber (reg:CC FLAGS_REG))]
7038   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7039   "imul{<imodesuffix>}\t%2"
7040   [(set_attr "type" "imul")
7041    (set_attr "length_immediate" "0")
7042    (set (attr "athlon_decode")
7043      (if_then_else (eq_attr "cpu" "athlon")
7044         (const_string "vector")
7045         (const_string "double")))
7046    (set_attr "amdfam10_decode" "double")
7047    (set_attr "bdver1_decode" "direct")
7048    (set_attr "mode" "<MODE>")])
7050 (define_insn "*<u>mulqihi3_1"
7051   [(set (match_operand:HI 0 "register_operand" "=a")
7052         (mult:HI
7053           (any_extend:HI
7054             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7055           (any_extend:HI
7056             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7057    (clobber (reg:CC FLAGS_REG))]
7058   "TARGET_QIMODE_MATH
7059    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7060   "<sgnprefix>mul{b}\t%2"
7061   [(set_attr "type" "imul")
7062    (set_attr "length_immediate" "0")
7063    (set (attr "athlon_decode")
7064      (if_then_else (eq_attr "cpu" "athlon")
7065         (const_string "vector")
7066         (const_string "direct")))
7067    (set_attr "amdfam10_decode" "direct")
7068    (set_attr "bdver1_decode" "direct")
7069    (set_attr "mode" "QI")])
7071 (define_expand "<s>mul<mode>3_highpart"
7072   [(parallel [(set (match_operand:SWI48 0 "register_operand")
7073                    (truncate:SWI48
7074                      (lshiftrt:<DWI>
7075                        (mult:<DWI>
7076                          (any_extend:<DWI>
7077                            (match_operand:SWI48 1 "nonimmediate_operand"))
7078                          (any_extend:<DWI>
7079                            (match_operand:SWI48 2 "register_operand")))
7080                        (match_dup 4))))
7081               (clobber (match_scratch:SWI48 3))
7082               (clobber (reg:CC FLAGS_REG))])]
7083   ""
7084   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7086 (define_insn "*<s>muldi3_highpart_1"
7087   [(set (match_operand:DI 0 "register_operand" "=d")
7088         (truncate:DI
7089           (lshiftrt:TI
7090             (mult:TI
7091               (any_extend:TI
7092                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7093               (any_extend:TI
7094                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7095             (const_int 64))))
7096    (clobber (match_scratch:DI 3 "=1"))
7097    (clobber (reg:CC FLAGS_REG))]
7098   "TARGET_64BIT
7099    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7100   "<sgnprefix>mul{q}\t%2"
7101   [(set_attr "type" "imul")
7102    (set_attr "length_immediate" "0")
7103    (set (attr "athlon_decode")
7104      (if_then_else (eq_attr "cpu" "athlon")
7105         (const_string "vector")
7106         (const_string "double")))
7107    (set_attr "amdfam10_decode" "double")
7108    (set_attr "bdver1_decode" "direct")
7109    (set_attr "mode" "DI")])
7111 (define_insn "*<s>mulsi3_highpart_1"
7112   [(set (match_operand:SI 0 "register_operand" "=d")
7113         (truncate:SI
7114           (lshiftrt:DI
7115             (mult:DI
7116               (any_extend:DI
7117                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7118               (any_extend:DI
7119                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7120             (const_int 32))))
7121    (clobber (match_scratch:SI 3 "=1"))
7122    (clobber (reg:CC FLAGS_REG))]
7123   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7124   "<sgnprefix>mul{l}\t%2"
7125   [(set_attr "type" "imul")
7126    (set_attr "length_immediate" "0")
7127    (set (attr "athlon_decode")
7128      (if_then_else (eq_attr "cpu" "athlon")
7129         (const_string "vector")
7130         (const_string "double")))
7131    (set_attr "amdfam10_decode" "double")
7132    (set_attr "bdver1_decode" "direct")
7133    (set_attr "mode" "SI")])
7135 (define_insn "*<s>mulsi3_highpart_zext"
7136   [(set (match_operand:DI 0 "register_operand" "=d")
7137         (zero_extend:DI (truncate:SI
7138           (lshiftrt:DI
7139             (mult:DI (any_extend:DI
7140                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7141                      (any_extend:DI
7142                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7143             (const_int 32)))))
7144    (clobber (match_scratch:SI 3 "=1"))
7145    (clobber (reg:CC FLAGS_REG))]
7146   "TARGET_64BIT
7147    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7148   "<sgnprefix>mul{l}\t%2"
7149   [(set_attr "type" "imul")
7150    (set_attr "length_immediate" "0")
7151    (set (attr "athlon_decode")
7152      (if_then_else (eq_attr "cpu" "athlon")
7153         (const_string "vector")
7154         (const_string "double")))
7155    (set_attr "amdfam10_decode" "double")
7156    (set_attr "bdver1_decode" "direct")
7157    (set_attr "mode" "SI")])
7159 ;; The patterns that match these are at the end of this file.
7161 (define_expand "mulxf3"
7162   [(set (match_operand:XF 0 "register_operand")
7163         (mult:XF (match_operand:XF 1 "register_operand")
7164                  (match_operand:XF 2 "register_operand")))]
7165   "TARGET_80387")
7167 (define_expand "mul<mode>3"
7168   [(set (match_operand:MODEF 0 "register_operand")
7169         (mult:MODEF (match_operand:MODEF 1 "register_operand")
7170                     (match_operand:MODEF 2 "nonimmediate_operand")))]
7171   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7172     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7174 ;; Divide instructions
7176 ;; The patterns that match these are at the end of this file.
7178 (define_expand "divxf3"
7179   [(set (match_operand:XF 0 "register_operand")
7180         (div:XF (match_operand:XF 1 "register_operand")
7181                 (match_operand:XF 2 "register_operand")))]
7182   "TARGET_80387")
7184 (define_expand "divdf3"
7185   [(set (match_operand:DF 0 "register_operand")
7186         (div:DF (match_operand:DF 1 "register_operand")
7187                 (match_operand:DF 2 "nonimmediate_operand")))]
7188    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7189     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7191 (define_expand "divsf3"
7192   [(set (match_operand:SF 0 "register_operand")
7193         (div:SF (match_operand:SF 1 "register_operand")
7194                 (match_operand:SF 2 "nonimmediate_operand")))]
7195   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7196     || TARGET_SSE_MATH"
7198   if (TARGET_SSE_MATH
7199       && TARGET_RECIP_DIV
7200       && optimize_insn_for_speed_p ()
7201       && flag_finite_math_only && !flag_trapping_math
7202       && flag_unsafe_math_optimizations)
7203     {
7204       ix86_emit_swdivsf (operands[0], operands[1],
7205                          operands[2], SFmode);
7206       DONE;
7207     }
7210 ;; Divmod instructions.
7212 (define_expand "divmod<mode>4"
7213   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7214                    (div:SWIM248
7215                      (match_operand:SWIM248 1 "register_operand")
7216                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7217               (set (match_operand:SWIM248 3 "register_operand")
7218                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7219               (clobber (reg:CC FLAGS_REG))])])
7221 ;; Split with 8bit unsigned divide:
7222 ;;      if (dividend an divisor are in [0-255])
7223 ;;         use 8bit unsigned integer divide
7224 ;;       else
7225 ;;         use original integer divide
7226 (define_split
7227   [(set (match_operand:SWI48 0 "register_operand")
7228         (div:SWI48 (match_operand:SWI48 2 "register_operand")
7229                     (match_operand:SWI48 3 "nonimmediate_operand")))
7230    (set (match_operand:SWI48 1 "register_operand")
7231         (mod:SWI48 (match_dup 2) (match_dup 3)))
7232    (clobber (reg:CC FLAGS_REG))]
7233   "TARGET_USE_8BIT_IDIV
7234    && TARGET_QIMODE_MATH
7235    && can_create_pseudo_p ()
7236    && !optimize_insn_for_size_p ()"
7237   [(const_int 0)]
7238   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7240 (define_insn_and_split "divmod<mode>4_1"
7241   [(set (match_operand:SWI48 0 "register_operand" "=a")
7242         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7243                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7244    (set (match_operand:SWI48 1 "register_operand" "=&d")
7245         (mod:SWI48 (match_dup 2) (match_dup 3)))
7246    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7247    (clobber (reg:CC FLAGS_REG))]
7248   ""
7249   "#"
7250   "reload_completed"
7251   [(parallel [(set (match_dup 1)
7252                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7253               (clobber (reg:CC FLAGS_REG))])
7254    (parallel [(set (match_dup 0)
7255                    (div:SWI48 (match_dup 2) (match_dup 3)))
7256               (set (match_dup 1)
7257                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7258               (use (match_dup 1))
7259               (clobber (reg:CC FLAGS_REG))])]
7261   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7263   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7264     operands[4] = operands[2];
7265   else
7266     {
7267       /* Avoid use of cltd in favor of a mov+shift.  */
7268       emit_move_insn (operands[1], operands[2]);
7269       operands[4] = operands[1];
7270     }
7272   [(set_attr "type" "multi")
7273    (set_attr "mode" "<MODE>")])
7275 (define_insn_and_split "*divmod<mode>4"
7276   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7277         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7278                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7279    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7280         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7281    (clobber (reg:CC FLAGS_REG))]
7282   ""
7283   "#"
7284   "reload_completed"
7285   [(parallel [(set (match_dup 1)
7286                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7287               (clobber (reg:CC FLAGS_REG))])
7288    (parallel [(set (match_dup 0)
7289                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7290               (set (match_dup 1)
7291                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7292               (use (match_dup 1))
7293               (clobber (reg:CC FLAGS_REG))])]
7295   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7297   if (<MODE>mode != HImode
7298       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7299     operands[4] = operands[2];
7300   else
7301     {
7302       /* Avoid use of cltd in favor of a mov+shift.  */
7303       emit_move_insn (operands[1], operands[2]);
7304       operands[4] = operands[1];
7305     }
7307   [(set_attr "type" "multi")
7308    (set_attr "mode" "<MODE>")])
7310 (define_insn "*divmod<mode>4_noext"
7311   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7312         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7313                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7314    (set (match_operand:SWIM248 1 "register_operand" "=d")
7315         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7316    (use (match_operand:SWIM248 4 "register_operand" "1"))
7317    (clobber (reg:CC FLAGS_REG))]
7318   ""
7319   "idiv{<imodesuffix>}\t%3"
7320   [(set_attr "type" "idiv")
7321    (set_attr "mode" "<MODE>")])
7323 (define_expand "divmodqi4"
7324   [(parallel [(set (match_operand:QI 0 "register_operand")
7325                    (div:QI
7326                      (match_operand:QI 1 "register_operand")
7327                      (match_operand:QI 2 "nonimmediate_operand")))
7328               (set (match_operand:QI 3 "register_operand")
7329                    (mod:QI (match_dup 1) (match_dup 2)))
7330               (clobber (reg:CC FLAGS_REG))])]
7331   "TARGET_QIMODE_MATH"
7333   rtx div, mod, insn;
7334   rtx tmp0, tmp1;
7335   
7336   tmp0 = gen_reg_rtx (HImode);
7337   tmp1 = gen_reg_rtx (HImode);
7339   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7340      in AX.  */
7341   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7342   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7344   /* Extract remainder from AH.  */
7345   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7346   insn = emit_move_insn (operands[3], tmp1);
7348   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7349   set_unique_reg_note (insn, REG_EQUAL, mod);
7351   /* Extract quotient from AL.  */
7352   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7354   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7355   set_unique_reg_note (insn, REG_EQUAL, div);
7357   DONE;
7360 ;; Divide AX by r/m8, with result stored in
7361 ;; AL <- Quotient
7362 ;; AH <- Remainder
7363 ;; Change div/mod to HImode and extend the second argument to HImode
7364 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7365 ;; combine may fail.
7366 (define_insn "divmodhiqi3"
7367   [(set (match_operand:HI 0 "register_operand" "=a")
7368         (ior:HI
7369           (ashift:HI
7370             (zero_extend:HI
7371               (truncate:QI
7372                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7373                         (sign_extend:HI
7374                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7375             (const_int 8))
7376           (zero_extend:HI
7377             (truncate:QI
7378               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7379    (clobber (reg:CC FLAGS_REG))]
7380   "TARGET_QIMODE_MATH"
7381   "idiv{b}\t%2"
7382   [(set_attr "type" "idiv")
7383    (set_attr "mode" "QI")])
7385 (define_expand "udivmod<mode>4"
7386   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7387                    (udiv:SWIM248
7388                      (match_operand:SWIM248 1 "register_operand")
7389                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7390               (set (match_operand:SWIM248 3 "register_operand")
7391                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7392               (clobber (reg:CC FLAGS_REG))])])
7394 ;; Split with 8bit unsigned divide:
7395 ;;      if (dividend an divisor are in [0-255])
7396 ;;         use 8bit unsigned integer divide
7397 ;;       else
7398 ;;         use original integer divide
7399 (define_split
7400   [(set (match_operand:SWI48 0 "register_operand")
7401         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7402                     (match_operand:SWI48 3 "nonimmediate_operand")))
7403    (set (match_operand:SWI48 1 "register_operand")
7404         (umod:SWI48 (match_dup 2) (match_dup 3)))
7405    (clobber (reg:CC FLAGS_REG))]
7406   "TARGET_USE_8BIT_IDIV
7407    && TARGET_QIMODE_MATH
7408    && can_create_pseudo_p ()
7409    && !optimize_insn_for_size_p ()"
7410   [(const_int 0)]
7411   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7413 (define_insn_and_split "udivmod<mode>4_1"
7414   [(set (match_operand:SWI48 0 "register_operand" "=a")
7415         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7416                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7417    (set (match_operand:SWI48 1 "register_operand" "=&d")
7418         (umod:SWI48 (match_dup 2) (match_dup 3)))
7419    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7420    (clobber (reg:CC FLAGS_REG))]
7421   ""
7422   "#"
7423   "reload_completed"
7424   [(set (match_dup 1) (const_int 0))
7425    (parallel [(set (match_dup 0)
7426                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7427               (set (match_dup 1)
7428                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7429               (use (match_dup 1))
7430               (clobber (reg:CC FLAGS_REG))])]
7431   ""
7432   [(set_attr "type" "multi")
7433    (set_attr "mode" "<MODE>")])
7435 (define_insn_and_split "*udivmod<mode>4"
7436   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7437         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7438                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7439    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7440         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7441    (clobber (reg:CC FLAGS_REG))]
7442   ""
7443   "#"
7444   "reload_completed"
7445   [(set (match_dup 1) (const_int 0))
7446    (parallel [(set (match_dup 0)
7447                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7448               (set (match_dup 1)
7449                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7450               (use (match_dup 1))
7451               (clobber (reg:CC FLAGS_REG))])]
7452   ""
7453   [(set_attr "type" "multi")
7454    (set_attr "mode" "<MODE>")])
7456 (define_insn "*udivmod<mode>4_noext"
7457   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7458         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7459                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7460    (set (match_operand:SWIM248 1 "register_operand" "=d")
7461         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7462    (use (match_operand:SWIM248 4 "register_operand" "1"))
7463    (clobber (reg:CC FLAGS_REG))]
7464   ""
7465   "div{<imodesuffix>}\t%3"
7466   [(set_attr "type" "idiv")
7467    (set_attr "mode" "<MODE>")])
7469 (define_expand "udivmodqi4"
7470   [(parallel [(set (match_operand:QI 0 "register_operand")
7471                    (udiv:QI
7472                      (match_operand:QI 1 "register_operand")
7473                      (match_operand:QI 2 "nonimmediate_operand")))
7474               (set (match_operand:QI 3 "register_operand")
7475                    (umod:QI (match_dup 1) (match_dup 2)))
7476               (clobber (reg:CC FLAGS_REG))])]
7477   "TARGET_QIMODE_MATH"
7479   rtx div, mod, insn;
7480   rtx tmp0, tmp1;
7481   
7482   tmp0 = gen_reg_rtx (HImode);
7483   tmp1 = gen_reg_rtx (HImode);
7485   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7486      in AX.  */
7487   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7488   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7490   /* Extract remainder from AH.  */
7491   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7492   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7493   insn = emit_move_insn (operands[3], tmp1);
7495   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7496   set_unique_reg_note (insn, REG_EQUAL, mod);
7498   /* Extract quotient from AL.  */
7499   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7501   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7502   set_unique_reg_note (insn, REG_EQUAL, div);
7504   DONE;
7507 (define_insn "udivmodhiqi3"
7508   [(set (match_operand:HI 0 "register_operand" "=a")
7509         (ior:HI
7510           (ashift:HI
7511             (zero_extend:HI
7512               (truncate:QI
7513                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7514                         (zero_extend:HI
7515                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7516             (const_int 8))
7517           (zero_extend:HI
7518             (truncate:QI
7519               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7520    (clobber (reg:CC FLAGS_REG))]
7521   "TARGET_QIMODE_MATH"
7522   "div{b}\t%2"
7523   [(set_attr "type" "idiv")
7524    (set_attr "mode" "QI")])
7526 ;; We cannot use div/idiv for double division, because it causes
7527 ;; "division by zero" on the overflow and that's not what we expect
7528 ;; from truncate.  Because true (non truncating) double division is
7529 ;; never generated, we can't create this insn anyway.
7531 ;(define_insn ""
7532 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7533 ;       (truncate:SI
7534 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7535 ;                  (zero_extend:DI
7536 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7537 ;   (set (match_operand:SI 3 "register_operand" "=d")
7538 ;       (truncate:SI
7539 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7540 ;   (clobber (reg:CC FLAGS_REG))]
7541 ;  ""
7542 ;  "div{l}\t{%2, %0|%0, %2}"
7543 ;  [(set_attr "type" "idiv")])
7545 ;;- Logical AND instructions
7547 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7548 ;; Note that this excludes ah.
7550 (define_expand "testsi_ccno_1"
7551   [(set (reg:CCNO FLAGS_REG)
7552         (compare:CCNO
7553           (and:SI (match_operand:SI 0 "nonimmediate_operand")
7554                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
7555           (const_int 0)))])
7557 (define_expand "testqi_ccz_1"
7558   [(set (reg:CCZ FLAGS_REG)
7559         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7560                              (match_operand:QI 1 "nonmemory_operand"))
7561                  (const_int 0)))])
7563 (define_expand "testdi_ccno_1"
7564   [(set (reg:CCNO FLAGS_REG)
7565         (compare:CCNO
7566           (and:DI (match_operand:DI 0 "nonimmediate_operand")
7567                   (match_operand:DI 1 "x86_64_szext_general_operand"))
7568           (const_int 0)))]
7569   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7571 (define_insn "*testdi_1"
7572   [(set (reg FLAGS_REG)
7573         (compare
7574          (and:DI
7575           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7576           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7577          (const_int 0)))]
7578   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7579    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7580   "@
7581    test{l}\t{%k1, %k0|%k0, %k1}
7582    test{l}\t{%k1, %k0|%k0, %k1}
7583    test{q}\t{%1, %0|%0, %1}
7584    test{q}\t{%1, %0|%0, %1}
7585    test{q}\t{%1, %0|%0, %1}"
7586   [(set_attr "type" "test")
7587    (set_attr "modrm" "0,1,0,1,1")
7588    (set_attr "mode" "SI,SI,DI,DI,DI")])
7590 (define_insn "*testqi_1_maybe_si"
7591   [(set (reg FLAGS_REG)
7592         (compare
7593           (and:QI
7594             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7595             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7596           (const_int 0)))]
7597    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7598     && ix86_match_ccmode (insn,
7599                          CONST_INT_P (operands[1])
7600                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7602   if (which_alternative == 3)
7603     {
7604       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7605         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7606       return "test{l}\t{%1, %k0|%k0, %1}";
7607     }
7608   return "test{b}\t{%1, %0|%0, %1}";
7610   [(set_attr "type" "test")
7611    (set_attr "modrm" "0,1,1,1")
7612    (set_attr "mode" "QI,QI,QI,SI")
7613    (set_attr "pent_pair" "uv,np,uv,np")])
7615 (define_insn "*test<mode>_1"
7616   [(set (reg FLAGS_REG)
7617         (compare
7618          (and:SWI124
7619           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7620           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7621          (const_int 0)))]
7622   "ix86_match_ccmode (insn, CCNOmode)
7623    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7624   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7625   [(set_attr "type" "test")
7626    (set_attr "modrm" "0,1,1")
7627    (set_attr "mode" "<MODE>")
7628    (set_attr "pent_pair" "uv,np,uv")])
7630 (define_expand "testqi_ext_ccno_0"
7631   [(set (reg:CCNO FLAGS_REG)
7632         (compare:CCNO
7633           (and:SI
7634             (zero_extract:SI
7635               (match_operand 0 "ext_register_operand")
7636               (const_int 8)
7637               (const_int 8))
7638             (match_operand 1 "const_int_operand"))
7639           (const_int 0)))])
7641 (define_insn "*testqi_ext_0"
7642   [(set (reg FLAGS_REG)
7643         (compare
7644           (and:SI
7645             (zero_extract:SI
7646               (match_operand 0 "ext_register_operand" "Q")
7647               (const_int 8)
7648               (const_int 8))
7649             (match_operand 1 "const_int_operand" "n"))
7650           (const_int 0)))]
7651   "ix86_match_ccmode (insn, CCNOmode)"
7652   "test{b}\t{%1, %h0|%h0, %1}"
7653   [(set_attr "type" "test")
7654    (set_attr "mode" "QI")
7655    (set_attr "length_immediate" "1")
7656    (set_attr "modrm" "1")
7657    (set_attr "pent_pair" "np")])
7659 (define_insn "*testqi_ext_1"
7660   [(set (reg FLAGS_REG)
7661         (compare
7662           (and:SI
7663             (zero_extract:SI
7664               (match_operand 0 "ext_register_operand" "Q,Q")
7665               (const_int 8)
7666               (const_int 8))
7667             (zero_extend:SI
7668               (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7669           (const_int 0)))]
7670   "ix86_match_ccmode (insn, CCNOmode)"
7671   "test{b}\t{%1, %h0|%h0, %1}"
7672   [(set_attr "isa" "*,nox64")
7673    (set_attr "type" "test")
7674    (set_attr "mode" "QI")])
7676 (define_insn "*testqi_ext_2"
7677   [(set (reg FLAGS_REG)
7678         (compare
7679           (and:SI
7680             (zero_extract:SI
7681               (match_operand 0 "ext_register_operand" "Q")
7682               (const_int 8)
7683               (const_int 8))
7684             (zero_extract:SI
7685               (match_operand 1 "ext_register_operand" "Q")
7686               (const_int 8)
7687               (const_int 8)))
7688           (const_int 0)))]
7689   "ix86_match_ccmode (insn, CCNOmode)"
7690   "test{b}\t{%h1, %h0|%h0, %h1}"
7691   [(set_attr "type" "test")
7692    (set_attr "mode" "QI")])
7694 ;; Combine likes to form bit extractions for some tests.  Humor it.
7695 (define_insn "*testqi_ext_3"
7696   [(set (reg FLAGS_REG)
7697         (compare (zero_extract:SWI48
7698                    (match_operand 0 "nonimmediate_operand" "rm")
7699                    (match_operand:SWI48 1 "const_int_operand")
7700                    (match_operand:SWI48 2 "const_int_operand"))
7701                  (const_int 0)))]
7702   "ix86_match_ccmode (insn, CCNOmode)
7703    && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7704        || GET_MODE (operands[0]) == SImode
7705        || GET_MODE (operands[0]) == HImode
7706        || GET_MODE (operands[0]) == QImode)
7707    /* Ensure that resulting mask is zero or sign extended operand.  */
7708    && INTVAL (operands[2]) >= 0
7709    && ((INTVAL (operands[1]) > 0
7710         && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7711        || (<MODE>mode == DImode
7712            && INTVAL (operands[1]) > 32
7713            && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7714   "#")
7716 (define_split
7717   [(set (match_operand 0 "flags_reg_operand")
7718         (match_operator 1 "compare_operator"
7719           [(zero_extract
7720              (match_operand 2 "nonimmediate_operand")
7721              (match_operand 3 "const_int_operand")
7722              (match_operand 4 "const_int_operand"))
7723            (const_int 0)]))]
7724   "ix86_match_ccmode (insn, CCNOmode)"
7725   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7727   rtx val = operands[2];
7728   HOST_WIDE_INT len = INTVAL (operands[3]);
7729   HOST_WIDE_INT pos = INTVAL (operands[4]);
7730   HOST_WIDE_INT mask;
7731   enum machine_mode mode, submode;
7733   mode = GET_MODE (val);
7734   if (MEM_P (val))
7735     {
7736       /* ??? Combine likes to put non-volatile mem extractions in QImode
7737          no matter the size of the test.  So find a mode that works.  */
7738       if (! MEM_VOLATILE_P (val))
7739         {
7740           mode = smallest_mode_for_size (pos + len, MODE_INT);
7741           val = adjust_address (val, mode, 0);
7742         }
7743     }
7744   else if (GET_CODE (val) == SUBREG
7745            && (submode = GET_MODE (SUBREG_REG (val)),
7746                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7747            && pos + len <= GET_MODE_BITSIZE (submode)
7748            && GET_MODE_CLASS (submode) == MODE_INT)
7749     {
7750       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7751       mode = submode;
7752       val = SUBREG_REG (val);
7753     }
7754   else if (mode == HImode && pos + len <= 8)
7755     {
7756       /* Small HImode tests can be converted to QImode.  */
7757       mode = QImode;
7758       val = gen_lowpart (QImode, val);
7759     }
7761   if (len == HOST_BITS_PER_WIDE_INT)
7762     mask = -1;
7763   else
7764     mask = ((HOST_WIDE_INT)1 << len) - 1;
7765   mask <<= pos;
7767   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7770 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7771 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7772 ;; this is relatively important trick.
7773 ;; Do the conversion only post-reload to avoid limiting of the register class
7774 ;; to QI regs.
7775 (define_split
7776   [(set (match_operand 0 "flags_reg_operand")
7777         (match_operator 1 "compare_operator"
7778           [(and (match_operand 2 "register_operand")
7779                 (match_operand 3 "const_int_operand"))
7780            (const_int 0)]))]
7781    "reload_completed
7782     && QI_REG_P (operands[2])
7783     && GET_MODE (operands[2]) != QImode
7784     && ((ix86_match_ccmode (insn, CCZmode)
7785          && !(INTVAL (operands[3]) & ~(255 << 8)))
7786         || (ix86_match_ccmode (insn, CCNOmode)
7787             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7788   [(set (match_dup 0)
7789         (match_op_dup 1
7790           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7791                    (match_dup 3))
7792            (const_int 0)]))]
7794   operands[2] = gen_lowpart (SImode, operands[2]);
7795   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7798 (define_split
7799   [(set (match_operand 0 "flags_reg_operand")
7800         (match_operator 1 "compare_operator"
7801           [(and (match_operand 2 "nonimmediate_operand")
7802                 (match_operand 3 "const_int_operand"))
7803            (const_int 0)]))]
7804    "reload_completed
7805     && GET_MODE (operands[2]) != QImode
7806     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7807     && ((ix86_match_ccmode (insn, CCZmode)
7808          && !(INTVAL (operands[3]) & ~255))
7809         || (ix86_match_ccmode (insn, CCNOmode)
7810             && !(INTVAL (operands[3]) & ~127)))"
7811   [(set (match_dup 0)
7812         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7813                          (const_int 0)]))]
7815   operands[2] = gen_lowpart (QImode, operands[2]);
7816   operands[3] = gen_lowpart (QImode, operands[3]);
7819 (define_split
7820   [(set (match_operand:SWI12 0 "mask_reg_operand")
7821         (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand")
7822                          (match_operand:SWI12 2 "mask_reg_operand")))
7823    (clobber (reg:CC FLAGS_REG))]
7824   "TARGET_AVX512F && reload_completed"
7825   [(set (match_dup 0)
7826         (any_logic:SWI12 (match_dup 1)
7827                          (match_dup 2)))])
7829 (define_insn "*k<logic><mode>"
7830   [(set (match_operand:SWI12 0 "mask_reg_operand" "=k")
7831         (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand" "k")
7832                          (match_operand:SWI12 2 "mask_reg_operand" "k")))]
7833   "TARGET_AVX512F"
7834   "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7835   [(set_attr "mode" "<MODE>")
7836    (set_attr "type" "msklog")
7837    (set_attr "prefix" "vex")])
7839 ;; %%% This used to optimize known byte-wide and operations to memory,
7840 ;; and sometimes to QImode registers.  If this is considered useful,
7841 ;; it should be done with splitters.
7843 (define_expand "and<mode>3"
7844   [(set (match_operand:SWIM 0 "nonimmediate_operand")
7845         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7846                   (match_operand:SWIM 2 "<general_szext_operand>")))]
7847   ""
7849   enum machine_mode mode = <MODE>mode;
7850   rtx (*insn) (rtx, rtx);
7852   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7853     {
7854       HOST_WIDE_INT ival = INTVAL (operands[2]);
7856       if (ival == (HOST_WIDE_INT) 0xffffffff)
7857         mode = SImode;
7858       else if (ival == 0xffff)
7859         mode = HImode;
7860       else if (ival == 0xff)
7861         mode = QImode;
7862       }
7864   if (mode == <MODE>mode)
7865     {
7866       ix86_expand_binary_operator (AND, <MODE>mode, operands);
7867       DONE;
7868     }
7870   if (<MODE>mode == DImode)
7871     insn = (mode == SImode)
7872            ? gen_zero_extendsidi2
7873            : (mode == HImode)
7874            ? gen_zero_extendhidi2
7875            : gen_zero_extendqidi2;
7876   else if (<MODE>mode == SImode)
7877     insn = (mode == HImode)
7878            ? gen_zero_extendhisi2
7879            : gen_zero_extendqisi2;
7880   else if (<MODE>mode == HImode)
7881     insn = gen_zero_extendqihi2;
7882   else
7883     gcc_unreachable ();
7885   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7886   DONE;
7889 (define_insn "*anddi_1"
7890   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7891         (and:DI
7892          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7893          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7894    (clobber (reg:CC FLAGS_REG))]
7895   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7897   switch (get_attr_type (insn))
7898     {
7899     case TYPE_IMOVX:
7900       return "#";
7902     default:
7903       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7904       if (get_attr_mode (insn) == MODE_SI)
7905         return "and{l}\t{%k2, %k0|%k0, %k2}";
7906       else
7907         return "and{q}\t{%2, %0|%0, %2}";
7908     }
7910   [(set_attr "type" "alu,alu,alu,imovx")
7911    (set_attr "length_immediate" "*,*,*,0")
7912    (set (attr "prefix_rex")
7913      (if_then_else
7914        (and (eq_attr "type" "imovx")
7915             (and (match_test "INTVAL (operands[2]) == 0xff")
7916                  (match_operand 1 "ext_QIreg_operand")))
7917        (const_string "1")
7918        (const_string "*")))
7919    (set_attr "mode" "SI,DI,DI,SI")])
7921 (define_insn "*andsi_1"
7922   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7923         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7924                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7925    (clobber (reg:CC FLAGS_REG))]
7926   "ix86_binary_operator_ok (AND, SImode, operands)"
7928   switch (get_attr_type (insn))
7929     {
7930     case TYPE_IMOVX:
7931       return "#";
7933     default:
7934       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7935       return "and{l}\t{%2, %0|%0, %2}";
7936     }
7938   [(set_attr "type" "alu,alu,imovx")
7939    (set (attr "prefix_rex")
7940      (if_then_else
7941        (and (eq_attr "type" "imovx")
7942             (and (match_test "INTVAL (operands[2]) == 0xff")
7943                  (match_operand 1 "ext_QIreg_operand")))
7944        (const_string "1")
7945        (const_string "*")))
7946    (set_attr "length_immediate" "*,*,0")
7947    (set_attr "mode" "SI")])
7949 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7950 (define_insn "*andsi_1_zext"
7951   [(set (match_operand:DI 0 "register_operand" "=r")
7952         (zero_extend:DI
7953           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7954                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7955    (clobber (reg:CC FLAGS_REG))]
7956   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7957   "and{l}\t{%2, %k0|%k0, %2}"
7958   [(set_attr "type" "alu")
7959    (set_attr "mode" "SI")])
7961 (define_insn "*andhi_1"
7962   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7963         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7964                 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7965    (clobber (reg:CC FLAGS_REG))]
7966   "ix86_binary_operator_ok (AND, HImode, operands)"
7968   switch (get_attr_type (insn))
7969     {
7970     case TYPE_IMOVX:
7971       return "#";
7973     case TYPE_MSKLOG:
7974       return "kandw\t{%2, %1, %0|%0, %1, %2}";
7976     default:
7977       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7978       return "and{w}\t{%2, %0|%0, %2}";
7979     }
7981   [(set_attr "type" "alu,alu,imovx,msklog")
7982    (set_attr "length_immediate" "*,*,0,*")
7983    (set (attr "prefix_rex")
7984      (if_then_else
7985        (and (eq_attr "type" "imovx")
7986             (match_operand 1 "ext_QIreg_operand"))
7987        (const_string "1")
7988        (const_string "*")))
7989    (set_attr "mode" "HI,HI,SI,HI")])
7991 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7992 (define_insn "*andqi_1"
7993   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7994         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7995                 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7996    (clobber (reg:CC FLAGS_REG))]
7997   "ix86_binary_operator_ok (AND, QImode, operands)"
7998   "@
7999    and{b}\t{%2, %0|%0, %2}
8000    and{b}\t{%2, %0|%0, %2}
8001    and{l}\t{%k2, %k0|%k0, %k2}
8002    kandw\t{%2, %1, %0|%0, %1, %2}"
8003   [(set_attr "type" "alu,alu,alu,msklog")
8004    (set_attr "mode" "QI,QI,SI,HI")])
8006 (define_insn "*andqi_1_slp"
8007   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8008         (and:QI (match_dup 0)
8009                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8010    (clobber (reg:CC FLAGS_REG))]
8011   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8012    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8013   "and{b}\t{%1, %0|%0, %1}"
8014   [(set_attr "type" "alu1")
8015    (set_attr "mode" "QI")])
8017 (define_insn "kandn<mode>"
8018   [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
8019         (and:SWI12
8020           (not:SWI12
8021             (match_operand:SWI12 1 "register_operand" "r,0,k"))
8022           (match_operand:SWI12 2 "register_operand" "r,r,k")))
8023    (clobber (reg:CC FLAGS_REG))]
8024   "TARGET_AVX512F"
8025   "@
8026    andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
8027    #
8028    kandnw\t{%2, %1, %0|%0, %1, %2}"
8029   [(set_attr "isa" "bmi,*,avx512f")
8030    (set_attr "type" "bitmanip,*,msklog")
8031    (set_attr "prefix" "*,*,vex")
8032    (set_attr "btver2_decode" "direct,*,*")
8033    (set_attr "mode" "<MODE>")])
8035 (define_split
8036   [(set (match_operand:SWI12 0 "general_reg_operand")
8037         (and:SWI12
8038           (not:SWI12
8039             (match_dup 0))
8040           (match_operand:SWI12 1 "general_reg_operand")))
8041    (clobber (reg:CC FLAGS_REG))]
8042   "TARGET_AVX512F && !TARGET_BMI && reload_completed"
8043   [(set (match_dup 0)
8044         (not:HI (match_dup 0)))
8045    (parallel [(set (match_dup 0)
8046                    (and:HI (match_dup 0)
8047                            (match_dup 1)))
8048               (clobber (reg:CC FLAGS_REG))])])
8050 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8051 (define_split
8052   [(set (match_operand:DI 0 "register_operand")
8053         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8054                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8055    (clobber (reg:CC FLAGS_REG))]
8056   "TARGET_64BIT"
8057   [(parallel [(set (match_dup 0)
8058                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8059               (clobber (reg:CC FLAGS_REG))])]
8060   "operands[2] = gen_lowpart (SImode, operands[2]);")
8062 (define_split
8063   [(set (match_operand:SWI248 0 "register_operand")
8064         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8065                     (match_operand:SWI248 2 "const_int_operand")))
8066    (clobber (reg:CC FLAGS_REG))]
8067   "reload_completed
8068    && true_regnum (operands[0]) != true_regnum (operands[1])"
8069   [(const_int 0)]
8071   HOST_WIDE_INT ival = INTVAL (operands[2]);
8072   enum machine_mode mode;
8073   rtx (*insn) (rtx, rtx);
8075   if (ival == (HOST_WIDE_INT) 0xffffffff)
8076     mode = SImode;
8077   else if (ival == 0xffff)
8078     mode = HImode;
8079   else
8080     {
8081       gcc_assert (ival == 0xff);
8082       mode = QImode;
8083     }
8085   if (<MODE>mode == DImode)
8086     insn = (mode == SImode)
8087            ? gen_zero_extendsidi2
8088            : (mode == HImode)
8089            ? gen_zero_extendhidi2
8090            : gen_zero_extendqidi2;
8091   else
8092     {
8093       if (<MODE>mode != SImode)
8094         /* Zero extend to SImode to avoid partial register stalls.  */
8095         operands[0] = gen_lowpart (SImode, operands[0]);
8097       insn = (mode == HImode)
8098              ? gen_zero_extendhisi2
8099              : gen_zero_extendqisi2;
8100     }
8101   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8102   DONE;
8105 (define_split
8106   [(set (match_operand 0 "register_operand")
8107         (and (match_dup 0)
8108              (const_int -65536)))
8109    (clobber (reg:CC FLAGS_REG))]
8110   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8111     || optimize_function_for_size_p (cfun)"
8112   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8113   "operands[1] = gen_lowpart (HImode, operands[0]);")
8115 (define_split
8116   [(set (match_operand 0 "ext_register_operand")
8117         (and (match_dup 0)
8118              (const_int -256)))
8119    (clobber (reg:CC FLAGS_REG))]
8120   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8121    && reload_completed"
8122   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8123   "operands[1] = gen_lowpart (QImode, operands[0]);")
8125 (define_split
8126   [(set (match_operand 0 "ext_register_operand")
8127         (and (match_dup 0)
8128              (const_int -65281)))
8129    (clobber (reg:CC FLAGS_REG))]
8130   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8131    && reload_completed"
8132   [(parallel [(set (zero_extract:SI (match_dup 0)
8133                                     (const_int 8)
8134                                     (const_int 8))
8135                    (xor:SI
8136                      (zero_extract:SI (match_dup 0)
8137                                       (const_int 8)
8138                                       (const_int 8))
8139                      (zero_extract:SI (match_dup 0)
8140                                       (const_int 8)
8141                                       (const_int 8))))
8142               (clobber (reg:CC FLAGS_REG))])]
8143   "operands[0] = gen_lowpart (SImode, operands[0]);")
8145 (define_insn "*anddi_2"
8146   [(set (reg FLAGS_REG)
8147         (compare
8148          (and:DI
8149           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8150           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8151          (const_int 0)))
8152    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8153         (and:DI (match_dup 1) (match_dup 2)))]
8154   "TARGET_64BIT
8155    && ix86_match_ccmode
8156         (insn,
8157          /* If we are going to emit andl instead of andq, and the operands[2]
8158             constant might have the SImode sign bit set, make sure the sign
8159             flag isn't tested, because the instruction will set the sign flag
8160             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
8161             conservatively assume it might have bit 31 set.  */
8162          (satisfies_constraint_Z (operands[2])
8163           && (!CONST_INT_P (operands[2])
8164               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8165          ? CCZmode : CCNOmode)
8166    && ix86_binary_operator_ok (AND, DImode, operands)"
8167   "@
8168    and{l}\t{%k2, %k0|%k0, %k2}
8169    and{q}\t{%2, %0|%0, %2}
8170    and{q}\t{%2, %0|%0, %2}"
8171   [(set_attr "type" "alu")
8172    (set_attr "mode" "SI,DI,DI")])
8174 (define_insn "*andqi_2_maybe_si"
8175   [(set (reg FLAGS_REG)
8176         (compare (and:QI
8177                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8178                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8179                  (const_int 0)))
8180    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8181         (and:QI (match_dup 1) (match_dup 2)))]
8182   "ix86_binary_operator_ok (AND, QImode, operands)
8183    && ix86_match_ccmode (insn,
8184                          CONST_INT_P (operands[2])
8185                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8187   if (which_alternative == 2)
8188     {
8189       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8190         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8191       return "and{l}\t{%2, %k0|%k0, %2}";
8192     }
8193   return "and{b}\t{%2, %0|%0, %2}";
8195   [(set_attr "type" "alu")
8196    (set_attr "mode" "QI,QI,SI")])
8198 (define_insn "*and<mode>_2"
8199   [(set (reg FLAGS_REG)
8200         (compare (and:SWI124
8201                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8202                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8203                  (const_int 0)))
8204    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8205         (and:SWI124 (match_dup 1) (match_dup 2)))]
8206   "ix86_match_ccmode (insn, CCNOmode)
8207    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8208   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8209   [(set_attr "type" "alu")
8210    (set_attr "mode" "<MODE>")])
8212 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8213 (define_insn "*andsi_2_zext"
8214   [(set (reg FLAGS_REG)
8215         (compare (and:SI
8216                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8217                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
8218                  (const_int 0)))
8219    (set (match_operand:DI 0 "register_operand" "=r")
8220         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8221   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8222    && ix86_binary_operator_ok (AND, SImode, operands)"
8223   "and{l}\t{%2, %k0|%k0, %2}"
8224   [(set_attr "type" "alu")
8225    (set_attr "mode" "SI")])
8227 (define_insn "*andqi_2_slp"
8228   [(set (reg FLAGS_REG)
8229         (compare (and:QI
8230                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8231                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8232                  (const_int 0)))
8233    (set (strict_low_part (match_dup 0))
8234         (and:QI (match_dup 0) (match_dup 1)))]
8235   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8236    && ix86_match_ccmode (insn, CCNOmode)
8237    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8238   "and{b}\t{%1, %0|%0, %1}"
8239   [(set_attr "type" "alu1")
8240    (set_attr "mode" "QI")])
8242 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8243 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8244 ;; for a QImode operand, which of course failed.
8245 (define_insn "andqi_ext_0"
8246   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8247                          (const_int 8)
8248                          (const_int 8))
8249         (and:SI
8250           (zero_extract:SI
8251             (match_operand 1 "ext_register_operand" "0")
8252             (const_int 8)
8253             (const_int 8))
8254           (match_operand 2 "const_int_operand" "n")))
8255    (clobber (reg:CC FLAGS_REG))]
8256   ""
8257   "and{b}\t{%2, %h0|%h0, %2}"
8258   [(set_attr "type" "alu")
8259    (set_attr "length_immediate" "1")
8260    (set_attr "modrm" "1")
8261    (set_attr "mode" "QI")])
8263 ;; Generated by peephole translating test to and.  This shows up
8264 ;; often in fp comparisons.
8265 (define_insn "*andqi_ext_0_cc"
8266   [(set (reg FLAGS_REG)
8267         (compare
8268           (and:SI
8269             (zero_extract:SI
8270               (match_operand 1 "ext_register_operand" "0")
8271               (const_int 8)
8272               (const_int 8))
8273             (match_operand 2 "const_int_operand" "n"))
8274           (const_int 0)))
8275    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8276                          (const_int 8)
8277                          (const_int 8))
8278         (and:SI
8279           (zero_extract:SI
8280             (match_dup 1)
8281             (const_int 8)
8282             (const_int 8))
8283           (match_dup 2)))]
8284   "ix86_match_ccmode (insn, CCNOmode)"
8285   "and{b}\t{%2, %h0|%h0, %2}"
8286   [(set_attr "type" "alu")
8287    (set_attr "length_immediate" "1")
8288    (set_attr "modrm" "1")
8289    (set_attr "mode" "QI")])
8291 (define_insn "*andqi_ext_1"
8292   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8293                          (const_int 8)
8294                          (const_int 8))
8295         (and:SI
8296           (zero_extract:SI
8297             (match_operand 1 "ext_register_operand" "0,0")
8298             (const_int 8)
8299             (const_int 8))
8300           (zero_extend:SI
8301             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8302    (clobber (reg:CC FLAGS_REG))]
8303   ""
8304   "and{b}\t{%2, %h0|%h0, %2}"
8305   [(set_attr "isa" "*,nox64")
8306    (set_attr "type" "alu")
8307    (set_attr "length_immediate" "0")
8308    (set_attr "mode" "QI")])
8310 (define_insn "*andqi_ext_2"
8311   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8312                          (const_int 8)
8313                          (const_int 8))
8314         (and:SI
8315           (zero_extract:SI
8316             (match_operand 1 "ext_register_operand" "%0")
8317             (const_int 8)
8318             (const_int 8))
8319           (zero_extract:SI
8320             (match_operand 2 "ext_register_operand" "Q")
8321             (const_int 8)
8322             (const_int 8))))
8323    (clobber (reg:CC FLAGS_REG))]
8324   ""
8325   "and{b}\t{%h2, %h0|%h0, %h2}"
8326   [(set_attr "type" "alu")
8327    (set_attr "length_immediate" "0")
8328    (set_attr "mode" "QI")])
8330 ;; Convert wide AND instructions with immediate operand to shorter QImode
8331 ;; equivalents when possible.
8332 ;; Don't do the splitting with memory operands, since it introduces risk
8333 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8334 ;; for size, but that can (should?) be handled by generic code instead.
8335 (define_split
8336   [(set (match_operand 0 "register_operand")
8337         (and (match_operand 1 "register_operand")
8338              (match_operand 2 "const_int_operand")))
8339    (clobber (reg:CC FLAGS_REG))]
8340    "reload_completed
8341     && QI_REG_P (operands[0])
8342     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8343     && !(~INTVAL (operands[2]) & ~(255 << 8))
8344     && GET_MODE (operands[0]) != QImode"
8345   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8346                    (and:SI (zero_extract:SI (match_dup 1)
8347                                             (const_int 8) (const_int 8))
8348                            (match_dup 2)))
8349               (clobber (reg:CC FLAGS_REG))])]
8351   operands[0] = gen_lowpart (SImode, operands[0]);
8352   operands[1] = gen_lowpart (SImode, operands[1]);
8353   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8356 ;; Since AND can be encoded with sign extended immediate, this is only
8357 ;; profitable when 7th bit is not set.
8358 (define_split
8359   [(set (match_operand 0 "register_operand")
8360         (and (match_operand 1 "general_operand")
8361              (match_operand 2 "const_int_operand")))
8362    (clobber (reg:CC FLAGS_REG))]
8363    "reload_completed
8364     && ANY_QI_REG_P (operands[0])
8365     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8366     && !(~INTVAL (operands[2]) & ~255)
8367     && !(INTVAL (operands[2]) & 128)
8368     && GET_MODE (operands[0]) != QImode"
8369   [(parallel [(set (strict_low_part (match_dup 0))
8370                    (and:QI (match_dup 1)
8371                            (match_dup 2)))
8372               (clobber (reg:CC FLAGS_REG))])]
8374   operands[0] = gen_lowpart (QImode, operands[0]);
8375   operands[1] = gen_lowpart (QImode, operands[1]);
8376   operands[2] = gen_lowpart (QImode, operands[2]);
8379 ;; Logical inclusive and exclusive OR instructions
8381 ;; %%% This used to optimize known byte-wide and operations to memory.
8382 ;; If this is considered useful, it should be done with splitters.
8384 (define_expand "<code><mode>3"
8385   [(set (match_operand:SWIM 0 "nonimmediate_operand")
8386         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8387                      (match_operand:SWIM 2 "<general_operand>")))]
8388   ""
8389   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8391 (define_insn "*<code><mode>_1"
8392   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
8393         (any_or:SWI48
8394          (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
8395          (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>")))
8396    (clobber (reg:CC FLAGS_REG))]
8397   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8398   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8399   [(set_attr "type" "alu")
8400    (set_attr "mode" "<MODE>")])
8402 (define_insn "*<code>hi_1"
8403   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8404         (any_or:HI
8405          (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8406          (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8407    (clobber (reg:CC FLAGS_REG))]
8408   "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8409   "@
8410   <logic>{w}\t{%2, %0|%0, %2}
8411   <logic>{w}\t{%2, %0|%0, %2}
8412   k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8413   [(set_attr "type" "alu,alu,msklog")
8414    (set_attr "mode" "HI")])
8416 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8417 (define_insn "*<code>qi_1"
8418   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8419         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8420                    (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8421    (clobber (reg:CC FLAGS_REG))]
8422   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8423   "@
8424    <logic>{b}\t{%2, %0|%0, %2}
8425    <logic>{b}\t{%2, %0|%0, %2}
8426    <logic>{l}\t{%k2, %k0|%k0, %k2}
8427    k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8428   [(set_attr "type" "alu,alu,alu,msklog")
8429    (set_attr "mode" "QI,QI,SI,HI")])
8431 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8432 (define_insn "*<code>si_1_zext"
8433   [(set (match_operand:DI 0 "register_operand" "=r")
8434         (zero_extend:DI
8435          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8436                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8437    (clobber (reg:CC FLAGS_REG))]
8438   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8439   "<logic>{l}\t{%2, %k0|%k0, %2}"
8440   [(set_attr "type" "alu")
8441    (set_attr "mode" "SI")])
8443 (define_insn "*<code>si_1_zext_imm"
8444   [(set (match_operand:DI 0 "register_operand" "=r")
8445         (any_or:DI
8446          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8447          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8448    (clobber (reg:CC FLAGS_REG))]
8449   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8450   "<logic>{l}\t{%2, %k0|%k0, %2}"
8451   [(set_attr "type" "alu")
8452    (set_attr "mode" "SI")])
8454 (define_insn "*<code>qi_1_slp"
8455   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8456         (any_or:QI (match_dup 0)
8457                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8458    (clobber (reg:CC FLAGS_REG))]
8459   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8460    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8461   "<logic>{b}\t{%1, %0|%0, %1}"
8462   [(set_attr "type" "alu1")
8463    (set_attr "mode" "QI")])
8465 (define_insn "*<code><mode>_2"
8466   [(set (reg FLAGS_REG)
8467         (compare (any_or:SWI
8468                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8469                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8470                  (const_int 0)))
8471    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8472         (any_or:SWI (match_dup 1) (match_dup 2)))]
8473   "ix86_match_ccmode (insn, CCNOmode)
8474    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8475   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8476   [(set_attr "type" "alu")
8477    (set_attr "mode" "<MODE>")])
8479 (define_insn "kxnor<mode>"
8480   [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8481         (not:SWI12
8482           (xor:SWI12
8483             (match_operand:SWI12 1 "register_operand" "0,k")
8484             (match_operand:SWI12 2 "register_operand" "r,k"))))
8485    (clobber (reg:CC FLAGS_REG))]
8486   "TARGET_AVX512F"
8487   "@
8488    #
8489    kxnorw\t{%2, %1, %0|%0, %1, %2}"
8490   [(set_attr "type" "*,msklog")
8491    (set_attr "prefix" "*,vex")
8492    (set_attr "mode" "<MODE>")])
8494 (define_split
8495   [(set (match_operand:SWI12 0 "general_reg_operand")
8496         (not:SWI12
8497           (xor:SWI12
8498             (match_dup 0)
8499             (match_operand:SWI12 1 "general_reg_operand"))))
8500    (clobber (reg:CC FLAGS_REG))]
8501   "TARGET_AVX512F && reload_completed"
8502    [(parallel [(set (match_dup 0)
8503                     (xor:HI (match_dup 0)
8504                             (match_dup 1)))
8505                (clobber (reg:CC FLAGS_REG))])
8506     (set (match_dup 0)
8507          (not:HI (match_dup 0)))])
8509 (define_insn "kortestzhi"
8510   [(set (reg:CCZ FLAGS_REG)
8511         (compare:CCZ
8512           (ior:HI
8513             (match_operand:HI 0 "register_operand" "k")
8514             (match_operand:HI 1 "register_operand" "k"))
8515           (const_int 0)))]
8516   "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8517   "kortestw\t{%1, %0|%0, %1}"
8518   [(set_attr "mode" "HI")
8519    (set_attr "type" "msklog")
8520    (set_attr "prefix" "vex")])
8522 (define_insn "kortestchi"
8523   [(set (reg:CCC FLAGS_REG)
8524         (compare:CCC
8525           (ior:HI
8526             (match_operand:HI 0 "register_operand" "k")
8527             (match_operand:HI 1 "register_operand" "k"))
8528           (const_int -1)))]
8529   "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8530   "kortestw\t{%1, %0|%0, %1}"
8531   [(set_attr "mode" "HI")
8532    (set_attr "type" "msklog")
8533    (set_attr "prefix" "vex")])
8535 (define_insn "kunpckhi"
8536   [(set (match_operand:HI 0 "register_operand" "=k")
8537         (ior:HI
8538           (ashift:HI
8539             (match_operand:HI 1 "register_operand" "k")
8540             (const_int 8))
8541           (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8542   "TARGET_AVX512F"
8543   "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8544   [(set_attr "mode" "HI")
8545    (set_attr "type" "msklog")
8546    (set_attr "prefix" "vex")])
8548 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8549 ;; ??? Special case for immediate operand is missing - it is tricky.
8550 (define_insn "*<code>si_2_zext"
8551   [(set (reg FLAGS_REG)
8552         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8553                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8554                  (const_int 0)))
8555    (set (match_operand:DI 0 "register_operand" "=r")
8556         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8557   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8558    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8559   "<logic>{l}\t{%2, %k0|%k0, %2}"
8560   [(set_attr "type" "alu")
8561    (set_attr "mode" "SI")])
8563 (define_insn "*<code>si_2_zext_imm"
8564   [(set (reg FLAGS_REG)
8565         (compare (any_or:SI
8566                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8567                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8568                  (const_int 0)))
8569    (set (match_operand:DI 0 "register_operand" "=r")
8570         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8571   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8572    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8573   "<logic>{l}\t{%2, %k0|%k0, %2}"
8574   [(set_attr "type" "alu")
8575    (set_attr "mode" "SI")])
8577 (define_insn "*<code>qi_2_slp"
8578   [(set (reg FLAGS_REG)
8579         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8580                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8581                  (const_int 0)))
8582    (set (strict_low_part (match_dup 0))
8583         (any_or:QI (match_dup 0) (match_dup 1)))]
8584   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8585    && ix86_match_ccmode (insn, CCNOmode)
8586    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8587   "<logic>{b}\t{%1, %0|%0, %1}"
8588   [(set_attr "type" "alu1")
8589    (set_attr "mode" "QI")])
8591 (define_insn "*<code><mode>_3"
8592   [(set (reg FLAGS_REG)
8593         (compare (any_or:SWI
8594                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8595                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8596                  (const_int 0)))
8597    (clobber (match_scratch:SWI 0 "=<r>"))]
8598   "ix86_match_ccmode (insn, CCNOmode)
8599    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8600   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8601   [(set_attr "type" "alu")
8602    (set_attr "mode" "<MODE>")])
8604 (define_insn "*<code>qi_ext_0"
8605   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8606                          (const_int 8)
8607                          (const_int 8))
8608         (any_or:SI
8609           (zero_extract:SI
8610             (match_operand 1 "ext_register_operand" "0")
8611             (const_int 8)
8612             (const_int 8))
8613           (match_operand 2 "const_int_operand" "n")))
8614    (clobber (reg:CC FLAGS_REG))]
8615   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8616   "<logic>{b}\t{%2, %h0|%h0, %2}"
8617   [(set_attr "type" "alu")
8618    (set_attr "length_immediate" "1")
8619    (set_attr "modrm" "1")
8620    (set_attr "mode" "QI")])
8622 (define_insn "*<code>qi_ext_1"
8623   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8624                          (const_int 8)
8625                          (const_int 8))
8626         (any_or:SI
8627           (zero_extract:SI
8628             (match_operand 1 "ext_register_operand" "0,0")
8629             (const_int 8)
8630             (const_int 8))
8631           (zero_extend:SI
8632             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8633    (clobber (reg:CC FLAGS_REG))]
8634   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8635   "<logic>{b}\t{%2, %h0|%h0, %2}"
8636   [(set_attr "isa" "*,nox64")
8637    (set_attr "type" "alu")
8638    (set_attr "length_immediate" "0")
8639    (set_attr "mode" "QI")])
8641 (define_insn "*<code>qi_ext_2"
8642   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8643                          (const_int 8)
8644                          (const_int 8))
8645         (any_or:SI
8646           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8647                            (const_int 8)
8648                            (const_int 8))
8649           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8650                            (const_int 8)
8651                            (const_int 8))))
8652    (clobber (reg:CC FLAGS_REG))]
8653   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8654   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8655   [(set_attr "type" "alu")
8656    (set_attr "length_immediate" "0")
8657    (set_attr "mode" "QI")])
8659 (define_split
8660   [(set (match_operand 0 "register_operand")
8661         (any_or (match_operand 1 "register_operand")
8662                 (match_operand 2 "const_int_operand")))
8663    (clobber (reg:CC FLAGS_REG))]
8664    "reload_completed
8665     && QI_REG_P (operands[0])
8666     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8667     && !(INTVAL (operands[2]) & ~(255 << 8))
8668     && GET_MODE (operands[0]) != QImode"
8669   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8670                    (any_or:SI (zero_extract:SI (match_dup 1)
8671                                                (const_int 8) (const_int 8))
8672                               (match_dup 2)))
8673               (clobber (reg:CC FLAGS_REG))])]
8675   operands[0] = gen_lowpart (SImode, operands[0]);
8676   operands[1] = gen_lowpart (SImode, operands[1]);
8677   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8680 ;; Since OR can be encoded with sign extended immediate, this is only
8681 ;; profitable when 7th bit is set.
8682 (define_split
8683   [(set (match_operand 0 "register_operand")
8684         (any_or (match_operand 1 "general_operand")
8685                 (match_operand 2 "const_int_operand")))
8686    (clobber (reg:CC FLAGS_REG))]
8687    "reload_completed
8688     && ANY_QI_REG_P (operands[0])
8689     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8690     && !(INTVAL (operands[2]) & ~255)
8691     && (INTVAL (operands[2]) & 128)
8692     && GET_MODE (operands[0]) != QImode"
8693   [(parallel [(set (strict_low_part (match_dup 0))
8694                    (any_or:QI (match_dup 1)
8695                               (match_dup 2)))
8696               (clobber (reg:CC FLAGS_REG))])]
8698   operands[0] = gen_lowpart (QImode, operands[0]);
8699   operands[1] = gen_lowpart (QImode, operands[1]);
8700   operands[2] = gen_lowpart (QImode, operands[2]);
8703 (define_expand "xorqi_cc_ext_1"
8704   [(parallel [
8705      (set (reg:CCNO FLAGS_REG)
8706           (compare:CCNO
8707             (xor:SI
8708               (zero_extract:SI
8709                 (match_operand 1 "ext_register_operand")
8710                 (const_int 8)
8711                 (const_int 8))
8712               (match_operand:QI 2 "const_int_operand"))
8713             (const_int 0)))
8714      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8715                            (const_int 8)
8716                            (const_int 8))
8717           (xor:SI
8718             (zero_extract:SI
8719              (match_dup 1)
8720              (const_int 8)
8721              (const_int 8))
8722             (match_dup 2)))])])
8724 (define_insn "*xorqi_cc_ext_1"
8725   [(set (reg FLAGS_REG)
8726         (compare
8727           (xor:SI
8728             (zero_extract:SI
8729               (match_operand 1 "ext_register_operand" "0,0")
8730               (const_int 8)
8731               (const_int 8))
8732             (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8733           (const_int 0)))
8734    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8735                          (const_int 8)
8736                          (const_int 8))
8737         (xor:SI
8738           (zero_extract:SI
8739            (match_dup 1)
8740            (const_int 8)
8741            (const_int 8))
8742           (match_dup 2)))]
8743   "ix86_match_ccmode (insn, CCNOmode)"
8744   "xor{b}\t{%2, %h0|%h0, %2}"
8745   [(set_attr "isa" "*,nox64")
8746    (set_attr "type" "alu")
8747    (set_attr "modrm" "1")
8748    (set_attr "mode" "QI")])
8750 ;; Negation instructions
8752 (define_expand "neg<mode>2"
8753   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8754         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8755   ""
8756   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8758 (define_insn_and_split "*neg<dwi>2_doubleword"
8759   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8760         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8761    (clobber (reg:CC FLAGS_REG))]
8762   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8763   "#"
8764   "reload_completed"
8765   [(parallel
8766     [(set (reg:CCZ FLAGS_REG)
8767           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8768      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8769    (parallel
8770     [(set (match_dup 2)
8771           (plus:DWIH (match_dup 3)
8772                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8773                                 (const_int 0))))
8774      (clobber (reg:CC FLAGS_REG))])
8775    (parallel
8776     [(set (match_dup 2)
8777           (neg:DWIH (match_dup 2)))
8778      (clobber (reg:CC FLAGS_REG))])]
8779   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8781 (define_insn "*neg<mode>2_1"
8782   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8783         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8784    (clobber (reg:CC FLAGS_REG))]
8785   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8786   "neg{<imodesuffix>}\t%0"
8787   [(set_attr "type" "negnot")
8788    (set_attr "mode" "<MODE>")])
8790 ;; Combine is quite creative about this pattern.
8791 (define_insn "*negsi2_1_zext"
8792   [(set (match_operand:DI 0 "register_operand" "=r")
8793         (lshiftrt:DI
8794           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8795                              (const_int 32)))
8796         (const_int 32)))
8797    (clobber (reg:CC FLAGS_REG))]
8798   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8799   "neg{l}\t%k0"
8800   [(set_attr "type" "negnot")
8801    (set_attr "mode" "SI")])
8803 ;; The problem with neg is that it does not perform (compare x 0),
8804 ;; it really performs (compare 0 x), which leaves us with the zero
8805 ;; flag being the only useful item.
8807 (define_insn "*neg<mode>2_cmpz"
8808   [(set (reg:CCZ FLAGS_REG)
8809         (compare:CCZ
8810           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8811                    (const_int 0)))
8812    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8813         (neg:SWI (match_dup 1)))]
8814   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8815   "neg{<imodesuffix>}\t%0"
8816   [(set_attr "type" "negnot")
8817    (set_attr "mode" "<MODE>")])
8819 (define_insn "*negsi2_cmpz_zext"
8820   [(set (reg:CCZ FLAGS_REG)
8821         (compare:CCZ
8822           (lshiftrt:DI
8823             (neg:DI (ashift:DI
8824                       (match_operand:DI 1 "register_operand" "0")
8825                       (const_int 32)))
8826             (const_int 32))
8827           (const_int 0)))
8828    (set (match_operand:DI 0 "register_operand" "=r")
8829         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8830                                         (const_int 32)))
8831                      (const_int 32)))]
8832   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8833   "neg{l}\t%k0"
8834   [(set_attr "type" "negnot")
8835    (set_attr "mode" "SI")])
8837 ;; Negate with jump on overflow.
8838 (define_expand "negv<mode>3"
8839   [(parallel [(set (reg:CCO FLAGS_REG)
8840                    (ne:CCO (match_operand:SWI 1 "register_operand")
8841                            (match_dup 3)))
8842               (set (match_operand:SWI 0 "register_operand")
8843                    (neg:SWI (match_dup 1)))])
8844    (set (pc) (if_then_else
8845                (eq (reg:CCO FLAGS_REG) (const_int 0))
8846                (label_ref (match_operand 2))
8847                (pc)))]
8848   ""
8850   operands[3]
8851     = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8852                     <MODE>mode);
8855 (define_insn "*negv<mode>3"
8856   [(set (reg:CCO FLAGS_REG)
8857         (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8858                 (match_operand:SWI 2 "const_int_operand")))
8859    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8860         (neg:SWI (match_dup 1)))]
8861   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8862    && mode_signbit_p (<MODE>mode, operands[2])"
8863   "neg{<imodesuffix>}\t%0"
8864   [(set_attr "type" "negnot")
8865    (set_attr "mode" "<MODE>")])
8867 ;; Changing of sign for FP values is doable using integer unit too.
8869 (define_expand "<code><mode>2"
8870   [(set (match_operand:X87MODEF 0 "register_operand")
8871         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8872   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8873   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8875 (define_insn "*absneg<mode>2_mixed"
8876   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8877         (match_operator:MODEF 3 "absneg_operator"
8878           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8879    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8880    (clobber (reg:CC FLAGS_REG))]
8881   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8882   "#")
8884 (define_insn "*absneg<mode>2_sse"
8885   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8886         (match_operator:MODEF 3 "absneg_operator"
8887           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8888    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8889    (clobber (reg:CC FLAGS_REG))]
8890   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8891   "#")
8893 (define_insn "*absneg<mode>2_i387"
8894   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8895         (match_operator:X87MODEF 3 "absneg_operator"
8896           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8897    (use (match_operand 2))
8898    (clobber (reg:CC FLAGS_REG))]
8899   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8900   "#")
8902 (define_expand "<code>tf2"
8903   [(set (match_operand:TF 0 "register_operand")
8904         (absneg:TF (match_operand:TF 1 "register_operand")))]
8905   "TARGET_SSE"
8906   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8908 (define_insn "*absnegtf2_sse"
8909   [(set (match_operand:TF 0 "register_operand" "=x,x")
8910         (match_operator:TF 3 "absneg_operator"
8911           [(match_operand:TF 1 "register_operand" "0,x")]))
8912    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8913    (clobber (reg:CC FLAGS_REG))]
8914   "TARGET_SSE"
8915   "#")
8917 ;; Splitters for fp abs and neg.
8919 (define_split
8920   [(set (match_operand 0 "fp_register_operand")
8921         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8922    (use (match_operand 2))
8923    (clobber (reg:CC FLAGS_REG))]
8924   "reload_completed"
8925   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8927 (define_split
8928   [(set (match_operand 0 "register_operand")
8929         (match_operator 3 "absneg_operator"
8930           [(match_operand 1 "register_operand")]))
8931    (use (match_operand 2 "nonimmediate_operand"))
8932    (clobber (reg:CC FLAGS_REG))]
8933   "reload_completed && SSE_REG_P (operands[0])"
8934   [(set (match_dup 0) (match_dup 3))]
8936   enum machine_mode mode = GET_MODE (operands[0]);
8937   enum machine_mode vmode = GET_MODE (operands[2]);
8938   rtx tmp;
8940   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8941   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8942   if (operands_match_p (operands[0], operands[2]))
8943     {
8944       tmp = operands[1];
8945       operands[1] = operands[2];
8946       operands[2] = tmp;
8947     }
8948   if (GET_CODE (operands[3]) == ABS)
8949     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8950   else
8951     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8952   operands[3] = tmp;
8955 (define_split
8956   [(set (match_operand:SF 0 "register_operand")
8957         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8958    (use (match_operand:V4SF 2))
8959    (clobber (reg:CC FLAGS_REG))]
8960   "reload_completed"
8961   [(parallel [(set (match_dup 0) (match_dup 1))
8962               (clobber (reg:CC FLAGS_REG))])]
8964   rtx tmp;
8965   operands[0] = gen_lowpart (SImode, operands[0]);
8966   if (GET_CODE (operands[1]) == ABS)
8967     {
8968       tmp = gen_int_mode (0x7fffffff, SImode);
8969       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8970     }
8971   else
8972     {
8973       tmp = gen_int_mode (0x80000000, SImode);
8974       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8975     }
8976   operands[1] = tmp;
8979 (define_split
8980   [(set (match_operand:DF 0 "register_operand")
8981         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8982    (use (match_operand 2))
8983    (clobber (reg:CC FLAGS_REG))]
8984   "reload_completed"
8985   [(parallel [(set (match_dup 0) (match_dup 1))
8986               (clobber (reg:CC FLAGS_REG))])]
8988   rtx tmp;
8989   if (TARGET_64BIT)
8990     {
8991       tmp = gen_lowpart (DImode, operands[0]);
8992       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8993       operands[0] = tmp;
8995       if (GET_CODE (operands[1]) == ABS)
8996         tmp = const0_rtx;
8997       else
8998         tmp = gen_rtx_NOT (DImode, tmp);
8999     }
9000   else
9001     {
9002       operands[0] = gen_highpart (SImode, operands[0]);
9003       if (GET_CODE (operands[1]) == ABS)
9004         {
9005           tmp = gen_int_mode (0x7fffffff, SImode);
9006           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9007         }
9008       else
9009         {
9010           tmp = gen_int_mode (0x80000000, SImode);
9011           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9012         }
9013     }
9014   operands[1] = tmp;
9017 (define_split
9018   [(set (match_operand:XF 0 "register_operand")
9019         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9020    (use (match_operand 2))
9021    (clobber (reg:CC FLAGS_REG))]
9022   "reload_completed"
9023   [(parallel [(set (match_dup 0) (match_dup 1))
9024               (clobber (reg:CC FLAGS_REG))])]
9026   rtx tmp;
9027   operands[0] = gen_rtx_REG (SImode,
9028                              true_regnum (operands[0])
9029                              + (TARGET_64BIT ? 1 : 2));
9030   if (GET_CODE (operands[1]) == ABS)
9031     {
9032       tmp = GEN_INT (0x7fff);
9033       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9034     }
9035   else
9036     {
9037       tmp = GEN_INT (0x8000);
9038       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9039     }
9040   operands[1] = tmp;
9043 ;; Conditionalize these after reload. If they match before reload, we
9044 ;; lose the clobber and ability to use integer instructions.
9046 (define_insn "*<code><mode>2_1"
9047   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9048         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9049   "TARGET_80387
9050    && (reload_completed
9051        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9052   "f<absneg_mnemonic>"
9053   [(set_attr "type" "fsgn")
9054    (set_attr "mode" "<MODE>")])
9056 (define_insn "*<code>extendsfdf2"
9057   [(set (match_operand:DF 0 "register_operand" "=f")
9058         (absneg:DF (float_extend:DF
9059                      (match_operand:SF 1 "register_operand" "0"))))]
9060   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9061   "f<absneg_mnemonic>"
9062   [(set_attr "type" "fsgn")
9063    (set_attr "mode" "DF")])
9065 (define_insn "*<code>extendsfxf2"
9066   [(set (match_operand:XF 0 "register_operand" "=f")
9067         (absneg:XF (float_extend:XF
9068                      (match_operand:SF 1 "register_operand" "0"))))]
9069   "TARGET_80387"
9070   "f<absneg_mnemonic>"
9071   [(set_attr "type" "fsgn")
9072    (set_attr "mode" "XF")])
9074 (define_insn "*<code>extenddfxf2"
9075   [(set (match_operand:XF 0 "register_operand" "=f")
9076         (absneg:XF (float_extend:XF
9077                      (match_operand:DF 1 "register_operand" "0"))))]
9078   "TARGET_80387"
9079   "f<absneg_mnemonic>"
9080   [(set_attr "type" "fsgn")
9081    (set_attr "mode" "XF")])
9083 ;; Copysign instructions
9085 (define_mode_iterator CSGNMODE [SF DF TF])
9086 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9088 (define_expand "copysign<mode>3"
9089   [(match_operand:CSGNMODE 0 "register_operand")
9090    (match_operand:CSGNMODE 1 "nonmemory_operand")
9091    (match_operand:CSGNMODE 2 "register_operand")]
9092   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9093    || (TARGET_SSE && (<MODE>mode == TFmode))"
9094   "ix86_expand_copysign (operands); DONE;")
9096 (define_insn_and_split "copysign<mode>3_const"
9097   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9098         (unspec:CSGNMODE
9099           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9100            (match_operand:CSGNMODE 2 "register_operand" "0")
9101            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9102           UNSPEC_COPYSIGN))]
9103   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9104    || (TARGET_SSE && (<MODE>mode == TFmode))"
9105   "#"
9106   "&& reload_completed"
9107   [(const_int 0)]
9108   "ix86_split_copysign_const (operands); DONE;")
9110 (define_insn "copysign<mode>3_var"
9111   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9112         (unspec:CSGNMODE
9113           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9114            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9115            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9116            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9117           UNSPEC_COPYSIGN))
9118    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9119   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9120    || (TARGET_SSE && (<MODE>mode == TFmode))"
9121   "#")
9123 (define_split
9124   [(set (match_operand:CSGNMODE 0 "register_operand")
9125         (unspec:CSGNMODE
9126           [(match_operand:CSGNMODE 2 "register_operand")
9127            (match_operand:CSGNMODE 3 "register_operand")
9128            (match_operand:<CSGNVMODE> 4)
9129            (match_operand:<CSGNVMODE> 5)]
9130           UNSPEC_COPYSIGN))
9131    (clobber (match_scratch:<CSGNVMODE> 1))]
9132   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9133     || (TARGET_SSE && (<MODE>mode == TFmode)))
9134    && reload_completed"
9135   [(const_int 0)]
9136   "ix86_split_copysign_var (operands); DONE;")
9138 ;; One complement instructions
9140 (define_expand "one_cmpl<mode>2"
9141   [(set (match_operand:SWIM 0 "nonimmediate_operand")
9142         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9143   ""
9144   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9146 (define_insn "*one_cmpl<mode>2_1"
9147   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9148         (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0")))]
9149   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9150   "not{<imodesuffix>}\t%0"
9151   [(set_attr "type" "negnot")
9152    (set_attr "mode" "<MODE>")])
9154 (define_insn "*one_cmplhi2_1"
9155   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9156         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9157   "ix86_unary_operator_ok (NOT, HImode, operands)"
9158   "@
9159    not{w}\t%0
9160    knotw\t{%1, %0|%0, %1}"
9161   [(set_attr "isa" "*,avx512f")
9162    (set_attr "type" "negnot,msklog")
9163    (set_attr "prefix" "*,vex")
9164    (set_attr "mode" "HI")])
9166 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9167 (define_insn "*one_cmplqi2_1"
9168   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9169         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9170   "ix86_unary_operator_ok (NOT, QImode, operands)"
9171   "@
9172    not{b}\t%0
9173    not{l}\t%k0
9174    knotw\t{%1, %0|%0, %1}"
9175   [(set_attr "isa" "*,*,avx512f")
9176    (set_attr "type" "negnot,negnot,msklog")
9177    (set_attr "prefix" "*,*,vex")
9178    (set_attr "mode" "QI,SI,QI")])
9180 ;; ??? Currently never generated - xor is used instead.
9181 (define_insn "*one_cmplsi2_1_zext"
9182   [(set (match_operand:DI 0 "register_operand" "=r")
9183         (zero_extend:DI
9184           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9185   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9186   "not{l}\t%k0"
9187   [(set_attr "type" "negnot")
9188    (set_attr "mode" "SI")])
9190 (define_insn "*one_cmpl<mode>2_2"
9191   [(set (reg FLAGS_REG)
9192         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9193                  (const_int 0)))
9194    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9195         (not:SWI (match_dup 1)))]
9196   "ix86_match_ccmode (insn, CCNOmode)
9197    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9198   "#"
9199   [(set_attr "type" "alu1")
9200    (set_attr "mode" "<MODE>")])
9202 (define_split
9203   [(set (match_operand 0 "flags_reg_operand")
9204         (match_operator 2 "compare_operator"
9205           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9206            (const_int 0)]))
9207    (set (match_operand:SWI 1 "nonimmediate_operand")
9208         (not:SWI (match_dup 3)))]
9209   "ix86_match_ccmode (insn, CCNOmode)"
9210   [(parallel [(set (match_dup 0)
9211                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9212                                     (const_int 0)]))
9213               (set (match_dup 1)
9214                    (xor:SWI (match_dup 3) (const_int -1)))])])
9216 ;; ??? Currently never generated - xor is used instead.
9217 (define_insn "*one_cmplsi2_2_zext"
9218   [(set (reg FLAGS_REG)
9219         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9220                  (const_int 0)))
9221    (set (match_operand:DI 0 "register_operand" "=r")
9222         (zero_extend:DI (not:SI (match_dup 1))))]
9223   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9224    && ix86_unary_operator_ok (NOT, SImode, operands)"
9225   "#"
9226   [(set_attr "type" "alu1")
9227    (set_attr "mode" "SI")])
9229 (define_split
9230   [(set (match_operand 0 "flags_reg_operand")
9231         (match_operator 2 "compare_operator"
9232           [(not:SI (match_operand:SI 3 "register_operand"))
9233            (const_int 0)]))
9234    (set (match_operand:DI 1 "register_operand")
9235         (zero_extend:DI (not:SI (match_dup 3))))]
9236   "ix86_match_ccmode (insn, CCNOmode)"
9237   [(parallel [(set (match_dup 0)
9238                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9239                                     (const_int 0)]))
9240               (set (match_dup 1)
9241                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9243 ;; Shift instructions
9245 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9246 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9247 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9248 ;; from the assembler input.
9250 ;; This instruction shifts the target reg/mem as usual, but instead of
9251 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9252 ;; is a left shift double, bits are taken from the high order bits of
9253 ;; reg, else if the insn is a shift right double, bits are taken from the
9254 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9255 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9257 ;; Since sh[lr]d does not change the `reg' operand, that is done
9258 ;; separately, making all shifts emit pairs of shift double and normal
9259 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9260 ;; support a 63 bit shift, each shift where the count is in a reg expands
9261 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9263 ;; If the shift count is a constant, we need never emit more than one
9264 ;; shift pair, instead using moves and sign extension for counts greater
9265 ;; than 31.
9267 (define_expand "ashl<mode>3"
9268   [(set (match_operand:SDWIM 0 "<shift_operand>")
9269         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9270                       (match_operand:QI 2 "nonmemory_operand")))]
9271   ""
9272   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9274 (define_insn "*ashl<mode>3_doubleword"
9275   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9276         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9277                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9278    (clobber (reg:CC FLAGS_REG))]
9279   ""
9280   "#"
9281   [(set_attr "type" "multi")])
9283 (define_split
9284   [(set (match_operand:DWI 0 "register_operand")
9285         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9286                     (match_operand:QI 2 "nonmemory_operand")))
9287    (clobber (reg:CC FLAGS_REG))]
9288   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9289   [(const_int 0)]
9290   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9292 ;; By default we don't ask for a scratch register, because when DWImode
9293 ;; values are manipulated, registers are already at a premium.  But if
9294 ;; we have one handy, we won't turn it away.
9296 (define_peephole2
9297   [(match_scratch:DWIH 3 "r")
9298    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9299                    (ashift:<DWI>
9300                      (match_operand:<DWI> 1 "nonmemory_operand")
9301                      (match_operand:QI 2 "nonmemory_operand")))
9302               (clobber (reg:CC FLAGS_REG))])
9303    (match_dup 3)]
9304   "TARGET_CMOVE"
9305   [(const_int 0)]
9306   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9308 (define_insn "x86_64_shld"
9309   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9310         (ior:DI (ashift:DI (match_dup 0)
9311                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9312                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9313                   (minus:QI (const_int 64) (match_dup 2)))))
9314    (clobber (reg:CC FLAGS_REG))]
9315   "TARGET_64BIT"
9316   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9317   [(set_attr "type" "ishift")
9318    (set_attr "prefix_0f" "1")
9319    (set_attr "mode" "DI")
9320    (set_attr "athlon_decode" "vector")
9321    (set_attr "amdfam10_decode" "vector")
9322    (set_attr "bdver1_decode" "vector")])
9324 (define_insn "x86_shld"
9325   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9326         (ior:SI (ashift:SI (match_dup 0)
9327                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9328                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9329                   (minus:QI (const_int 32) (match_dup 2)))))
9330    (clobber (reg:CC FLAGS_REG))]
9331   ""
9332   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9333   [(set_attr "type" "ishift")
9334    (set_attr "prefix_0f" "1")
9335    (set_attr "mode" "SI")
9336    (set_attr "pent_pair" "np")
9337    (set_attr "athlon_decode" "vector")
9338    (set_attr "amdfam10_decode" "vector")
9339    (set_attr "bdver1_decode" "vector")])
9341 (define_expand "x86_shift<mode>_adj_1"
9342   [(set (reg:CCZ FLAGS_REG)
9343         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9344                              (match_dup 4))
9345                      (const_int 0)))
9346    (set (match_operand:SWI48 0 "register_operand")
9347         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9348                             (match_operand:SWI48 1 "register_operand")
9349                             (match_dup 0)))
9350    (set (match_dup 1)
9351         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9352                             (match_operand:SWI48 3 "register_operand")
9353                             (match_dup 1)))]
9354   "TARGET_CMOVE"
9355   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9357 (define_expand "x86_shift<mode>_adj_2"
9358   [(use (match_operand:SWI48 0 "register_operand"))
9359    (use (match_operand:SWI48 1 "register_operand"))
9360    (use (match_operand:QI 2 "register_operand"))]
9361   ""
9363   rtx label = gen_label_rtx ();
9364   rtx tmp;
9366   emit_insn (gen_testqi_ccz_1 (operands[2],
9367                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9369   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9370   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9371   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9372                               gen_rtx_LABEL_REF (VOIDmode, label),
9373                               pc_rtx);
9374   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9375   JUMP_LABEL (tmp) = label;
9377   emit_move_insn (operands[0], operands[1]);
9378   ix86_expand_clear (operands[1]);
9380   emit_label (label);
9381   LABEL_NUSES (label) = 1;
9383   DONE;
9386 ;; Avoid useless masking of count operand.
9387 (define_insn "*ashl<mode>3_mask"
9388   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9389         (ashift:SWI48
9390           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9391           (subreg:QI
9392             (and:SI
9393               (match_operand:SI 2 "register_operand" "c")
9394               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9395    (clobber (reg:CC FLAGS_REG))]
9396   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9397    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9398       == GET_MODE_BITSIZE (<MODE>mode)-1"
9400   return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9402   [(set_attr "type" "ishift")
9403    (set_attr "mode" "<MODE>")])
9405 (define_insn "*bmi2_ashl<mode>3_1"
9406   [(set (match_operand:SWI48 0 "register_operand" "=r")
9407         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9408                       (match_operand:SWI48 2 "register_operand" "r")))]
9409   "TARGET_BMI2"
9410   "shlx\t{%2, %1, %0|%0, %1, %2}"
9411   [(set_attr "type" "ishiftx")
9412    (set_attr "mode" "<MODE>")])
9414 (define_insn "*ashl<mode>3_1"
9415   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9416         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9417                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9418    (clobber (reg:CC FLAGS_REG))]
9419   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9421   switch (get_attr_type (insn))
9422     {
9423     case TYPE_LEA:
9424     case TYPE_ISHIFTX:
9425       return "#";
9427     case TYPE_ALU:
9428       gcc_assert (operands[2] == const1_rtx);
9429       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9430       return "add{<imodesuffix>}\t%0, %0";
9432     default:
9433       if (operands[2] == const1_rtx
9434           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9435         return "sal{<imodesuffix>}\t%0";
9436       else
9437         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9438     }
9440   [(set_attr "isa" "*,*,bmi2")
9441    (set (attr "type")
9442      (cond [(eq_attr "alternative" "1")
9443               (const_string "lea")
9444             (eq_attr "alternative" "2")
9445               (const_string "ishiftx")
9446             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9447                       (match_operand 0 "register_operand"))
9448                  (match_operand 2 "const1_operand"))
9449               (const_string "alu")
9450            ]
9451            (const_string "ishift")))
9452    (set (attr "length_immediate")
9453      (if_then_else
9454        (ior (eq_attr "type" "alu")
9455             (and (eq_attr "type" "ishift")
9456                  (and (match_operand 2 "const1_operand")
9457                       (ior (match_test "TARGET_SHIFT1")
9458                            (match_test "optimize_function_for_size_p (cfun)")))))
9459        (const_string "0")
9460        (const_string "*")))
9461    (set_attr "mode" "<MODE>")])
9463 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9464 (define_split
9465   [(set (match_operand:SWI48 0 "register_operand")
9466         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9467                       (match_operand:QI 2 "register_operand")))
9468    (clobber (reg:CC FLAGS_REG))]
9469   "TARGET_BMI2 && reload_completed"
9470   [(set (match_dup 0)
9471         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9472   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9474 (define_insn "*bmi2_ashlsi3_1_zext"
9475   [(set (match_operand:DI 0 "register_operand" "=r")
9476         (zero_extend:DI
9477           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9478                      (match_operand:SI 2 "register_operand" "r"))))]
9479   "TARGET_64BIT && TARGET_BMI2"
9480   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9481   [(set_attr "type" "ishiftx")
9482    (set_attr "mode" "SI")])
9484 (define_insn "*ashlsi3_1_zext"
9485   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9486         (zero_extend:DI
9487           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9488                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9489    (clobber (reg:CC FLAGS_REG))]
9490   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9492   switch (get_attr_type (insn))
9493     {
9494     case TYPE_LEA:
9495     case TYPE_ISHIFTX:
9496       return "#";
9498     case TYPE_ALU:
9499       gcc_assert (operands[2] == const1_rtx);
9500       return "add{l}\t%k0, %k0";
9502     default:
9503       if (operands[2] == const1_rtx
9504           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9505         return "sal{l}\t%k0";
9506       else
9507         return "sal{l}\t{%2, %k0|%k0, %2}";
9508     }
9510   [(set_attr "isa" "*,*,bmi2")
9511    (set (attr "type")
9512      (cond [(eq_attr "alternative" "1")
9513               (const_string "lea")
9514             (eq_attr "alternative" "2")
9515               (const_string "ishiftx")
9516             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9517                  (match_operand 2 "const1_operand"))
9518               (const_string "alu")
9519            ]
9520            (const_string "ishift")))
9521    (set (attr "length_immediate")
9522      (if_then_else
9523        (ior (eq_attr "type" "alu")
9524             (and (eq_attr "type" "ishift")
9525                  (and (match_operand 2 "const1_operand")
9526                       (ior (match_test "TARGET_SHIFT1")
9527                            (match_test "optimize_function_for_size_p (cfun)")))))
9528        (const_string "0")
9529        (const_string "*")))
9530    (set_attr "mode" "SI")])
9532 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9533 (define_split
9534   [(set (match_operand:DI 0 "register_operand")
9535         (zero_extend:DI
9536           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9537                      (match_operand:QI 2 "register_operand"))))
9538    (clobber (reg:CC FLAGS_REG))]
9539   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9540   [(set (match_dup 0)
9541         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9542   "operands[2] = gen_lowpart (SImode, operands[2]);")
9544 (define_insn "*ashlhi3_1"
9545   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9546         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9547                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9548    (clobber (reg:CC FLAGS_REG))]
9549   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9551   switch (get_attr_type (insn))
9552     {
9553     case TYPE_LEA:
9554       return "#";
9556     case TYPE_ALU:
9557       gcc_assert (operands[2] == const1_rtx);
9558       return "add{w}\t%0, %0";
9560     default:
9561       if (operands[2] == const1_rtx
9562           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9563         return "sal{w}\t%0";
9564       else
9565         return "sal{w}\t{%2, %0|%0, %2}";
9566     }
9568   [(set (attr "type")
9569      (cond [(eq_attr "alternative" "1")
9570               (const_string "lea")
9571             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9572                       (match_operand 0 "register_operand"))
9573                  (match_operand 2 "const1_operand"))
9574               (const_string "alu")
9575            ]
9576            (const_string "ishift")))
9577    (set (attr "length_immediate")
9578      (if_then_else
9579        (ior (eq_attr "type" "alu")
9580             (and (eq_attr "type" "ishift")
9581                  (and (match_operand 2 "const1_operand")
9582                       (ior (match_test "TARGET_SHIFT1")
9583                            (match_test "optimize_function_for_size_p (cfun)")))))
9584        (const_string "0")
9585        (const_string "*")))
9586    (set_attr "mode" "HI,SI")])
9588 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9589 (define_insn "*ashlqi3_1"
9590   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9591         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9592                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9593    (clobber (reg:CC FLAGS_REG))]
9594   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9596   switch (get_attr_type (insn))
9597     {
9598     case TYPE_LEA:
9599       return "#";
9601     case TYPE_ALU:
9602       gcc_assert (operands[2] == const1_rtx);
9603       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9604         return "add{l}\t%k0, %k0";
9605       else
9606         return "add{b}\t%0, %0";
9608     default:
9609       if (operands[2] == const1_rtx
9610           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9611         {
9612           if (get_attr_mode (insn) == MODE_SI)
9613             return "sal{l}\t%k0";
9614           else
9615             return "sal{b}\t%0";
9616         }
9617       else
9618         {
9619           if (get_attr_mode (insn) == MODE_SI)
9620             return "sal{l}\t{%2, %k0|%k0, %2}";
9621           else
9622             return "sal{b}\t{%2, %0|%0, %2}";
9623         }
9624     }
9626   [(set (attr "type")
9627      (cond [(eq_attr "alternative" "2")
9628               (const_string "lea")
9629             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9630                       (match_operand 0 "register_operand"))
9631                  (match_operand 2 "const1_operand"))
9632               (const_string "alu")
9633            ]
9634            (const_string "ishift")))
9635    (set (attr "length_immediate")
9636      (if_then_else
9637        (ior (eq_attr "type" "alu")
9638             (and (eq_attr "type" "ishift")
9639                  (and (match_operand 2 "const1_operand")
9640                       (ior (match_test "TARGET_SHIFT1")
9641                            (match_test "optimize_function_for_size_p (cfun)")))))
9642        (const_string "0")
9643        (const_string "*")))
9644    (set_attr "mode" "QI,SI,SI")])
9646 (define_insn "*ashlqi3_1_slp"
9647   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9648         (ashift:QI (match_dup 0)
9649                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9650    (clobber (reg:CC FLAGS_REG))]
9651   "(optimize_function_for_size_p (cfun)
9652     || !TARGET_PARTIAL_FLAG_REG_STALL
9653     || (operands[1] == const1_rtx
9654         && (TARGET_SHIFT1
9655             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9657   switch (get_attr_type (insn))
9658     {
9659     case TYPE_ALU:
9660       gcc_assert (operands[1] == const1_rtx);
9661       return "add{b}\t%0, %0";
9663     default:
9664       if (operands[1] == const1_rtx
9665           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9666         return "sal{b}\t%0";
9667       else
9668         return "sal{b}\t{%1, %0|%0, %1}";
9669     }
9671   [(set (attr "type")
9672      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9673                       (match_operand 0 "register_operand"))
9674                  (match_operand 1 "const1_operand"))
9675               (const_string "alu")
9676            ]
9677            (const_string "ishift1")))
9678    (set (attr "length_immediate")
9679      (if_then_else
9680        (ior (eq_attr "type" "alu")
9681             (and (eq_attr "type" "ishift1")
9682                  (and (match_operand 1 "const1_operand")
9683                       (ior (match_test "TARGET_SHIFT1")
9684                            (match_test "optimize_function_for_size_p (cfun)")))))
9685        (const_string "0")
9686        (const_string "*")))
9687    (set_attr "mode" "QI")])
9689 ;; Convert ashift to the lea pattern to avoid flags dependency.
9690 (define_split
9691   [(set (match_operand 0 "register_operand")
9692         (ashift (match_operand 1 "index_register_operand")
9693                 (match_operand:QI 2 "const_int_operand")))
9694    (clobber (reg:CC FLAGS_REG))]
9695   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9696    && reload_completed
9697    && true_regnum (operands[0]) != true_regnum (operands[1])"
9698   [(const_int 0)]
9700   enum machine_mode mode = GET_MODE (operands[0]);
9701   rtx pat;
9703   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9704     { 
9705       mode = SImode; 
9706       operands[0] = gen_lowpart (mode, operands[0]);
9707       operands[1] = gen_lowpart (mode, operands[1]);
9708     }
9710   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9712   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9714   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9715   DONE;
9718 ;; Convert ashift to the lea pattern to avoid flags dependency.
9719 (define_split
9720   [(set (match_operand:DI 0 "register_operand")
9721         (zero_extend:DI
9722           (ashift:SI (match_operand:SI 1 "index_register_operand")
9723                      (match_operand:QI 2 "const_int_operand"))))
9724    (clobber (reg:CC FLAGS_REG))]
9725   "TARGET_64BIT && reload_completed
9726    && true_regnum (operands[0]) != true_regnum (operands[1])"
9727   [(set (match_dup 0)
9728         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9730   operands[1] = gen_lowpart (SImode, operands[1]);
9731   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9734 ;; This pattern can't accept a variable shift count, since shifts by
9735 ;; zero don't affect the flags.  We assume that shifts by constant
9736 ;; zero are optimized away.
9737 (define_insn "*ashl<mode>3_cmp"
9738   [(set (reg FLAGS_REG)
9739         (compare
9740           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9741                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9742           (const_int 0)))
9743    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9744         (ashift:SWI (match_dup 1) (match_dup 2)))]
9745   "(optimize_function_for_size_p (cfun)
9746     || !TARGET_PARTIAL_FLAG_REG_STALL
9747     || (operands[2] == const1_rtx
9748         && (TARGET_SHIFT1
9749             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9750    && ix86_match_ccmode (insn, CCGOCmode)
9751    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9753   switch (get_attr_type (insn))
9754     {
9755     case TYPE_ALU:
9756       gcc_assert (operands[2] == const1_rtx);
9757       return "add{<imodesuffix>}\t%0, %0";
9759     default:
9760       if (operands[2] == const1_rtx
9761           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9762         return "sal{<imodesuffix>}\t%0";
9763       else
9764         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9765     }
9767   [(set (attr "type")
9768      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9769                       (match_operand 0 "register_operand"))
9770                  (match_operand 2 "const1_operand"))
9771               (const_string "alu")
9772            ]
9773            (const_string "ishift")))
9774    (set (attr "length_immediate")
9775      (if_then_else
9776        (ior (eq_attr "type" "alu")
9777             (and (eq_attr "type" "ishift")
9778                  (and (match_operand 2 "const1_operand")
9779                       (ior (match_test "TARGET_SHIFT1")
9780                            (match_test "optimize_function_for_size_p (cfun)")))))
9781        (const_string "0")
9782        (const_string "*")))
9783    (set_attr "mode" "<MODE>")])
9785 (define_insn "*ashlsi3_cmp_zext"
9786   [(set (reg FLAGS_REG)
9787         (compare
9788           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9789                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9790           (const_int 0)))
9791    (set (match_operand:DI 0 "register_operand" "=r")
9792         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9793   "TARGET_64BIT
9794    && (optimize_function_for_size_p (cfun)
9795        || !TARGET_PARTIAL_FLAG_REG_STALL
9796        || (operands[2] == const1_rtx
9797            && (TARGET_SHIFT1
9798                || TARGET_DOUBLE_WITH_ADD)))
9799    && ix86_match_ccmode (insn, CCGOCmode)
9800    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9802   switch (get_attr_type (insn))
9803     {
9804     case TYPE_ALU:
9805       gcc_assert (operands[2] == const1_rtx);
9806       return "add{l}\t%k0, %k0";
9808     default:
9809       if (operands[2] == const1_rtx
9810           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9811         return "sal{l}\t%k0";
9812       else
9813         return "sal{l}\t{%2, %k0|%k0, %2}";
9814     }
9816   [(set (attr "type")
9817      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9818                  (match_operand 2 "const1_operand"))
9819               (const_string "alu")
9820            ]
9821            (const_string "ishift")))
9822    (set (attr "length_immediate")
9823      (if_then_else
9824        (ior (eq_attr "type" "alu")
9825             (and (eq_attr "type" "ishift")
9826                  (and (match_operand 2 "const1_operand")
9827                       (ior (match_test "TARGET_SHIFT1")
9828                            (match_test "optimize_function_for_size_p (cfun)")))))
9829        (const_string "0")
9830        (const_string "*")))
9831    (set_attr "mode" "SI")])
9833 (define_insn "*ashl<mode>3_cconly"
9834   [(set (reg FLAGS_REG)
9835         (compare
9836           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9837                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9838           (const_int 0)))
9839    (clobber (match_scratch:SWI 0 "=<r>"))]
9840   "(optimize_function_for_size_p (cfun)
9841     || !TARGET_PARTIAL_FLAG_REG_STALL
9842     || (operands[2] == const1_rtx
9843         && (TARGET_SHIFT1
9844             || TARGET_DOUBLE_WITH_ADD)))
9845    && ix86_match_ccmode (insn, CCGOCmode)"
9847   switch (get_attr_type (insn))
9848     {
9849     case TYPE_ALU:
9850       gcc_assert (operands[2] == const1_rtx);
9851       return "add{<imodesuffix>}\t%0, %0";
9853     default:
9854       if (operands[2] == const1_rtx
9855           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9856         return "sal{<imodesuffix>}\t%0";
9857       else
9858         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9859     }
9861   [(set (attr "type")
9862      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9863                       (match_operand 0 "register_operand"))
9864                  (match_operand 2 "const1_operand"))
9865               (const_string "alu")
9866            ]
9867            (const_string "ishift")))
9868    (set (attr "length_immediate")
9869      (if_then_else
9870        (ior (eq_attr "type" "alu")
9871             (and (eq_attr "type" "ishift")
9872                  (and (match_operand 2 "const1_operand")
9873                       (ior (match_test "TARGET_SHIFT1")
9874                            (match_test "optimize_function_for_size_p (cfun)")))))
9875        (const_string "0")
9876        (const_string "*")))
9877    (set_attr "mode" "<MODE>")])
9879 ;; See comment above `ashl<mode>3' about how this works.
9881 (define_expand "<shift_insn><mode>3"
9882   [(set (match_operand:SDWIM 0 "<shift_operand>")
9883         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9884                            (match_operand:QI 2 "nonmemory_operand")))]
9885   ""
9886   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9888 ;; Avoid useless masking of count operand.
9889 (define_insn "*<shift_insn><mode>3_mask"
9890   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9891         (any_shiftrt:SWI48
9892           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9893           (subreg:QI
9894             (and:SI
9895               (match_operand:SI 2 "register_operand" "c")
9896               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9897    (clobber (reg:CC FLAGS_REG))]
9898   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9899    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9900       == GET_MODE_BITSIZE (<MODE>mode)-1"
9902   return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9904   [(set_attr "type" "ishift")
9905    (set_attr "mode" "<MODE>")])
9907 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9908   [(set (match_operand:DWI 0 "register_operand" "=r")
9909         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9910                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9911    (clobber (reg:CC FLAGS_REG))]
9912   ""
9913   "#"
9914   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9915   [(const_int 0)]
9916   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9917   [(set_attr "type" "multi")])
9919 ;; By default we don't ask for a scratch register, because when DWImode
9920 ;; values are manipulated, registers are already at a premium.  But if
9921 ;; we have one handy, we won't turn it away.
9923 (define_peephole2
9924   [(match_scratch:DWIH 3 "r")
9925    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9926                    (any_shiftrt:<DWI>
9927                      (match_operand:<DWI> 1 "register_operand")
9928                      (match_operand:QI 2 "nonmemory_operand")))
9929               (clobber (reg:CC FLAGS_REG))])
9930    (match_dup 3)]
9931   "TARGET_CMOVE"
9932   [(const_int 0)]
9933   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9935 (define_insn "x86_64_shrd"
9936   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9937         (ior:DI (ashiftrt:DI (match_dup 0)
9938                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9939                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9940                   (minus:QI (const_int 64) (match_dup 2)))))
9941    (clobber (reg:CC FLAGS_REG))]
9942   "TARGET_64BIT"
9943   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9944   [(set_attr "type" "ishift")
9945    (set_attr "prefix_0f" "1")
9946    (set_attr "mode" "DI")
9947    (set_attr "athlon_decode" "vector")
9948    (set_attr "amdfam10_decode" "vector")
9949    (set_attr "bdver1_decode" "vector")])
9951 (define_insn "x86_shrd"
9952   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9953         (ior:SI (ashiftrt:SI (match_dup 0)
9954                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9955                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9956                   (minus:QI (const_int 32) (match_dup 2)))))
9957    (clobber (reg:CC FLAGS_REG))]
9958   ""
9959   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9960   [(set_attr "type" "ishift")
9961    (set_attr "prefix_0f" "1")
9962    (set_attr "mode" "SI")
9963    (set_attr "pent_pair" "np")
9964    (set_attr "athlon_decode" "vector")
9965    (set_attr "amdfam10_decode" "vector")
9966    (set_attr "bdver1_decode" "vector")])
9968 (define_insn "ashrdi3_cvt"
9969   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9970         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9971                      (match_operand:QI 2 "const_int_operand")))
9972    (clobber (reg:CC FLAGS_REG))]
9973   "TARGET_64BIT && INTVAL (operands[2]) == 63
9974    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9975    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9976   "@
9977    {cqto|cqo}
9978    sar{q}\t{%2, %0|%0, %2}"
9979   [(set_attr "type" "imovx,ishift")
9980    (set_attr "prefix_0f" "0,*")
9981    (set_attr "length_immediate" "0,*")
9982    (set_attr "modrm" "0,1")
9983    (set_attr "mode" "DI")])
9985 (define_insn "ashrsi3_cvt"
9986   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9987         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9988                      (match_operand:QI 2 "const_int_operand")))
9989    (clobber (reg:CC FLAGS_REG))]
9990   "INTVAL (operands[2]) == 31
9991    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9992    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9993   "@
9994    {cltd|cdq}
9995    sar{l}\t{%2, %0|%0, %2}"
9996   [(set_attr "type" "imovx,ishift")
9997    (set_attr "prefix_0f" "0,*")
9998    (set_attr "length_immediate" "0,*")
9999    (set_attr "modrm" "0,1")
10000    (set_attr "mode" "SI")])
10002 (define_insn "*ashrsi3_cvt_zext"
10003   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10004         (zero_extend:DI
10005           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10006                        (match_operand:QI 2 "const_int_operand"))))
10007    (clobber (reg:CC FLAGS_REG))]
10008   "TARGET_64BIT && INTVAL (operands[2]) == 31
10009    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10010    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10011   "@
10012    {cltd|cdq}
10013    sar{l}\t{%2, %k0|%k0, %2}"
10014   [(set_attr "type" "imovx,ishift")
10015    (set_attr "prefix_0f" "0,*")
10016    (set_attr "length_immediate" "0,*")
10017    (set_attr "modrm" "0,1")
10018    (set_attr "mode" "SI")])
10020 (define_expand "x86_shift<mode>_adj_3"
10021   [(use (match_operand:SWI48 0 "register_operand"))
10022    (use (match_operand:SWI48 1 "register_operand"))
10023    (use (match_operand:QI 2 "register_operand"))]
10024   ""
10026   rtx label = gen_label_rtx ();
10027   rtx tmp;
10029   emit_insn (gen_testqi_ccz_1 (operands[2],
10030                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10032   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10033   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10034   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10035                               gen_rtx_LABEL_REF (VOIDmode, label),
10036                               pc_rtx);
10037   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10038   JUMP_LABEL (tmp) = label;
10040   emit_move_insn (operands[0], operands[1]);
10041   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10042                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10043   emit_label (label);
10044   LABEL_NUSES (label) = 1;
10046   DONE;
10049 (define_insn "*bmi2_<shift_insn><mode>3_1"
10050   [(set (match_operand:SWI48 0 "register_operand" "=r")
10051         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10052                            (match_operand:SWI48 2 "register_operand" "r")))]
10053   "TARGET_BMI2"
10054   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10055   [(set_attr "type" "ishiftx")
10056    (set_attr "mode" "<MODE>")])
10058 (define_insn "*<shift_insn><mode>3_1"
10059   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10060         (any_shiftrt:SWI48
10061           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10062           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10063    (clobber (reg:CC FLAGS_REG))]
10064   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10066   switch (get_attr_type (insn))
10067     {
10068     case TYPE_ISHIFTX:
10069       return "#";
10071     default:
10072       if (operands[2] == const1_rtx
10073           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10074         return "<shift>{<imodesuffix>}\t%0";
10075       else
10076         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10077     }
10079   [(set_attr "isa" "*,bmi2")
10080    (set_attr "type" "ishift,ishiftx")
10081    (set (attr "length_immediate")
10082      (if_then_else
10083        (and (match_operand 2 "const1_operand")
10084             (ior (match_test "TARGET_SHIFT1")
10085                  (match_test "optimize_function_for_size_p (cfun)")))
10086        (const_string "0")
10087        (const_string "*")))
10088    (set_attr "mode" "<MODE>")])
10090 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10091 (define_split
10092   [(set (match_operand:SWI48 0 "register_operand")
10093         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10094                            (match_operand:QI 2 "register_operand")))
10095    (clobber (reg:CC FLAGS_REG))]
10096   "TARGET_BMI2 && reload_completed"
10097   [(set (match_dup 0)
10098         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10099   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10101 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10102   [(set (match_operand:DI 0 "register_operand" "=r")
10103         (zero_extend:DI
10104           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10105                           (match_operand:SI 2 "register_operand" "r"))))]
10106   "TARGET_64BIT && TARGET_BMI2"
10107   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10108   [(set_attr "type" "ishiftx")
10109    (set_attr "mode" "SI")])
10111 (define_insn "*<shift_insn>si3_1_zext"
10112   [(set (match_operand:DI 0 "register_operand" "=r,r")
10113         (zero_extend:DI
10114           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10115                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10116    (clobber (reg:CC FLAGS_REG))]
10117   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10119   switch (get_attr_type (insn))
10120     {
10121     case TYPE_ISHIFTX:
10122       return "#";
10124     default:
10125       if (operands[2] == const1_rtx
10126           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10127         return "<shift>{l}\t%k0";
10128       else
10129         return "<shift>{l}\t{%2, %k0|%k0, %2}";
10130     }
10132   [(set_attr "isa" "*,bmi2")
10133    (set_attr "type" "ishift,ishiftx")
10134    (set (attr "length_immediate")
10135      (if_then_else
10136        (and (match_operand 2 "const1_operand")
10137             (ior (match_test "TARGET_SHIFT1")
10138                  (match_test "optimize_function_for_size_p (cfun)")))
10139        (const_string "0")
10140        (const_string "*")))
10141    (set_attr "mode" "SI")])
10143 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10144 (define_split
10145   [(set (match_operand:DI 0 "register_operand")
10146         (zero_extend:DI
10147           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10148                           (match_operand:QI 2 "register_operand"))))
10149    (clobber (reg:CC FLAGS_REG))]
10150   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10151   [(set (match_dup 0)
10152         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10153   "operands[2] = gen_lowpart (SImode, operands[2]);")
10155 (define_insn "*<shift_insn><mode>3_1"
10156   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10157         (any_shiftrt:SWI12
10158           (match_operand:SWI12 1 "nonimmediate_operand" "0")
10159           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10160    (clobber (reg:CC FLAGS_REG))]
10161   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10163   if (operands[2] == const1_rtx
10164       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10165     return "<shift>{<imodesuffix>}\t%0";
10166   else
10167     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10169   [(set_attr "type" "ishift")
10170    (set (attr "length_immediate")
10171      (if_then_else
10172        (and (match_operand 2 "const1_operand")
10173             (ior (match_test "TARGET_SHIFT1")
10174                  (match_test "optimize_function_for_size_p (cfun)")))
10175        (const_string "0")
10176        (const_string "*")))
10177    (set_attr "mode" "<MODE>")])
10179 (define_insn "*<shift_insn>qi3_1_slp"
10180   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10181         (any_shiftrt:QI (match_dup 0)
10182                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10183    (clobber (reg:CC FLAGS_REG))]
10184   "(optimize_function_for_size_p (cfun)
10185     || !TARGET_PARTIAL_REG_STALL
10186     || (operands[1] == const1_rtx
10187         && TARGET_SHIFT1))"
10189   if (operands[1] == const1_rtx
10190       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10191     return "<shift>{b}\t%0";
10192   else
10193     return "<shift>{b}\t{%1, %0|%0, %1}";
10195   [(set_attr "type" "ishift1")
10196    (set (attr "length_immediate")
10197      (if_then_else
10198        (and (match_operand 1 "const1_operand")
10199             (ior (match_test "TARGET_SHIFT1")
10200                  (match_test "optimize_function_for_size_p (cfun)")))
10201        (const_string "0")
10202        (const_string "*")))
10203    (set_attr "mode" "QI")])
10205 ;; This pattern can't accept a variable shift count, since shifts by
10206 ;; zero don't affect the flags.  We assume that shifts by constant
10207 ;; zero are optimized away.
10208 (define_insn "*<shift_insn><mode>3_cmp"
10209   [(set (reg FLAGS_REG)
10210         (compare
10211           (any_shiftrt:SWI
10212             (match_operand:SWI 1 "nonimmediate_operand" "0")
10213             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10214           (const_int 0)))
10215    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10216         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10217   "(optimize_function_for_size_p (cfun)
10218     || !TARGET_PARTIAL_FLAG_REG_STALL
10219     || (operands[2] == const1_rtx
10220         && TARGET_SHIFT1))
10221    && ix86_match_ccmode (insn, CCGOCmode)
10222    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10224   if (operands[2] == const1_rtx
10225       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10226     return "<shift>{<imodesuffix>}\t%0";
10227   else
10228     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10230   [(set_attr "type" "ishift")
10231    (set (attr "length_immediate")
10232      (if_then_else
10233        (and (match_operand 2 "const1_operand")
10234             (ior (match_test "TARGET_SHIFT1")
10235                  (match_test "optimize_function_for_size_p (cfun)")))
10236        (const_string "0")
10237        (const_string "*")))
10238    (set_attr "mode" "<MODE>")])
10240 (define_insn "*<shift_insn>si3_cmp_zext"
10241   [(set (reg FLAGS_REG)
10242         (compare
10243           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10244                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10245           (const_int 0)))
10246    (set (match_operand:DI 0 "register_operand" "=r")
10247         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10248   "TARGET_64BIT
10249    && (optimize_function_for_size_p (cfun)
10250        || !TARGET_PARTIAL_FLAG_REG_STALL
10251        || (operands[2] == const1_rtx
10252            && TARGET_SHIFT1))
10253    && ix86_match_ccmode (insn, CCGOCmode)
10254    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10256   if (operands[2] == const1_rtx
10257       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10258     return "<shift>{l}\t%k0";
10259   else
10260     return "<shift>{l}\t{%2, %k0|%k0, %2}";
10262   [(set_attr "type" "ishift")
10263    (set (attr "length_immediate")
10264      (if_then_else
10265        (and (match_operand 2 "const1_operand")
10266             (ior (match_test "TARGET_SHIFT1")
10267                  (match_test "optimize_function_for_size_p (cfun)")))
10268        (const_string "0")
10269        (const_string "*")))
10270    (set_attr "mode" "SI")])
10272 (define_insn "*<shift_insn><mode>3_cconly"
10273   [(set (reg FLAGS_REG)
10274         (compare
10275           (any_shiftrt:SWI
10276             (match_operand:SWI 1 "register_operand" "0")
10277             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10278           (const_int 0)))
10279    (clobber (match_scratch:SWI 0 "=<r>"))]
10280   "(optimize_function_for_size_p (cfun)
10281     || !TARGET_PARTIAL_FLAG_REG_STALL
10282     || (operands[2] == const1_rtx
10283         && TARGET_SHIFT1))
10284    && ix86_match_ccmode (insn, CCGOCmode)"
10286   if (operands[2] == const1_rtx
10287       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10288     return "<shift>{<imodesuffix>}\t%0";
10289   else
10290     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10292   [(set_attr "type" "ishift")
10293    (set (attr "length_immediate")
10294      (if_then_else
10295        (and (match_operand 2 "const1_operand")
10296             (ior (match_test "TARGET_SHIFT1")
10297                  (match_test "optimize_function_for_size_p (cfun)")))
10298        (const_string "0")
10299        (const_string "*")))
10300    (set_attr "mode" "<MODE>")])
10302 ;; Rotate instructions
10304 (define_expand "<rotate_insn>ti3"
10305   [(set (match_operand:TI 0 "register_operand")
10306         (any_rotate:TI (match_operand:TI 1 "register_operand")
10307                        (match_operand:QI 2 "nonmemory_operand")))]
10308   "TARGET_64BIT"
10310   if (const_1_to_63_operand (operands[2], VOIDmode))
10311     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10312                 (operands[0], operands[1], operands[2]));
10313   else
10314     FAIL;
10316   DONE;
10319 (define_expand "<rotate_insn>di3"
10320   [(set (match_operand:DI 0 "shiftdi_operand")
10321         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10322                        (match_operand:QI 2 "nonmemory_operand")))]
10323  ""
10325   if (TARGET_64BIT)
10326     ix86_expand_binary_operator (<CODE>, DImode, operands);
10327   else if (const_1_to_31_operand (operands[2], VOIDmode))
10328     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10329                 (operands[0], operands[1], operands[2]));
10330   else
10331     FAIL;
10333   DONE;
10336 (define_expand "<rotate_insn><mode>3"
10337   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10338         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10339                             (match_operand:QI 2 "nonmemory_operand")))]
10340   ""
10341   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10343 ;; Avoid useless masking of count operand.
10344 (define_insn "*<rotate_insn><mode>3_mask"
10345   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10346         (any_rotate:SWI48
10347           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10348           (subreg:QI
10349             (and:SI
10350               (match_operand:SI 2 "register_operand" "c")
10351               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10352    (clobber (reg:CC FLAGS_REG))]
10353   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10354    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10355       == GET_MODE_BITSIZE (<MODE>mode)-1"
10357   return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10359   [(set_attr "type" "rotate")
10360    (set_attr "mode" "<MODE>")])
10362 ;; Implement rotation using two double-precision
10363 ;; shift instructions and a scratch register.
10365 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10366  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10367        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10368                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10369   (clobber (reg:CC FLAGS_REG))
10370   (clobber (match_scratch:DWIH 3 "=&r"))]
10371  ""
10372  "#"
10373  "reload_completed"
10374  [(set (match_dup 3) (match_dup 4))
10375   (parallel
10376    [(set (match_dup 4)
10377          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10378                    (lshiftrt:DWIH (match_dup 5)
10379                                   (minus:QI (match_dup 6) (match_dup 2)))))
10380     (clobber (reg:CC FLAGS_REG))])
10381   (parallel
10382    [(set (match_dup 5)
10383          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10384                    (lshiftrt:DWIH (match_dup 3)
10385                                   (minus:QI (match_dup 6) (match_dup 2)))))
10386     (clobber (reg:CC FLAGS_REG))])]
10388   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10390   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10393 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10394  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10395        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10396                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10397   (clobber (reg:CC FLAGS_REG))
10398   (clobber (match_scratch:DWIH 3 "=&r"))]
10399  ""
10400  "#"
10401  "reload_completed"
10402  [(set (match_dup 3) (match_dup 4))
10403   (parallel
10404    [(set (match_dup 4)
10405          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10406                    (ashift:DWIH (match_dup 5)
10407                                 (minus:QI (match_dup 6) (match_dup 2)))))
10408     (clobber (reg:CC FLAGS_REG))])
10409   (parallel
10410    [(set (match_dup 5)
10411          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10412                    (ashift:DWIH (match_dup 3)
10413                                 (minus:QI (match_dup 6) (match_dup 2)))))
10414     (clobber (reg:CC FLAGS_REG))])]
10416   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10418   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10421 (define_insn "*bmi2_rorx<mode>3_1"
10422   [(set (match_operand:SWI48 0 "register_operand" "=r")
10423         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10424                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10425   "TARGET_BMI2"
10426   "rorx\t{%2, %1, %0|%0, %1, %2}"
10427   [(set_attr "type" "rotatex")
10428    (set_attr "mode" "<MODE>")])
10430 (define_insn "*<rotate_insn><mode>3_1"
10431   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10432         (any_rotate:SWI48
10433           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10434           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10435    (clobber (reg:CC FLAGS_REG))]
10436   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10438   switch (get_attr_type (insn))
10439     {
10440     case TYPE_ROTATEX:
10441       return "#";
10443     default:
10444       if (operands[2] == const1_rtx
10445           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10446         return "<rotate>{<imodesuffix>}\t%0";
10447       else
10448         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10449     }
10451   [(set_attr "isa" "*,bmi2")
10452    (set_attr "type" "rotate,rotatex")
10453    (set (attr "length_immediate")
10454      (if_then_else
10455        (and (eq_attr "type" "rotate")
10456             (and (match_operand 2 "const1_operand")
10457                  (ior (match_test "TARGET_SHIFT1")
10458                       (match_test "optimize_function_for_size_p (cfun)"))))
10459        (const_string "0")
10460        (const_string "*")))
10461    (set_attr "mode" "<MODE>")])
10463 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10464 (define_split
10465   [(set (match_operand:SWI48 0 "register_operand")
10466         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10467                       (match_operand:QI 2 "immediate_operand")))
10468    (clobber (reg:CC FLAGS_REG))]
10469   "TARGET_BMI2 && reload_completed"
10470   [(set (match_dup 0)
10471         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10473   operands[2]
10474     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10477 (define_split
10478   [(set (match_operand:SWI48 0 "register_operand")
10479         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10480                         (match_operand:QI 2 "immediate_operand")))
10481    (clobber (reg:CC FLAGS_REG))]
10482   "TARGET_BMI2 && reload_completed"
10483   [(set (match_dup 0)
10484         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10486 (define_insn "*bmi2_rorxsi3_1_zext"
10487   [(set (match_operand:DI 0 "register_operand" "=r")
10488         (zero_extend:DI
10489           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10490                        (match_operand:QI 2 "immediate_operand" "I"))))]
10491   "TARGET_64BIT && TARGET_BMI2"
10492   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10493   [(set_attr "type" "rotatex")
10494    (set_attr "mode" "SI")])
10496 (define_insn "*<rotate_insn>si3_1_zext"
10497   [(set (match_operand:DI 0 "register_operand" "=r,r")
10498         (zero_extend:DI
10499           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10500                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10501    (clobber (reg:CC FLAGS_REG))]
10502   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10504   switch (get_attr_type (insn))
10505     {
10506     case TYPE_ROTATEX:
10507       return "#";
10509     default:
10510       if (operands[2] == const1_rtx
10511           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10512         return "<rotate>{l}\t%k0";
10513       else
10514         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10515     }
10517   [(set_attr "isa" "*,bmi2")
10518    (set_attr "type" "rotate,rotatex")
10519    (set (attr "length_immediate")
10520      (if_then_else
10521        (and (eq_attr "type" "rotate")
10522             (and (match_operand 2 "const1_operand")
10523                  (ior (match_test "TARGET_SHIFT1")
10524                       (match_test "optimize_function_for_size_p (cfun)"))))
10525        (const_string "0")
10526        (const_string "*")))
10527    (set_attr "mode" "SI")])
10529 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10530 (define_split
10531   [(set (match_operand:DI 0 "register_operand")
10532         (zero_extend:DI
10533           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10534                      (match_operand:QI 2 "immediate_operand"))))
10535    (clobber (reg:CC FLAGS_REG))]
10536   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10537   [(set (match_dup 0)
10538         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10540   operands[2]
10541     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10544 (define_split
10545   [(set (match_operand:DI 0 "register_operand")
10546         (zero_extend:DI
10547           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10548                        (match_operand:QI 2 "immediate_operand"))))
10549    (clobber (reg:CC FLAGS_REG))]
10550   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10551   [(set (match_dup 0)
10552         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10554 (define_insn "*<rotate_insn><mode>3_1"
10555   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10556         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10557                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10558    (clobber (reg:CC FLAGS_REG))]
10559   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10561   if (operands[2] == const1_rtx
10562       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10563     return "<rotate>{<imodesuffix>}\t%0";
10564   else
10565     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10567   [(set_attr "type" "rotate")
10568    (set (attr "length_immediate")
10569      (if_then_else
10570        (and (match_operand 2 "const1_operand")
10571             (ior (match_test "TARGET_SHIFT1")
10572                  (match_test "optimize_function_for_size_p (cfun)")))
10573        (const_string "0")
10574        (const_string "*")))
10575    (set_attr "mode" "<MODE>")])
10577 (define_insn "*<rotate_insn>qi3_1_slp"
10578   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10579         (any_rotate:QI (match_dup 0)
10580                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10581    (clobber (reg:CC FLAGS_REG))]
10582   "(optimize_function_for_size_p (cfun)
10583     || !TARGET_PARTIAL_REG_STALL
10584     || (operands[1] == const1_rtx
10585         && TARGET_SHIFT1))"
10587   if (operands[1] == const1_rtx
10588       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10589     return "<rotate>{b}\t%0";
10590   else
10591     return "<rotate>{b}\t{%1, %0|%0, %1}";
10593   [(set_attr "type" "rotate1")
10594    (set (attr "length_immediate")
10595      (if_then_else
10596        (and (match_operand 1 "const1_operand")
10597             (ior (match_test "TARGET_SHIFT1")
10598                  (match_test "optimize_function_for_size_p (cfun)")))
10599        (const_string "0")
10600        (const_string "*")))
10601    (set_attr "mode" "QI")])
10603 (define_split
10604  [(set (match_operand:HI 0 "register_operand")
10605        (any_rotate:HI (match_dup 0) (const_int 8)))
10606   (clobber (reg:CC FLAGS_REG))]
10607  "reload_completed
10608   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10609  [(parallel [(set (strict_low_part (match_dup 0))
10610                   (bswap:HI (match_dup 0)))
10611              (clobber (reg:CC FLAGS_REG))])])
10613 ;; Bit set / bit test instructions
10615 (define_expand "extv"
10616   [(set (match_operand:SI 0 "register_operand")
10617         (sign_extract:SI (match_operand:SI 1 "register_operand")
10618                          (match_operand:SI 2 "const8_operand")
10619                          (match_operand:SI 3 "const8_operand")))]
10620   ""
10622   /* Handle extractions from %ah et al.  */
10623   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10624     FAIL;
10626   /* From mips.md: extract_bit_field doesn't verify that our source
10627      matches the predicate, so check it again here.  */
10628   if (! ext_register_operand (operands[1], VOIDmode))
10629     FAIL;
10632 (define_expand "extzv"
10633   [(set (match_operand:SI 0 "register_operand")
10634         (zero_extract:SI (match_operand 1 "ext_register_operand")
10635                          (match_operand:SI 2 "const8_operand")
10636                          (match_operand:SI 3 "const8_operand")))]
10637   ""
10639   /* Handle extractions from %ah et al.  */
10640   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10641     FAIL;
10643   /* From mips.md: extract_bit_field doesn't verify that our source
10644      matches the predicate, so check it again here.  */
10645   if (! ext_register_operand (operands[1], VOIDmode))
10646     FAIL;
10649 (define_expand "insv"
10650   [(set (zero_extract (match_operand 0 "register_operand")
10651                       (match_operand 1 "const_int_operand")
10652                       (match_operand 2 "const_int_operand"))
10653         (match_operand 3 "register_operand"))]
10654   ""
10656   rtx (*gen_mov_insv_1) (rtx, rtx);
10658   if (ix86_expand_pinsr (operands))
10659     DONE;
10661   /* Handle insertions to %ah et al.  */
10662   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10663     FAIL;
10665   /* From mips.md: insert_bit_field doesn't verify that our source
10666      matches the predicate, so check it again here.  */
10667   if (! ext_register_operand (operands[0], VOIDmode))
10668     FAIL;
10670   gen_mov_insv_1 = (TARGET_64BIT
10671                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10673   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10674   DONE;
10677 ;; %%% bts, btr, btc, bt.
10678 ;; In general these instructions are *slow* when applied to memory,
10679 ;; since they enforce atomic operation.  When applied to registers,
10680 ;; it depends on the cpu implementation.  They're never faster than
10681 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10682 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10683 ;; within the instruction itself, so operating on bits in the high
10684 ;; 32-bits of a register becomes easier.
10686 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10687 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10688 ;; negdf respectively, so they can never be disabled entirely.
10690 (define_insn "*btsq"
10691   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10692                          (const_int 1)
10693                          (match_operand:DI 1 "const_0_to_63_operand"))
10694         (const_int 1))
10695    (clobber (reg:CC FLAGS_REG))]
10696   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10697   "bts{q}\t{%1, %0|%0, %1}"
10698   [(set_attr "type" "alu1")
10699    (set_attr "prefix_0f" "1")
10700    (set_attr "mode" "DI")])
10702 (define_insn "*btrq"
10703   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10704                          (const_int 1)
10705                          (match_operand:DI 1 "const_0_to_63_operand"))
10706         (const_int 0))
10707    (clobber (reg:CC FLAGS_REG))]
10708   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10709   "btr{q}\t{%1, %0|%0, %1}"
10710   [(set_attr "type" "alu1")
10711    (set_attr "prefix_0f" "1")
10712    (set_attr "mode" "DI")])
10714 (define_insn "*btcq"
10715   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10716                          (const_int 1)
10717                          (match_operand:DI 1 "const_0_to_63_operand"))
10718         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10719    (clobber (reg:CC FLAGS_REG))]
10720   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10721   "btc{q}\t{%1, %0|%0, %1}"
10722   [(set_attr "type" "alu1")
10723    (set_attr "prefix_0f" "1")
10724    (set_attr "mode" "DI")])
10726 ;; Allow Nocona to avoid these instructions if a register is available.
10728 (define_peephole2
10729   [(match_scratch:DI 2 "r")
10730    (parallel [(set (zero_extract:DI
10731                      (match_operand:DI 0 "register_operand")
10732                      (const_int 1)
10733                      (match_operand:DI 1 "const_0_to_63_operand"))
10734                    (const_int 1))
10735               (clobber (reg:CC FLAGS_REG))])]
10736   "TARGET_64BIT && !TARGET_USE_BT"
10737   [(const_int 0)]
10739   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10740   rtx op1;
10742   if (HOST_BITS_PER_WIDE_INT >= 64)
10743     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10744   else if (i < HOST_BITS_PER_WIDE_INT)
10745     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10746   else
10747     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10749   op1 = immed_double_const (lo, hi, DImode);
10750   if (i >= 31)
10751     {
10752       emit_move_insn (operands[2], op1);
10753       op1 = operands[2];
10754     }
10756   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10757   DONE;
10760 (define_peephole2
10761   [(match_scratch:DI 2 "r")
10762    (parallel [(set (zero_extract:DI
10763                      (match_operand:DI 0 "register_operand")
10764                      (const_int 1)
10765                      (match_operand:DI 1 "const_0_to_63_operand"))
10766                    (const_int 0))
10767               (clobber (reg:CC FLAGS_REG))])]
10768   "TARGET_64BIT && !TARGET_USE_BT"
10769   [(const_int 0)]
10771   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10772   rtx op1;
10774   if (HOST_BITS_PER_WIDE_INT >= 64)
10775     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10776   else if (i < HOST_BITS_PER_WIDE_INT)
10777     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10778   else
10779     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10781   op1 = immed_double_const (~lo, ~hi, DImode);
10782   if (i >= 32)
10783     {
10784       emit_move_insn (operands[2], op1);
10785       op1 = operands[2];
10786     }
10788   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10789   DONE;
10792 (define_peephole2
10793   [(match_scratch:DI 2 "r")
10794    (parallel [(set (zero_extract:DI
10795                      (match_operand:DI 0 "register_operand")
10796                      (const_int 1)
10797                      (match_operand:DI 1 "const_0_to_63_operand"))
10798               (not:DI (zero_extract:DI
10799                         (match_dup 0) (const_int 1) (match_dup 1))))
10800               (clobber (reg:CC FLAGS_REG))])]
10801   "TARGET_64BIT && !TARGET_USE_BT"
10802   [(const_int 0)]
10804   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10805   rtx op1;
10807   if (HOST_BITS_PER_WIDE_INT >= 64)
10808     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10809   else if (i < HOST_BITS_PER_WIDE_INT)
10810     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10811   else
10812     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10814   op1 = immed_double_const (lo, hi, DImode);
10815   if (i >= 31)
10816     {
10817       emit_move_insn (operands[2], op1);
10818       op1 = operands[2];
10819     }
10821   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10822   DONE;
10825 (define_insn "*bt<mode>"
10826   [(set (reg:CCC FLAGS_REG)
10827         (compare:CCC
10828           (zero_extract:SWI48
10829             (match_operand:SWI48 0 "register_operand" "r")
10830             (const_int 1)
10831             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10832           (const_int 0)))]
10833   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10834   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10835   [(set_attr "type" "alu1")
10836    (set_attr "prefix_0f" "1")
10837    (set_attr "mode" "<MODE>")])
10839 ;; Store-flag instructions.
10841 ;; For all sCOND expanders, also expand the compare or test insn that
10842 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10844 (define_insn_and_split "*setcc_di_1"
10845   [(set (match_operand:DI 0 "register_operand" "=q")
10846         (match_operator:DI 1 "ix86_comparison_operator"
10847           [(reg FLAGS_REG) (const_int 0)]))]
10848   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10849   "#"
10850   "&& reload_completed"
10851   [(set (match_dup 2) (match_dup 1))
10852    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10854   PUT_MODE (operands[1], QImode);
10855   operands[2] = gen_lowpart (QImode, operands[0]);
10858 (define_insn_and_split "*setcc_si_1_and"
10859   [(set (match_operand:SI 0 "register_operand" "=q")
10860         (match_operator:SI 1 "ix86_comparison_operator"
10861           [(reg FLAGS_REG) (const_int 0)]))
10862    (clobber (reg:CC FLAGS_REG))]
10863   "!TARGET_PARTIAL_REG_STALL
10864    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10865   "#"
10866   "&& reload_completed"
10867   [(set (match_dup 2) (match_dup 1))
10868    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10869               (clobber (reg:CC FLAGS_REG))])]
10871   PUT_MODE (operands[1], QImode);
10872   operands[2] = gen_lowpart (QImode, operands[0]);
10875 (define_insn_and_split "*setcc_si_1_movzbl"
10876   [(set (match_operand:SI 0 "register_operand" "=q")
10877         (match_operator:SI 1 "ix86_comparison_operator"
10878           [(reg FLAGS_REG) (const_int 0)]))]
10879   "!TARGET_PARTIAL_REG_STALL
10880    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10881   "#"
10882   "&& reload_completed"
10883   [(set (match_dup 2) (match_dup 1))
10884    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10886   PUT_MODE (operands[1], QImode);
10887   operands[2] = gen_lowpart (QImode, operands[0]);
10890 (define_insn "*setcc_qi"
10891   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10892         (match_operator:QI 1 "ix86_comparison_operator"
10893           [(reg FLAGS_REG) (const_int 0)]))]
10894   ""
10895   "set%C1\t%0"
10896   [(set_attr "type" "setcc")
10897    (set_attr "mode" "QI")])
10899 (define_insn "*setcc_qi_slp"
10900   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10901         (match_operator:QI 1 "ix86_comparison_operator"
10902           [(reg FLAGS_REG) (const_int 0)]))]
10903   ""
10904   "set%C1\t%0"
10905   [(set_attr "type" "setcc")
10906    (set_attr "mode" "QI")])
10908 ;; In general it is not safe to assume too much about CCmode registers,
10909 ;; so simplify-rtx stops when it sees a second one.  Under certain
10910 ;; conditions this is safe on x86, so help combine not create
10912 ;;      seta    %al
10913 ;;      testb   %al, %al
10914 ;;      sete    %al
10916 (define_split
10917   [(set (match_operand:QI 0 "nonimmediate_operand")
10918         (ne:QI (match_operator 1 "ix86_comparison_operator"
10919                  [(reg FLAGS_REG) (const_int 0)])
10920             (const_int 0)))]
10921   ""
10922   [(set (match_dup 0) (match_dup 1))]
10923   "PUT_MODE (operands[1], QImode);")
10925 (define_split
10926   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10927         (ne:QI (match_operator 1 "ix86_comparison_operator"
10928                  [(reg FLAGS_REG) (const_int 0)])
10929             (const_int 0)))]
10930   ""
10931   [(set (match_dup 0) (match_dup 1))]
10932   "PUT_MODE (operands[1], QImode);")
10934 (define_split
10935   [(set (match_operand:QI 0 "nonimmediate_operand")
10936         (eq:QI (match_operator 1 "ix86_comparison_operator"
10937                  [(reg FLAGS_REG) (const_int 0)])
10938             (const_int 0)))]
10939   ""
10940   [(set (match_dup 0) (match_dup 1))]
10942   rtx new_op1 = copy_rtx (operands[1]);
10943   operands[1] = new_op1;
10944   PUT_MODE (new_op1, QImode);
10945   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10946                                              GET_MODE (XEXP (new_op1, 0))));
10948   /* Make sure that (a) the CCmode we have for the flags is strong
10949      enough for the reversed compare or (b) we have a valid FP compare.  */
10950   if (! ix86_comparison_operator (new_op1, VOIDmode))
10951     FAIL;
10954 (define_split
10955   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10956         (eq:QI (match_operator 1 "ix86_comparison_operator"
10957                  [(reg FLAGS_REG) (const_int 0)])
10958             (const_int 0)))]
10959   ""
10960   [(set (match_dup 0) (match_dup 1))]
10962   rtx new_op1 = copy_rtx (operands[1]);
10963   operands[1] = new_op1;
10964   PUT_MODE (new_op1, QImode);
10965   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10966                                              GET_MODE (XEXP (new_op1, 0))));
10968   /* Make sure that (a) the CCmode we have for the flags is strong
10969      enough for the reversed compare or (b) we have a valid FP compare.  */
10970   if (! ix86_comparison_operator (new_op1, VOIDmode))
10971     FAIL;
10974 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10975 ;; subsequent logical operations are used to imitate conditional moves.
10976 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10977 ;; it directly.
10979 (define_insn "setcc_<mode>_sse"
10980   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10981         (match_operator:MODEF 3 "sse_comparison_operator"
10982           [(match_operand:MODEF 1 "register_operand" "0,x")
10983            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10984   "SSE_FLOAT_MODE_P (<MODE>mode)"
10985   "@
10986    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10987    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10988   [(set_attr "isa" "noavx,avx")
10989    (set_attr "type" "ssecmp")
10990    (set_attr "length_immediate" "1")
10991    (set_attr "prefix" "orig,vex")
10992    (set_attr "mode" "<MODE>")])
10994 ;; Basic conditional jump instructions.
10995 ;; We ignore the overflow flag for signed branch instructions.
10997 (define_insn "*jcc_1"
10998   [(set (pc)
10999         (if_then_else (match_operator 1 "ix86_comparison_operator"
11000                                       [(reg FLAGS_REG) (const_int 0)])
11001                       (label_ref (match_operand 0))
11002                       (pc)))]
11003   ""
11004   "%+j%C1\t%l0"
11005   [(set_attr "type" "ibr")
11006    (set_attr "modrm" "0")
11007    (set (attr "length")
11008            (if_then_else (and (ge (minus (match_dup 0) (pc))
11009                                   (const_int -126))
11010                               (lt (minus (match_dup 0) (pc))
11011                                   (const_int 128)))
11012              (const_int 2)
11013              (const_int 6)))])
11015 (define_insn "*jcc_2"
11016   [(set (pc)
11017         (if_then_else (match_operator 1 "ix86_comparison_operator"
11018                                       [(reg FLAGS_REG) (const_int 0)])
11019                       (pc)
11020                       (label_ref (match_operand 0))))]
11021   ""
11022   "%+j%c1\t%l0"
11023   [(set_attr "type" "ibr")
11024    (set_attr "modrm" "0")
11025    (set (attr "length")
11026            (if_then_else (and (ge (minus (match_dup 0) (pc))
11027                                   (const_int -126))
11028                               (lt (minus (match_dup 0) (pc))
11029                                   (const_int 128)))
11030              (const_int 2)
11031              (const_int 6)))])
11033 ;; In general it is not safe to assume too much about CCmode registers,
11034 ;; so simplify-rtx stops when it sees a second one.  Under certain
11035 ;; conditions this is safe on x86, so help combine not create
11037 ;;      seta    %al
11038 ;;      testb   %al, %al
11039 ;;      je      Lfoo
11041 (define_split
11042   [(set (pc)
11043         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11044                                       [(reg FLAGS_REG) (const_int 0)])
11045                           (const_int 0))
11046                       (label_ref (match_operand 1))
11047                       (pc)))]
11048   ""
11049   [(set (pc)
11050         (if_then_else (match_dup 0)
11051                       (label_ref (match_dup 1))
11052                       (pc)))]
11053   "PUT_MODE (operands[0], VOIDmode);")
11055 (define_split
11056   [(set (pc)
11057         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11058                                       [(reg FLAGS_REG) (const_int 0)])
11059                           (const_int 0))
11060                       (label_ref (match_operand 1))
11061                       (pc)))]
11062   ""
11063   [(set (pc)
11064         (if_then_else (match_dup 0)
11065                       (label_ref (match_dup 1))
11066                       (pc)))]
11068   rtx new_op0 = copy_rtx (operands[0]);
11069   operands[0] = new_op0;
11070   PUT_MODE (new_op0, VOIDmode);
11071   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
11072                                              GET_MODE (XEXP (new_op0, 0))));
11074   /* Make sure that (a) the CCmode we have for the flags is strong
11075      enough for the reversed compare or (b) we have a valid FP compare.  */
11076   if (! ix86_comparison_operator (new_op0, VOIDmode))
11077     FAIL;
11080 ;; zero_extend in SImode is correct also for DImode, since this is what combine
11081 ;; pass generates from shift insn with QImode operand.  Actually, the mode
11082 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
11083 ;; appropriate modulo of the bit offset value.
11085 (define_insn_and_split "*jcc_bt<mode>"
11086   [(set (pc)
11087         (if_then_else (match_operator 0 "bt_comparison_operator"
11088                         [(zero_extract:SWI48
11089                            (match_operand:SWI48 1 "register_operand" "r")
11090                            (const_int 1)
11091                            (zero_extend:SI
11092                              (match_operand:QI 2 "register_operand" "r")))
11093                          (const_int 0)])
11094                       (label_ref (match_operand 3))
11095                       (pc)))
11096    (clobber (reg:CC FLAGS_REG))]
11097   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11098   "#"
11099   "&& 1"
11100   [(set (reg:CCC FLAGS_REG)
11101         (compare:CCC
11102           (zero_extract:SWI48
11103             (match_dup 1)
11104             (const_int 1)
11105             (match_dup 2))
11106           (const_int 0)))
11107    (set (pc)
11108         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11109                       (label_ref (match_dup 3))
11110                       (pc)))]
11112   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11114   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11117 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
11118 ;; zero extended to SImode.
11119 (define_insn_and_split "*jcc_bt<mode>_1"
11120   [(set (pc)
11121         (if_then_else (match_operator 0 "bt_comparison_operator"
11122                         [(zero_extract:SWI48
11123                            (match_operand:SWI48 1 "register_operand" "r")
11124                            (const_int 1)
11125                            (match_operand:SI 2 "register_operand" "r"))
11126                          (const_int 0)])
11127                       (label_ref (match_operand 3))
11128                       (pc)))
11129    (clobber (reg:CC FLAGS_REG))]
11130   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11131   "#"
11132   "&& 1"
11133   [(set (reg:CCC FLAGS_REG)
11134         (compare:CCC
11135           (zero_extract:SWI48
11136             (match_dup 1)
11137             (const_int 1)
11138             (match_dup 2))
11139           (const_int 0)))
11140    (set (pc)
11141         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11142                       (label_ref (match_dup 3))
11143                       (pc)))]
11145   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11147   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11150 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
11151 ;; also for DImode, this is what combine produces.
11152 (define_insn_and_split "*jcc_bt<mode>_mask"
11153   [(set (pc)
11154         (if_then_else (match_operator 0 "bt_comparison_operator"
11155                         [(zero_extract:SWI48
11156                            (match_operand:SWI48 1 "register_operand" "r")
11157                            (const_int 1)
11158                            (and:SI
11159                              (match_operand:SI 2 "register_operand" "r")
11160                              (match_operand:SI 3 "const_int_operand" "n")))])
11161                       (label_ref (match_operand 4))
11162                       (pc)))
11163    (clobber (reg:CC FLAGS_REG))]
11164   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11165    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11166       == GET_MODE_BITSIZE (<MODE>mode)-1"
11167   "#"
11168   "&& 1"
11169   [(set (reg:CCC FLAGS_REG)
11170         (compare:CCC
11171           (zero_extract:SWI48
11172             (match_dup 1)
11173             (const_int 1)
11174             (match_dup 2))
11175           (const_int 0)))
11176    (set (pc)
11177         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11178                       (label_ref (match_dup 4))
11179                       (pc)))]
11181   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11183   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11186 (define_insn_and_split "*jcc_btsi_1"
11187   [(set (pc)
11188         (if_then_else (match_operator 0 "bt_comparison_operator"
11189                         [(and:SI
11190                            (lshiftrt:SI
11191                              (match_operand:SI 1 "register_operand" "r")
11192                              (match_operand:QI 2 "register_operand" "r"))
11193                            (const_int 1))
11194                          (const_int 0)])
11195                       (label_ref (match_operand 3))
11196                       (pc)))
11197    (clobber (reg:CC FLAGS_REG))]
11198   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11199   "#"
11200   "&& 1"
11201   [(set (reg:CCC FLAGS_REG)
11202         (compare:CCC
11203           (zero_extract:SI
11204             (match_dup 1)
11205             (const_int 1)
11206             (match_dup 2))
11207           (const_int 0)))
11208    (set (pc)
11209         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11210                       (label_ref (match_dup 3))
11211                       (pc)))]
11213   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11215   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11218 ;; avoid useless masking of bit offset operand
11219 (define_insn_and_split "*jcc_btsi_mask_1"
11220   [(set (pc)
11221         (if_then_else
11222           (match_operator 0 "bt_comparison_operator"
11223             [(and:SI
11224                (lshiftrt:SI
11225                  (match_operand:SI 1 "register_operand" "r")
11226                  (subreg:QI
11227                    (and:SI
11228                      (match_operand:SI 2 "register_operand" "r")
11229                      (match_operand:SI 3 "const_int_operand" "n")) 0))
11230                (const_int 1))
11231              (const_int 0)])
11232           (label_ref (match_operand 4))
11233           (pc)))
11234    (clobber (reg:CC FLAGS_REG))]
11235   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11236    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11237   "#"
11238   "&& 1"
11239   [(set (reg:CCC FLAGS_REG)
11240         (compare:CCC
11241           (zero_extract:SI
11242             (match_dup 1)
11243             (const_int 1)
11244             (match_dup 2))
11245           (const_int 0)))
11246    (set (pc)
11247         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11248                       (label_ref (match_dup 4))
11249                       (pc)))]
11250   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11252 ;; Define combination compare-and-branch fp compare instructions to help
11253 ;; combine.
11255 (define_insn "*jcc<mode>_0_i387"
11256   [(set (pc)
11257         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11258                         [(match_operand:X87MODEF 1 "register_operand" "f")
11259                          (match_operand:X87MODEF 2 "const0_operand")])
11260           (label_ref (match_operand 3))
11261           (pc)))
11262    (clobber (reg:CCFP FPSR_REG))
11263    (clobber (reg:CCFP FLAGS_REG))
11264    (clobber (match_scratch:HI 4 "=a"))]
11265   "TARGET_80387 && !TARGET_CMOVE"
11266   "#")
11268 (define_insn "*jcc<mode>_0_r_i387"
11269   [(set (pc)
11270         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11271                         [(match_operand:X87MODEF 1 "register_operand" "f")
11272                          (match_operand:X87MODEF 2 "const0_operand")])
11273           (pc)
11274           (label_ref (match_operand 3))))
11275    (clobber (reg:CCFP FPSR_REG))
11276    (clobber (reg:CCFP FLAGS_REG))
11277    (clobber (match_scratch:HI 4 "=a"))]
11278   "TARGET_80387 && !TARGET_CMOVE"
11279   "#")
11281 (define_insn "*jccxf_i387"
11282   [(set (pc)
11283         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11284                         [(match_operand:XF 1 "register_operand" "f")
11285                          (match_operand:XF 2 "register_operand" "f")])
11286           (label_ref (match_operand 3))
11287           (pc)))
11288    (clobber (reg:CCFP FPSR_REG))
11289    (clobber (reg:CCFP FLAGS_REG))
11290    (clobber (match_scratch:HI 4 "=a"))]
11291   "TARGET_80387 && !TARGET_CMOVE"
11292   "#")
11294 (define_insn "*jccxf_r_i387"
11295   [(set (pc)
11296         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11297                         [(match_operand:XF 1 "register_operand" "f")
11298                          (match_operand:XF 2 "register_operand" "f")])
11299           (pc)
11300           (label_ref (match_operand 3))))
11301    (clobber (reg:CCFP FPSR_REG))
11302    (clobber (reg:CCFP FLAGS_REG))
11303    (clobber (match_scratch:HI 4 "=a"))]
11304   "TARGET_80387 && !TARGET_CMOVE"
11305   "#")
11307 (define_insn "*jcc<mode>_i387"
11308   [(set (pc)
11309         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11310                         [(match_operand:MODEF 1 "register_operand" "f")
11311                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11312           (label_ref (match_operand 3))
11313           (pc)))
11314    (clobber (reg:CCFP FPSR_REG))
11315    (clobber (reg:CCFP FLAGS_REG))
11316    (clobber (match_scratch:HI 4 "=a"))]
11317   "TARGET_80387 && !TARGET_CMOVE"
11318   "#")
11320 (define_insn "*jcc<mode>_r_i387"
11321   [(set (pc)
11322         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11323                         [(match_operand:MODEF 1 "register_operand" "f")
11324                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11325           (pc)
11326           (label_ref (match_operand 3))))
11327    (clobber (reg:CCFP FPSR_REG))
11328    (clobber (reg:CCFP FLAGS_REG))
11329    (clobber (match_scratch:HI 4 "=a"))]
11330   "TARGET_80387 && !TARGET_CMOVE"
11331   "#")
11333 (define_insn "*jccu<mode>_i387"
11334   [(set (pc)
11335         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11336                         [(match_operand:X87MODEF 1 "register_operand" "f")
11337                          (match_operand:X87MODEF 2 "register_operand" "f")])
11338           (label_ref (match_operand 3))
11339           (pc)))
11340    (clobber (reg:CCFP FPSR_REG))
11341    (clobber (reg:CCFP FLAGS_REG))
11342    (clobber (match_scratch:HI 4 "=a"))]
11343   "TARGET_80387 && !TARGET_CMOVE"
11344   "#")
11346 (define_insn "*jccu<mode>_r_i387"
11347   [(set (pc)
11348         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11349                         [(match_operand:X87MODEF 1 "register_operand" "f")
11350                          (match_operand:X87MODEF 2 "register_operand" "f")])
11351           (pc)
11352           (label_ref (match_operand 3))))
11353    (clobber (reg:CCFP FPSR_REG))
11354    (clobber (reg:CCFP FLAGS_REG))
11355    (clobber (match_scratch:HI 4 "=a"))]
11356   "TARGET_80387 && !TARGET_CMOVE"
11357   "#")
11359 (define_split
11360   [(set (pc)
11361         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11362                         [(match_operand:X87MODEF 1 "register_operand")
11363                          (match_operand:X87MODEF 2 "nonimmediate_operand")])
11364           (match_operand 3)
11365           (match_operand 4)))
11366    (clobber (reg:CCFP FPSR_REG))
11367    (clobber (reg:CCFP FLAGS_REG))]
11368   "TARGET_80387 && !TARGET_CMOVE
11369    && reload_completed"
11370   [(const_int 0)]
11372   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11373                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11374   DONE;
11377 (define_split
11378   [(set (pc)
11379         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11380                         [(match_operand:X87MODEF 1 "register_operand")
11381                          (match_operand:X87MODEF 2 "general_operand")])
11382           (match_operand 3)
11383           (match_operand 4)))
11384    (clobber (reg:CCFP FPSR_REG))
11385    (clobber (reg:CCFP FLAGS_REG))
11386    (clobber (match_scratch:HI 5))]
11387   "TARGET_80387 && !TARGET_CMOVE
11388    && reload_completed"
11389   [(const_int 0)]
11391   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11392                         operands[3], operands[4], operands[5], NULL_RTX);
11393   DONE;
11396 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11397 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11398 ;; with a precedence over other operators and is always put in the first
11399 ;; place. Swap condition and operands to match ficom instruction.
11401 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11402   [(set (pc)
11403         (if_then_else
11404           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11405             [(match_operator:X87MODEF 1 "float_operator"
11406               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11407              (match_operand:X87MODEF 3 "register_operand" "f,f")])
11408           (label_ref (match_operand 4))
11409           (pc)))
11410    (clobber (reg:CCFP FPSR_REG))
11411    (clobber (reg:CCFP FLAGS_REG))
11412    (clobber (match_scratch:HI 5 "=a,a"))]
11413   "TARGET_80387 && !TARGET_CMOVE
11414    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11415        || optimize_function_for_size_p (cfun))"
11416   "#")
11418 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11419   [(set (pc)
11420         (if_then_else
11421           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11422             [(match_operator:X87MODEF 1 "float_operator"
11423               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11424              (match_operand:X87MODEF 3 "register_operand" "f,f")])
11425           (pc)
11426           (label_ref (match_operand 4))))
11427    (clobber (reg:CCFP FPSR_REG))
11428    (clobber (reg:CCFP FLAGS_REG))
11429    (clobber (match_scratch:HI 5 "=a,a"))]
11430   "TARGET_80387 && !TARGET_CMOVE
11431    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11432        || optimize_function_for_size_p (cfun))"
11433   "#")
11435 (define_split
11436   [(set (pc)
11437         (if_then_else
11438           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11439             [(match_operator:X87MODEF 1 "float_operator"
11440               [(match_operand:SWI24 2 "memory_operand")])
11441              (match_operand:X87MODEF 3 "register_operand")])
11442           (match_operand 4)
11443           (match_operand 5)))
11444    (clobber (reg:CCFP FPSR_REG))
11445    (clobber (reg:CCFP FLAGS_REG))
11446    (clobber (match_scratch:HI 6))]
11447   "TARGET_80387 && !TARGET_CMOVE
11448    && reload_completed"
11449   [(const_int 0)]
11451   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11452                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11453                         operands[4], operands[5], operands[6], NULL_RTX);
11454   DONE;
11457 ;; %%% Kill this when reload knows how to do it.
11458 (define_split
11459   [(set (pc)
11460         (if_then_else
11461           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11462             [(match_operator:X87MODEF 1 "float_operator"
11463               [(match_operand:SWI24 2 "register_operand")])
11464              (match_operand:X87MODEF 3 "register_operand")])
11465           (match_operand 4)
11466           (match_operand 5)))
11467    (clobber (reg:CCFP FPSR_REG))
11468    (clobber (reg:CCFP FLAGS_REG))
11469    (clobber (match_scratch:HI 6))]
11470   "TARGET_80387 && !TARGET_CMOVE
11471    && reload_completed"
11472   [(const_int 0)]
11474   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11476   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11477                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]),
11478                         operands[4], operands[5], operands[6], operands[2]);
11479   DONE;
11482 ;; Unconditional and other jump instructions
11484 (define_insn "jump"
11485   [(set (pc)
11486         (label_ref (match_operand 0)))]
11487   ""
11488   "jmp\t%l0"
11489   [(set_attr "type" "ibr")
11490    (set (attr "length")
11491            (if_then_else (and (ge (minus (match_dup 0) (pc))
11492                                   (const_int -126))
11493                               (lt (minus (match_dup 0) (pc))
11494                                   (const_int 128)))
11495              (const_int 2)
11496              (const_int 5)))
11497    (set_attr "modrm" "0")])
11499 (define_expand "indirect_jump"
11500   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11501   ""
11503   if (TARGET_X32)
11504     operands[0] = convert_memory_address (word_mode, operands[0]);
11507 (define_insn "*indirect_jump"
11508   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11509   ""
11510   "jmp\t%A0"
11511   [(set_attr "type" "ibr")
11512    (set_attr "length_immediate" "0")])
11514 (define_expand "tablejump"
11515   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11516               (use (label_ref (match_operand 1)))])]
11517   ""
11519   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11520      relative.  Convert the relative address to an absolute address.  */
11521   if (flag_pic)
11522     {
11523       rtx op0, op1;
11524       enum rtx_code code;
11526       /* We can't use @GOTOFF for text labels on VxWorks;
11527          see gotoff_operand.  */
11528       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11529         {
11530           code = PLUS;
11531           op0 = operands[0];
11532           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11533         }
11534       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11535         {
11536           code = PLUS;
11537           op0 = operands[0];
11538           op1 = pic_offset_table_rtx;
11539         }
11540       else
11541         {
11542           code = MINUS;
11543           op0 = pic_offset_table_rtx;
11544           op1 = operands[0];
11545         }
11547       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11548                                          OPTAB_DIRECT);
11549     }
11551   if (TARGET_X32)
11552     operands[0] = convert_memory_address (word_mode, operands[0]);
11555 (define_insn "*tablejump_1"
11556   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11557    (use (label_ref (match_operand 1)))]
11558   ""
11559   "jmp\t%A0"
11560   [(set_attr "type" "ibr")
11561    (set_attr "length_immediate" "0")])
11563 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11565 (define_peephole2
11566   [(set (reg FLAGS_REG) (match_operand 0))
11567    (set (match_operand:QI 1 "register_operand")
11568         (match_operator:QI 2 "ix86_comparison_operator"
11569           [(reg FLAGS_REG) (const_int 0)]))
11570    (set (match_operand 3 "q_regs_operand")
11571         (zero_extend (match_dup 1)))]
11572   "(peep2_reg_dead_p (3, operands[1])
11573     || operands_match_p (operands[1], operands[3]))
11574    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11575   [(set (match_dup 4) (match_dup 0))
11576    (set (strict_low_part (match_dup 5))
11577         (match_dup 2))]
11579   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11580   operands[5] = gen_lowpart (QImode, operands[3]);
11581   ix86_expand_clear (operands[3]);
11584 (define_peephole2
11585   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11586               (match_operand 4)])
11587    (set (match_operand:QI 1 "register_operand")
11588         (match_operator:QI 2 "ix86_comparison_operator"
11589           [(reg FLAGS_REG) (const_int 0)]))
11590    (set (match_operand 3 "q_regs_operand")
11591         (zero_extend (match_dup 1)))]
11592   "(peep2_reg_dead_p (3, operands[1])
11593     || operands_match_p (operands[1], operands[3]))
11594    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11595   [(parallel [(set (match_dup 5) (match_dup 0))
11596               (match_dup 4)])
11597    (set (strict_low_part (match_dup 6))
11598         (match_dup 2))]
11600   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11601   operands[6] = gen_lowpart (QImode, operands[3]);
11602   ix86_expand_clear (operands[3]);
11605 ;; Similar, but match zero extend with andsi3.
11607 (define_peephole2
11608   [(set (reg FLAGS_REG) (match_operand 0))
11609    (set (match_operand:QI 1 "register_operand")
11610         (match_operator:QI 2 "ix86_comparison_operator"
11611           [(reg FLAGS_REG) (const_int 0)]))
11612    (parallel [(set (match_operand:SI 3 "q_regs_operand")
11613                    (and:SI (match_dup 3) (const_int 255)))
11614               (clobber (reg:CC FLAGS_REG))])]
11615   "REGNO (operands[1]) == REGNO (operands[3])
11616    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11617   [(set (match_dup 4) (match_dup 0))
11618    (set (strict_low_part (match_dup 5))
11619         (match_dup 2))]
11621   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11622   operands[5] = gen_lowpart (QImode, operands[3]);
11623   ix86_expand_clear (operands[3]);
11626 (define_peephole2
11627   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11628               (match_operand 4)])
11629    (set (match_operand:QI 1 "register_operand")
11630         (match_operator:QI 2 "ix86_comparison_operator"
11631           [(reg FLAGS_REG) (const_int 0)]))
11632    (parallel [(set (match_operand 3 "q_regs_operand")
11633                    (zero_extend (match_dup 1)))
11634               (clobber (reg:CC FLAGS_REG))])]
11635   "(peep2_reg_dead_p (3, operands[1])
11636     || operands_match_p (operands[1], operands[3]))
11637    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11638   [(parallel [(set (match_dup 5) (match_dup 0))
11639               (match_dup 4)])
11640    (set (strict_low_part (match_dup 6))
11641         (match_dup 2))]
11643   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11644   operands[6] = gen_lowpart (QImode, operands[3]);
11645   ix86_expand_clear (operands[3]);
11648 ;; Call instructions.
11650 ;; The predicates normally associated with named expanders are not properly
11651 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11652 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11654 ;; P6 processors will jump to the address after the decrement when %esp
11655 ;; is used as a call operand, so they will execute return address as a code.
11656 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11658 ;; Register constraint for call instruction.
11659 (define_mode_attr c [(SI "l") (DI "r")])
11661 ;; Call subroutine returning no value.
11663 (define_expand "call"
11664   [(call (match_operand:QI 0)
11665          (match_operand 1))
11666    (use (match_operand 2))]
11667   ""
11669   ix86_expand_call (NULL, operands[0], operands[1],
11670                     operands[2], NULL, false);
11671   DONE;
11674 (define_expand "sibcall"
11675   [(call (match_operand:QI 0)
11676          (match_operand 1))
11677    (use (match_operand 2))]
11678   ""
11680   ix86_expand_call (NULL, operands[0], operands[1],
11681                     operands[2], NULL, true);
11682   DONE;
11685 (define_insn "*call"
11686   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11687          (match_operand 1))]
11688   "!SIBLING_CALL_P (insn)"
11689   "* return ix86_output_call_insn (insn, operands[0]);"
11690   [(set_attr "type" "call")])
11692 (define_insn "*call_rex64_ms_sysv"
11693   [(match_parallel 2 "call_rex64_ms_sysv_operation"
11694     [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11695            (match_operand 1))
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[0]);"
11699   [(set_attr "type" "call")])
11701 (define_insn "*sibcall"
11702   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11703          (match_operand 1))]
11704   "SIBLING_CALL_P (insn)"
11705   "* return ix86_output_call_insn (insn, operands[0]);"
11706   [(set_attr "type" "call")])
11708 (define_expand "call_pop"
11709   [(parallel [(call (match_operand:QI 0)
11710                     (match_operand:SI 1))
11711               (set (reg:SI SP_REG)
11712                    (plus:SI (reg:SI SP_REG)
11713                             (match_operand:SI 3)))])]
11714   "!TARGET_64BIT"
11716   ix86_expand_call (NULL, operands[0], operands[1],
11717                     operands[2], operands[3], false);
11718   DONE;
11721 (define_insn "*call_pop"
11722   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11723          (match_operand 1))
11724    (set (reg:SI SP_REG)
11725         (plus:SI (reg:SI SP_REG)
11726                  (match_operand:SI 2 "immediate_operand" "i")))]
11727   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11728   "* return ix86_output_call_insn (insn, operands[0]);"
11729   [(set_attr "type" "call")])
11731 (define_insn "*sibcall_pop"
11732   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11733          (match_operand 1))
11734    (set (reg:SI SP_REG)
11735         (plus:SI (reg:SI SP_REG)
11736                  (match_operand:SI 2 "immediate_operand" "i")))]
11737   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11738   "* return ix86_output_call_insn (insn, operands[0]);"
11739   [(set_attr "type" "call")])
11741 ;; Call subroutine, returning value in operand 0
11743 (define_expand "call_value"
11744   [(set (match_operand 0)
11745         (call (match_operand:QI 1)
11746               (match_operand 2)))
11747    (use (match_operand 3))]
11748   ""
11750   ix86_expand_call (operands[0], operands[1], operands[2],
11751                     operands[3], NULL, false);
11752   DONE;
11755 (define_expand "sibcall_value"
11756   [(set (match_operand 0)
11757         (call (match_operand:QI 1)
11758               (match_operand 2)))
11759    (use (match_operand 3))]
11760   ""
11762   ix86_expand_call (operands[0], operands[1], operands[2],
11763                     operands[3], NULL, true);
11764   DONE;
11767 (define_insn "*call_value"
11768   [(set (match_operand 0)
11769         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11770               (match_operand 2)))]
11771   "!SIBLING_CALL_P (insn)"
11772   "* return ix86_output_call_insn (insn, operands[1]);"
11773   [(set_attr "type" "callv")])
11775 (define_insn "*sibcall_value"
11776   [(set (match_operand 0)
11777         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11778               (match_operand 2)))]
11779   "SIBLING_CALL_P (insn)"
11780   "* return ix86_output_call_insn (insn, operands[1]);"
11781   [(set_attr "type" "callv")])
11783 (define_insn "*call_value_rex64_ms_sysv"
11784   [(match_parallel 3 "call_rex64_ms_sysv_operation"
11785     [(set (match_operand 0)
11786           (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11787                 (match_operand 2)))
11788      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11789  "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11790   "* return ix86_output_call_insn (insn, operands[1]);"
11791   [(set_attr "type" "callv")])
11793 (define_expand "call_value_pop"
11794   [(parallel [(set (match_operand 0)
11795                    (call (match_operand:QI 1)
11796                          (match_operand:SI 2)))
11797               (set (reg:SI SP_REG)
11798                    (plus:SI (reg:SI SP_REG)
11799                             (match_operand:SI 4)))])]
11800   "!TARGET_64BIT"
11802   ix86_expand_call (operands[0], operands[1], operands[2],
11803                     operands[3], operands[4], false);
11804   DONE;
11807 (define_insn "*call_value_pop"
11808   [(set (match_operand 0)
11809         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11810               (match_operand 2)))
11811    (set (reg:SI SP_REG)
11812         (plus:SI (reg:SI SP_REG)
11813                  (match_operand:SI 3 "immediate_operand" "i")))]
11814   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11815   "* return ix86_output_call_insn (insn, operands[1]);"
11816   [(set_attr "type" "callv")])
11818 (define_insn "*sibcall_value_pop"
11819   [(set (match_operand 0)
11820         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11821               (match_operand 2)))
11822    (set (reg:SI SP_REG)
11823         (plus:SI (reg:SI SP_REG)
11824                  (match_operand:SI 3 "immediate_operand" "i")))]
11825   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11826   "* return ix86_output_call_insn (insn, operands[1]);"
11827   [(set_attr "type" "callv")])
11829 ;; Call subroutine returning any type.
11831 (define_expand "untyped_call"
11832   [(parallel [(call (match_operand 0)
11833                     (const_int 0))
11834               (match_operand 1)
11835               (match_operand 2)])]
11836   ""
11838   int i;
11840   /* In order to give reg-stack an easier job in validating two
11841      coprocessor registers as containing a possible return value,
11842      simply pretend the untyped call returns a complex long double
11843      value. 
11845      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11846      and should have the default ABI.  */
11848   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11849                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11850                     operands[0], const0_rtx,
11851                     GEN_INT ((TARGET_64BIT
11852                               ? (ix86_abi == SYSV_ABI
11853                                  ? X86_64_SSE_REGPARM_MAX
11854                                  : X86_64_MS_SSE_REGPARM_MAX)
11855                               : X86_32_SSE_REGPARM_MAX)
11856                              - 1),
11857                     NULL, false);
11859   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11860     {
11861       rtx set = XVECEXP (operands[2], 0, i);
11862       emit_move_insn (SET_DEST (set), SET_SRC (set));
11863     }
11865   /* The optimizer does not know that the call sets the function value
11866      registers we stored in the result block.  We avoid problems by
11867      claiming that all hard registers are used and clobbered at this
11868      point.  */
11869   emit_insn (gen_blockage ());
11871   DONE;
11874 ;; Prologue and epilogue instructions
11876 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11877 ;; all of memory.  This blocks insns from being moved across this point.
11879 (define_insn "blockage"
11880   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11881   ""
11882   ""
11883   [(set_attr "length" "0")])
11885 ;; Do not schedule instructions accessing memory across this point.
11887 (define_expand "memory_blockage"
11888   [(set (match_dup 0)
11889         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11890   ""
11892   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11893   MEM_VOLATILE_P (operands[0]) = 1;
11896 (define_insn "*memory_blockage"
11897   [(set (match_operand:BLK 0)
11898         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11899   ""
11900   ""
11901   [(set_attr "length" "0")])
11903 ;; As USE insns aren't meaningful after reload, this is used instead
11904 ;; to prevent deleting instructions setting registers for PIC code
11905 (define_insn "prologue_use"
11906   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11907   ""
11908   ""
11909   [(set_attr "length" "0")])
11911 ;; Insn emitted into the body of a function to return from a function.
11912 ;; This is only done if the function's epilogue is known to be simple.
11913 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11915 (define_expand "return"
11916   [(simple_return)]
11917   "ix86_can_use_return_insn_p ()"
11919   if (crtl->args.pops_args)
11920     {
11921       rtx popc = GEN_INT (crtl->args.pops_args);
11922       emit_jump_insn (gen_simple_return_pop_internal (popc));
11923       DONE;
11924     }
11927 ;; We need to disable this for TARGET_SEH, as otherwise
11928 ;; shrink-wrapped prologue gets enabled too.  This might exceed
11929 ;; the maximum size of prologue in unwind information.
11931 (define_expand "simple_return"
11932   [(simple_return)]
11933   "!TARGET_SEH"
11935   if (crtl->args.pops_args)
11936     {
11937       rtx popc = GEN_INT (crtl->args.pops_args);
11938       emit_jump_insn (gen_simple_return_pop_internal (popc));
11939       DONE;
11940     }
11943 (define_insn "simple_return_internal"
11944   [(simple_return)]
11945   "reload_completed"
11946   "ret"
11947   [(set_attr "length" "1")
11948    (set_attr "atom_unit" "jeu")
11949    (set_attr "length_immediate" "0")
11950    (set_attr "modrm" "0")])
11952 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11953 ;; instruction Athlon and K8 have.
11955 (define_insn "simple_return_internal_long"
11956   [(simple_return)
11957    (unspec [(const_int 0)] UNSPEC_REP)]
11958   "reload_completed"
11959   "rep%; ret"
11960   [(set_attr "length" "2")
11961    (set_attr "atom_unit" "jeu")
11962    (set_attr "length_immediate" "0")
11963    (set_attr "prefix_rep" "1")
11964    (set_attr "modrm" "0")])
11966 (define_insn "simple_return_pop_internal"
11967   [(simple_return)
11968    (use (match_operand:SI 0 "const_int_operand"))]
11969   "reload_completed"
11970   "ret\t%0"
11971   [(set_attr "length" "3")
11972    (set_attr "atom_unit" "jeu")
11973    (set_attr "length_immediate" "2")
11974    (set_attr "modrm" "0")])
11976 (define_insn "simple_return_indirect_internal"
11977   [(simple_return)
11978    (use (match_operand:SI 0 "register_operand" "r"))]
11979   "reload_completed"
11980   "jmp\t%A0"
11981   [(set_attr "type" "ibr")
11982    (set_attr "length_immediate" "0")])
11984 (define_insn "nop"
11985   [(const_int 0)]
11986   ""
11987   "nop"
11988   [(set_attr "length" "1")
11989    (set_attr "length_immediate" "0")
11990    (set_attr "modrm" "0")])
11992 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11993 (define_insn "nops"
11994   [(unspec_volatile [(match_operand 0 "const_int_operand")]
11995                     UNSPECV_NOPS)]
11996   "reload_completed"
11998   int num = INTVAL (operands[0]);
12000   gcc_assert (IN_RANGE (num, 1, 8));
12002   while (num--)
12003     fputs ("\tnop\n", asm_out_file);
12005   return "";
12007   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12008    (set_attr "length_immediate" "0")
12009    (set_attr "modrm" "0")])
12011 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
12012 ;; branch prediction penalty for the third jump in a 16-byte
12013 ;; block on K8.
12015 (define_insn "pad"
12016   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12017   ""
12019 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12020   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12021 #else
12022   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12023      The align insn is used to avoid 3 jump instructions in the row to improve
12024      branch prediction and the benefits hardly outweigh the cost of extra 8
12025      nops on the average inserted by full alignment pseudo operation.  */
12026 #endif
12027   return "";
12029   [(set_attr "length" "16")])
12031 (define_expand "prologue"
12032   [(const_int 0)]
12033   ""
12034   "ix86_expand_prologue (); DONE;")
12036 (define_insn "set_got"
12037   [(set (match_operand:SI 0 "register_operand" "=r")
12038         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12039    (clobber (reg:CC FLAGS_REG))]
12040   "!TARGET_64BIT"
12041   "* return output_set_got (operands[0], NULL_RTX);"
12042   [(set_attr "type" "multi")
12043    (set_attr "length" "12")])
12045 (define_insn "set_got_labelled"
12046   [(set (match_operand:SI 0 "register_operand" "=r")
12047         (unspec:SI [(label_ref (match_operand 1))]
12048          UNSPEC_SET_GOT))
12049    (clobber (reg:CC FLAGS_REG))]
12050   "!TARGET_64BIT"
12051   "* return output_set_got (operands[0], operands[1]);"
12052   [(set_attr "type" "multi")
12053    (set_attr "length" "12")])
12055 (define_insn "set_got_rex64"
12056   [(set (match_operand:DI 0 "register_operand" "=r")
12057         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12058   "TARGET_64BIT"
12059   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12060   [(set_attr "type" "lea")
12061    (set_attr "length_address" "4")
12062    (set_attr "mode" "DI")])
12064 (define_insn "set_rip_rex64"
12065   [(set (match_operand:DI 0 "register_operand" "=r")
12066         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12067   "TARGET_64BIT"
12068   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12069   [(set_attr "type" "lea")
12070    (set_attr "length_address" "4")
12071    (set_attr "mode" "DI")])
12073 (define_insn "set_got_offset_rex64"
12074   [(set (match_operand:DI 0 "register_operand" "=r")
12075         (unspec:DI
12076           [(label_ref (match_operand 1))]
12077           UNSPEC_SET_GOT_OFFSET))]
12078   "TARGET_LP64"
12079   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12080   [(set_attr "type" "imov")
12081    (set_attr "length_immediate" "0")
12082    (set_attr "length_address" "8")
12083    (set_attr "mode" "DI")])
12085 (define_expand "epilogue"
12086   [(const_int 0)]
12087   ""
12088   "ix86_expand_epilogue (1); DONE;")
12090 (define_expand "sibcall_epilogue"
12091   [(const_int 0)]
12092   ""
12093   "ix86_expand_epilogue (0); DONE;")
12095 (define_expand "eh_return"
12096   [(use (match_operand 0 "register_operand"))]
12097   ""
12099   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12101   /* Tricky bit: we write the address of the handler to which we will
12102      be returning into someone else's stack frame, one word below the
12103      stack address we wish to restore.  */
12104   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12105   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12106   tmp = gen_rtx_MEM (Pmode, tmp);
12107   emit_move_insn (tmp, ra);
12109   emit_jump_insn (gen_eh_return_internal ());
12110   emit_barrier ();
12111   DONE;
12114 (define_insn_and_split "eh_return_internal"
12115   [(eh_return)]
12116   ""
12117   "#"
12118   "epilogue_completed"
12119   [(const_int 0)]
12120   "ix86_expand_epilogue (2); DONE;")
12122 (define_insn "leave"
12123   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12124    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12125    (clobber (mem:BLK (scratch)))]
12126   "!TARGET_64BIT"
12127   "leave"
12128   [(set_attr "type" "leave")])
12130 (define_insn "leave_rex64"
12131   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12132    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12133    (clobber (mem:BLK (scratch)))]
12134   "TARGET_64BIT"
12135   "leave"
12136   [(set_attr "type" "leave")])
12138 ;; Handle -fsplit-stack.
12140 (define_expand "split_stack_prologue"
12141   [(const_int 0)]
12142   ""
12144   ix86_expand_split_stack_prologue ();
12145   DONE;
12148 ;; In order to support the call/return predictor, we use a return
12149 ;; instruction which the middle-end doesn't see.
12150 (define_insn "split_stack_return"
12151   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12152                      UNSPECV_SPLIT_STACK_RETURN)]
12153   ""
12155   if (operands[0] == const0_rtx)
12156     return "ret";
12157   else
12158     return "ret\t%0";
12160   [(set_attr "atom_unit" "jeu")
12161    (set_attr "modrm" "0")
12162    (set (attr "length")
12163         (if_then_else (match_operand:SI 0 "const0_operand")
12164                       (const_int 1)
12165                       (const_int 3)))
12166    (set (attr "length_immediate")
12167         (if_then_else (match_operand:SI 0 "const0_operand")
12168                       (const_int 0)
12169                       (const_int 2)))])
12171 ;; If there are operand 0 bytes available on the stack, jump to
12172 ;; operand 1.
12174 (define_expand "split_stack_space_check"
12175   [(set (pc) (if_then_else
12176               (ltu (minus (reg SP_REG)
12177                           (match_operand 0 "register_operand"))
12178                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12179               (label_ref (match_operand 1))
12180               (pc)))]
12181   ""
12183   rtx reg, size, limit;
12185   reg = gen_reg_rtx (Pmode);
12186   size = force_reg (Pmode, operands[0]);
12187   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12188   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12189                           UNSPEC_STACK_CHECK);
12190   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12191   ix86_expand_branch (GEU, reg, limit, operands[1]);
12193   DONE;
12196 ;; Bit manipulation instructions.
12198 (define_expand "ffs<mode>2"
12199   [(set (match_dup 2) (const_int -1))
12200    (parallel [(set (match_dup 3) (match_dup 4))
12201               (set (match_operand:SWI48 0 "register_operand")
12202                    (ctz:SWI48
12203                      (match_operand:SWI48 1 "nonimmediate_operand")))])
12204    (set (match_dup 0) (if_then_else:SWI48
12205                         (eq (match_dup 3) (const_int 0))
12206                         (match_dup 2)
12207                         (match_dup 0)))
12208    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12209               (clobber (reg:CC FLAGS_REG))])]
12210   ""
12212   enum machine_mode flags_mode;
12214   if (<MODE>mode == SImode && !TARGET_CMOVE)
12215     {
12216       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12217       DONE;
12218     }
12220   flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12222   operands[2] = gen_reg_rtx (<MODE>mode);
12223   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12224   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12227 (define_insn_and_split "ffssi2_no_cmove"
12228   [(set (match_operand:SI 0 "register_operand" "=r")
12229         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12230    (clobber (match_scratch:SI 2 "=&q"))
12231    (clobber (reg:CC FLAGS_REG))]
12232   "!TARGET_CMOVE"
12233   "#"
12234   "&& reload_completed"
12235   [(parallel [(set (match_dup 4) (match_dup 5))
12236               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12237    (set (strict_low_part (match_dup 3))
12238         (eq:QI (match_dup 4) (const_int 0)))
12239    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12240               (clobber (reg:CC FLAGS_REG))])
12241    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12242               (clobber (reg:CC FLAGS_REG))])
12243    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12244               (clobber (reg:CC FLAGS_REG))])]
12246   enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12248   operands[3] = gen_lowpart (QImode, operands[2]);
12249   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12250   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12252   ix86_expand_clear (operands[2]);
12255 (define_insn "*tzcnt<mode>_1"
12256   [(set (reg:CCC FLAGS_REG)
12257         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12258                      (const_int 0)))
12259    (set (match_operand:SWI48 0 "register_operand" "=r")
12260         (ctz:SWI48 (match_dup 1)))]
12261   "TARGET_BMI"
12262   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12263   [(set_attr "type" "alu1")
12264    (set_attr "prefix_0f" "1")
12265    (set_attr "prefix_rep" "1")
12266    (set_attr "btver2_decode" "double")
12267    (set_attr "mode" "<MODE>")])
12269 (define_insn "*bsf<mode>_1"
12270   [(set (reg:CCZ FLAGS_REG)
12271         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12272                      (const_int 0)))
12273    (set (match_operand:SWI48 0 "register_operand" "=r")
12274         (ctz:SWI48 (match_dup 1)))]
12275   ""
12276   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12277   [(set_attr "type" "alu1")
12278    (set_attr "prefix_0f" "1")
12279    (set_attr "btver2_decode" "double")
12280    (set_attr "mode" "<MODE>")])
12282 (define_insn "ctz<mode>2"
12283   [(set (match_operand:SWI248 0 "register_operand" "=r")
12284         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12285    (clobber (reg:CC FLAGS_REG))]
12286   ""
12288   if (TARGET_BMI)
12289     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12290   else if (optimize_function_for_size_p (cfun))
12291     ;
12292   else if (TARGET_GENERIC)
12293     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12294     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12296   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12298   [(set_attr "type" "alu1")
12299    (set_attr "prefix_0f" "1")
12300    (set (attr "prefix_rep")
12301      (if_then_else
12302        (ior (match_test "TARGET_BMI")
12303             (and (not (match_test "optimize_function_for_size_p (cfun)"))
12304                  (match_test "TARGET_GENERIC")))
12305        (const_string "1")
12306        (const_string "0")))
12307    (set_attr "mode" "<MODE>")])
12309 (define_expand "clz<mode>2"
12310   [(parallel
12311      [(set (match_operand:SWI248 0 "register_operand")
12312            (minus:SWI248
12313              (match_dup 2)
12314              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12315       (clobber (reg:CC FLAGS_REG))])
12316    (parallel
12317      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12318       (clobber (reg:CC FLAGS_REG))])]
12319   ""
12321   if (TARGET_LZCNT)
12322     {
12323       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12324       DONE;
12325     }
12326   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12329 (define_insn "clz<mode>2_lzcnt"
12330   [(set (match_operand:SWI248 0 "register_operand" "=r")
12331         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12332    (clobber (reg:CC FLAGS_REG))]
12333   "TARGET_LZCNT"
12334   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12335   [(set_attr "prefix_rep" "1")
12336    (set_attr "type" "bitmanip")
12337    (set_attr "mode" "<MODE>")])
12339 ;; BMI instructions.
12340 (define_insn "*bmi_andn_<mode>"
12341   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12342         (and:SWI48
12343           (not:SWI48
12344             (match_operand:SWI48 1 "register_operand" "r,r"))
12345             (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12346    (clobber (reg:CC FLAGS_REG))]
12347   "TARGET_BMI"
12348   "andn\t{%2, %1, %0|%0, %1, %2}"
12349   [(set_attr "type" "bitmanip")
12350    (set_attr "btver2_decode" "direct, double")
12351    (set_attr "mode" "<MODE>")])
12353 (define_insn "bmi_bextr_<mode>"
12354   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12355         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12356                        (match_operand:SWI48 2 "register_operand" "r,r")]
12357                        UNSPEC_BEXTR))
12358    (clobber (reg:CC FLAGS_REG))]
12359   "TARGET_BMI"
12360   "bextr\t{%2, %1, %0|%0, %1, %2}"
12361   [(set_attr "type" "bitmanip")
12362    (set_attr "btver2_decode" "direct, double")
12363    (set_attr "mode" "<MODE>")])
12365 (define_insn "*bmi_blsi_<mode>"
12366   [(set (match_operand:SWI48 0 "register_operand" "=r")
12367         (and:SWI48
12368           (neg:SWI48
12369             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12370           (match_dup 1)))
12371    (clobber (reg:CC FLAGS_REG))]
12372   "TARGET_BMI"
12373   "blsi\t{%1, %0|%0, %1}"
12374   [(set_attr "type" "bitmanip")
12375    (set_attr "btver2_decode" "double")
12376    (set_attr "mode" "<MODE>")])
12378 (define_insn "*bmi_blsmsk_<mode>"
12379   [(set (match_operand:SWI48 0 "register_operand" "=r")
12380         (xor:SWI48
12381           (plus:SWI48
12382             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12383             (const_int -1))
12384           (match_dup 1)))
12385    (clobber (reg:CC FLAGS_REG))]
12386   "TARGET_BMI"
12387   "blsmsk\t{%1, %0|%0, %1}"
12388   [(set_attr "type" "bitmanip")
12389    (set_attr "btver2_decode" "double")
12390    (set_attr "mode" "<MODE>")])
12392 (define_insn "*bmi_blsr_<mode>"
12393   [(set (match_operand:SWI48 0 "register_operand" "=r")
12394         (and:SWI48
12395           (plus:SWI48
12396             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12397             (const_int -1))
12398           (match_dup 1)))
12399    (clobber (reg:CC FLAGS_REG))]
12400    "TARGET_BMI"
12401    "blsr\t{%1, %0|%0, %1}"
12402   [(set_attr "type" "bitmanip")
12403    (set_attr "btver2_decode" "double")
12404    (set_attr "mode" "<MODE>")])
12406 ;; BMI2 instructions.
12407 (define_insn "bmi2_bzhi_<mode>3"
12408   [(set (match_operand:SWI48 0 "register_operand" "=r")
12409         (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12410                                    (match_operand:SWI48 2 "register_operand" "r"))
12411                    (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12412    (clobber (reg:CC FLAGS_REG))]
12413   "TARGET_BMI2"
12414   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12415   [(set_attr "type" "bitmanip")
12416    (set_attr "prefix" "vex")
12417    (set_attr "mode" "<MODE>")])
12419 (define_insn "bmi2_pdep_<mode>3"
12420   [(set (match_operand:SWI48 0 "register_operand" "=r")
12421         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12422                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12423                        UNSPEC_PDEP))]
12424   "TARGET_BMI2"
12425   "pdep\t{%2, %1, %0|%0, %1, %2}"
12426   [(set_attr "type" "bitmanip")
12427    (set_attr "prefix" "vex")
12428    (set_attr "mode" "<MODE>")])
12430 (define_insn "bmi2_pext_<mode>3"
12431   [(set (match_operand:SWI48 0 "register_operand" "=r")
12432         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12433                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12434                        UNSPEC_PEXT))]
12435   "TARGET_BMI2"
12436   "pext\t{%2, %1, %0|%0, %1, %2}"
12437   [(set_attr "type" "bitmanip")
12438    (set_attr "prefix" "vex")
12439    (set_attr "mode" "<MODE>")])
12441 ;; TBM instructions.
12442 (define_insn "tbm_bextri_<mode>"
12443   [(set (match_operand:SWI48 0 "register_operand" "=r")
12444         (zero_extract:SWI48
12445           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12446           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12447           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12448    (clobber (reg:CC FLAGS_REG))]
12449    "TARGET_TBM"
12451   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12452   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12454   [(set_attr "type" "bitmanip")
12455    (set_attr "mode" "<MODE>")])
12457 (define_insn "*tbm_blcfill_<mode>"
12458   [(set (match_operand:SWI48 0 "register_operand" "=r")
12459         (and:SWI48
12460           (plus:SWI48
12461             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12462             (const_int 1))
12463           (match_dup 1)))
12464    (clobber (reg:CC FLAGS_REG))]
12465    "TARGET_TBM"
12466    "blcfill\t{%1, %0|%0, %1}"
12467   [(set_attr "type" "bitmanip")
12468    (set_attr "mode" "<MODE>")])
12470 (define_insn "*tbm_blci_<mode>"
12471   [(set (match_operand:SWI48 0 "register_operand" "=r")
12472         (ior:SWI48
12473           (not: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    "blci\t{%1, %0|%0, %1}"
12481   [(set_attr "type" "bitmanip")
12482    (set_attr "mode" "<MODE>")])
12484 (define_insn "*tbm_blcic_<mode>"
12485   [(set (match_operand:SWI48 0 "register_operand" "=r")
12486         (and:SWI48
12487           (plus:SWI48
12488             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12489             (const_int 1))
12490           (not:SWI48
12491             (match_dup 1))))
12492    (clobber (reg:CC FLAGS_REG))]
12493    "TARGET_TBM"
12494    "blcic\t{%1, %0|%0, %1}"
12495   [(set_attr "type" "bitmanip")
12496    (set_attr "mode" "<MODE>")])
12498 (define_insn "*tbm_blcmsk_<mode>"
12499   [(set (match_operand:SWI48 0 "register_operand" "=r")
12500         (xor:SWI48
12501           (plus:SWI48
12502             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12503             (const_int 1))
12504           (match_dup 1)))
12505    (clobber (reg:CC FLAGS_REG))]
12506    "TARGET_TBM"
12507    "blcmsk\t{%1, %0|%0, %1}"
12508   [(set_attr "type" "bitmanip")
12509    (set_attr "mode" "<MODE>")])
12511 (define_insn "*tbm_blcs_<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           (match_dup 1)))
12518    (clobber (reg:CC FLAGS_REG))]
12519    "TARGET_TBM"
12520    "blcs\t{%1, %0|%0, %1}"
12521   [(set_attr "type" "bitmanip")
12522    (set_attr "mode" "<MODE>")])
12524 (define_insn "*tbm_blsfill_<mode>"
12525   [(set (match_operand:SWI48 0 "register_operand" "=r")
12526         (ior:SWI48
12527           (plus:SWI48
12528             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12529             (const_int -1))
12530           (match_dup 1)))
12531    (clobber (reg:CC FLAGS_REG))]
12532    "TARGET_TBM"
12533    "blsfill\t{%1, %0|%0, %1}"
12534   [(set_attr "type" "bitmanip")
12535    (set_attr "mode" "<MODE>")])
12537 (define_insn "*tbm_blsic_<mode>"
12538   [(set (match_operand:SWI48 0 "register_operand" "=r")
12539         (ior:SWI48
12540           (plus:SWI48
12541             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12542             (const_int -1))
12543           (not:SWI48
12544             (match_dup 1))))
12545    (clobber (reg:CC FLAGS_REG))]
12546    "TARGET_TBM"
12547    "blsic\t{%1, %0|%0, %1}"
12548   [(set_attr "type" "bitmanip")
12549    (set_attr "mode" "<MODE>")])
12551 (define_insn "*tbm_t1mskc_<mode>"
12552   [(set (match_operand:SWI48 0 "register_operand" "=r")
12553         (ior:SWI48
12554           (plus:SWI48
12555             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12556             (const_int 1))
12557           (not:SWI48
12558             (match_dup 1))))
12559    (clobber (reg:CC FLAGS_REG))]
12560    "TARGET_TBM"
12561    "t1mskc\t{%1, %0|%0, %1}"
12562   [(set_attr "type" "bitmanip")
12563    (set_attr "mode" "<MODE>")])
12565 (define_insn "*tbm_tzmsk_<mode>"
12566   [(set (match_operand:SWI48 0 "register_operand" "=r")
12567         (and:SWI48
12568           (plus:SWI48
12569             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12570             (const_int -1))
12571           (not:SWI48
12572             (match_dup 1))))
12573    (clobber (reg:CC FLAGS_REG))]
12574    "TARGET_TBM"
12575    "tzmsk\t{%1, %0|%0, %1}"
12576   [(set_attr "type" "bitmanip")
12577    (set_attr "mode" "<MODE>")])
12579 (define_insn "bsr_rex64"
12580   [(set (match_operand:DI 0 "register_operand" "=r")
12581         (minus:DI (const_int 63)
12582                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12583    (clobber (reg:CC FLAGS_REG))]
12584   "TARGET_64BIT"
12585   "bsr{q}\t{%1, %0|%0, %1}"
12586   [(set_attr "type" "alu1")
12587    (set_attr "prefix_0f" "1")
12588    (set_attr "mode" "DI")])
12590 (define_insn "bsr"
12591   [(set (match_operand:SI 0 "register_operand" "=r")
12592         (minus:SI (const_int 31)
12593                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12594    (clobber (reg:CC FLAGS_REG))]
12595   ""
12596   "bsr{l}\t{%1, %0|%0, %1}"
12597   [(set_attr "type" "alu1")
12598    (set_attr "prefix_0f" "1")
12599    (set_attr "mode" "SI")])
12601 (define_insn "*bsrhi"
12602   [(set (match_operand:HI 0 "register_operand" "=r")
12603         (minus:HI (const_int 15)
12604                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12605    (clobber (reg:CC FLAGS_REG))]
12606   ""
12607   "bsr{w}\t{%1, %0|%0, %1}"
12608   [(set_attr "type" "alu1")
12609    (set_attr "prefix_0f" "1")
12610    (set_attr "mode" "HI")])
12612 (define_insn "popcount<mode>2"
12613   [(set (match_operand:SWI248 0 "register_operand" "=r")
12614         (popcount:SWI248
12615           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12616    (clobber (reg:CC FLAGS_REG))]
12617   "TARGET_POPCNT"
12619 #if TARGET_MACHO
12620   return "popcnt\t{%1, %0|%0, %1}";
12621 #else
12622   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12623 #endif
12625   [(set_attr "prefix_rep" "1")
12626    (set_attr "type" "bitmanip")
12627    (set_attr "mode" "<MODE>")])
12629 (define_insn "*popcount<mode>2_cmp"
12630   [(set (reg FLAGS_REG)
12631         (compare
12632           (popcount:SWI248
12633             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12634           (const_int 0)))
12635    (set (match_operand:SWI248 0 "register_operand" "=r")
12636         (popcount:SWI248 (match_dup 1)))]
12637   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12639 #if TARGET_MACHO
12640   return "popcnt\t{%1, %0|%0, %1}";
12641 #else
12642   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12643 #endif
12645   [(set_attr "prefix_rep" "1")
12646    (set_attr "type" "bitmanip")
12647    (set_attr "mode" "<MODE>")])
12649 (define_insn "*popcountsi2_cmp_zext"
12650   [(set (reg FLAGS_REG)
12651         (compare
12652           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12653           (const_int 0)))
12654    (set (match_operand:DI 0 "register_operand" "=r")
12655         (zero_extend:DI(popcount:SI (match_dup 1))))]
12656   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12658 #if TARGET_MACHO
12659   return "popcnt\t{%1, %0|%0, %1}";
12660 #else
12661   return "popcnt{l}\t{%1, %0|%0, %1}";
12662 #endif
12664   [(set_attr "prefix_rep" "1")
12665    (set_attr "type" "bitmanip")
12666    (set_attr "mode" "SI")])
12668 (define_expand "bswapdi2"
12669   [(set (match_operand:DI 0 "register_operand")
12670         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12671   "TARGET_64BIT"
12673   if (!TARGET_MOVBE)
12674     operands[1] = force_reg (DImode, operands[1]);
12677 (define_expand "bswapsi2"
12678   [(set (match_operand:SI 0 "register_operand")
12679         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12680   ""
12682   if (TARGET_MOVBE)
12683     ;
12684   else if (TARGET_BSWAP)
12685     operands[1] = force_reg (SImode, operands[1]);
12686   else
12687     {
12688       rtx x = operands[0];
12690       emit_move_insn (x, operands[1]);
12691       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12692       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12693       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12694       DONE;
12695     }
12698 (define_insn "*bswap<mode>2_movbe"
12699   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12700         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12701   "TARGET_MOVBE
12702    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12703   "@
12704     bswap\t%0
12705     movbe\t{%1, %0|%0, %1}
12706     movbe\t{%1, %0|%0, %1}"
12707   [(set_attr "type" "bitmanip,imov,imov")
12708    (set_attr "modrm" "0,1,1")
12709    (set_attr "prefix_0f" "*,1,1")
12710    (set_attr "prefix_extra" "*,1,1")
12711    (set_attr "mode" "<MODE>")])
12713 (define_insn "*bswap<mode>2"
12714   [(set (match_operand:SWI48 0 "register_operand" "=r")
12715         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12716   "TARGET_BSWAP"
12717   "bswap\t%0"
12718   [(set_attr "type" "bitmanip")
12719    (set_attr "modrm" "0")
12720    (set_attr "mode" "<MODE>")])
12722 (define_insn "*bswaphi_lowpart_1"
12723   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12724         (bswap:HI (match_dup 0)))
12725    (clobber (reg:CC FLAGS_REG))]
12726   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12727   "@
12728     xchg{b}\t{%h0, %b0|%b0, %h0}
12729     rol{w}\t{$8, %0|%0, 8}"
12730   [(set_attr "length" "2,4")
12731    (set_attr "mode" "QI,HI")])
12733 (define_insn "bswaphi_lowpart"
12734   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12735         (bswap:HI (match_dup 0)))
12736    (clobber (reg:CC FLAGS_REG))]
12737   ""
12738   "rol{w}\t{$8, %0|%0, 8}"
12739   [(set_attr "length" "4")
12740    (set_attr "mode" "HI")])
12742 (define_expand "paritydi2"
12743   [(set (match_operand:DI 0 "register_operand")
12744         (parity:DI (match_operand:DI 1 "register_operand")))]
12745   "! TARGET_POPCNT"
12747   rtx scratch = gen_reg_rtx (QImode);
12748   rtx cond;
12750   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12751                                 NULL_RTX, operands[1]));
12753   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12754                          gen_rtx_REG (CCmode, FLAGS_REG),
12755                          const0_rtx);
12756   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12758   if (TARGET_64BIT)
12759     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12760   else
12761     {
12762       rtx tmp = gen_reg_rtx (SImode);
12764       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12765       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12766     }
12767   DONE;
12770 (define_expand "paritysi2"
12771   [(set (match_operand:SI 0 "register_operand")
12772         (parity:SI (match_operand:SI 1 "register_operand")))]
12773   "! TARGET_POPCNT"
12775   rtx scratch = gen_reg_rtx (QImode);
12776   rtx cond;
12778   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12780   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12781                          gen_rtx_REG (CCmode, FLAGS_REG),
12782                          const0_rtx);
12783   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12785   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12786   DONE;
12789 (define_insn_and_split "paritydi2_cmp"
12790   [(set (reg:CC FLAGS_REG)
12791         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12792                    UNSPEC_PARITY))
12793    (clobber (match_scratch:DI 0 "=r"))
12794    (clobber (match_scratch:SI 1 "=&r"))
12795    (clobber (match_scratch:HI 2 "=Q"))]
12796   "! TARGET_POPCNT"
12797   "#"
12798   "&& reload_completed"
12799   [(parallel
12800      [(set (match_dup 1)
12801            (xor:SI (match_dup 1) (match_dup 4)))
12802       (clobber (reg:CC FLAGS_REG))])
12803    (parallel
12804      [(set (reg:CC FLAGS_REG)
12805            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12806       (clobber (match_dup 1))
12807       (clobber (match_dup 2))])]
12809   operands[4] = gen_lowpart (SImode, operands[3]);
12811   if (TARGET_64BIT)
12812     {
12813       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12814       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12815     }
12816   else
12817     operands[1] = gen_highpart (SImode, operands[3]);
12820 (define_insn_and_split "paritysi2_cmp"
12821   [(set (reg:CC FLAGS_REG)
12822         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12823                    UNSPEC_PARITY))
12824    (clobber (match_scratch:SI 0 "=r"))
12825    (clobber (match_scratch:HI 1 "=&Q"))]
12826   "! TARGET_POPCNT"
12827   "#"
12828   "&& reload_completed"
12829   [(parallel
12830      [(set (match_dup 1)
12831            (xor:HI (match_dup 1) (match_dup 3)))
12832       (clobber (reg:CC FLAGS_REG))])
12833    (parallel
12834      [(set (reg:CC FLAGS_REG)
12835            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12836       (clobber (match_dup 1))])]
12838   operands[3] = gen_lowpart (HImode, operands[2]);
12840   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12841   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12844 (define_insn "*parityhi2_cmp"
12845   [(set (reg:CC FLAGS_REG)
12846         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12847                    UNSPEC_PARITY))
12848    (clobber (match_scratch:HI 0 "=Q"))]
12849   "! TARGET_POPCNT"
12850   "xor{b}\t{%h0, %b0|%b0, %h0}"
12851   [(set_attr "length" "2")
12852    (set_attr "mode" "HI")])
12855 ;; Thread-local storage patterns for ELF.
12857 ;; Note that these code sequences must appear exactly as shown
12858 ;; in order to allow linker relaxation.
12860 (define_insn "*tls_global_dynamic_32_gnu"
12861   [(set (match_operand:SI 0 "register_operand" "=a")
12862         (unspec:SI
12863          [(match_operand:SI 1 "register_operand" "b")
12864           (match_operand 2 "tls_symbolic_operand")
12865           (match_operand 3 "constant_call_address_operand" "z")]
12866          UNSPEC_TLS_GD))
12867    (clobber (match_scratch:SI 4 "=d"))
12868    (clobber (match_scratch:SI 5 "=c"))
12869    (clobber (reg:CC FLAGS_REG))]
12870   "!TARGET_64BIT && TARGET_GNU_TLS"
12872   output_asm_insn
12873     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12874   if (TARGET_SUN_TLS)
12875 #ifdef HAVE_AS_IX86_TLSGDPLT
12876     return "call\t%a2@tlsgdplt";
12877 #else
12878     return "call\t%p3@plt";
12879 #endif
12880   return "call\t%P3";
12882   [(set_attr "type" "multi")
12883    (set_attr "length" "12")])
12885 (define_expand "tls_global_dynamic_32"
12886   [(parallel
12887     [(set (match_operand:SI 0 "register_operand")
12888           (unspec:SI [(match_operand:SI 2 "register_operand")
12889                       (match_operand 1 "tls_symbolic_operand")
12890                       (match_operand 3 "constant_call_address_operand")]
12891                      UNSPEC_TLS_GD))
12892      (clobber (match_scratch:SI 4))
12893      (clobber (match_scratch:SI 5))
12894      (clobber (reg:CC FLAGS_REG))])])
12896 (define_insn "*tls_global_dynamic_64_<mode>"
12897   [(set (match_operand:P 0 "register_operand" "=a")
12898         (call:P
12899          (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12900          (match_operand 3)))
12901    (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12902              UNSPEC_TLS_GD)]
12903   "TARGET_64BIT"
12905   if (!TARGET_X32)
12906     fputs (ASM_BYTE "0x66\n", asm_out_file);
12907   output_asm_insn
12908     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12909   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12910   fputs ("\trex64\n", asm_out_file);
12911   if (TARGET_SUN_TLS)
12912     return "call\t%p2@plt";
12913   return "call\t%P2";
12915   [(set_attr "type" "multi")
12916    (set (attr "length")
12917         (symbol_ref "TARGET_X32 ? 15 : 16"))])
12919 (define_insn "*tls_global_dynamic_64_largepic"
12920   [(set (match_operand:DI 0 "register_operand" "=a")
12921         (call:DI
12922          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
12923                           (match_operand:DI 3 "immediate_operand" "i")))
12924          (match_operand 4)))
12925    (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12926              UNSPEC_TLS_GD)]
12927   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12928    && GET_CODE (operands[3]) == CONST
12929    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
12930    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
12932   output_asm_insn
12933     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12934   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
12935   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
12936   return "call\t{*%%rax|rax}";
12938   [(set_attr "type" "multi")
12939    (set_attr "length" "22")])
12941 (define_expand "tls_global_dynamic_64_<mode>"
12942   [(parallel
12943     [(set (match_operand:P 0 "register_operand")
12944           (call:P
12945            (mem:QI (match_operand 2))
12946            (const_int 0)))
12947      (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12948                UNSPEC_TLS_GD)])]
12949   "TARGET_64BIT")
12951 (define_insn "*tls_local_dynamic_base_32_gnu"
12952   [(set (match_operand:SI 0 "register_operand" "=a")
12953         (unspec:SI
12954          [(match_operand:SI 1 "register_operand" "b")
12955           (match_operand 2 "constant_call_address_operand" "z")]
12956          UNSPEC_TLS_LD_BASE))
12957    (clobber (match_scratch:SI 3 "=d"))
12958    (clobber (match_scratch:SI 4 "=c"))
12959    (clobber (reg:CC FLAGS_REG))]
12960   "!TARGET_64BIT && TARGET_GNU_TLS"
12962   output_asm_insn
12963     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12964   if (TARGET_SUN_TLS)
12965     {
12966       if (HAVE_AS_IX86_TLSLDMPLT)
12967         return "call\t%&@tlsldmplt";
12968       else
12969         return "call\t%p2@plt";
12970     }
12971   return "call\t%P2";
12973   [(set_attr "type" "multi")
12974    (set_attr "length" "11")])
12976 (define_expand "tls_local_dynamic_base_32"
12977   [(parallel
12978      [(set (match_operand:SI 0 "register_operand")
12979            (unspec:SI
12980             [(match_operand:SI 1 "register_operand")
12981              (match_operand 2 "constant_call_address_operand")]
12982             UNSPEC_TLS_LD_BASE))
12983       (clobber (match_scratch:SI 3))
12984       (clobber (match_scratch:SI 4))
12985       (clobber (reg:CC FLAGS_REG))])])
12987 (define_insn "*tls_local_dynamic_base_64_<mode>"
12988   [(set (match_operand:P 0 "register_operand" "=a")
12989         (call:P
12990          (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12991          (match_operand 2)))
12992    (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12993   "TARGET_64BIT"
12995   output_asm_insn
12996     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12997   if (TARGET_SUN_TLS)
12998     return "call\t%p1@plt";
12999   return "call\t%P1";
13001   [(set_attr "type" "multi")
13002    (set_attr "length" "12")])
13004 (define_insn "*tls_local_dynamic_base_64_largepic"
13005   [(set (match_operand:DI 0 "register_operand" "=a")
13006         (call:DI
13007          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13008                           (match_operand:DI 2 "immediate_operand" "i")))
13009          (match_operand 3)))
13010    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13011   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13012    && GET_CODE (operands[2]) == CONST
13013    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13014    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13016   output_asm_insn
13017     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13018   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13019   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13020   return "call\t{*%%rax|rax}";
13022   [(set_attr "type" "multi")
13023    (set_attr "length" "22")])
13025 (define_expand "tls_local_dynamic_base_64_<mode>"
13026   [(parallel
13027      [(set (match_operand:P 0 "register_operand")
13028            (call:P
13029             (mem:QI (match_operand 1))
13030             (const_int 0)))
13031       (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13032   "TARGET_64BIT")
13034 ;; Local dynamic of a single variable is a lose.  Show combine how
13035 ;; to convert that back to global dynamic.
13037 (define_insn_and_split "*tls_local_dynamic_32_once"
13038   [(set (match_operand:SI 0 "register_operand" "=a")
13039         (plus:SI
13040          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13041                      (match_operand 2 "constant_call_address_operand" "z")]
13042                     UNSPEC_TLS_LD_BASE)
13043          (const:SI (unspec:SI
13044                     [(match_operand 3 "tls_symbolic_operand")]
13045                     UNSPEC_DTPOFF))))
13046    (clobber (match_scratch:SI 4 "=d"))
13047    (clobber (match_scratch:SI 5 "=c"))
13048    (clobber (reg:CC FLAGS_REG))]
13049   ""
13050   "#"
13051   ""
13052   [(parallel
13053      [(set (match_dup 0)
13054            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13055                       UNSPEC_TLS_GD))
13056       (clobber (match_dup 4))
13057       (clobber (match_dup 5))
13058       (clobber (reg:CC FLAGS_REG))])])
13060 ;; Segment register for the thread base ptr load
13061 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13063 ;; Load and add the thread base pointer from %<tp_seg>:0.
13064 (define_insn "*load_tp_x32"
13065   [(set (match_operand:SI 0 "register_operand" "=r")
13066         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13067   "TARGET_X32"
13068   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13069   [(set_attr "type" "imov")
13070    (set_attr "modrm" "0")
13071    (set_attr "length" "7")
13072    (set_attr "memory" "load")
13073    (set_attr "imm_disp" "false")])
13075 (define_insn "*load_tp_x32_zext"
13076   [(set (match_operand:DI 0 "register_operand" "=r")
13077         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13078   "TARGET_X32"
13079   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13080   [(set_attr "type" "imov")
13081    (set_attr "modrm" "0")
13082    (set_attr "length" "7")
13083    (set_attr "memory" "load")
13084    (set_attr "imm_disp" "false")])
13086 (define_insn "*load_tp_<mode>"
13087   [(set (match_operand:P 0 "register_operand" "=r")
13088         (unspec:P [(const_int 0)] UNSPEC_TP))]
13089   "!TARGET_X32"
13090   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13091   [(set_attr "type" "imov")
13092    (set_attr "modrm" "0")
13093    (set_attr "length" "7")
13094    (set_attr "memory" "load")
13095    (set_attr "imm_disp" "false")])
13097 (define_insn "*add_tp_x32"
13098   [(set (match_operand:SI 0 "register_operand" "=r")
13099         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13100                  (match_operand:SI 1 "register_operand" "0")))
13101    (clobber (reg:CC FLAGS_REG))]
13102   "TARGET_X32"
13103   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13104   [(set_attr "type" "alu")
13105    (set_attr "modrm" "0")
13106    (set_attr "length" "7")
13107    (set_attr "memory" "load")
13108    (set_attr "imm_disp" "false")])
13110 (define_insn "*add_tp_x32_zext"
13111   [(set (match_operand:DI 0 "register_operand" "=r")
13112         (zero_extend:DI
13113           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13114                    (match_operand:SI 1 "register_operand" "0"))))
13115    (clobber (reg:CC FLAGS_REG))]
13116   "TARGET_X32"
13117   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13118   [(set_attr "type" "alu")
13119    (set_attr "modrm" "0")
13120    (set_attr "length" "7")
13121    (set_attr "memory" "load")
13122    (set_attr "imm_disp" "false")])
13124 (define_insn "*add_tp_<mode>"
13125   [(set (match_operand:P 0 "register_operand" "=r")
13126         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13127                 (match_operand:P 1 "register_operand" "0")))
13128    (clobber (reg:CC FLAGS_REG))]
13129   "!TARGET_X32"
13130   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13131   [(set_attr "type" "alu")
13132    (set_attr "modrm" "0")
13133    (set_attr "length" "7")
13134    (set_attr "memory" "load")
13135    (set_attr "imm_disp" "false")])
13137 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13138 ;; %rax as destination of the initial executable code sequence.
13139 (define_insn "tls_initial_exec_64_sun"
13140   [(set (match_operand:DI 0 "register_operand" "=a")
13141         (unspec:DI
13142          [(match_operand 1 "tls_symbolic_operand")]
13143          UNSPEC_TLS_IE_SUN))
13144    (clobber (reg:CC FLAGS_REG))]
13145   "TARGET_64BIT && TARGET_SUN_TLS"
13147   output_asm_insn
13148     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13149   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13151   [(set_attr "type" "multi")])
13153 ;; GNU2 TLS patterns can be split.
13155 (define_expand "tls_dynamic_gnu2_32"
13156   [(set (match_dup 3)
13157         (plus:SI (match_operand:SI 2 "register_operand")
13158                  (const:SI
13159                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13160                              UNSPEC_TLSDESC))))
13161    (parallel
13162     [(set (match_operand:SI 0 "register_operand")
13163           (unspec:SI [(match_dup 1) (match_dup 3)
13164                       (match_dup 2) (reg:SI SP_REG)]
13165                       UNSPEC_TLSDESC))
13166      (clobber (reg:CC FLAGS_REG))])]
13167   "!TARGET_64BIT && TARGET_GNU2_TLS"
13169   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13170   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13173 (define_insn "*tls_dynamic_gnu2_lea_32"
13174   [(set (match_operand:SI 0 "register_operand" "=r")
13175         (plus:SI (match_operand:SI 1 "register_operand" "b")
13176                  (const:SI
13177                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13178                               UNSPEC_TLSDESC))))]
13179   "!TARGET_64BIT && TARGET_GNU2_TLS"
13180   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13181   [(set_attr "type" "lea")
13182    (set_attr "mode" "SI")
13183    (set_attr "length" "6")
13184    (set_attr "length_address" "4")])
13186 (define_insn "*tls_dynamic_gnu2_call_32"
13187   [(set (match_operand:SI 0 "register_operand" "=a")
13188         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13189                     (match_operand:SI 2 "register_operand" "0")
13190                     ;; we have to make sure %ebx still points to the GOT
13191                     (match_operand:SI 3 "register_operand" "b")
13192                     (reg:SI SP_REG)]
13193                    UNSPEC_TLSDESC))
13194    (clobber (reg:CC FLAGS_REG))]
13195   "!TARGET_64BIT && TARGET_GNU2_TLS"
13196   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13197   [(set_attr "type" "call")
13198    (set_attr "length" "2")
13199    (set_attr "length_address" "0")])
13201 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13202   [(set (match_operand:SI 0 "register_operand" "=&a")
13203         (plus:SI
13204          (unspec:SI [(match_operand 3 "tls_modbase_operand")
13205                      (match_operand:SI 4)
13206                      (match_operand:SI 2 "register_operand" "b")
13207                      (reg:SI SP_REG)]
13208                     UNSPEC_TLSDESC)
13209          (const:SI (unspec:SI
13210                     [(match_operand 1 "tls_symbolic_operand")]
13211                     UNSPEC_DTPOFF))))
13212    (clobber (reg:CC FLAGS_REG))]
13213   "!TARGET_64BIT && TARGET_GNU2_TLS"
13214   "#"
13215   ""
13216   [(set (match_dup 0) (match_dup 5))]
13218   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13219   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13222 (define_expand "tls_dynamic_gnu2_64"
13223   [(set (match_dup 2)
13224         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13225                    UNSPEC_TLSDESC))
13226    (parallel
13227     [(set (match_operand:DI 0 "register_operand")
13228           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13229                      UNSPEC_TLSDESC))
13230      (clobber (reg:CC FLAGS_REG))])]
13231   "TARGET_64BIT && TARGET_GNU2_TLS"
13233   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13234   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13237 (define_insn "*tls_dynamic_gnu2_lea_64"
13238   [(set (match_operand:DI 0 "register_operand" "=r")
13239         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13240                    UNSPEC_TLSDESC))]
13241   "TARGET_64BIT && TARGET_GNU2_TLS"
13242   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13243   [(set_attr "type" "lea")
13244    (set_attr "mode" "DI")
13245    (set_attr "length" "7")
13246    (set_attr "length_address" "4")])
13248 (define_insn "*tls_dynamic_gnu2_call_64"
13249   [(set (match_operand:DI 0 "register_operand" "=a")
13250         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13251                     (match_operand:DI 2 "register_operand" "0")
13252                     (reg:DI SP_REG)]
13253                    UNSPEC_TLSDESC))
13254    (clobber (reg:CC FLAGS_REG))]
13255   "TARGET_64BIT && TARGET_GNU2_TLS"
13256   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13257   [(set_attr "type" "call")
13258    (set_attr "length" "2")
13259    (set_attr "length_address" "0")])
13261 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13262   [(set (match_operand:DI 0 "register_operand" "=&a")
13263         (plus:DI
13264          (unspec:DI [(match_operand 2 "tls_modbase_operand")
13265                      (match_operand:DI 3)
13266                      (reg:DI SP_REG)]
13267                     UNSPEC_TLSDESC)
13268          (const:DI (unspec:DI
13269                     [(match_operand 1 "tls_symbolic_operand")]
13270                     UNSPEC_DTPOFF))))
13271    (clobber (reg:CC FLAGS_REG))]
13272   "TARGET_64BIT && TARGET_GNU2_TLS"
13273   "#"
13274   ""
13275   [(set (match_dup 0) (match_dup 4))]
13277   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13278   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13281 ;; These patterns match the binary 387 instructions for addM3, subM3,
13282 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13283 ;; SFmode.  The first is the normal insn, the second the same insn but
13284 ;; with one operand a conversion, and the third the same insn but with
13285 ;; the other operand a conversion.  The conversion may be SFmode or
13286 ;; SImode if the target mode DFmode, but only SImode if the target mode
13287 ;; is SFmode.
13289 ;; Gcc is slightly more smart about handling normal two address instructions
13290 ;; so use special patterns for add and mull.
13292 (define_insn "*fop_<mode>_comm_mixed"
13293   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13294         (match_operator:MODEF 3 "binary_fp_operator"
13295           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13296            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13297   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13298    && COMMUTATIVE_ARITH_P (operands[3])
13299    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13300   "* return output_387_binary_op (insn, operands);"
13301   [(set (attr "type")
13302         (if_then_else (eq_attr "alternative" "1,2")
13303            (if_then_else (match_operand:MODEF 3 "mult_operator")
13304               (const_string "ssemul")
13305               (const_string "sseadd"))
13306            (if_then_else (match_operand:MODEF 3 "mult_operator")
13307               (const_string "fmul")
13308               (const_string "fop"))))
13309    (set_attr "isa" "*,noavx,avx")
13310    (set_attr "prefix" "orig,orig,vex")
13311    (set_attr "mode" "<MODE>")])
13313 (define_insn "*fop_<mode>_comm_sse"
13314   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13315         (match_operator:MODEF 3 "binary_fp_operator"
13316           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13317            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13318   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13319    && COMMUTATIVE_ARITH_P (operands[3])
13320    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13321   "* return output_387_binary_op (insn, operands);"
13322   [(set (attr "type")
13323         (if_then_else (match_operand:MODEF 3 "mult_operator")
13324            (const_string "ssemul")
13325            (const_string "sseadd")))
13326    (set_attr "isa" "noavx,avx")
13327    (set_attr "prefix" "orig,vex")
13328    (set_attr "mode" "<MODE>")])
13330 (define_insn "*fop_<mode>_comm_i387"
13331   [(set (match_operand:MODEF 0 "register_operand" "=f")
13332         (match_operator:MODEF 3 "binary_fp_operator"
13333           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13334            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13335   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13336    && COMMUTATIVE_ARITH_P (operands[3])
13337    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13338   "* return output_387_binary_op (insn, operands);"
13339   [(set (attr "type")
13340         (if_then_else (match_operand:MODEF 3 "mult_operator")
13341            (const_string "fmul")
13342            (const_string "fop")))
13343    (set_attr "mode" "<MODE>")])
13345 (define_insn "*fop_<mode>_1_mixed"
13346   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13347         (match_operator:MODEF 3 "binary_fp_operator"
13348           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13349            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13350   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13351    && !COMMUTATIVE_ARITH_P (operands[3])
13352    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13353   "* return output_387_binary_op (insn, operands);"
13354   [(set (attr "type")
13355         (cond [(and (eq_attr "alternative" "2,3")
13356                     (match_operand:MODEF 3 "mult_operator"))
13357                  (const_string "ssemul")
13358                (and (eq_attr "alternative" "2,3")
13359                     (match_operand:MODEF 3 "div_operator"))
13360                  (const_string "ssediv")
13361                (eq_attr "alternative" "2,3")
13362                  (const_string "sseadd")
13363                (match_operand:MODEF 3 "mult_operator")
13364                  (const_string "fmul")
13365                (match_operand:MODEF 3 "div_operator")
13366                  (const_string "fdiv")
13367               ]
13368               (const_string "fop")))
13369    (set_attr "isa" "*,*,noavx,avx")
13370    (set_attr "prefix" "orig,orig,orig,vex")
13371    (set_attr "mode" "<MODE>")])
13373 (define_insn "*rcpsf2_sse"
13374   [(set (match_operand:SF 0 "register_operand" "=x")
13375         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13376                    UNSPEC_RCP))]
13377   "TARGET_SSE_MATH"
13378   "%vrcpss\t{%1, %d0|%d0, %1}"
13379   [(set_attr "type" "sse")
13380    (set_attr "atom_sse_attr" "rcp")
13381    (set_attr "btver2_sse_attr" "rcp")
13382    (set_attr "prefix" "maybe_vex")
13383    (set_attr "mode" "SF")])
13385 (define_insn "*fop_<mode>_1_sse"
13386   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13387         (match_operator:MODEF 3 "binary_fp_operator"
13388           [(match_operand:MODEF 1 "register_operand" "0,x")
13389            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13390   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13391    && !COMMUTATIVE_ARITH_P (operands[3])"
13392   "* return output_387_binary_op (insn, operands);"
13393   [(set (attr "type")
13394         (cond [(match_operand:MODEF 3 "mult_operator")
13395                  (const_string "ssemul")
13396                (match_operand:MODEF 3 "div_operator")
13397                  (const_string "ssediv")
13398               ]
13399               (const_string "sseadd")))
13400    (set_attr "isa" "noavx,avx")
13401    (set_attr "prefix" "orig,vex")
13402    (set_attr "mode" "<MODE>")])
13404 ;; This pattern is not fully shadowed by the pattern above.
13405 (define_insn "*fop_<mode>_1_i387"
13406   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13407         (match_operator:MODEF 3 "binary_fp_operator"
13408           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13409            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13410   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13411    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13412    && !COMMUTATIVE_ARITH_P (operands[3])
13413    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13414   "* return output_387_binary_op (insn, operands);"
13415   [(set (attr "type")
13416         (cond [(match_operand:MODEF 3 "mult_operator")
13417                  (const_string "fmul")
13418                (match_operand:MODEF 3 "div_operator")
13419                  (const_string "fdiv")
13420               ]
13421               (const_string "fop")))
13422    (set_attr "mode" "<MODE>")])
13424 ;; ??? Add SSE splitters for these!
13425 (define_insn "*fop_<MODEF:mode>_2_i387"
13426   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13427         (match_operator:MODEF 3 "binary_fp_operator"
13428           [(float:MODEF
13429              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13430            (match_operand:MODEF 2 "register_operand" "0,0")]))]
13431   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13432    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13433    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13434   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13435   [(set (attr "type")
13436         (cond [(match_operand:MODEF 3 "mult_operator")
13437                  (const_string "fmul")
13438                (match_operand:MODEF 3 "div_operator")
13439                  (const_string "fdiv")
13440               ]
13441               (const_string "fop")))
13442    (set_attr "fp_int_src" "true")
13443    (set_attr "mode" "<SWI24:MODE>")])
13445 (define_insn "*fop_<MODEF:mode>_3_i387"
13446   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13447         (match_operator:MODEF 3 "binary_fp_operator"
13448           [(match_operand:MODEF 1 "register_operand" "0,0")
13449            (float:MODEF
13450              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13451   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13452    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13453    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13454   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13455   [(set (attr "type")
13456         (cond [(match_operand:MODEF 3 "mult_operator")
13457                  (const_string "fmul")
13458                (match_operand:MODEF 3 "div_operator")
13459                  (const_string "fdiv")
13460               ]
13461               (const_string "fop")))
13462    (set_attr "fp_int_src" "true")
13463    (set_attr "mode" "<MODE>")])
13465 (define_insn "*fop_df_4_i387"
13466   [(set (match_operand:DF 0 "register_operand" "=f,f")
13467         (match_operator:DF 3 "binary_fp_operator"
13468            [(float_extend:DF
13469              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13470             (match_operand:DF 2 "register_operand" "0,f")]))]
13471   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13472    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13473    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13474   "* return output_387_binary_op (insn, operands);"
13475   [(set (attr "type")
13476         (cond [(match_operand:DF 3 "mult_operator")
13477                  (const_string "fmul")
13478                (match_operand:DF 3 "div_operator")
13479                  (const_string "fdiv")
13480               ]
13481               (const_string "fop")))
13482    (set_attr "mode" "SF")])
13484 (define_insn "*fop_df_5_i387"
13485   [(set (match_operand:DF 0 "register_operand" "=f,f")
13486         (match_operator:DF 3 "binary_fp_operator"
13487           [(match_operand:DF 1 "register_operand" "0,f")
13488            (float_extend:DF
13489             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13490   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13491    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13492   "* return output_387_binary_op (insn, operands);"
13493   [(set (attr "type")
13494         (cond [(match_operand:DF 3 "mult_operator")
13495                  (const_string "fmul")
13496                (match_operand:DF 3 "div_operator")
13497                  (const_string "fdiv")
13498               ]
13499               (const_string "fop")))
13500    (set_attr "mode" "SF")])
13502 (define_insn "*fop_df_6_i387"
13503   [(set (match_operand:DF 0 "register_operand" "=f,f")
13504         (match_operator:DF 3 "binary_fp_operator"
13505           [(float_extend:DF
13506             (match_operand:SF 1 "register_operand" "0,f"))
13507            (float_extend:DF
13508             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13509   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13510    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13511   "* return output_387_binary_op (insn, operands);"
13512   [(set (attr "type")
13513         (cond [(match_operand:DF 3 "mult_operator")
13514                  (const_string "fmul")
13515                (match_operand:DF 3 "div_operator")
13516                  (const_string "fdiv")
13517               ]
13518               (const_string "fop")))
13519    (set_attr "mode" "SF")])
13521 (define_insn "*fop_xf_comm_i387"
13522   [(set (match_operand:XF 0 "register_operand" "=f")
13523         (match_operator:XF 3 "binary_fp_operator"
13524                         [(match_operand:XF 1 "register_operand" "%0")
13525                          (match_operand:XF 2 "register_operand" "f")]))]
13526   "TARGET_80387
13527    && COMMUTATIVE_ARITH_P (operands[3])"
13528   "* return output_387_binary_op (insn, operands);"
13529   [(set (attr "type")
13530         (if_then_else (match_operand:XF 3 "mult_operator")
13531            (const_string "fmul")
13532            (const_string "fop")))
13533    (set_attr "mode" "XF")])
13535 (define_insn "*fop_xf_1_i387"
13536   [(set (match_operand:XF 0 "register_operand" "=f,f")
13537         (match_operator:XF 3 "binary_fp_operator"
13538                         [(match_operand:XF 1 "register_operand" "0,f")
13539                          (match_operand:XF 2 "register_operand" "f,0")]))]
13540   "TARGET_80387
13541    && !COMMUTATIVE_ARITH_P (operands[3])"
13542   "* return output_387_binary_op (insn, operands);"
13543   [(set (attr "type")
13544         (cond [(match_operand:XF 3 "mult_operator")
13545                  (const_string "fmul")
13546                (match_operand:XF 3 "div_operator")
13547                  (const_string "fdiv")
13548               ]
13549               (const_string "fop")))
13550    (set_attr "mode" "XF")])
13552 (define_insn "*fop_xf_2_i387"
13553   [(set (match_operand:XF 0 "register_operand" "=f,f")
13554         (match_operator:XF 3 "binary_fp_operator"
13555           [(float:XF
13556              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13557            (match_operand:XF 2 "register_operand" "0,0")]))]
13558   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13559   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13560   [(set (attr "type")
13561         (cond [(match_operand:XF 3 "mult_operator")
13562                  (const_string "fmul")
13563                (match_operand:XF 3 "div_operator")
13564                  (const_string "fdiv")
13565               ]
13566               (const_string "fop")))
13567    (set_attr "fp_int_src" "true")
13568    (set_attr "mode" "<MODE>")])
13570 (define_insn "*fop_xf_3_i387"
13571   [(set (match_operand:XF 0 "register_operand" "=f,f")
13572         (match_operator:XF 3 "binary_fp_operator"
13573           [(match_operand:XF 1 "register_operand" "0,0")
13574            (float:XF
13575              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13576   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13577   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13578   [(set (attr "type")
13579         (cond [(match_operand:XF 3 "mult_operator")
13580                  (const_string "fmul")
13581                (match_operand:XF 3 "div_operator")
13582                  (const_string "fdiv")
13583               ]
13584               (const_string "fop")))
13585    (set_attr "fp_int_src" "true")
13586    (set_attr "mode" "<MODE>")])
13588 (define_insn "*fop_xf_4_i387"
13589   [(set (match_operand:XF 0 "register_operand" "=f,f")
13590         (match_operator:XF 3 "binary_fp_operator"
13591            [(float_extend:XF
13592               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13593             (match_operand:XF 2 "register_operand" "0,f")]))]
13594   "TARGET_80387"
13595   "* return output_387_binary_op (insn, operands);"
13596   [(set (attr "type")
13597         (cond [(match_operand:XF 3 "mult_operator")
13598                  (const_string "fmul")
13599                (match_operand:XF 3 "div_operator")
13600                  (const_string "fdiv")
13601               ]
13602               (const_string "fop")))
13603    (set_attr "mode" "<MODE>")])
13605 (define_insn "*fop_xf_5_i387"
13606   [(set (match_operand:XF 0 "register_operand" "=f,f")
13607         (match_operator:XF 3 "binary_fp_operator"
13608           [(match_operand:XF 1 "register_operand" "0,f")
13609            (float_extend:XF
13610              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13611   "TARGET_80387"
13612   "* return output_387_binary_op (insn, operands);"
13613   [(set (attr "type")
13614         (cond [(match_operand:XF 3 "mult_operator")
13615                  (const_string "fmul")
13616                (match_operand:XF 3 "div_operator")
13617                  (const_string "fdiv")
13618               ]
13619               (const_string "fop")))
13620    (set_attr "mode" "<MODE>")])
13622 (define_insn "*fop_xf_6_i387"
13623   [(set (match_operand:XF 0 "register_operand" "=f,f")
13624         (match_operator:XF 3 "binary_fp_operator"
13625           [(float_extend:XF
13626              (match_operand:MODEF 1 "register_operand" "0,f"))
13627            (float_extend:XF
13628              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13629   "TARGET_80387"
13630   "* return output_387_binary_op (insn, operands);"
13631   [(set (attr "type")
13632         (cond [(match_operand:XF 3 "mult_operator")
13633                  (const_string "fmul")
13634                (match_operand:XF 3 "div_operator")
13635                  (const_string "fdiv")
13636               ]
13637               (const_string "fop")))
13638    (set_attr "mode" "<MODE>")])
13640 (define_split
13641   [(set (match_operand 0 "register_operand")
13642         (match_operator 3 "binary_fp_operator"
13643            [(float (match_operand:SWI24 1 "register_operand"))
13644             (match_operand 2 "register_operand")]))]
13645   "reload_completed
13646    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13647    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13648   [(const_int 0)]
13650   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13651   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13652   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13653                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13654                                           GET_MODE (operands[3]),
13655                                           operands[4],
13656                                           operands[2])));
13657   ix86_free_from_memory (GET_MODE (operands[1]));
13658   DONE;
13661 (define_split
13662   [(set (match_operand 0 "register_operand")
13663         (match_operator 3 "binary_fp_operator"
13664            [(match_operand 1 "register_operand")
13665             (float (match_operand:SWI24 2 "register_operand"))]))]
13666   "reload_completed
13667    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13668    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13669   [(const_int 0)]
13671   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13672   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13673   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13674                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13675                                           GET_MODE (operands[3]),
13676                                           operands[1],
13677                                           operands[4])));
13678   ix86_free_from_memory (GET_MODE (operands[2]));
13679   DONE;
13682 ;; FPU special functions.
13684 ;; This pattern implements a no-op XFmode truncation for
13685 ;; all fancy i386 XFmode math functions.
13687 (define_insn "truncxf<mode>2_i387_noop_unspec"
13688   [(set (match_operand:MODEF 0 "register_operand" "=f")
13689         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13690         UNSPEC_TRUNC_NOOP))]
13691   "TARGET_USE_FANCY_MATH_387"
13692   "* return output_387_reg_move (insn, operands);"
13693   [(set_attr "type" "fmov")
13694    (set_attr "mode" "<MODE>")])
13696 (define_insn "sqrtxf2"
13697   [(set (match_operand:XF 0 "register_operand" "=f")
13698         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13699   "TARGET_USE_FANCY_MATH_387"
13700   "fsqrt"
13701   [(set_attr "type" "fpspc")
13702    (set_attr "mode" "XF")
13703    (set_attr "athlon_decode" "direct")
13704    (set_attr "amdfam10_decode" "direct")
13705    (set_attr "bdver1_decode" "direct")])
13707 (define_insn "sqrt_extend<mode>xf2_i387"
13708   [(set (match_operand:XF 0 "register_operand" "=f")
13709         (sqrt:XF
13710           (float_extend:XF
13711             (match_operand:MODEF 1 "register_operand" "0"))))]
13712   "TARGET_USE_FANCY_MATH_387"
13713   "fsqrt"
13714   [(set_attr "type" "fpspc")
13715    (set_attr "mode" "XF")
13716    (set_attr "athlon_decode" "direct")
13717    (set_attr "amdfam10_decode" "direct")
13718    (set_attr "bdver1_decode" "direct")])
13720 (define_insn "*rsqrtsf2_sse"
13721   [(set (match_operand:SF 0 "register_operand" "=x")
13722         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13723                    UNSPEC_RSQRT))]
13724   "TARGET_SSE_MATH"
13725   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13726   [(set_attr "type" "sse")
13727    (set_attr "atom_sse_attr" "rcp")
13728    (set_attr "btver2_sse_attr" "rcp")
13729    (set_attr "prefix" "maybe_vex")
13730    (set_attr "mode" "SF")])
13732 (define_expand "rsqrtsf2"
13733   [(set (match_operand:SF 0 "register_operand")
13734         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13735                    UNSPEC_RSQRT))]
13736   "TARGET_SSE_MATH"
13738   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13739   DONE;
13742 (define_insn "*sqrt<mode>2_sse"
13743   [(set (match_operand:MODEF 0 "register_operand" "=x")
13744         (sqrt:MODEF
13745           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13746   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13747   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13748   [(set_attr "type" "sse")
13749    (set_attr "atom_sse_attr" "sqrt")
13750    (set_attr "btver2_sse_attr" "sqrt")
13751    (set_attr "prefix" "maybe_vex")
13752    (set_attr "mode" "<MODE>")
13753    (set_attr "athlon_decode" "*")
13754    (set_attr "amdfam10_decode" "*")
13755    (set_attr "bdver1_decode" "*")])
13757 (define_expand "sqrt<mode>2"
13758   [(set (match_operand:MODEF 0 "register_operand")
13759         (sqrt:MODEF
13760           (match_operand:MODEF 1 "nonimmediate_operand")))]
13761   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13762    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13764   if (<MODE>mode == SFmode
13765       && TARGET_SSE_MATH
13766       && TARGET_RECIP_SQRT
13767       && !optimize_function_for_size_p (cfun)
13768       && flag_finite_math_only && !flag_trapping_math
13769       && flag_unsafe_math_optimizations)
13770     {
13771       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13772       DONE;
13773     }
13775   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13776     {
13777       rtx op0 = gen_reg_rtx (XFmode);
13778       rtx op1 = force_reg (<MODE>mode, operands[1]);
13780       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13781       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13782       DONE;
13783    }
13786 (define_insn "fpremxf4_i387"
13787   [(set (match_operand:XF 0 "register_operand" "=f")
13788         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13789                     (match_operand:XF 3 "register_operand" "1")]
13790                    UNSPEC_FPREM_F))
13791    (set (match_operand:XF 1 "register_operand" "=u")
13792         (unspec:XF [(match_dup 2) (match_dup 3)]
13793                    UNSPEC_FPREM_U))
13794    (set (reg:CCFP FPSR_REG)
13795         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13796                      UNSPEC_C2_FLAG))]
13797   "TARGET_USE_FANCY_MATH_387"
13798   "fprem"
13799   [(set_attr "type" "fpspc")
13800    (set_attr "mode" "XF")])
13802 (define_expand "fmodxf3"
13803   [(use (match_operand:XF 0 "register_operand"))
13804    (use (match_operand:XF 1 "general_operand"))
13805    (use (match_operand:XF 2 "general_operand"))]
13806   "TARGET_USE_FANCY_MATH_387"
13808   rtx label = gen_label_rtx ();
13810   rtx op1 = gen_reg_rtx (XFmode);
13811   rtx op2 = gen_reg_rtx (XFmode);
13813   emit_move_insn (op2, operands[2]);
13814   emit_move_insn (op1, operands[1]);
13816   emit_label (label);
13817   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13818   ix86_emit_fp_unordered_jump (label);
13819   LABEL_NUSES (label) = 1;
13821   emit_move_insn (operands[0], op1);
13822   DONE;
13825 (define_expand "fmod<mode>3"
13826   [(use (match_operand:MODEF 0 "register_operand"))
13827    (use (match_operand:MODEF 1 "general_operand"))
13828    (use (match_operand:MODEF 2 "general_operand"))]
13829   "TARGET_USE_FANCY_MATH_387"
13831   rtx (*gen_truncxf) (rtx, rtx);
13833   rtx label = gen_label_rtx ();
13835   rtx op1 = gen_reg_rtx (XFmode);
13836   rtx op2 = gen_reg_rtx (XFmode);
13838   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13839   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13841   emit_label (label);
13842   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13843   ix86_emit_fp_unordered_jump (label);
13844   LABEL_NUSES (label) = 1;
13846   /* Truncate the result properly for strict SSE math.  */
13847   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13848       && !TARGET_MIX_SSE_I387)
13849     gen_truncxf = gen_truncxf<mode>2;
13850   else
13851     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13853   emit_insn (gen_truncxf (operands[0], op1));
13854   DONE;
13857 (define_insn "fprem1xf4_i387"
13858   [(set (match_operand:XF 0 "register_operand" "=f")
13859         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13860                     (match_operand:XF 3 "register_operand" "1")]
13861                    UNSPEC_FPREM1_F))
13862    (set (match_operand:XF 1 "register_operand" "=u")
13863         (unspec:XF [(match_dup 2) (match_dup 3)]
13864                    UNSPEC_FPREM1_U))
13865    (set (reg:CCFP FPSR_REG)
13866         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13867                      UNSPEC_C2_FLAG))]
13868   "TARGET_USE_FANCY_MATH_387"
13869   "fprem1"
13870   [(set_attr "type" "fpspc")
13871    (set_attr "mode" "XF")])
13873 (define_expand "remainderxf3"
13874   [(use (match_operand:XF 0 "register_operand"))
13875    (use (match_operand:XF 1 "general_operand"))
13876    (use (match_operand:XF 2 "general_operand"))]
13877   "TARGET_USE_FANCY_MATH_387"
13879   rtx label = gen_label_rtx ();
13881   rtx op1 = gen_reg_rtx (XFmode);
13882   rtx op2 = gen_reg_rtx (XFmode);
13884   emit_move_insn (op2, operands[2]);
13885   emit_move_insn (op1, operands[1]);
13887   emit_label (label);
13888   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13889   ix86_emit_fp_unordered_jump (label);
13890   LABEL_NUSES (label) = 1;
13892   emit_move_insn (operands[0], op1);
13893   DONE;
13896 (define_expand "remainder<mode>3"
13897   [(use (match_operand:MODEF 0 "register_operand"))
13898    (use (match_operand:MODEF 1 "general_operand"))
13899    (use (match_operand:MODEF 2 "general_operand"))]
13900   "TARGET_USE_FANCY_MATH_387"
13902   rtx (*gen_truncxf) (rtx, rtx);
13904   rtx label = gen_label_rtx ();
13906   rtx op1 = gen_reg_rtx (XFmode);
13907   rtx op2 = gen_reg_rtx (XFmode);
13909   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13910   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13912   emit_label (label);
13914   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13915   ix86_emit_fp_unordered_jump (label);
13916   LABEL_NUSES (label) = 1;
13918   /* Truncate the result properly for strict SSE math.  */
13919   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13920       && !TARGET_MIX_SSE_I387)
13921     gen_truncxf = gen_truncxf<mode>2;
13922   else
13923     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13925   emit_insn (gen_truncxf (operands[0], op1));
13926   DONE;
13929 (define_int_iterator SINCOS
13930         [UNSPEC_SIN
13931          UNSPEC_COS])
13933 (define_int_attr sincos
13934         [(UNSPEC_SIN "sin")
13935          (UNSPEC_COS "cos")])
13937 (define_insn "*<sincos>xf2_i387"
13938   [(set (match_operand:XF 0 "register_operand" "=f")
13939         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13940                    SINCOS))]
13941   "TARGET_USE_FANCY_MATH_387
13942    && flag_unsafe_math_optimizations"
13943   "f<sincos>"
13944   [(set_attr "type" "fpspc")
13945    (set_attr "mode" "XF")])
13947 (define_insn "*<sincos>_extend<mode>xf2_i387"
13948   [(set (match_operand:XF 0 "register_operand" "=f")
13949         (unspec:XF [(float_extend:XF
13950                       (match_operand:MODEF 1 "register_operand" "0"))]
13951                    SINCOS))]
13952   "TARGET_USE_FANCY_MATH_387
13953    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13954        || TARGET_MIX_SSE_I387)
13955    && flag_unsafe_math_optimizations"
13956   "f<sincos>"
13957   [(set_attr "type" "fpspc")
13958    (set_attr "mode" "XF")])
13960 ;; When sincos pattern is defined, sin and cos builtin functions will be
13961 ;; expanded to sincos pattern with one of its outputs left unused.
13962 ;; CSE pass will figure out if two sincos patterns can be combined,
13963 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13964 ;; depending on the unused output.
13966 (define_insn "sincosxf3"
13967   [(set (match_operand:XF 0 "register_operand" "=f")
13968         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13969                    UNSPEC_SINCOS_COS))
13970    (set (match_operand:XF 1 "register_operand" "=u")
13971         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13972   "TARGET_USE_FANCY_MATH_387
13973    && flag_unsafe_math_optimizations"
13974   "fsincos"
13975   [(set_attr "type" "fpspc")
13976    (set_attr "mode" "XF")])
13978 (define_split
13979   [(set (match_operand:XF 0 "register_operand")
13980         (unspec:XF [(match_operand:XF 2 "register_operand")]
13981                    UNSPEC_SINCOS_COS))
13982    (set (match_operand:XF 1 "register_operand")
13983         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13984   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13985    && can_create_pseudo_p ()"
13986   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13988 (define_split
13989   [(set (match_operand:XF 0 "register_operand")
13990         (unspec:XF [(match_operand:XF 2 "register_operand")]
13991                    UNSPEC_SINCOS_COS))
13992    (set (match_operand:XF 1 "register_operand")
13993         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13994   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13995    && can_create_pseudo_p ()"
13996   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13998 (define_insn "sincos_extend<mode>xf3_i387"
13999   [(set (match_operand:XF 0 "register_operand" "=f")
14000         (unspec:XF [(float_extend:XF
14001                       (match_operand:MODEF 2 "register_operand" "0"))]
14002                    UNSPEC_SINCOS_COS))
14003    (set (match_operand:XF 1 "register_operand" "=u")
14004         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14005   "TARGET_USE_FANCY_MATH_387
14006    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14007        || TARGET_MIX_SSE_I387)
14008    && flag_unsafe_math_optimizations"
14009   "fsincos"
14010   [(set_attr "type" "fpspc")
14011    (set_attr "mode" "XF")])
14013 (define_split
14014   [(set (match_operand:XF 0 "register_operand")
14015         (unspec:XF [(float_extend:XF
14016                       (match_operand:MODEF 2 "register_operand"))]
14017                    UNSPEC_SINCOS_COS))
14018    (set (match_operand:XF 1 "register_operand")
14019         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14020   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14021    && can_create_pseudo_p ()"
14022   [(set (match_dup 1)
14023         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14025 (define_split
14026   [(set (match_operand:XF 0 "register_operand")
14027         (unspec:XF [(float_extend:XF
14028                       (match_operand:MODEF 2 "register_operand"))]
14029                    UNSPEC_SINCOS_COS))
14030    (set (match_operand:XF 1 "register_operand")
14031         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14032   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14033    && can_create_pseudo_p ()"
14034   [(set (match_dup 0)
14035         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14037 (define_expand "sincos<mode>3"
14038   [(use (match_operand:MODEF 0 "register_operand"))
14039    (use (match_operand:MODEF 1 "register_operand"))
14040    (use (match_operand:MODEF 2 "register_operand"))]
14041   "TARGET_USE_FANCY_MATH_387
14042    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14043        || TARGET_MIX_SSE_I387)
14044    && flag_unsafe_math_optimizations"
14046   rtx op0 = gen_reg_rtx (XFmode);
14047   rtx op1 = gen_reg_rtx (XFmode);
14049   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14050   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14051   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14052   DONE;
14055 (define_insn "fptanxf4_i387"
14056   [(set (match_operand:XF 0 "register_operand" "=f")
14057         (match_operand:XF 3 "const_double_operand" "F"))
14058    (set (match_operand:XF 1 "register_operand" "=u")
14059         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14060                    UNSPEC_TAN))]
14061   "TARGET_USE_FANCY_MATH_387
14062    && flag_unsafe_math_optimizations
14063    && standard_80387_constant_p (operands[3]) == 2"
14064   "fptan"
14065   [(set_attr "type" "fpspc")
14066    (set_attr "mode" "XF")])
14068 (define_insn "fptan_extend<mode>xf4_i387"
14069   [(set (match_operand:MODEF 0 "register_operand" "=f")
14070         (match_operand:MODEF 3 "const_double_operand" "F"))
14071    (set (match_operand:XF 1 "register_operand" "=u")
14072         (unspec:XF [(float_extend:XF
14073                       (match_operand:MODEF 2 "register_operand" "0"))]
14074                    UNSPEC_TAN))]
14075   "TARGET_USE_FANCY_MATH_387
14076    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14077        || TARGET_MIX_SSE_I387)
14078    && flag_unsafe_math_optimizations
14079    && standard_80387_constant_p (operands[3]) == 2"
14080   "fptan"
14081   [(set_attr "type" "fpspc")
14082    (set_attr "mode" "XF")])
14084 (define_expand "tanxf2"
14085   [(use (match_operand:XF 0 "register_operand"))
14086    (use (match_operand:XF 1 "register_operand"))]
14087   "TARGET_USE_FANCY_MATH_387
14088    && flag_unsafe_math_optimizations"
14090   rtx one = gen_reg_rtx (XFmode);
14091   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14093   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14094   DONE;
14097 (define_expand "tan<mode>2"
14098   [(use (match_operand:MODEF 0 "register_operand"))
14099    (use (match_operand:MODEF 1 "register_operand"))]
14100   "TARGET_USE_FANCY_MATH_387
14101    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14102        || TARGET_MIX_SSE_I387)
14103    && flag_unsafe_math_optimizations"
14105   rtx op0 = gen_reg_rtx (XFmode);
14107   rtx one = gen_reg_rtx (<MODE>mode);
14108   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14110   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14111                                              operands[1], op2));
14112   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14113   DONE;
14116 (define_insn "*fpatanxf3_i387"
14117   [(set (match_operand:XF 0 "register_operand" "=f")
14118         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14119                     (match_operand:XF 2 "register_operand" "u")]
14120                    UNSPEC_FPATAN))
14121    (clobber (match_scratch:XF 3 "=2"))]
14122   "TARGET_USE_FANCY_MATH_387
14123    && flag_unsafe_math_optimizations"
14124   "fpatan"
14125   [(set_attr "type" "fpspc")
14126    (set_attr "mode" "XF")])
14128 (define_insn "fpatan_extend<mode>xf3_i387"
14129   [(set (match_operand:XF 0 "register_operand" "=f")
14130         (unspec:XF [(float_extend:XF
14131                       (match_operand:MODEF 1 "register_operand" "0"))
14132                     (float_extend:XF
14133                       (match_operand:MODEF 2 "register_operand" "u"))]
14134                    UNSPEC_FPATAN))
14135    (clobber (match_scratch:XF 3 "=2"))]
14136   "TARGET_USE_FANCY_MATH_387
14137    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14138        || TARGET_MIX_SSE_I387)
14139    && flag_unsafe_math_optimizations"
14140   "fpatan"
14141   [(set_attr "type" "fpspc")
14142    (set_attr "mode" "XF")])
14144 (define_expand "atan2xf3"
14145   [(parallel [(set (match_operand:XF 0 "register_operand")
14146                    (unspec:XF [(match_operand:XF 2 "register_operand")
14147                                (match_operand:XF 1 "register_operand")]
14148                               UNSPEC_FPATAN))
14149               (clobber (match_scratch:XF 3))])]
14150   "TARGET_USE_FANCY_MATH_387
14151    && flag_unsafe_math_optimizations")
14153 (define_expand "atan2<mode>3"
14154   [(use (match_operand:MODEF 0 "register_operand"))
14155    (use (match_operand:MODEF 1 "register_operand"))
14156    (use (match_operand:MODEF 2 "register_operand"))]
14157   "TARGET_USE_FANCY_MATH_387
14158    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14159        || TARGET_MIX_SSE_I387)
14160    && flag_unsafe_math_optimizations"
14162   rtx op0 = gen_reg_rtx (XFmode);
14164   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14165   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14166   DONE;
14169 (define_expand "atanxf2"
14170   [(parallel [(set (match_operand:XF 0 "register_operand")
14171                    (unspec:XF [(match_dup 2)
14172                                (match_operand:XF 1 "register_operand")]
14173                               UNSPEC_FPATAN))
14174               (clobber (match_scratch:XF 3))])]
14175   "TARGET_USE_FANCY_MATH_387
14176    && flag_unsafe_math_optimizations"
14178   operands[2] = gen_reg_rtx (XFmode);
14179   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
14182 (define_expand "atan<mode>2"
14183   [(use (match_operand:MODEF 0 "register_operand"))
14184    (use (match_operand:MODEF 1 "register_operand"))]
14185   "TARGET_USE_FANCY_MATH_387
14186    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14187        || TARGET_MIX_SSE_I387)
14188    && flag_unsafe_math_optimizations"
14190   rtx op0 = gen_reg_rtx (XFmode);
14192   rtx op2 = gen_reg_rtx (<MODE>mode);
14193   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
14195   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14196   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14197   DONE;
14200 (define_expand "asinxf2"
14201   [(set (match_dup 2)
14202         (mult:XF (match_operand:XF 1 "register_operand")
14203                  (match_dup 1)))
14204    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14205    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14206    (parallel [(set (match_operand:XF 0 "register_operand")
14207                    (unspec:XF [(match_dup 5) (match_dup 1)]
14208                               UNSPEC_FPATAN))
14209               (clobber (match_scratch:XF 6))])]
14210   "TARGET_USE_FANCY_MATH_387
14211    && flag_unsafe_math_optimizations"
14213   int i;
14215   if (optimize_insn_for_size_p ())
14216     FAIL;
14218   for (i = 2; i < 6; i++)
14219     operands[i] = gen_reg_rtx (XFmode);
14221   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14224 (define_expand "asin<mode>2"
14225   [(use (match_operand:MODEF 0 "register_operand"))
14226    (use (match_operand:MODEF 1 "general_operand"))]
14227  "TARGET_USE_FANCY_MATH_387
14228    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14229        || TARGET_MIX_SSE_I387)
14230    && flag_unsafe_math_optimizations"
14232   rtx op0 = gen_reg_rtx (XFmode);
14233   rtx op1 = gen_reg_rtx (XFmode);
14235   if (optimize_insn_for_size_p ())
14236     FAIL;
14238   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14239   emit_insn (gen_asinxf2 (op0, op1));
14240   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14241   DONE;
14244 (define_expand "acosxf2"
14245   [(set (match_dup 2)
14246         (mult:XF (match_operand:XF 1 "register_operand")
14247                  (match_dup 1)))
14248    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14249    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14250    (parallel [(set (match_operand:XF 0 "register_operand")
14251                    (unspec:XF [(match_dup 1) (match_dup 5)]
14252                               UNSPEC_FPATAN))
14253               (clobber (match_scratch:XF 6))])]
14254   "TARGET_USE_FANCY_MATH_387
14255    && flag_unsafe_math_optimizations"
14257   int i;
14259   if (optimize_insn_for_size_p ())
14260     FAIL;
14262   for (i = 2; i < 6; i++)
14263     operands[i] = gen_reg_rtx (XFmode);
14265   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14268 (define_expand "acos<mode>2"
14269   [(use (match_operand:MODEF 0 "register_operand"))
14270    (use (match_operand:MODEF 1 "general_operand"))]
14271  "TARGET_USE_FANCY_MATH_387
14272    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14273        || TARGET_MIX_SSE_I387)
14274    && flag_unsafe_math_optimizations"
14276   rtx op0 = gen_reg_rtx (XFmode);
14277   rtx op1 = gen_reg_rtx (XFmode);
14279   if (optimize_insn_for_size_p ())
14280     FAIL;
14282   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14283   emit_insn (gen_acosxf2 (op0, op1));
14284   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14285   DONE;
14288 (define_insn "fyl2xxf3_i387"
14289   [(set (match_operand:XF 0 "register_operand" "=f")
14290         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14291                     (match_operand:XF 2 "register_operand" "u")]
14292                    UNSPEC_FYL2X))
14293    (clobber (match_scratch:XF 3 "=2"))]
14294   "TARGET_USE_FANCY_MATH_387
14295    && flag_unsafe_math_optimizations"
14296   "fyl2x"
14297   [(set_attr "type" "fpspc")
14298    (set_attr "mode" "XF")])
14300 (define_insn "fyl2x_extend<mode>xf3_i387"
14301   [(set (match_operand:XF 0 "register_operand" "=f")
14302         (unspec:XF [(float_extend:XF
14303                       (match_operand:MODEF 1 "register_operand" "0"))
14304                     (match_operand:XF 2 "register_operand" "u")]
14305                    UNSPEC_FYL2X))
14306    (clobber (match_scratch:XF 3 "=2"))]
14307   "TARGET_USE_FANCY_MATH_387
14308    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14309        || TARGET_MIX_SSE_I387)
14310    && flag_unsafe_math_optimizations"
14311   "fyl2x"
14312   [(set_attr "type" "fpspc")
14313    (set_attr "mode" "XF")])
14315 (define_expand "logxf2"
14316   [(parallel [(set (match_operand:XF 0 "register_operand")
14317                    (unspec:XF [(match_operand:XF 1 "register_operand")
14318                                (match_dup 2)] UNSPEC_FYL2X))
14319               (clobber (match_scratch:XF 3))])]
14320   "TARGET_USE_FANCY_MATH_387
14321    && flag_unsafe_math_optimizations"
14323   operands[2] = gen_reg_rtx (XFmode);
14324   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14327 (define_expand "log<mode>2"
14328   [(use (match_operand:MODEF 0 "register_operand"))
14329    (use (match_operand:MODEF 1 "register_operand"))]
14330   "TARGET_USE_FANCY_MATH_387
14331    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14332        || TARGET_MIX_SSE_I387)
14333    && flag_unsafe_math_optimizations"
14335   rtx op0 = gen_reg_rtx (XFmode);
14337   rtx op2 = gen_reg_rtx (XFmode);
14338   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14340   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14341   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14342   DONE;
14345 (define_expand "log10xf2"
14346   [(parallel [(set (match_operand:XF 0 "register_operand")
14347                    (unspec:XF [(match_operand:XF 1 "register_operand")
14348                                (match_dup 2)] UNSPEC_FYL2X))
14349               (clobber (match_scratch:XF 3))])]
14350   "TARGET_USE_FANCY_MATH_387
14351    && flag_unsafe_math_optimizations"
14353   operands[2] = gen_reg_rtx (XFmode);
14354   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14357 (define_expand "log10<mode>2"
14358   [(use (match_operand:MODEF 0 "register_operand"))
14359    (use (match_operand:MODEF 1 "register_operand"))]
14360   "TARGET_USE_FANCY_MATH_387
14361    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14362        || TARGET_MIX_SSE_I387)
14363    && flag_unsafe_math_optimizations"
14365   rtx op0 = gen_reg_rtx (XFmode);
14367   rtx op2 = gen_reg_rtx (XFmode);
14368   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14370   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14371   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14372   DONE;
14375 (define_expand "log2xf2"
14376   [(parallel [(set (match_operand:XF 0 "register_operand")
14377                    (unspec:XF [(match_operand:XF 1 "register_operand")
14378                                (match_dup 2)] UNSPEC_FYL2X))
14379               (clobber (match_scratch:XF 3))])]
14380   "TARGET_USE_FANCY_MATH_387
14381    && flag_unsafe_math_optimizations"
14383   operands[2] = gen_reg_rtx (XFmode);
14384   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14387 (define_expand "log2<mode>2"
14388   [(use (match_operand:MODEF 0 "register_operand"))
14389    (use (match_operand:MODEF 1 "register_operand"))]
14390   "TARGET_USE_FANCY_MATH_387
14391    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14392        || TARGET_MIX_SSE_I387)
14393    && flag_unsafe_math_optimizations"
14395   rtx op0 = gen_reg_rtx (XFmode);
14397   rtx op2 = gen_reg_rtx (XFmode);
14398   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14400   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14401   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14402   DONE;
14405 (define_insn "fyl2xp1xf3_i387"
14406   [(set (match_operand:XF 0 "register_operand" "=f")
14407         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14408                     (match_operand:XF 2 "register_operand" "u")]
14409                    UNSPEC_FYL2XP1))
14410    (clobber (match_scratch:XF 3 "=2"))]
14411   "TARGET_USE_FANCY_MATH_387
14412    && flag_unsafe_math_optimizations"
14413   "fyl2xp1"
14414   [(set_attr "type" "fpspc")
14415    (set_attr "mode" "XF")])
14417 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14418   [(set (match_operand:XF 0 "register_operand" "=f")
14419         (unspec:XF [(float_extend:XF
14420                       (match_operand:MODEF 1 "register_operand" "0"))
14421                     (match_operand:XF 2 "register_operand" "u")]
14422                    UNSPEC_FYL2XP1))
14423    (clobber (match_scratch:XF 3 "=2"))]
14424   "TARGET_USE_FANCY_MATH_387
14425    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14426        || TARGET_MIX_SSE_I387)
14427    && flag_unsafe_math_optimizations"
14428   "fyl2xp1"
14429   [(set_attr "type" "fpspc")
14430    (set_attr "mode" "XF")])
14432 (define_expand "log1pxf2"
14433   [(use (match_operand:XF 0 "register_operand"))
14434    (use (match_operand:XF 1 "register_operand"))]
14435   "TARGET_USE_FANCY_MATH_387
14436    && flag_unsafe_math_optimizations"
14438   if (optimize_insn_for_size_p ())
14439     FAIL;
14441   ix86_emit_i387_log1p (operands[0], operands[1]);
14442   DONE;
14445 (define_expand "log1p<mode>2"
14446   [(use (match_operand:MODEF 0 "register_operand"))
14447    (use (match_operand:MODEF 1 "register_operand"))]
14448   "TARGET_USE_FANCY_MATH_387
14449    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14450        || TARGET_MIX_SSE_I387)
14451    && flag_unsafe_math_optimizations"
14453   rtx op0;
14455   if (optimize_insn_for_size_p ())
14456     FAIL;
14458   op0 = gen_reg_rtx (XFmode);
14460   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14462   ix86_emit_i387_log1p (op0, operands[1]);
14463   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14464   DONE;
14467 (define_insn "fxtractxf3_i387"
14468   [(set (match_operand:XF 0 "register_operand" "=f")
14469         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14470                    UNSPEC_XTRACT_FRACT))
14471    (set (match_operand:XF 1 "register_operand" "=u")
14472         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14473   "TARGET_USE_FANCY_MATH_387
14474    && flag_unsafe_math_optimizations"
14475   "fxtract"
14476   [(set_attr "type" "fpspc")
14477    (set_attr "mode" "XF")])
14479 (define_insn "fxtract_extend<mode>xf3_i387"
14480   [(set (match_operand:XF 0 "register_operand" "=f")
14481         (unspec:XF [(float_extend:XF
14482                       (match_operand:MODEF 2 "register_operand" "0"))]
14483                    UNSPEC_XTRACT_FRACT))
14484    (set (match_operand:XF 1 "register_operand" "=u")
14485         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14486   "TARGET_USE_FANCY_MATH_387
14487    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14488        || TARGET_MIX_SSE_I387)
14489    && flag_unsafe_math_optimizations"
14490   "fxtract"
14491   [(set_attr "type" "fpspc")
14492    (set_attr "mode" "XF")])
14494 (define_expand "logbxf2"
14495   [(parallel [(set (match_dup 2)
14496                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14497                               UNSPEC_XTRACT_FRACT))
14498               (set (match_operand:XF 0 "register_operand")
14499                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14500   "TARGET_USE_FANCY_MATH_387
14501    && flag_unsafe_math_optimizations"
14502   "operands[2] = gen_reg_rtx (XFmode);")
14504 (define_expand "logb<mode>2"
14505   [(use (match_operand:MODEF 0 "register_operand"))
14506    (use (match_operand:MODEF 1 "register_operand"))]
14507   "TARGET_USE_FANCY_MATH_387
14508    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14509        || TARGET_MIX_SSE_I387)
14510    && flag_unsafe_math_optimizations"
14512   rtx op0 = gen_reg_rtx (XFmode);
14513   rtx op1 = gen_reg_rtx (XFmode);
14515   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14516   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14517   DONE;
14520 (define_expand "ilogbxf2"
14521   [(use (match_operand:SI 0 "register_operand"))
14522    (use (match_operand:XF 1 "register_operand"))]
14523   "TARGET_USE_FANCY_MATH_387
14524    && flag_unsafe_math_optimizations"
14526   rtx op0, op1;
14528   if (optimize_insn_for_size_p ())
14529     FAIL;
14531   op0 = gen_reg_rtx (XFmode);
14532   op1 = gen_reg_rtx (XFmode);
14534   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14535   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14536   DONE;
14539 (define_expand "ilogb<mode>2"
14540   [(use (match_operand:SI 0 "register_operand"))
14541    (use (match_operand:MODEF 1 "register_operand"))]
14542   "TARGET_USE_FANCY_MATH_387
14543    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14544        || TARGET_MIX_SSE_I387)
14545    && flag_unsafe_math_optimizations"
14547   rtx op0, op1;
14549   if (optimize_insn_for_size_p ())
14550     FAIL;
14552   op0 = gen_reg_rtx (XFmode);
14553   op1 = gen_reg_rtx (XFmode);
14555   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14556   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14557   DONE;
14560 (define_insn "*f2xm1xf2_i387"
14561   [(set (match_operand:XF 0 "register_operand" "=f")
14562         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14563                    UNSPEC_F2XM1))]
14564   "TARGET_USE_FANCY_MATH_387
14565    && flag_unsafe_math_optimizations"
14566   "f2xm1"
14567   [(set_attr "type" "fpspc")
14568    (set_attr "mode" "XF")])
14570 (define_insn "*fscalexf4_i387"
14571   [(set (match_operand:XF 0 "register_operand" "=f")
14572         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14573                     (match_operand:XF 3 "register_operand" "1")]
14574                    UNSPEC_FSCALE_FRACT))
14575    (set (match_operand:XF 1 "register_operand" "=u")
14576         (unspec:XF [(match_dup 2) (match_dup 3)]
14577                    UNSPEC_FSCALE_EXP))]
14578   "TARGET_USE_FANCY_MATH_387
14579    && flag_unsafe_math_optimizations"
14580   "fscale"
14581   [(set_attr "type" "fpspc")
14582    (set_attr "mode" "XF")])
14584 (define_expand "expNcorexf3"
14585   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14586                                (match_operand:XF 2 "register_operand")))
14587    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14588    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14589    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14590    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14591    (parallel [(set (match_operand:XF 0 "register_operand")
14592                    (unspec:XF [(match_dup 8) (match_dup 4)]
14593                               UNSPEC_FSCALE_FRACT))
14594               (set (match_dup 9)
14595                    (unspec:XF [(match_dup 8) (match_dup 4)]
14596                               UNSPEC_FSCALE_EXP))])]
14597   "TARGET_USE_FANCY_MATH_387
14598    && flag_unsafe_math_optimizations"
14600   int i;
14602   if (optimize_insn_for_size_p ())
14603     FAIL;
14605   for (i = 3; i < 10; i++)
14606     operands[i] = gen_reg_rtx (XFmode);
14608   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14611 (define_expand "expxf2"
14612   [(use (match_operand:XF 0 "register_operand"))
14613    (use (match_operand:XF 1 "register_operand"))]
14614   "TARGET_USE_FANCY_MATH_387
14615    && flag_unsafe_math_optimizations"
14617   rtx op2;
14619   if (optimize_insn_for_size_p ())
14620     FAIL;
14622   op2 = gen_reg_rtx (XFmode);
14623   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14625   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14626   DONE;
14629 (define_expand "exp<mode>2"
14630   [(use (match_operand:MODEF 0 "register_operand"))
14631    (use (match_operand:MODEF 1 "general_operand"))]
14632  "TARGET_USE_FANCY_MATH_387
14633    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14634        || TARGET_MIX_SSE_I387)
14635    && flag_unsafe_math_optimizations"
14637   rtx op0, op1;
14639   if (optimize_insn_for_size_p ())
14640     FAIL;
14642   op0 = gen_reg_rtx (XFmode);
14643   op1 = gen_reg_rtx (XFmode);
14645   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14646   emit_insn (gen_expxf2 (op0, op1));
14647   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14648   DONE;
14651 (define_expand "exp10xf2"
14652   [(use (match_operand:XF 0 "register_operand"))
14653    (use (match_operand:XF 1 "register_operand"))]
14654   "TARGET_USE_FANCY_MATH_387
14655    && flag_unsafe_math_optimizations"
14657   rtx op2;
14659   if (optimize_insn_for_size_p ())
14660     FAIL;
14662   op2 = gen_reg_rtx (XFmode);
14663   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14665   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14666   DONE;
14669 (define_expand "exp10<mode>2"
14670   [(use (match_operand:MODEF 0 "register_operand"))
14671    (use (match_operand:MODEF 1 "general_operand"))]
14672  "TARGET_USE_FANCY_MATH_387
14673    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14674        || TARGET_MIX_SSE_I387)
14675    && flag_unsafe_math_optimizations"
14677   rtx op0, op1;
14679   if (optimize_insn_for_size_p ())
14680     FAIL;
14682   op0 = gen_reg_rtx (XFmode);
14683   op1 = gen_reg_rtx (XFmode);
14685   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14686   emit_insn (gen_exp10xf2 (op0, op1));
14687   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14688   DONE;
14691 (define_expand "exp2xf2"
14692   [(use (match_operand:XF 0 "register_operand"))
14693    (use (match_operand:XF 1 "register_operand"))]
14694   "TARGET_USE_FANCY_MATH_387
14695    && flag_unsafe_math_optimizations"
14697   rtx op2;
14699   if (optimize_insn_for_size_p ())
14700     FAIL;
14702   op2 = gen_reg_rtx (XFmode);
14703   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14705   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14706   DONE;
14709 (define_expand "exp2<mode>2"
14710   [(use (match_operand:MODEF 0 "register_operand"))
14711    (use (match_operand:MODEF 1 "general_operand"))]
14712  "TARGET_USE_FANCY_MATH_387
14713    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14714        || TARGET_MIX_SSE_I387)
14715    && flag_unsafe_math_optimizations"
14717   rtx op0, op1;
14719   if (optimize_insn_for_size_p ())
14720     FAIL;
14722   op0 = gen_reg_rtx (XFmode);
14723   op1 = gen_reg_rtx (XFmode);
14725   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14726   emit_insn (gen_exp2xf2 (op0, op1));
14727   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14728   DONE;
14731 (define_expand "expm1xf2"
14732   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14733                                (match_dup 2)))
14734    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14735    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14736    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14737    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14738    (parallel [(set (match_dup 7)
14739                    (unspec:XF [(match_dup 6) (match_dup 4)]
14740                               UNSPEC_FSCALE_FRACT))
14741               (set (match_dup 8)
14742                    (unspec:XF [(match_dup 6) (match_dup 4)]
14743                               UNSPEC_FSCALE_EXP))])
14744    (parallel [(set (match_dup 10)
14745                    (unspec:XF [(match_dup 9) (match_dup 8)]
14746                               UNSPEC_FSCALE_FRACT))
14747               (set (match_dup 11)
14748                    (unspec:XF [(match_dup 9) (match_dup 8)]
14749                               UNSPEC_FSCALE_EXP))])
14750    (set (match_dup 12) (minus:XF (match_dup 10)
14751                                  (float_extend:XF (match_dup 13))))
14752    (set (match_operand:XF 0 "register_operand")
14753         (plus:XF (match_dup 12) (match_dup 7)))]
14754   "TARGET_USE_FANCY_MATH_387
14755    && flag_unsafe_math_optimizations"
14757   int i;
14759   if (optimize_insn_for_size_p ())
14760     FAIL;
14762   for (i = 2; i < 13; i++)
14763     operands[i] = gen_reg_rtx (XFmode);
14765   operands[13]
14766     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14768   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14771 (define_expand "expm1<mode>2"
14772   [(use (match_operand:MODEF 0 "register_operand"))
14773    (use (match_operand:MODEF 1 "general_operand"))]
14774  "TARGET_USE_FANCY_MATH_387
14775    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14776        || TARGET_MIX_SSE_I387)
14777    && flag_unsafe_math_optimizations"
14779   rtx op0, op1;
14781   if (optimize_insn_for_size_p ())
14782     FAIL;
14784   op0 = gen_reg_rtx (XFmode);
14785   op1 = gen_reg_rtx (XFmode);
14787   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14788   emit_insn (gen_expm1xf2 (op0, op1));
14789   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14790   DONE;
14793 (define_expand "ldexpxf3"
14794   [(set (match_dup 3)
14795         (float:XF (match_operand:SI 2 "register_operand")))
14796    (parallel [(set (match_operand:XF 0 " register_operand")
14797                    (unspec:XF [(match_operand:XF 1 "register_operand")
14798                                (match_dup 3)]
14799                               UNSPEC_FSCALE_FRACT))
14800               (set (match_dup 4)
14801                    (unspec:XF [(match_dup 1) (match_dup 3)]
14802                               UNSPEC_FSCALE_EXP))])]
14803   "TARGET_USE_FANCY_MATH_387
14804    && flag_unsafe_math_optimizations"
14806   if (optimize_insn_for_size_p ())
14807     FAIL;
14809   operands[3] = gen_reg_rtx (XFmode);
14810   operands[4] = gen_reg_rtx (XFmode);
14813 (define_expand "ldexp<mode>3"
14814   [(use (match_operand:MODEF 0 "register_operand"))
14815    (use (match_operand:MODEF 1 "general_operand"))
14816    (use (match_operand:SI 2 "register_operand"))]
14817  "TARGET_USE_FANCY_MATH_387
14818    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14819        || TARGET_MIX_SSE_I387)
14820    && flag_unsafe_math_optimizations"
14822   rtx op0, op1;
14824   if (optimize_insn_for_size_p ())
14825     FAIL;
14827   op0 = gen_reg_rtx (XFmode);
14828   op1 = gen_reg_rtx (XFmode);
14830   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14831   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14832   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14833   DONE;
14836 (define_expand "scalbxf3"
14837   [(parallel [(set (match_operand:XF 0 " register_operand")
14838                    (unspec:XF [(match_operand:XF 1 "register_operand")
14839                                (match_operand:XF 2 "register_operand")]
14840                               UNSPEC_FSCALE_FRACT))
14841               (set (match_dup 3)
14842                    (unspec:XF [(match_dup 1) (match_dup 2)]
14843                               UNSPEC_FSCALE_EXP))])]
14844   "TARGET_USE_FANCY_MATH_387
14845    && flag_unsafe_math_optimizations"
14847   if (optimize_insn_for_size_p ())
14848     FAIL;
14850   operands[3] = gen_reg_rtx (XFmode);
14853 (define_expand "scalb<mode>3"
14854   [(use (match_operand:MODEF 0 "register_operand"))
14855    (use (match_operand:MODEF 1 "general_operand"))
14856    (use (match_operand:MODEF 2 "general_operand"))]
14857  "TARGET_USE_FANCY_MATH_387
14858    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14859        || TARGET_MIX_SSE_I387)
14860    && flag_unsafe_math_optimizations"
14862   rtx op0, op1, op2;
14864   if (optimize_insn_for_size_p ())
14865     FAIL;
14867   op0 = gen_reg_rtx (XFmode);
14868   op1 = gen_reg_rtx (XFmode);
14869   op2 = gen_reg_rtx (XFmode);
14871   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14872   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14873   emit_insn (gen_scalbxf3 (op0, op1, op2));
14874   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14875   DONE;
14878 (define_expand "significandxf2"
14879   [(parallel [(set (match_operand:XF 0 "register_operand")
14880                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14881                               UNSPEC_XTRACT_FRACT))
14882               (set (match_dup 2)
14883                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14884   "TARGET_USE_FANCY_MATH_387
14885    && flag_unsafe_math_optimizations"
14886   "operands[2] = gen_reg_rtx (XFmode);")
14888 (define_expand "significand<mode>2"
14889   [(use (match_operand:MODEF 0 "register_operand"))
14890    (use (match_operand:MODEF 1 "register_operand"))]
14891   "TARGET_USE_FANCY_MATH_387
14892    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14893        || TARGET_MIX_SSE_I387)
14894    && flag_unsafe_math_optimizations"
14896   rtx op0 = gen_reg_rtx (XFmode);
14897   rtx op1 = gen_reg_rtx (XFmode);
14899   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14900   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14901   DONE;
14905 (define_insn "sse4_1_round<mode>2"
14906   [(set (match_operand:MODEF 0 "register_operand" "=x")
14907         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14908                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14909                       UNSPEC_ROUND))]
14910   "TARGET_ROUND"
14911   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14912   [(set_attr "type" "ssecvt")
14913    (set_attr "prefix_extra" "1")
14914    (set_attr "prefix" "maybe_vex")
14915    (set_attr "mode" "<MODE>")])
14917 (define_insn "rintxf2"
14918   [(set (match_operand:XF 0 "register_operand" "=f")
14919         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14920                    UNSPEC_FRNDINT))]
14921   "TARGET_USE_FANCY_MATH_387
14922    && flag_unsafe_math_optimizations"
14923   "frndint"
14924   [(set_attr "type" "fpspc")
14925    (set_attr "mode" "XF")])
14927 (define_expand "rint<mode>2"
14928   [(use (match_operand:MODEF 0 "register_operand"))
14929    (use (match_operand:MODEF 1 "register_operand"))]
14930   "(TARGET_USE_FANCY_MATH_387
14931     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14932         || TARGET_MIX_SSE_I387)
14933     && flag_unsafe_math_optimizations)
14934    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14935        && !flag_trapping_math)"
14937   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14938       && !flag_trapping_math)
14939     {
14940       if (TARGET_ROUND)
14941         emit_insn (gen_sse4_1_round<mode>2
14942                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14943       else if (optimize_insn_for_size_p ())
14944         FAIL;
14945       else
14946         ix86_expand_rint (operands[0], operands[1]);
14947     }
14948   else
14949     {
14950       rtx op0 = gen_reg_rtx (XFmode);
14951       rtx op1 = gen_reg_rtx (XFmode);
14953       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14954       emit_insn (gen_rintxf2 (op0, op1));
14956       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14957     }
14958   DONE;
14961 (define_expand "round<mode>2"
14962   [(match_operand:X87MODEF 0 "register_operand")
14963    (match_operand:X87MODEF 1 "nonimmediate_operand")]
14964   "(TARGET_USE_FANCY_MATH_387
14965     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14966         || TARGET_MIX_SSE_I387)
14967     && flag_unsafe_math_optimizations)
14968    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14969        && !flag_trapping_math && !flag_rounding_math)"
14971   if (optimize_insn_for_size_p ())
14972     FAIL;
14974   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14975       && !flag_trapping_math && !flag_rounding_math)
14976     {
14977       if (TARGET_ROUND)
14978         {
14979           operands[1] = force_reg (<MODE>mode, operands[1]);
14980           ix86_expand_round_sse4 (operands[0], operands[1]);
14981         }
14982       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14983         ix86_expand_round (operands[0], operands[1]);
14984       else
14985         ix86_expand_rounddf_32 (operands[0], operands[1]);
14986     }
14987   else
14988     {
14989       operands[1] = force_reg (<MODE>mode, operands[1]);
14990       ix86_emit_i387_round (operands[0], operands[1]);
14991     }
14992   DONE;
14995 (define_insn_and_split "*fistdi2_1"
14996   [(set (match_operand:DI 0 "nonimmediate_operand")
14997         (unspec:DI [(match_operand:XF 1 "register_operand")]
14998                    UNSPEC_FIST))]
14999   "TARGET_USE_FANCY_MATH_387
15000    && can_create_pseudo_p ()"
15001   "#"
15002   "&& 1"
15003   [(const_int 0)]
15005   if (memory_operand (operands[0], VOIDmode))
15006     emit_insn (gen_fistdi2 (operands[0], operands[1]));
15007   else
15008     {
15009       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15010       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15011                                          operands[2]));
15012     }
15013   DONE;
15015   [(set_attr "type" "fpspc")
15016    (set_attr "mode" "DI")])
15018 (define_insn "fistdi2"
15019   [(set (match_operand:DI 0 "memory_operand" "=m")
15020         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15021                    UNSPEC_FIST))
15022    (clobber (match_scratch:XF 2 "=&1f"))]
15023   "TARGET_USE_FANCY_MATH_387"
15024   "* return output_fix_trunc (insn, operands, false);"
15025   [(set_attr "type" "fpspc")
15026    (set_attr "mode" "DI")])
15028 (define_insn "fistdi2_with_temp"
15029   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15030         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15031                    UNSPEC_FIST))
15032    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15033    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15034   "TARGET_USE_FANCY_MATH_387"
15035   "#"
15036   [(set_attr "type" "fpspc")
15037    (set_attr "mode" "DI")])
15039 (define_split
15040   [(set (match_operand:DI 0 "register_operand")
15041         (unspec:DI [(match_operand:XF 1 "register_operand")]
15042                    UNSPEC_FIST))
15043    (clobber (match_operand:DI 2 "memory_operand"))
15044    (clobber (match_scratch 3))]
15045   "reload_completed"
15046   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15047               (clobber (match_dup 3))])
15048    (set (match_dup 0) (match_dup 2))])
15050 (define_split
15051   [(set (match_operand:DI 0 "memory_operand")
15052         (unspec:DI [(match_operand:XF 1 "register_operand")]
15053                    UNSPEC_FIST))
15054    (clobber (match_operand:DI 2 "memory_operand"))
15055    (clobber (match_scratch 3))]
15056   "reload_completed"
15057   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15058               (clobber (match_dup 3))])])
15060 (define_insn_and_split "*fist<mode>2_1"
15061   [(set (match_operand:SWI24 0 "register_operand")
15062         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15063                       UNSPEC_FIST))]
15064   "TARGET_USE_FANCY_MATH_387
15065    && can_create_pseudo_p ()"
15066   "#"
15067   "&& 1"
15068   [(const_int 0)]
15070   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15071   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15072                                         operands[2]));
15073   DONE;
15075   [(set_attr "type" "fpspc")
15076    (set_attr "mode" "<MODE>")])
15078 (define_insn "fist<mode>2"
15079   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15080         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15081                       UNSPEC_FIST))]
15082   "TARGET_USE_FANCY_MATH_387"
15083   "* return output_fix_trunc (insn, operands, false);"
15084   [(set_attr "type" "fpspc")
15085    (set_attr "mode" "<MODE>")])
15087 (define_insn "fist<mode>2_with_temp"
15088   [(set (match_operand:SWI24 0 "register_operand" "=r")
15089         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15090                       UNSPEC_FIST))
15091    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15092   "TARGET_USE_FANCY_MATH_387"
15093   "#"
15094   [(set_attr "type" "fpspc")
15095    (set_attr "mode" "<MODE>")])
15097 (define_split
15098   [(set (match_operand:SWI24 0 "register_operand")
15099         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15100                       UNSPEC_FIST))
15101    (clobber (match_operand:SWI24 2 "memory_operand"))]
15102   "reload_completed"
15103   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15104    (set (match_dup 0) (match_dup 2))])
15106 (define_split
15107   [(set (match_operand:SWI24 0 "memory_operand")
15108         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15109                       UNSPEC_FIST))
15110    (clobber (match_operand:SWI24 2 "memory_operand"))]
15111   "reload_completed"
15112   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15114 (define_expand "lrintxf<mode>2"
15115   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15116      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15117                      UNSPEC_FIST))]
15118   "TARGET_USE_FANCY_MATH_387")
15120 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15121   [(set (match_operand:SWI48 0 "nonimmediate_operand")
15122      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15123                    UNSPEC_FIX_NOTRUNC))]
15124   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15126 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15127   [(match_operand:SWI248x 0 "nonimmediate_operand")
15128    (match_operand:X87MODEF 1 "register_operand")]
15129   "(TARGET_USE_FANCY_MATH_387
15130     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15131         || TARGET_MIX_SSE_I387)
15132     && flag_unsafe_math_optimizations)
15133    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15134        && <SWI248x:MODE>mode != HImode 
15135        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15136        && !flag_trapping_math && !flag_rounding_math)"
15138   if (optimize_insn_for_size_p ())
15139     FAIL;
15141   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15142       && <SWI248x:MODE>mode != HImode
15143       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15144       && !flag_trapping_math && !flag_rounding_math)
15145     ix86_expand_lround (operands[0], operands[1]);
15146   else
15147     ix86_emit_i387_round (operands[0], operands[1]);
15148   DONE;
15151 (define_int_iterator FRNDINT_ROUNDING
15152         [UNSPEC_FRNDINT_FLOOR
15153          UNSPEC_FRNDINT_CEIL
15154          UNSPEC_FRNDINT_TRUNC])
15156 (define_int_iterator FIST_ROUNDING
15157         [UNSPEC_FIST_FLOOR
15158          UNSPEC_FIST_CEIL])
15160 ;; Base name for define_insn
15161 (define_int_attr rounding_insn
15162         [(UNSPEC_FRNDINT_FLOOR "floor")
15163          (UNSPEC_FRNDINT_CEIL "ceil")
15164          (UNSPEC_FRNDINT_TRUNC "btrunc")
15165          (UNSPEC_FIST_FLOOR "floor")
15166          (UNSPEC_FIST_CEIL "ceil")])
15168 (define_int_attr rounding
15169         [(UNSPEC_FRNDINT_FLOOR "floor")
15170          (UNSPEC_FRNDINT_CEIL "ceil")
15171          (UNSPEC_FRNDINT_TRUNC "trunc")
15172          (UNSPEC_FIST_FLOOR "floor")
15173          (UNSPEC_FIST_CEIL "ceil")])
15175 (define_int_attr ROUNDING
15176         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15177          (UNSPEC_FRNDINT_CEIL "CEIL")
15178          (UNSPEC_FRNDINT_TRUNC "TRUNC")
15179          (UNSPEC_FIST_FLOOR "FLOOR")
15180          (UNSPEC_FIST_CEIL "CEIL")])
15182 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15183 (define_insn_and_split "frndintxf2_<rounding>"
15184   [(set (match_operand:XF 0 "register_operand")
15185         (unspec:XF [(match_operand:XF 1 "register_operand")]
15186                    FRNDINT_ROUNDING))
15187    (clobber (reg:CC FLAGS_REG))]
15188   "TARGET_USE_FANCY_MATH_387
15189    && flag_unsafe_math_optimizations
15190    && can_create_pseudo_p ()"
15191   "#"
15192   "&& 1"
15193   [(const_int 0)]
15195   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15197   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15198   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15200   emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15201                                              operands[2], operands[3]));
15202   DONE;
15204   [(set_attr "type" "frndint")
15205    (set_attr "i387_cw" "<rounding>")
15206    (set_attr "mode" "XF")])
15208 (define_insn "frndintxf2_<rounding>_i387"
15209   [(set (match_operand:XF 0 "register_operand" "=f")
15210         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15211                    FRNDINT_ROUNDING))
15212    (use (match_operand:HI 2 "memory_operand" "m"))
15213    (use (match_operand:HI 3 "memory_operand" "m"))]
15214   "TARGET_USE_FANCY_MATH_387
15215    && flag_unsafe_math_optimizations"
15216   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15217   [(set_attr "type" "frndint")
15218    (set_attr "i387_cw" "<rounding>")
15219    (set_attr "mode" "XF")])
15221 (define_expand "<rounding_insn>xf2"
15222   [(parallel [(set (match_operand:XF 0 "register_operand")
15223                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15224                               FRNDINT_ROUNDING))
15225               (clobber (reg:CC FLAGS_REG))])]
15226   "TARGET_USE_FANCY_MATH_387
15227    && flag_unsafe_math_optimizations
15228    && !optimize_insn_for_size_p ()")
15230 (define_expand "<rounding_insn><mode>2"
15231   [(parallel [(set (match_operand:MODEF 0 "register_operand")
15232                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15233                                  FRNDINT_ROUNDING))
15234               (clobber (reg:CC FLAGS_REG))])]
15235   "(TARGET_USE_FANCY_MATH_387
15236     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15237         || TARGET_MIX_SSE_I387)
15238     && flag_unsafe_math_optimizations)
15239    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15240        && !flag_trapping_math)"
15242   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15243       && !flag_trapping_math)
15244     {
15245       if (TARGET_ROUND)
15246         emit_insn (gen_sse4_1_round<mode>2
15247                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15248       else if (optimize_insn_for_size_p ())
15249         FAIL;
15250       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15251         {
15252           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15253             ix86_expand_floorceil (operands[0], operands[1], true);
15254           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15255             ix86_expand_floorceil (operands[0], operands[1], false);
15256           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15257             ix86_expand_trunc (operands[0], operands[1]);
15258           else
15259             gcc_unreachable ();
15260         }
15261       else
15262         {
15263           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15264             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15265           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15266             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15267           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15268             ix86_expand_truncdf_32 (operands[0], operands[1]);
15269           else
15270             gcc_unreachable ();
15271         }
15272     }
15273   else
15274     {
15275       rtx op0, op1;
15277       if (optimize_insn_for_size_p ())
15278         FAIL;
15280       op0 = gen_reg_rtx (XFmode);
15281       op1 = gen_reg_rtx (XFmode);
15282       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15283       emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15285       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15286     }
15287   DONE;
15290 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15291 (define_insn_and_split "frndintxf2_mask_pm"
15292   [(set (match_operand:XF 0 "register_operand")
15293         (unspec:XF [(match_operand:XF 1 "register_operand")]
15294                    UNSPEC_FRNDINT_MASK_PM))
15295    (clobber (reg:CC FLAGS_REG))]
15296   "TARGET_USE_FANCY_MATH_387
15297    && flag_unsafe_math_optimizations
15298    && can_create_pseudo_p ()"
15299   "#"
15300   "&& 1"
15301   [(const_int 0)]
15303   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15305   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15306   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15308   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15309                                           operands[2], operands[3]));
15310   DONE;
15312   [(set_attr "type" "frndint")
15313    (set_attr "i387_cw" "mask_pm")
15314    (set_attr "mode" "XF")])
15316 (define_insn "frndintxf2_mask_pm_i387"
15317   [(set (match_operand:XF 0 "register_operand" "=f")
15318         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15319                    UNSPEC_FRNDINT_MASK_PM))
15320    (use (match_operand:HI 2 "memory_operand" "m"))
15321    (use (match_operand:HI 3 "memory_operand" "m"))]
15322   "TARGET_USE_FANCY_MATH_387
15323    && flag_unsafe_math_optimizations"
15324   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15325   [(set_attr "type" "frndint")
15326    (set_attr "i387_cw" "mask_pm")
15327    (set_attr "mode" "XF")])
15329 (define_expand "nearbyintxf2"
15330   [(parallel [(set (match_operand:XF 0 "register_operand")
15331                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15332                               UNSPEC_FRNDINT_MASK_PM))
15333               (clobber (reg:CC FLAGS_REG))])]
15334   "TARGET_USE_FANCY_MATH_387
15335    && flag_unsafe_math_optimizations")
15337 (define_expand "nearbyint<mode>2"
15338   [(use (match_operand:MODEF 0 "register_operand"))
15339    (use (match_operand:MODEF 1 "register_operand"))]
15340   "TARGET_USE_FANCY_MATH_387
15341    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15342        || TARGET_MIX_SSE_I387)
15343    && flag_unsafe_math_optimizations"
15345   rtx op0 = gen_reg_rtx (XFmode);
15346   rtx op1 = gen_reg_rtx (XFmode);
15348   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15349   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15351   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15352   DONE;
15355 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15356 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15357   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15358         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15359                         FIST_ROUNDING))
15360    (clobber (reg:CC FLAGS_REG))]
15361   "TARGET_USE_FANCY_MATH_387
15362    && flag_unsafe_math_optimizations
15363    && can_create_pseudo_p ()"
15364   "#"
15365   "&& 1"
15366   [(const_int 0)]
15368   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15370   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15371   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15372   if (memory_operand (operands[0], VOIDmode))
15373     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15374                                            operands[2], operands[3]));
15375   else
15376     {
15377       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15378       emit_insn (gen_fist<mode>2_<rounding>_with_temp
15379                   (operands[0], operands[1], operands[2],
15380                    operands[3], operands[4]));
15381     }
15382   DONE;
15384   [(set_attr "type" "fistp")
15385    (set_attr "i387_cw" "<rounding>")
15386    (set_attr "mode" "<MODE>")])
15388 (define_insn "fistdi2_<rounding>"
15389   [(set (match_operand:DI 0 "memory_operand" "=m")
15390         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15391                    FIST_ROUNDING))
15392    (use (match_operand:HI 2 "memory_operand" "m"))
15393    (use (match_operand:HI 3 "memory_operand" "m"))
15394    (clobber (match_scratch:XF 4 "=&1f"))]
15395   "TARGET_USE_FANCY_MATH_387
15396    && flag_unsafe_math_optimizations"
15397   "* return output_fix_trunc (insn, operands, false);"
15398   [(set_attr "type" "fistp")
15399    (set_attr "i387_cw" "<rounding>")
15400    (set_attr "mode" "DI")])
15402 (define_insn "fistdi2_<rounding>_with_temp"
15403   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15404         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15405                    FIST_ROUNDING))
15406    (use (match_operand:HI 2 "memory_operand" "m,m"))
15407    (use (match_operand:HI 3 "memory_operand" "m,m"))
15408    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15409    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15410   "TARGET_USE_FANCY_MATH_387
15411    && flag_unsafe_math_optimizations"
15412   "#"
15413   [(set_attr "type" "fistp")
15414    (set_attr "i387_cw" "<rounding>")
15415    (set_attr "mode" "DI")])
15417 (define_split
15418   [(set (match_operand:DI 0 "register_operand")
15419         (unspec:DI [(match_operand:XF 1 "register_operand")]
15420                    FIST_ROUNDING))
15421    (use (match_operand:HI 2 "memory_operand"))
15422    (use (match_operand:HI 3 "memory_operand"))
15423    (clobber (match_operand:DI 4 "memory_operand"))
15424    (clobber (match_scratch 5))]
15425   "reload_completed"
15426   [(parallel [(set (match_dup 4)
15427                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15428               (use (match_dup 2))
15429               (use (match_dup 3))
15430               (clobber (match_dup 5))])
15431    (set (match_dup 0) (match_dup 4))])
15433 (define_split
15434   [(set (match_operand:DI 0 "memory_operand")
15435         (unspec:DI [(match_operand:XF 1 "register_operand")]
15436                    FIST_ROUNDING))
15437    (use (match_operand:HI 2 "memory_operand"))
15438    (use (match_operand:HI 3 "memory_operand"))
15439    (clobber (match_operand:DI 4 "memory_operand"))
15440    (clobber (match_scratch 5))]
15441   "reload_completed"
15442   [(parallel [(set (match_dup 0)
15443                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15444               (use (match_dup 2))
15445               (use (match_dup 3))
15446               (clobber (match_dup 5))])])
15448 (define_insn "fist<mode>2_<rounding>"
15449   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15450         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15451                       FIST_ROUNDING))
15452    (use (match_operand:HI 2 "memory_operand" "m"))
15453    (use (match_operand:HI 3 "memory_operand" "m"))]
15454   "TARGET_USE_FANCY_MATH_387
15455    && flag_unsafe_math_optimizations"
15456   "* return output_fix_trunc (insn, operands, false);"
15457   [(set_attr "type" "fistp")
15458    (set_attr "i387_cw" "<rounding>")
15459    (set_attr "mode" "<MODE>")])
15461 (define_insn "fist<mode>2_<rounding>_with_temp"
15462   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15463         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15464                       FIST_ROUNDING))
15465    (use (match_operand:HI 2 "memory_operand" "m,m"))
15466    (use (match_operand:HI 3 "memory_operand" "m,m"))
15467    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15468   "TARGET_USE_FANCY_MATH_387
15469    && flag_unsafe_math_optimizations"
15470   "#"
15471   [(set_attr "type" "fistp")
15472    (set_attr "i387_cw" "<rounding>")
15473    (set_attr "mode" "<MODE>")])
15475 (define_split
15476   [(set (match_operand:SWI24 0 "register_operand")
15477         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15478                       FIST_ROUNDING))
15479    (use (match_operand:HI 2 "memory_operand"))
15480    (use (match_operand:HI 3 "memory_operand"))
15481    (clobber (match_operand:SWI24 4 "memory_operand"))]
15482   "reload_completed"
15483   [(parallel [(set (match_dup 4)
15484                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15485               (use (match_dup 2))
15486               (use (match_dup 3))])
15487    (set (match_dup 0) (match_dup 4))])
15489 (define_split
15490   [(set (match_operand:SWI24 0 "memory_operand")
15491         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15492                       FIST_ROUNDING))
15493    (use (match_operand:HI 2 "memory_operand"))
15494    (use (match_operand:HI 3 "memory_operand"))
15495    (clobber (match_operand:SWI24 4 "memory_operand"))]
15496   "reload_completed"
15497   [(parallel [(set (match_dup 0)
15498                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15499               (use (match_dup 2))
15500               (use (match_dup 3))])])
15502 (define_expand "l<rounding_insn>xf<mode>2"
15503   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15504                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15505                                    FIST_ROUNDING))
15506               (clobber (reg:CC FLAGS_REG))])]
15507   "TARGET_USE_FANCY_MATH_387
15508    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15509    && flag_unsafe_math_optimizations")
15511 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15512   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15513                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15514                                  FIST_ROUNDING))
15515               (clobber (reg:CC FLAGS_REG))])]
15516   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15517    && !flag_trapping_math"
15519   if (TARGET_64BIT && optimize_insn_for_size_p ())
15520     FAIL;
15522   if (ROUND_<ROUNDING> == ROUND_FLOOR)
15523     ix86_expand_lfloorceil (operands[0], operands[1], true);
15524   else if (ROUND_<ROUNDING> == ROUND_CEIL)
15525     ix86_expand_lfloorceil (operands[0], operands[1], false);
15526   else
15527     gcc_unreachable ();
15529   DONE;
15532 (define_insn "fxam<mode>2_i387"
15533   [(set (match_operand:HI 0 "register_operand" "=a")
15534         (unspec:HI
15535           [(match_operand:X87MODEF 1 "register_operand" "f")]
15536           UNSPEC_FXAM))]
15537   "TARGET_USE_FANCY_MATH_387"
15538   "fxam\n\tfnstsw\t%0"
15539   [(set_attr "type" "multi")
15540    (set_attr "length" "4")
15541    (set_attr "unit" "i387")
15542    (set_attr "mode" "<MODE>")])
15544 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15545   [(set (match_operand:HI 0 "register_operand")
15546         (unspec:HI
15547           [(match_operand:MODEF 1 "memory_operand")]
15548           UNSPEC_FXAM_MEM))]
15549   "TARGET_USE_FANCY_MATH_387
15550    && can_create_pseudo_p ()"
15551   "#"
15552   "&& 1"
15553   [(set (match_dup 2)(match_dup 1))
15554    (set (match_dup 0)
15555         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15557   operands[2] = gen_reg_rtx (<MODE>mode);
15559   MEM_VOLATILE_P (operands[1]) = 1;
15561   [(set_attr "type" "multi")
15562    (set_attr "unit" "i387")
15563    (set_attr "mode" "<MODE>")])
15565 (define_expand "isinfxf2"
15566   [(use (match_operand:SI 0 "register_operand"))
15567    (use (match_operand:XF 1 "register_operand"))]
15568   "TARGET_USE_FANCY_MATH_387
15569    && ix86_libc_has_function (function_c99_misc)"
15571   rtx mask = GEN_INT (0x45);
15572   rtx val = GEN_INT (0x05);
15574   rtx cond;
15576   rtx scratch = gen_reg_rtx (HImode);
15577   rtx res = gen_reg_rtx (QImode);
15579   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15581   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15582   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15583   cond = gen_rtx_fmt_ee (EQ, QImode,
15584                          gen_rtx_REG (CCmode, FLAGS_REG),
15585                          const0_rtx);
15586   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15587   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15588   DONE;
15591 (define_expand "isinf<mode>2"
15592   [(use (match_operand:SI 0 "register_operand"))
15593    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15594   "TARGET_USE_FANCY_MATH_387
15595    && ix86_libc_has_function (function_c99_misc)
15596    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15598   rtx mask = GEN_INT (0x45);
15599   rtx val = GEN_INT (0x05);
15601   rtx cond;
15603   rtx scratch = gen_reg_rtx (HImode);
15604   rtx res = gen_reg_rtx (QImode);
15606   /* Remove excess precision by forcing value through memory. */
15607   if (memory_operand (operands[1], VOIDmode))
15608     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15609   else
15610     {
15611       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15613       emit_move_insn (temp, operands[1]);
15614       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15615     }
15617   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15618   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15619   cond = gen_rtx_fmt_ee (EQ, QImode,
15620                          gen_rtx_REG (CCmode, FLAGS_REG),
15621                          const0_rtx);
15622   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15623   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15624   DONE;
15627 (define_expand "signbitxf2"
15628   [(use (match_operand:SI 0 "register_operand"))
15629    (use (match_operand:XF 1 "register_operand"))]
15630   "TARGET_USE_FANCY_MATH_387"
15632   rtx scratch = gen_reg_rtx (HImode);
15634   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15635   emit_insn (gen_andsi3 (operands[0],
15636              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15637   DONE;
15640 (define_insn "movmsk_df"
15641   [(set (match_operand:SI 0 "register_operand" "=r")
15642         (unspec:SI
15643           [(match_operand:DF 1 "register_operand" "x")]
15644           UNSPEC_MOVMSK))]
15645   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15646   "%vmovmskpd\t{%1, %0|%0, %1}"
15647   [(set_attr "type" "ssemov")
15648    (set_attr "prefix" "maybe_vex")
15649    (set_attr "mode" "DF")])
15651 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15652 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15653 (define_expand "signbitdf2"
15654   [(use (match_operand:SI 0 "register_operand"))
15655    (use (match_operand:DF 1 "register_operand"))]
15656   "TARGET_USE_FANCY_MATH_387
15657    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15659   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15660     {
15661       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15662       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15663     }
15664   else
15665     {
15666       rtx scratch = gen_reg_rtx (HImode);
15668       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15669       emit_insn (gen_andsi3 (operands[0],
15670                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15671     }
15672   DONE;
15675 (define_expand "signbitsf2"
15676   [(use (match_operand:SI 0 "register_operand"))
15677    (use (match_operand:SF 1 "register_operand"))]
15678   "TARGET_USE_FANCY_MATH_387
15679    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15681   rtx scratch = gen_reg_rtx (HImode);
15683   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15684   emit_insn (gen_andsi3 (operands[0],
15685              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15686   DONE;
15689 ;; Block operation instructions
15691 (define_insn "cld"
15692   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15693   ""
15694   "cld"
15695   [(set_attr "length" "1")
15696    (set_attr "length_immediate" "0")
15697    (set_attr "modrm" "0")])
15699 (define_expand "movmem<mode>"
15700   [(use (match_operand:BLK 0 "memory_operand"))
15701    (use (match_operand:BLK 1 "memory_operand"))
15702    (use (match_operand:SWI48 2 "nonmemory_operand"))
15703    (use (match_operand:SWI48 3 "const_int_operand"))
15704    (use (match_operand:SI 4 "const_int_operand"))
15705    (use (match_operand:SI 5 "const_int_operand"))
15706    (use (match_operand:SI 6 ""))
15707    (use (match_operand:SI 7 ""))
15708    (use (match_operand:SI 8 ""))]
15709   ""
15711  if (ix86_expand_set_or_movmem (operands[0], operands[1],
15712                                 operands[2], NULL, operands[3],
15713                                 operands[4], operands[5],
15714                                 operands[6], operands[7],
15715                                 operands[8], false))
15716    DONE;
15717  else
15718    FAIL;
15721 ;; Most CPUs don't like single string operations
15722 ;; Handle this case here to simplify previous expander.
15724 (define_expand "strmov"
15725   [(set (match_dup 4) (match_operand 3 "memory_operand"))
15726    (set (match_operand 1 "memory_operand") (match_dup 4))
15727    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15728               (clobber (reg:CC FLAGS_REG))])
15729    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15730               (clobber (reg:CC FLAGS_REG))])]
15731   ""
15733   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15735   /* If .md ever supports :P for Pmode, these can be directly
15736      in the pattern above.  */
15737   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15738   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15740   /* Can't use this if the user has appropriated esi or edi.  */
15741   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15742       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15743     {
15744       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15745                                       operands[2], operands[3],
15746                                       operands[5], operands[6]));
15747       DONE;
15748     }
15750   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15753 (define_expand "strmov_singleop"
15754   [(parallel [(set (match_operand 1 "memory_operand")
15755                    (match_operand 3 "memory_operand"))
15756               (set (match_operand 0 "register_operand")
15757                    (match_operand 4))
15758               (set (match_operand 2 "register_operand")
15759                    (match_operand 5))])]
15760   ""
15761   "ix86_current_function_needs_cld = 1;")
15763 (define_insn "*strmovdi_rex_1"
15764   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15765         (mem:DI (match_operand:P 3 "register_operand" "1")))
15766    (set (match_operand:P 0 "register_operand" "=D")
15767         (plus:P (match_dup 2)
15768                 (const_int 8)))
15769    (set (match_operand:P 1 "register_operand" "=S")
15770         (plus:P (match_dup 3)
15771                 (const_int 8)))]
15772   "TARGET_64BIT
15773    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15774   "%^movsq"
15775   [(set_attr "type" "str")
15776    (set_attr "memory" "both")
15777    (set_attr "mode" "DI")])
15779 (define_insn "*strmovsi_1"
15780   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15781         (mem:SI (match_operand:P 3 "register_operand" "1")))
15782    (set (match_operand:P 0 "register_operand" "=D")
15783         (plus:P (match_dup 2)
15784                 (const_int 4)))
15785    (set (match_operand:P 1 "register_operand" "=S")
15786         (plus:P (match_dup 3)
15787                 (const_int 4)))]
15788   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15789   "%^movs{l|d}"
15790   [(set_attr "type" "str")
15791    (set_attr "memory" "both")
15792    (set_attr "mode" "SI")])
15794 (define_insn "*strmovhi_1"
15795   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15796         (mem:HI (match_operand:P 3 "register_operand" "1")))
15797    (set (match_operand:P 0 "register_operand" "=D")
15798         (plus:P (match_dup 2)
15799                 (const_int 2)))
15800    (set (match_operand:P 1 "register_operand" "=S")
15801         (plus:P (match_dup 3)
15802                 (const_int 2)))]
15803   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15804   "%^movsw"
15805   [(set_attr "type" "str")
15806    (set_attr "memory" "both")
15807    (set_attr "mode" "HI")])
15809 (define_insn "*strmovqi_1"
15810   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15811         (mem:QI (match_operand:P 3 "register_operand" "1")))
15812    (set (match_operand:P 0 "register_operand" "=D")
15813         (plus:P (match_dup 2)
15814                 (const_int 1)))
15815    (set (match_operand:P 1 "register_operand" "=S")
15816         (plus:P (match_dup 3)
15817                 (const_int 1)))]
15818   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15819   "%^movsb"
15820   [(set_attr "type" "str")
15821    (set_attr "memory" "both")
15822    (set (attr "prefix_rex")
15823         (if_then_else
15824           (match_test "<P:MODE>mode == DImode")
15825           (const_string "0")
15826           (const_string "*")))
15827    (set_attr "mode" "QI")])
15829 (define_expand "rep_mov"
15830   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15831               (set (match_operand 0 "register_operand")
15832                    (match_operand 5))
15833               (set (match_operand 2 "register_operand")
15834                    (match_operand 6))
15835               (set (match_operand 1 "memory_operand")
15836                    (match_operand 3 "memory_operand"))
15837               (use (match_dup 4))])]
15838   ""
15839   "ix86_current_function_needs_cld = 1;")
15841 (define_insn "*rep_movdi_rex64"
15842   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15843    (set (match_operand:P 0 "register_operand" "=D")
15844         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15845                           (const_int 3))
15846                 (match_operand:P 3 "register_operand" "0")))
15847    (set (match_operand:P 1 "register_operand" "=S")
15848         (plus:P (ashift:P (match_dup 5) (const_int 3))
15849                 (match_operand:P 4 "register_operand" "1")))
15850    (set (mem:BLK (match_dup 3))
15851         (mem:BLK (match_dup 4)))
15852    (use (match_dup 5))]
15853   "TARGET_64BIT
15854    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15855   "%^rep{%;} movsq"
15856   [(set_attr "type" "str")
15857    (set_attr "prefix_rep" "1")
15858    (set_attr "memory" "both")
15859    (set_attr "mode" "DI")])
15861 (define_insn "*rep_movsi"
15862   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15863    (set (match_operand:P 0 "register_operand" "=D")
15864         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15865                           (const_int 2))
15866                  (match_operand:P 3 "register_operand" "0")))
15867    (set (match_operand:P 1 "register_operand" "=S")
15868         (plus:P (ashift:P (match_dup 5) (const_int 2))
15869                 (match_operand:P 4 "register_operand" "1")))
15870    (set (mem:BLK (match_dup 3))
15871         (mem:BLK (match_dup 4)))
15872    (use (match_dup 5))]
15873   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15874   "%^rep{%;} movs{l|d}"
15875   [(set_attr "type" "str")
15876    (set_attr "prefix_rep" "1")
15877    (set_attr "memory" "both")
15878    (set_attr "mode" "SI")])
15880 (define_insn "*rep_movqi"
15881   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15882    (set (match_operand:P 0 "register_operand" "=D")
15883         (plus:P (match_operand:P 3 "register_operand" "0")
15884                 (match_operand:P 5 "register_operand" "2")))
15885    (set (match_operand:P 1 "register_operand" "=S")
15886         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15887    (set (mem:BLK (match_dup 3))
15888         (mem:BLK (match_dup 4)))
15889    (use (match_dup 5))]
15890   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15891   "%^rep{%;} movsb"
15892   [(set_attr "type" "str")
15893    (set_attr "prefix_rep" "1")
15894    (set_attr "memory" "both")
15895    (set_attr "mode" "QI")])
15897 (define_expand "setmem<mode>"
15898    [(use (match_operand:BLK 0 "memory_operand"))
15899     (use (match_operand:SWI48 1 "nonmemory_operand"))
15900     (use (match_operand:QI 2 "nonmemory_operand"))
15901     (use (match_operand 3 "const_int_operand"))
15902     (use (match_operand:SI 4 "const_int_operand"))
15903     (use (match_operand:SI 5 "const_int_operand"))
15904     (use (match_operand:SI 6 ""))
15905     (use (match_operand:SI 7 ""))
15906     (use (match_operand:SI 8 ""))]
15907   ""
15909  if (ix86_expand_set_or_movmem (operands[0], NULL,
15910                                 operands[1], operands[2],
15911                                 operands[3], operands[4],
15912                                 operands[5], operands[6],
15913                                 operands[7], operands[8], true))
15914    DONE;
15915  else
15916    FAIL;
15919 ;; Most CPUs don't like single string operations
15920 ;; Handle this case here to simplify previous expander.
15922 (define_expand "strset"
15923   [(set (match_operand 1 "memory_operand")
15924         (match_operand 2 "register_operand"))
15925    (parallel [(set (match_operand 0 "register_operand")
15926                    (match_dup 3))
15927               (clobber (reg:CC FLAGS_REG))])]
15928   ""
15930   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15931     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15933   /* If .md ever supports :P for Pmode, this can be directly
15934      in the pattern above.  */
15935   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15936                               GEN_INT (GET_MODE_SIZE (GET_MODE
15937                                                       (operands[2]))));
15938   /* Can't use this if the user has appropriated eax or edi.  */
15939   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15940       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15941     {
15942       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15943                                       operands[3]));
15944       DONE;
15945     }
15948 (define_expand "strset_singleop"
15949   [(parallel [(set (match_operand 1 "memory_operand")
15950                    (match_operand 2 "register_operand"))
15951               (set (match_operand 0 "register_operand")
15952                    (match_operand 3))
15953               (unspec [(const_int 0)] UNSPEC_STOS)])]
15954   ""
15955   "ix86_current_function_needs_cld = 1;")
15957 (define_insn "*strsetdi_rex_1"
15958   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15959         (match_operand:DI 2 "register_operand" "a"))
15960    (set (match_operand:P 0 "register_operand" "=D")
15961         (plus:P (match_dup 1)
15962                 (const_int 8)))
15963    (unspec [(const_int 0)] UNSPEC_STOS)]
15964   "TARGET_64BIT
15965    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15966   "%^stosq"
15967   [(set_attr "type" "str")
15968    (set_attr "memory" "store")
15969    (set_attr "mode" "DI")])
15971 (define_insn "*strsetsi_1"
15972   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15973         (match_operand:SI 2 "register_operand" "a"))
15974    (set (match_operand:P 0 "register_operand" "=D")
15975         (plus:P (match_dup 1)
15976                 (const_int 4)))
15977    (unspec [(const_int 0)] UNSPEC_STOS)]
15978   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15979   "%^stos{l|d}"
15980   [(set_attr "type" "str")
15981    (set_attr "memory" "store")
15982    (set_attr "mode" "SI")])
15984 (define_insn "*strsethi_1"
15985   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15986         (match_operand:HI 2 "register_operand" "a"))
15987    (set (match_operand:P 0 "register_operand" "=D")
15988         (plus:P (match_dup 1)
15989                 (const_int 2)))
15990    (unspec [(const_int 0)] UNSPEC_STOS)]
15991   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15992   "%^stosw"
15993   [(set_attr "type" "str")
15994    (set_attr "memory" "store")
15995    (set_attr "mode" "HI")])
15997 (define_insn "*strsetqi_1"
15998   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15999         (match_operand:QI 2 "register_operand" "a"))
16000    (set (match_operand:P 0 "register_operand" "=D")
16001         (plus:P (match_dup 1)
16002                 (const_int 1)))
16003    (unspec [(const_int 0)] UNSPEC_STOS)]
16004   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16005   "%^stosb"
16006   [(set_attr "type" "str")
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 "rep_stos"
16016   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16017               (set (match_operand 0 "register_operand")
16018                    (match_operand 4))
16019               (set (match_operand 2 "memory_operand") (const_int 0))
16020               (use (match_operand 3 "register_operand"))
16021               (use (match_dup 1))])]
16022   ""
16023   "ix86_current_function_needs_cld = 1;")
16025 (define_insn "*rep_stosdi_rex64"
16026   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16027    (set (match_operand:P 0 "register_operand" "=D")
16028         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16029                           (const_int 3))
16030                  (match_operand:P 3 "register_operand" "0")))
16031    (set (mem:BLK (match_dup 3))
16032         (const_int 0))
16033    (use (match_operand:DI 2 "register_operand" "a"))
16034    (use (match_dup 4))]
16035   "TARGET_64BIT
16036    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16037   "%^rep{%;} stosq"
16038   [(set_attr "type" "str")
16039    (set_attr "prefix_rep" "1")
16040    (set_attr "memory" "store")
16041    (set_attr "mode" "DI")])
16043 (define_insn "*rep_stossi"
16044   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16045    (set (match_operand:P 0 "register_operand" "=D")
16046         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16047                           (const_int 2))
16048                  (match_operand:P 3 "register_operand" "0")))
16049    (set (mem:BLK (match_dup 3))
16050         (const_int 0))
16051    (use (match_operand:SI 2 "register_operand" "a"))
16052    (use (match_dup 4))]
16053   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16054   "%^rep{%;} stos{l|d}"
16055   [(set_attr "type" "str")
16056    (set_attr "prefix_rep" "1")
16057    (set_attr "memory" "store")
16058    (set_attr "mode" "SI")])
16060 (define_insn "*rep_stosqi"
16061   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16062    (set (match_operand:P 0 "register_operand" "=D")
16063         (plus:P (match_operand:P 3 "register_operand" "0")
16064                 (match_operand:P 4 "register_operand" "1")))
16065    (set (mem:BLK (match_dup 3))
16066         (const_int 0))
16067    (use (match_operand:QI 2 "register_operand" "a"))
16068    (use (match_dup 4))]
16069   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16070   "%^rep{%;} stosb"
16071   [(set_attr "type" "str")
16072    (set_attr "prefix_rep" "1")
16073    (set_attr "memory" "store")
16074    (set (attr "prefix_rex")
16075         (if_then_else
16076           (match_test "<P:MODE>mode == DImode")
16077           (const_string "0")
16078           (const_string "*")))
16079    (set_attr "mode" "QI")])
16081 (define_expand "cmpstrnsi"
16082   [(set (match_operand:SI 0 "register_operand")
16083         (compare:SI (match_operand:BLK 1 "general_operand")
16084                     (match_operand:BLK 2 "general_operand")))
16085    (use (match_operand 3 "general_operand"))
16086    (use (match_operand 4 "immediate_operand"))]
16087   ""
16089   rtx addr1, addr2, out, outlow, count, countreg, align;
16091   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16092     FAIL;
16094   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16095   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16096     FAIL;
16098   out = operands[0];
16099   if (!REG_P (out))
16100     out = gen_reg_rtx (SImode);
16102   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16103   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16104   if (addr1 != XEXP (operands[1], 0))
16105     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16106   if (addr2 != XEXP (operands[2], 0))
16107     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16109   count = operands[3];
16110   countreg = ix86_zero_extend_to_Pmode (count);
16112   /* %%% Iff we are testing strict equality, we can use known alignment
16113      to good advantage.  This may be possible with combine, particularly
16114      once cc0 is dead.  */
16115   align = operands[4];
16117   if (CONST_INT_P (count))
16118     {
16119       if (INTVAL (count) == 0)
16120         {
16121           emit_move_insn (operands[0], const0_rtx);
16122           DONE;
16123         }
16124       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16125                                      operands[1], operands[2]));
16126     }
16127   else
16128     {
16129       rtx (*gen_cmp) (rtx, rtx);
16131       gen_cmp = (TARGET_64BIT
16132                  ? gen_cmpdi_1 : gen_cmpsi_1);
16134       emit_insn (gen_cmp (countreg, countreg));
16135       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16136                                   operands[1], operands[2]));
16137     }
16139   outlow = gen_lowpart (QImode, out);
16140   emit_insn (gen_cmpintqi (outlow));
16141   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16143   if (operands[0] != out)
16144     emit_move_insn (operands[0], out);
16146   DONE;
16149 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16151 (define_expand "cmpintqi"
16152   [(set (match_dup 1)
16153         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16154    (set (match_dup 2)
16155         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16156    (parallel [(set (match_operand:QI 0 "register_operand")
16157                    (minus:QI (match_dup 1)
16158                              (match_dup 2)))
16159               (clobber (reg:CC FLAGS_REG))])]
16160   ""
16162   operands[1] = gen_reg_rtx (QImode);
16163   operands[2] = gen_reg_rtx (QImode);
16166 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16167 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16169 (define_expand "cmpstrnqi_nz_1"
16170   [(parallel [(set (reg:CC FLAGS_REG)
16171                    (compare:CC (match_operand 4 "memory_operand")
16172                                (match_operand 5 "memory_operand")))
16173               (use (match_operand 2 "register_operand"))
16174               (use (match_operand:SI 3 "immediate_operand"))
16175               (clobber (match_operand 0 "register_operand"))
16176               (clobber (match_operand 1 "register_operand"))
16177               (clobber (match_dup 2))])]
16178   ""
16179   "ix86_current_function_needs_cld = 1;")
16181 (define_insn "*cmpstrnqi_nz_1"
16182   [(set (reg:CC FLAGS_REG)
16183         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16184                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16185    (use (match_operand:P 6 "register_operand" "2"))
16186    (use (match_operand:SI 3 "immediate_operand" "i"))
16187    (clobber (match_operand:P 0 "register_operand" "=S"))
16188    (clobber (match_operand:P 1 "register_operand" "=D"))
16189    (clobber (match_operand:P 2 "register_operand" "=c"))]
16190   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16191   "%^repz{%;} cmpsb"
16192   [(set_attr "type" "str")
16193    (set_attr "mode" "QI")
16194    (set (attr "prefix_rex")
16195         (if_then_else
16196           (match_test "<P:MODE>mode == DImode")
16197           (const_string "0")
16198           (const_string "*")))
16199    (set_attr "prefix_rep" "1")])
16201 ;; The same, but the count is not known to not be zero.
16203 (define_expand "cmpstrnqi_1"
16204   [(parallel [(set (reg:CC FLAGS_REG)
16205                 (if_then_else:CC (ne (match_operand 2 "register_operand")
16206                                      (const_int 0))
16207                   (compare:CC (match_operand 4 "memory_operand")
16208                               (match_operand 5 "memory_operand"))
16209                   (const_int 0)))
16210               (use (match_operand:SI 3 "immediate_operand"))
16211               (use (reg:CC FLAGS_REG))
16212               (clobber (match_operand 0 "register_operand"))
16213               (clobber (match_operand 1 "register_operand"))
16214               (clobber (match_dup 2))])]
16215   ""
16216   "ix86_current_function_needs_cld = 1;")
16218 (define_insn "*cmpstrnqi_1"
16219   [(set (reg:CC FLAGS_REG)
16220         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16221                              (const_int 0))
16222           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16223                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16224           (const_int 0)))
16225    (use (match_operand:SI 3 "immediate_operand" "i"))
16226    (use (reg:CC FLAGS_REG))
16227    (clobber (match_operand:P 0 "register_operand" "=S"))
16228    (clobber (match_operand:P 1 "register_operand" "=D"))
16229    (clobber (match_operand:P 2 "register_operand" "=c"))]
16230   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16231   "%^repz{%;} cmpsb"
16232   [(set_attr "type" "str")
16233    (set_attr "mode" "QI")
16234    (set (attr "prefix_rex")
16235         (if_then_else
16236           (match_test "<P:MODE>mode == DImode")
16237           (const_string "0")
16238           (const_string "*")))
16239    (set_attr "prefix_rep" "1")])
16241 (define_expand "strlen<mode>"
16242   [(set (match_operand:P 0 "register_operand")
16243         (unspec:P [(match_operand:BLK 1 "general_operand")
16244                    (match_operand:QI 2 "immediate_operand")
16245                    (match_operand 3 "immediate_operand")]
16246                   UNSPEC_SCAS))]
16247   ""
16249  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16250    DONE;
16251  else
16252    FAIL;
16255 (define_expand "strlenqi_1"
16256   [(parallel [(set (match_operand 0 "register_operand")
16257                    (match_operand 2))
16258               (clobber (match_operand 1 "register_operand"))
16259               (clobber (reg:CC FLAGS_REG))])]
16260   ""
16261   "ix86_current_function_needs_cld = 1;")
16263 (define_insn "*strlenqi_1"
16264   [(set (match_operand:P 0 "register_operand" "=&c")
16265         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16266                    (match_operand:QI 2 "register_operand" "a")
16267                    (match_operand:P 3 "immediate_operand" "i")
16268                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16269    (clobber (match_operand:P 1 "register_operand" "=D"))
16270    (clobber (reg:CC FLAGS_REG))]
16271   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16272   "%^repnz{%;} scasb"
16273   [(set_attr "type" "str")
16274    (set_attr "mode" "QI")
16275    (set (attr "prefix_rex")
16276         (if_then_else
16277           (match_test "<P:MODE>mode == DImode")
16278           (const_string "0")
16279           (const_string "*")))
16280    (set_attr "prefix_rep" "1")])
16282 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16283 ;; handled in combine, but it is not currently up to the task.
16284 ;; When used for their truth value, the cmpstrn* expanders generate
16285 ;; code like this:
16287 ;;   repz cmpsb
16288 ;;   seta       %al
16289 ;;   setb       %dl
16290 ;;   cmpb       %al, %dl
16291 ;;   jcc        label
16293 ;; The intermediate three instructions are unnecessary.
16295 ;; This one handles cmpstrn*_nz_1...
16296 (define_peephole2
16297   [(parallel[
16298      (set (reg:CC FLAGS_REG)
16299           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16300                       (mem:BLK (match_operand 5 "register_operand"))))
16301      (use (match_operand 6 "register_operand"))
16302      (use (match_operand:SI 3 "immediate_operand"))
16303      (clobber (match_operand 0 "register_operand"))
16304      (clobber (match_operand 1 "register_operand"))
16305      (clobber (match_operand 2 "register_operand"))])
16306    (set (match_operand:QI 7 "register_operand")
16307         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16308    (set (match_operand:QI 8 "register_operand")
16309         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16310    (set (reg FLAGS_REG)
16311         (compare (match_dup 7) (match_dup 8)))
16312   ]
16313   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16314   [(parallel[
16315      (set (reg:CC FLAGS_REG)
16316           (compare:CC (mem:BLK (match_dup 4))
16317                       (mem:BLK (match_dup 5))))
16318      (use (match_dup 6))
16319      (use (match_dup 3))
16320      (clobber (match_dup 0))
16321      (clobber (match_dup 1))
16322      (clobber (match_dup 2))])])
16324 ;; ...and this one handles cmpstrn*_1.
16325 (define_peephole2
16326   [(parallel[
16327      (set (reg:CC FLAGS_REG)
16328           (if_then_else:CC (ne (match_operand 6 "register_operand")
16329                                (const_int 0))
16330             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16331                         (mem:BLK (match_operand 5 "register_operand")))
16332             (const_int 0)))
16333      (use (match_operand:SI 3 "immediate_operand"))
16334      (use (reg:CC FLAGS_REG))
16335      (clobber (match_operand 0 "register_operand"))
16336      (clobber (match_operand 1 "register_operand"))
16337      (clobber (match_operand 2 "register_operand"))])
16338    (set (match_operand:QI 7 "register_operand")
16339         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16340    (set (match_operand:QI 8 "register_operand")
16341         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16342    (set (reg FLAGS_REG)
16343         (compare (match_dup 7) (match_dup 8)))
16344   ]
16345   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16346   [(parallel[
16347      (set (reg:CC FLAGS_REG)
16348           (if_then_else:CC (ne (match_dup 6)
16349                                (const_int 0))
16350             (compare:CC (mem:BLK (match_dup 4))
16351                         (mem:BLK (match_dup 5)))
16352             (const_int 0)))
16353      (use (match_dup 3))
16354      (use (reg:CC FLAGS_REG))
16355      (clobber (match_dup 0))
16356      (clobber (match_dup 1))
16357      (clobber (match_dup 2))])])
16359 ;; Conditional move instructions.
16361 (define_expand "mov<mode>cc"
16362   [(set (match_operand:SWIM 0 "register_operand")
16363         (if_then_else:SWIM (match_operand 1 "comparison_operator")
16364                            (match_operand:SWIM 2 "<general_operand>")
16365                            (match_operand:SWIM 3 "<general_operand>")))]
16366   ""
16367   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16369 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16370 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16371 ;; So just document what we're doing explicitly.
16373 (define_expand "x86_mov<mode>cc_0_m1"
16374   [(parallel
16375     [(set (match_operand:SWI48 0 "register_operand")
16376           (if_then_else:SWI48
16377             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16378              [(match_operand 1 "flags_reg_operand")
16379               (const_int 0)])
16380             (const_int -1)
16381             (const_int 0)))
16382      (clobber (reg:CC FLAGS_REG))])])
16384 (define_insn "*x86_mov<mode>cc_0_m1"
16385   [(set (match_operand:SWI48 0 "register_operand" "=r")
16386         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16387                              [(reg FLAGS_REG) (const_int 0)])
16388           (const_int -1)
16389           (const_int 0)))
16390    (clobber (reg:CC FLAGS_REG))]
16391   ""
16392   "sbb{<imodesuffix>}\t%0, %0"
16393   ; Since we don't have the proper number of operands for an alu insn,
16394   ; fill in all the blanks.
16395   [(set_attr "type" "alu")
16396    (set_attr "use_carry" "1")
16397    (set_attr "pent_pair" "pu")
16398    (set_attr "memory" "none")
16399    (set_attr "imm_disp" "false")
16400    (set_attr "mode" "<MODE>")
16401    (set_attr "length_immediate" "0")])
16403 (define_insn "*x86_mov<mode>cc_0_m1_se"
16404   [(set (match_operand:SWI48 0 "register_operand" "=r")
16405         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16406                              [(reg FLAGS_REG) (const_int 0)])
16407                             (const_int 1)
16408                             (const_int 0)))
16409    (clobber (reg:CC FLAGS_REG))]
16410   ""
16411   "sbb{<imodesuffix>}\t%0, %0"
16412   [(set_attr "type" "alu")
16413    (set_attr "use_carry" "1")
16414    (set_attr "pent_pair" "pu")
16415    (set_attr "memory" "none")
16416    (set_attr "imm_disp" "false")
16417    (set_attr "mode" "<MODE>")
16418    (set_attr "length_immediate" "0")])
16420 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16421   [(set (match_operand:SWI48 0 "register_operand" "=r")
16422         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16423                     [(reg FLAGS_REG) (const_int 0)])))
16424    (clobber (reg:CC FLAGS_REG))]
16425   ""
16426   "sbb{<imodesuffix>}\t%0, %0"
16427   [(set_attr "type" "alu")
16428    (set_attr "use_carry" "1")
16429    (set_attr "pent_pair" "pu")
16430    (set_attr "memory" "none")
16431    (set_attr "imm_disp" "false")
16432    (set_attr "mode" "<MODE>")
16433    (set_attr "length_immediate" "0")])
16435 (define_insn "*mov<mode>cc_noc"
16436   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16437         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16438                                [(reg FLAGS_REG) (const_int 0)])
16439           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16440           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16441   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16442   "@
16443    cmov%O2%C1\t{%2, %0|%0, %2}
16444    cmov%O2%c1\t{%3, %0|%0, %3}"
16445   [(set_attr "type" "icmov")
16446    (set_attr "mode" "<MODE>")])
16448 ;; Don't do conditional moves with memory inputs.  This splitter helps
16449 ;; register starved x86_32 by forcing inputs into registers before reload.
16450 (define_split
16451   [(set (match_operand:SWI248 0 "register_operand")
16452         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16453                                [(reg FLAGS_REG) (const_int 0)])
16454           (match_operand:SWI248 2 "nonimmediate_operand")
16455           (match_operand:SWI248 3 "nonimmediate_operand")))]
16456   "!TARGET_64BIT && TARGET_CMOVE
16457    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16458    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16459    && can_create_pseudo_p ()
16460    && optimize_insn_for_speed_p ()"
16461   [(set (match_dup 0)
16462         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16464   if (MEM_P (operands[2]))
16465     operands[2] = force_reg (<MODE>mode, operands[2]);
16466   if (MEM_P (operands[3]))
16467     operands[3] = force_reg (<MODE>mode, operands[3]);
16470 (define_insn "*movqicc_noc"
16471   [(set (match_operand:QI 0 "register_operand" "=r,r")
16472         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16473                            [(reg FLAGS_REG) (const_int 0)])
16474                       (match_operand:QI 2 "register_operand" "r,0")
16475                       (match_operand:QI 3 "register_operand" "0,r")))]
16476   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16477   "#"
16478   [(set_attr "type" "icmov")
16479    (set_attr "mode" "QI")])
16481 (define_split
16482   [(set (match_operand:SWI12 0 "register_operand")
16483         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16484                               [(reg FLAGS_REG) (const_int 0)])
16485                       (match_operand:SWI12 2 "register_operand")
16486                       (match_operand:SWI12 3 "register_operand")))]
16487   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16488    && reload_completed"
16489   [(set (match_dup 0)
16490         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16492   operands[0] = gen_lowpart (SImode, operands[0]);
16493   operands[2] = gen_lowpart (SImode, operands[2]);
16494   operands[3] = gen_lowpart (SImode, operands[3]);
16497 ;; Don't do conditional moves with memory inputs
16498 (define_peephole2
16499   [(match_scratch:SWI248 2 "r")
16500    (set (match_operand:SWI248 0 "register_operand")
16501         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16502                                [(reg FLAGS_REG) (const_int 0)])
16503           (match_dup 0)
16504           (match_operand:SWI248 3 "memory_operand")))]
16505   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16506    && optimize_insn_for_speed_p ()"
16507   [(set (match_dup 2) (match_dup 3))
16508    (set (match_dup 0)
16509         (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16511 (define_peephole2
16512   [(match_scratch:SWI248 2 "r")
16513    (set (match_operand:SWI248 0 "register_operand")
16514         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16515                                [(reg FLAGS_REG) (const_int 0)])
16516           (match_operand:SWI248 3 "memory_operand")
16517           (match_dup 0)))]
16518   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16519    && optimize_insn_for_speed_p ()"
16520   [(set (match_dup 2) (match_dup 3))
16521    (set (match_dup 0)
16522         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16524 (define_expand "mov<mode>cc"
16525   [(set (match_operand:X87MODEF 0 "register_operand")
16526         (if_then_else:X87MODEF
16527           (match_operand 1 "comparison_operator")
16528           (match_operand:X87MODEF 2 "register_operand")
16529           (match_operand:X87MODEF 3 "register_operand")))]
16530   "(TARGET_80387 && TARGET_CMOVE)
16531    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16532   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16534 (define_insn "*movxfcc_1"
16535   [(set (match_operand:XF 0 "register_operand" "=f,f")
16536         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16537                                 [(reg FLAGS_REG) (const_int 0)])
16538                       (match_operand:XF 2 "register_operand" "f,0")
16539                       (match_operand:XF 3 "register_operand" "0,f")))]
16540   "TARGET_80387 && TARGET_CMOVE"
16541   "@
16542    fcmov%F1\t{%2, %0|%0, %2}
16543    fcmov%f1\t{%3, %0|%0, %3}"
16544   [(set_attr "type" "fcmov")
16545    (set_attr "mode" "XF")])
16547 (define_insn "*movdfcc_1"
16548   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16549         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16550                                 [(reg FLAGS_REG) (const_int 0)])
16551                       (match_operand:DF 2 "nonimmediate_operand"
16552                                                "f ,0,rm,0 ,rm,0")
16553                       (match_operand:DF 3 "nonimmediate_operand"
16554                                                "0 ,f,0 ,rm,0, rm")))]
16555   "TARGET_80387 && TARGET_CMOVE
16556    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16557   "@
16558    fcmov%F1\t{%2, %0|%0, %2}
16559    fcmov%f1\t{%3, %0|%0, %3}
16560    #
16561    #
16562    cmov%O2%C1\t{%2, %0|%0, %2}
16563    cmov%O2%c1\t{%3, %0|%0, %3}"
16564   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16565    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16566    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16568 (define_split
16569   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16570         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16571                                 [(reg FLAGS_REG) (const_int 0)])
16572                       (match_operand:DF 2 "nonimmediate_operand")
16573                       (match_operand:DF 3 "nonimmediate_operand")))]
16574   "!TARGET_64BIT && reload_completed"
16575   [(set (match_dup 2)
16576         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16577    (set (match_dup 3)
16578         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16580   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16581   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16584 (define_insn "*movsfcc_1_387"
16585   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16586         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16587                                 [(reg FLAGS_REG) (const_int 0)])
16588                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16589                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16590   "TARGET_80387 && TARGET_CMOVE
16591    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16592   "@
16593    fcmov%F1\t{%2, %0|%0, %2}
16594    fcmov%f1\t{%3, %0|%0, %3}
16595    cmov%O2%C1\t{%2, %0|%0, %2}
16596    cmov%O2%c1\t{%3, %0|%0, %3}"
16597   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16598    (set_attr "mode" "SF,SF,SI,SI")])
16600 ;; Don't do conditional moves with memory inputs.  This splitter helps
16601 ;; register starved x86_32 by forcing inputs into registers before reload.
16602 (define_split
16603   [(set (match_operand:MODEF 0 "register_operand")
16604         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16605                               [(reg FLAGS_REG) (const_int 0)])
16606           (match_operand:MODEF 2 "nonimmediate_operand")
16607           (match_operand:MODEF 3 "nonimmediate_operand")))]
16608   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16609    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16610    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16611    && can_create_pseudo_p ()
16612    && optimize_insn_for_speed_p ()"
16613   [(set (match_dup 0)
16614         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16616   if (MEM_P (operands[2]))
16617     operands[2] = force_reg (<MODE>mode, operands[2]);
16618   if (MEM_P (operands[3]))
16619     operands[3] = force_reg (<MODE>mode, operands[3]);
16622 ;; Don't do conditional moves with memory inputs
16623 (define_peephole2
16624   [(match_scratch:MODEF 2 "r")
16625    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16626         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16627                               [(reg FLAGS_REG) (const_int 0)])
16628           (match_dup 0)
16629           (match_operand:MODEF 3 "memory_operand")))]
16630   "(<MODE>mode != DFmode || TARGET_64BIT)
16631    && TARGET_80387 && TARGET_CMOVE
16632    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16633    && optimize_insn_for_speed_p ()"
16634   [(set (match_dup 2) (match_dup 3))
16635    (set (match_dup 0)
16636         (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16638 (define_peephole2
16639   [(match_scratch:MODEF 2 "r")
16640    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16641         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16642                               [(reg FLAGS_REG) (const_int 0)])
16643           (match_operand:MODEF 3 "memory_operand")
16644           (match_dup 0)))]
16645   "(<MODE>mode != DFmode || TARGET_64BIT)
16646    && TARGET_80387 && TARGET_CMOVE
16647    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16648    && optimize_insn_for_speed_p ()"
16649   [(set (match_dup 2) (match_dup 3))
16650    (set (match_dup 0)
16651         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16653 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16654 ;; the scalar versions to have only XMM registers as operands.
16656 ;; XOP conditional move
16657 (define_insn "*xop_pcmov_<mode>"
16658   [(set (match_operand:MODEF 0 "register_operand" "=x")
16659         (if_then_else:MODEF
16660           (match_operand:MODEF 1 "register_operand" "x")
16661           (match_operand:MODEF 2 "register_operand" "x")
16662           (match_operand:MODEF 3 "register_operand" "x")))]
16663   "TARGET_XOP"
16664   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16665   [(set_attr "type" "sse4arg")])
16667 ;; These versions of the min/max patterns are intentionally ignorant of
16668 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16669 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16670 ;; are undefined in this condition, we're certain this is correct.
16672 (define_insn "<code><mode>3"
16673   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16674         (smaxmin:MODEF
16675           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16676           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16677   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16678   "@
16679    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16680    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16681   [(set_attr "isa" "noavx,avx")
16682    (set_attr "prefix" "orig,vex")
16683    (set_attr "type" "sseadd")
16684    (set_attr "mode" "<MODE>")])
16686 ;; These versions of the min/max patterns implement exactly the operations
16687 ;;   min = (op1 < op2 ? op1 : op2)
16688 ;;   max = (!(op1 < op2) ? op1 : op2)
16689 ;; Their operands are not commutative, and thus they may be used in the
16690 ;; presence of -0.0 and NaN.
16692 (define_int_iterator IEEE_MAXMIN
16693         [UNSPEC_IEEE_MAX
16694          UNSPEC_IEEE_MIN])
16696 (define_int_attr ieee_maxmin
16697         [(UNSPEC_IEEE_MAX "max")
16698          (UNSPEC_IEEE_MIN "min")])
16700 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16701   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16702         (unspec:MODEF
16703           [(match_operand:MODEF 1 "register_operand" "0,x")
16704            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16705           IEEE_MAXMIN))]
16706   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16707   "@
16708    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16709    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16710   [(set_attr "isa" "noavx,avx")
16711    (set_attr "prefix" "orig,vex")
16712    (set_attr "type" "sseadd")
16713    (set_attr "mode" "<MODE>")])
16715 ;; Make two stack loads independent:
16716 ;;   fld aa              fld aa
16717 ;;   fld %st(0)     ->   fld bb
16718 ;;   fmul bb             fmul %st(1), %st
16720 ;; Actually we only match the last two instructions for simplicity.
16721 (define_peephole2
16722   [(set (match_operand 0 "fp_register_operand")
16723         (match_operand 1 "fp_register_operand"))
16724    (set (match_dup 0)
16725         (match_operator 2 "binary_fp_operator"
16726            [(match_dup 0)
16727             (match_operand 3 "memory_operand")]))]
16728   "REGNO (operands[0]) != REGNO (operands[1])"
16729   [(set (match_dup 0) (match_dup 3))
16730    (set (match_dup 0) (match_dup 4))]
16732   ;; The % modifier is not operational anymore in peephole2's, so we have to
16733   ;; swap the operands manually in the case of addition and multiplication.
16735   rtx op0, op1;
16737   if (COMMUTATIVE_ARITH_P (operands[2]))
16738     op0 = operands[0], op1 = operands[1];
16739   else
16740     op0 = operands[1], op1 = operands[0];
16742   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16743                                 GET_MODE (operands[2]),
16744                                 op0, op1);
16747 ;; Conditional addition patterns
16748 (define_expand "add<mode>cc"
16749   [(match_operand:SWI 0 "register_operand")
16750    (match_operand 1 "ordered_comparison_operator")
16751    (match_operand:SWI 2 "register_operand")
16752    (match_operand:SWI 3 "const_int_operand")]
16753   ""
16754   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16756 ;; Misc patterns (?)
16758 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16759 ;; Otherwise there will be nothing to keep
16761 ;; [(set (reg ebp) (reg esp))]
16762 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16763 ;;  (clobber (eflags)]
16764 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16766 ;; in proper program order.
16768 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16769   [(set (match_operand:P 0 "register_operand" "=r,r")
16770         (plus:P (match_operand:P 1 "register_operand" "0,r")
16771                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16772    (clobber (reg:CC FLAGS_REG))
16773    (clobber (mem:BLK (scratch)))]
16774   ""
16776   switch (get_attr_type (insn))
16777     {
16778     case TYPE_IMOV:
16779       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16781     case TYPE_ALU:
16782       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16783       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16784         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16786       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16788     default:
16789       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16790       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16791     }
16793   [(set (attr "type")
16794         (cond [(and (eq_attr "alternative" "0")
16795                     (not (match_test "TARGET_OPT_AGU")))
16796                  (const_string "alu")
16797                (match_operand:<MODE> 2 "const0_operand")
16798                  (const_string "imov")
16799               ]
16800               (const_string "lea")))
16801    (set (attr "length_immediate")
16802         (cond [(eq_attr "type" "imov")
16803                  (const_string "0")
16804                (and (eq_attr "type" "alu")
16805                     (match_operand 2 "const128_operand"))
16806                  (const_string "1")
16807               ]
16808               (const_string "*")))
16809    (set_attr "mode" "<MODE>")])
16811 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16812   [(set (match_operand:P 0 "register_operand" "=r")
16813         (minus:P (match_operand:P 1 "register_operand" "0")
16814                  (match_operand:P 2 "register_operand" "r")))
16815    (clobber (reg:CC FLAGS_REG))
16816    (clobber (mem:BLK (scratch)))]
16817   ""
16818   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16819   [(set_attr "type" "alu")
16820    (set_attr "mode" "<MODE>")])
16822 (define_insn "allocate_stack_worker_probe_<mode>"
16823   [(set (match_operand:P 0 "register_operand" "=a")
16824         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16825                             UNSPECV_STACK_PROBE))
16826    (clobber (reg:CC FLAGS_REG))]
16827   "ix86_target_stack_probe ()"
16828   "call\t___chkstk_ms"
16829   [(set_attr "type" "multi")
16830    (set_attr "length" "5")])
16832 (define_expand "allocate_stack"
16833   [(match_operand 0 "register_operand")
16834    (match_operand 1 "general_operand")]
16835   "ix86_target_stack_probe ()"
16837   rtx x;
16839 #ifndef CHECK_STACK_LIMIT
16840 #define CHECK_STACK_LIMIT 0
16841 #endif
16843   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16844       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16845     x = operands[1];
16846   else
16847     {
16848       rtx (*insn) (rtx, rtx);
16850       x = copy_to_mode_reg (Pmode, operands[1]);
16852       insn = (TARGET_64BIT
16853               ? gen_allocate_stack_worker_probe_di
16854               : gen_allocate_stack_worker_probe_si);
16856       emit_insn (insn (x, x));
16857     }
16859   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16860                            stack_pointer_rtx, 0, OPTAB_DIRECT);
16862   if (x != stack_pointer_rtx)
16863     emit_move_insn (stack_pointer_rtx, x);
16865   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16866   DONE;
16869 ;; Use IOR for stack probes, this is shorter.
16870 (define_expand "probe_stack"
16871   [(match_operand 0 "memory_operand")]
16872   ""
16874   rtx (*gen_ior3) (rtx, rtx, rtx);
16876   gen_ior3 = (GET_MODE (operands[0]) == DImode
16877               ? gen_iordi3 : gen_iorsi3);
16879   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16880   DONE;
16883 (define_insn "adjust_stack_and_probe<mode>"
16884   [(set (match_operand:P 0 "register_operand" "=r")
16885         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16886                             UNSPECV_PROBE_STACK_RANGE))
16887    (set (reg:P SP_REG)
16888         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16889    (clobber (reg:CC FLAGS_REG))
16890    (clobber (mem:BLK (scratch)))]
16891   ""
16892   "* return output_adjust_stack_and_probe (operands[0]);"
16893   [(set_attr "type" "multi")])
16895 (define_insn "probe_stack_range<mode>"
16896   [(set (match_operand:P 0 "register_operand" "=r")
16897         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16898                             (match_operand:P 2 "const_int_operand" "n")]
16899                             UNSPECV_PROBE_STACK_RANGE))
16900    (clobber (reg:CC FLAGS_REG))]
16901   ""
16902   "* return output_probe_stack_range (operands[0], operands[2]);"
16903   [(set_attr "type" "multi")])
16905 (define_expand "builtin_setjmp_receiver"
16906   [(label_ref (match_operand 0))]
16907   "!TARGET_64BIT && flag_pic"
16909 #if TARGET_MACHO
16910   if (TARGET_MACHO)
16911     {
16912       rtx xops[3];
16913       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16914       rtx label_rtx = gen_label_rtx ();
16915       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16916       xops[0] = xops[1] = picreg;
16917       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16918       ix86_expand_binary_operator (MINUS, SImode, xops);
16919     }
16920   else
16921 #endif
16922     emit_insn (gen_set_got (pic_offset_table_rtx));
16923   DONE;
16926 (define_insn_and_split "nonlocal_goto_receiver"
16927   [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16928   "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16929   "#"
16930   "&& reload_completed"
16931   [(const_int 0)]
16933   if (crtl->uses_pic_offset_table)
16934     {
16935       rtx xops[3];
16936       rtx label_rtx = gen_label_rtx ();
16937       rtx tmp;
16939       /* Get a new pic base.  */
16940       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16941       /* Correct this with the offset from the new to the old.  */
16942       xops[0] = xops[1] = pic_offset_table_rtx;
16943       label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16944       tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16945                             UNSPEC_MACHOPIC_OFFSET);
16946       xops[2] = gen_rtx_CONST (Pmode, tmp);
16947       ix86_expand_binary_operator (MINUS, SImode, xops);
16948     }
16949   else
16950     /* No pic reg restore needed.  */
16951     emit_note (NOTE_INSN_DELETED);
16953   DONE;
16956 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16957 ;; Do not split instructions with mask registers.
16958 (define_split
16959   [(set (match_operand 0 "general_reg_operand")
16960         (match_operator 3 "promotable_binary_operator"
16961            [(match_operand 1 "general_reg_operand")
16962             (match_operand 2 "aligned_operand")]))
16963    (clobber (reg:CC FLAGS_REG))]
16964   "! TARGET_PARTIAL_REG_STALL && reload_completed
16965    && ((GET_MODE (operands[0]) == HImode
16966         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16967             /* ??? next two lines just !satisfies_constraint_K (...) */
16968             || !CONST_INT_P (operands[2])
16969             || satisfies_constraint_K (operands[2])))
16970        || (GET_MODE (operands[0]) == QImode
16971            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16972   [(parallel [(set (match_dup 0)
16973                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16974               (clobber (reg:CC FLAGS_REG))])]
16976   operands[0] = gen_lowpart (SImode, operands[0]);
16977   operands[1] = gen_lowpart (SImode, operands[1]);
16978   if (GET_CODE (operands[3]) != ASHIFT)
16979     operands[2] = gen_lowpart (SImode, operands[2]);
16980   PUT_MODE (operands[3], SImode);
16983 ; Promote the QImode tests, as i386 has encoding of the AND
16984 ; instruction with 32-bit sign-extended immediate and thus the
16985 ; instruction size is unchanged, except in the %eax case for
16986 ; which it is increased by one byte, hence the ! optimize_size.
16987 (define_split
16988   [(set (match_operand 0 "flags_reg_operand")
16989         (match_operator 2 "compare_operator"
16990           [(and (match_operand 3 "aligned_operand")
16991                 (match_operand 4 "const_int_operand"))
16992            (const_int 0)]))
16993    (set (match_operand 1 "register_operand")
16994         (and (match_dup 3) (match_dup 4)))]
16995   "! TARGET_PARTIAL_REG_STALL && reload_completed
16996    && optimize_insn_for_speed_p ()
16997    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16998        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16999    /* Ensure that the operand will remain sign-extended immediate.  */
17000    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17001   [(parallel [(set (match_dup 0)
17002                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17003                                     (const_int 0)]))
17004               (set (match_dup 1)
17005                    (and:SI (match_dup 3) (match_dup 4)))])]
17007   operands[4]
17008     = gen_int_mode (INTVAL (operands[4])
17009                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17010   operands[1] = gen_lowpart (SImode, operands[1]);
17011   operands[3] = gen_lowpart (SImode, operands[3]);
17014 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17015 ; the TEST instruction with 32-bit sign-extended immediate and thus
17016 ; the instruction size would at least double, which is not what we
17017 ; want even with ! optimize_size.
17018 (define_split
17019   [(set (match_operand 0 "flags_reg_operand")
17020         (match_operator 1 "compare_operator"
17021           [(and (match_operand:HI 2 "aligned_operand")
17022                 (match_operand:HI 3 "const_int_operand"))
17023            (const_int 0)]))]
17024   "! TARGET_PARTIAL_REG_STALL && reload_completed
17025    && ! TARGET_FAST_PREFIX
17026    && optimize_insn_for_speed_p ()
17027    /* Ensure that the operand will remain sign-extended immediate.  */
17028    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17029   [(set (match_dup 0)
17030         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17031                          (const_int 0)]))]
17033   operands[3]
17034     = gen_int_mode (INTVAL (operands[3])
17035                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17036   operands[2] = gen_lowpart (SImode, operands[2]);
17039 (define_split
17040   [(set (match_operand 0 "register_operand")
17041         (neg (match_operand 1 "register_operand")))
17042    (clobber (reg:CC FLAGS_REG))]
17043   "! TARGET_PARTIAL_REG_STALL && reload_completed
17044    && (GET_MODE (operands[0]) == HImode
17045        || (GET_MODE (operands[0]) == QImode
17046            && (TARGET_PROMOTE_QImode
17047                || optimize_insn_for_size_p ())))"
17048   [(parallel [(set (match_dup 0)
17049                    (neg:SI (match_dup 1)))
17050               (clobber (reg:CC FLAGS_REG))])]
17052   operands[0] = gen_lowpart (SImode, operands[0]);
17053   operands[1] = gen_lowpart (SImode, operands[1]);
17056 ;; Do not split instructions with mask regs.
17057 (define_split
17058   [(set (match_operand 0 "general_reg_operand")
17059         (not (match_operand 1 "general_reg_operand")))]
17060   "! TARGET_PARTIAL_REG_STALL && reload_completed
17061    && (GET_MODE (operands[0]) == HImode
17062        || (GET_MODE (operands[0]) == QImode
17063            && (TARGET_PROMOTE_QImode
17064                || optimize_insn_for_size_p ())))"
17065   [(set (match_dup 0)
17066         (not:SI (match_dup 1)))]
17068   operands[0] = gen_lowpart (SImode, operands[0]);
17069   operands[1] = gen_lowpart (SImode, operands[1]);
17072 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17073 ;; transform a complex memory operation into two memory to register operations.
17075 ;; Don't push memory operands
17076 (define_peephole2
17077   [(set (match_operand:SWI 0 "push_operand")
17078         (match_operand:SWI 1 "memory_operand"))
17079    (match_scratch:SWI 2 "<r>")]
17080   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17081    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17082   [(set (match_dup 2) (match_dup 1))
17083    (set (match_dup 0) (match_dup 2))])
17085 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17086 ;; SImode pushes.
17087 (define_peephole2
17088   [(set (match_operand:SF 0 "push_operand")
17089         (match_operand:SF 1 "memory_operand"))
17090    (match_scratch:SF 2 "r")]
17091   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17092    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17093   [(set (match_dup 2) (match_dup 1))
17094    (set (match_dup 0) (match_dup 2))])
17096 ;; Don't move an immediate directly to memory when the instruction
17097 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17098 (define_peephole2
17099   [(match_scratch:SWI124 1 "<r>")
17100    (set (match_operand:SWI124 0 "memory_operand")
17101         (const_int 0))]
17102   "optimize_insn_for_speed_p ()
17103    && ((<MODE>mode == HImode
17104        && TARGET_LCP_STALL)
17105        || (!TARGET_USE_MOV0
17106           && TARGET_SPLIT_LONG_MOVES
17107           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17108    && peep2_regno_dead_p (0, FLAGS_REG)"
17109   [(parallel [(set (match_dup 2) (const_int 0))
17110               (clobber (reg:CC FLAGS_REG))])
17111    (set (match_dup 0) (match_dup 1))]
17112   "operands[2] = gen_lowpart (SImode, operands[1]);")
17114 (define_peephole2
17115   [(match_scratch:SWI124 2 "<r>")
17116    (set (match_operand:SWI124 0 "memory_operand")
17117         (match_operand:SWI124 1 "immediate_operand"))]
17118   "optimize_insn_for_speed_p ()
17119    && ((<MODE>mode == HImode
17120        && TARGET_LCP_STALL)
17121        || (TARGET_SPLIT_LONG_MOVES
17122           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17123   [(set (match_dup 2) (match_dup 1))
17124    (set (match_dup 0) (match_dup 2))])
17126 ;; Don't compare memory with zero, load and use a test instead.
17127 (define_peephole2
17128   [(set (match_operand 0 "flags_reg_operand")
17129         (match_operator 1 "compare_operator"
17130           [(match_operand:SI 2 "memory_operand")
17131            (const_int 0)]))
17132    (match_scratch:SI 3 "r")]
17133   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17134   [(set (match_dup 3) (match_dup 2))
17135    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17137 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17138 ;; Don't split NOTs with a displacement operand, because resulting XOR
17139 ;; will not be pairable anyway.
17141 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17142 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17143 ;; so this split helps here as well.
17145 ;; Note: Can't do this as a regular split because we can't get proper
17146 ;; lifetime information then.
17148 (define_peephole2
17149   [(set (match_operand:SWI124 0 "nonimmediate_operand")
17150         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17151   "optimize_insn_for_speed_p ()
17152    && ((TARGET_NOT_UNPAIRABLE
17153         && (!MEM_P (operands[0])
17154             || !memory_displacement_operand (operands[0], <MODE>mode)))
17155        || (TARGET_NOT_VECTORMODE
17156            && long_memory_operand (operands[0], <MODE>mode)))
17157    && peep2_regno_dead_p (0, FLAGS_REG)"
17158   [(parallel [(set (match_dup 0)
17159                    (xor:SWI124 (match_dup 1) (const_int -1)))
17160               (clobber (reg:CC FLAGS_REG))])])
17162 ;; Non pairable "test imm, reg" instructions can be translated to
17163 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17164 ;; byte opcode instead of two, have a short form for byte operands),
17165 ;; so do it for other CPUs as well.  Given that the value was dead,
17166 ;; this should not create any new dependencies.  Pass on the sub-word
17167 ;; versions if we're concerned about partial register stalls.
17169 (define_peephole2
17170   [(set (match_operand 0 "flags_reg_operand")
17171         (match_operator 1 "compare_operator"
17172           [(and:SI (match_operand:SI 2 "register_operand")
17173                    (match_operand:SI 3 "immediate_operand"))
17174            (const_int 0)]))]
17175   "ix86_match_ccmode (insn, CCNOmode)
17176    && (true_regnum (operands[2]) != AX_REG
17177        || satisfies_constraint_K (operands[3]))
17178    && peep2_reg_dead_p (1, operands[2])"
17179   [(parallel
17180      [(set (match_dup 0)
17181            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17182                             (const_int 0)]))
17183       (set (match_dup 2)
17184            (and:SI (match_dup 2) (match_dup 3)))])])
17186 ;; We don't need to handle HImode case, because it will be promoted to SImode
17187 ;; on ! TARGET_PARTIAL_REG_STALL
17189 (define_peephole2
17190   [(set (match_operand 0 "flags_reg_operand")
17191         (match_operator 1 "compare_operator"
17192           [(and:QI (match_operand:QI 2 "register_operand")
17193                    (match_operand:QI 3 "immediate_operand"))
17194            (const_int 0)]))]
17195   "! TARGET_PARTIAL_REG_STALL
17196    && ix86_match_ccmode (insn, CCNOmode)
17197    && true_regnum (operands[2]) != AX_REG
17198    && peep2_reg_dead_p (1, operands[2])"
17199   [(parallel
17200      [(set (match_dup 0)
17201            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17202                             (const_int 0)]))
17203       (set (match_dup 2)
17204            (and:QI (match_dup 2) (match_dup 3)))])])
17206 (define_peephole2
17207   [(set (match_operand 0 "flags_reg_operand")
17208         (match_operator 1 "compare_operator"
17209           [(and:SI
17210              (zero_extract:SI
17211                (match_operand 2 "ext_register_operand")
17212                (const_int 8)
17213                (const_int 8))
17214              (match_operand 3 "const_int_operand"))
17215            (const_int 0)]))]
17216   "! TARGET_PARTIAL_REG_STALL
17217    && ix86_match_ccmode (insn, CCNOmode)
17218    && true_regnum (operands[2]) != AX_REG
17219    && peep2_reg_dead_p (1, operands[2])"
17220   [(parallel [(set (match_dup 0)
17221                    (match_op_dup 1
17222                      [(and:SI
17223                         (zero_extract:SI
17224                           (match_dup 2)
17225                           (const_int 8)
17226                           (const_int 8))
17227                         (match_dup 3))
17228                       (const_int 0)]))
17229               (set (zero_extract:SI (match_dup 2)
17230                                     (const_int 8)
17231                                     (const_int 8))
17232                    (and:SI
17233                      (zero_extract:SI
17234                        (match_dup 2)
17235                        (const_int 8)
17236                        (const_int 8))
17237                      (match_dup 3)))])])
17239 ;; Don't do logical operations with memory inputs.
17240 (define_peephole2
17241   [(match_scratch:SI 2 "r")
17242    (parallel [(set (match_operand:SI 0 "register_operand")
17243                    (match_operator:SI 3 "arith_or_logical_operator"
17244                      [(match_dup 0)
17245                       (match_operand:SI 1 "memory_operand")]))
17246               (clobber (reg:CC FLAGS_REG))])]
17247   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17248   [(set (match_dup 2) (match_dup 1))
17249    (parallel [(set (match_dup 0)
17250                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17251               (clobber (reg:CC FLAGS_REG))])])
17253 (define_peephole2
17254   [(match_scratch:SI 2 "r")
17255    (parallel [(set (match_operand:SI 0 "register_operand")
17256                    (match_operator:SI 3 "arith_or_logical_operator"
17257                      [(match_operand:SI 1 "memory_operand")
17258                       (match_dup 0)]))
17259               (clobber (reg:CC FLAGS_REG))])]
17260   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17261   [(set (match_dup 2) (match_dup 1))
17262    (parallel [(set (match_dup 0)
17263                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17264               (clobber (reg:CC FLAGS_REG))])])
17266 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17267 ;; refers to the destination of the load!
17269 (define_peephole2
17270   [(set (match_operand:SI 0 "register_operand")
17271         (match_operand:SI 1 "register_operand"))
17272    (parallel [(set (match_dup 0)
17273                    (match_operator:SI 3 "commutative_operator"
17274                      [(match_dup 0)
17275                       (match_operand:SI 2 "memory_operand")]))
17276               (clobber (reg:CC FLAGS_REG))])]
17277   "REGNO (operands[0]) != REGNO (operands[1])
17278    && GENERAL_REGNO_P (REGNO (operands[0]))
17279    && GENERAL_REGNO_P (REGNO (operands[1]))"
17280   [(set (match_dup 0) (match_dup 4))
17281    (parallel [(set (match_dup 0)
17282                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17283               (clobber (reg:CC FLAGS_REG))])]
17284   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17286 (define_peephole2
17287   [(set (match_operand 0 "register_operand")
17288         (match_operand 1 "register_operand"))
17289    (set (match_dup 0)
17290                    (match_operator 3 "commutative_operator"
17291                      [(match_dup 0)
17292                       (match_operand 2 "memory_operand")]))]
17293   "REGNO (operands[0]) != REGNO (operands[1])
17294    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17295        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17296   [(set (match_dup 0) (match_dup 2))
17297    (set (match_dup 0)
17298         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17300 ; Don't do logical operations with memory outputs
17302 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17303 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17304 ; the same decoder scheduling characteristics as the original.
17306 (define_peephole2
17307   [(match_scratch:SI 2 "r")
17308    (parallel [(set (match_operand:SI 0 "memory_operand")
17309                    (match_operator:SI 3 "arith_or_logical_operator"
17310                      [(match_dup 0)
17311                       (match_operand:SI 1 "nonmemory_operand")]))
17312               (clobber (reg:CC FLAGS_REG))])]
17313   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17314    /* Do not split stack checking probes.  */
17315    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17316   [(set (match_dup 2) (match_dup 0))
17317    (parallel [(set (match_dup 2)
17318                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17319               (clobber (reg:CC FLAGS_REG))])
17320    (set (match_dup 0) (match_dup 2))])
17322 (define_peephole2
17323   [(match_scratch:SI 2 "r")
17324    (parallel [(set (match_operand:SI 0 "memory_operand")
17325                    (match_operator:SI 3 "arith_or_logical_operator"
17326                      [(match_operand:SI 1 "nonmemory_operand")
17327                       (match_dup 0)]))
17328               (clobber (reg:CC FLAGS_REG))])]
17329   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17330    /* Do not split stack checking probes.  */
17331    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17332   [(set (match_dup 2) (match_dup 0))
17333    (parallel [(set (match_dup 2)
17334                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17335               (clobber (reg:CC FLAGS_REG))])
17336    (set (match_dup 0) (match_dup 2))])
17338 ;; Attempt to use arith or logical operations with memory outputs with
17339 ;; setting of flags.
17340 (define_peephole2
17341   [(set (match_operand:SWI 0 "register_operand")
17342         (match_operand:SWI 1 "memory_operand"))
17343    (parallel [(set (match_dup 0)
17344                    (match_operator:SWI 3 "plusminuslogic_operator"
17345                      [(match_dup 0)
17346                       (match_operand:SWI 2 "<nonmemory_operand>")]))
17347               (clobber (reg:CC FLAGS_REG))])
17348    (set (match_dup 1) (match_dup 0))
17349    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17350   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17351    && peep2_reg_dead_p (4, operands[0])
17352    && !reg_overlap_mentioned_p (operands[0], operands[1])
17353    && !reg_overlap_mentioned_p (operands[0], operands[2])
17354    && (<MODE>mode != QImode
17355        || immediate_operand (operands[2], QImode)
17356        || q_regs_operand (operands[2], QImode))
17357    && ix86_match_ccmode (peep2_next_insn (3),
17358                          (GET_CODE (operands[3]) == PLUS
17359                           || GET_CODE (operands[3]) == MINUS)
17360                          ? CCGOCmode : CCNOmode)"
17361   [(parallel [(set (match_dup 4) (match_dup 5))
17362               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17363                                                   (match_dup 2)]))])]
17365   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17366   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17367                                 copy_rtx (operands[1]),
17368                                 copy_rtx (operands[2]));
17369   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17370                                  operands[5], const0_rtx);
17373 (define_peephole2
17374   [(parallel [(set (match_operand:SWI 0 "register_operand")
17375                    (match_operator:SWI 2 "plusminuslogic_operator"
17376                      [(match_dup 0)
17377                       (match_operand:SWI 1 "memory_operand")]))
17378               (clobber (reg:CC FLAGS_REG))])
17379    (set (match_dup 1) (match_dup 0))
17380    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17381   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17382    && GET_CODE (operands[2]) != MINUS
17383    && peep2_reg_dead_p (3, operands[0])
17384    && !reg_overlap_mentioned_p (operands[0], operands[1])
17385    && ix86_match_ccmode (peep2_next_insn (2),
17386                          GET_CODE (operands[2]) == PLUS
17387                          ? CCGOCmode : CCNOmode)"
17388   [(parallel [(set (match_dup 3) (match_dup 4))
17389               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17390                                                   (match_dup 0)]))])]
17392   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17393   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17394                                 copy_rtx (operands[1]),
17395                                 copy_rtx (operands[0]));
17396   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17397                                  operands[4], const0_rtx);
17400 (define_peephole2
17401   [(set (match_operand:SWI12 0 "register_operand")
17402         (match_operand:SWI12 1 "memory_operand"))
17403    (parallel [(set (match_operand:SI 4 "register_operand")
17404                    (match_operator:SI 3 "plusminuslogic_operator"
17405                      [(match_dup 4)
17406                       (match_operand:SI 2 "nonmemory_operand")]))
17407               (clobber (reg:CC FLAGS_REG))])
17408    (set (match_dup 1) (match_dup 0))
17409    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17410   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17411    && REG_P (operands[0]) && REG_P (operands[4])
17412    && REGNO (operands[0]) == REGNO (operands[4])
17413    && peep2_reg_dead_p (4, operands[0])
17414    && (<MODE>mode != QImode
17415        || immediate_operand (operands[2], SImode)
17416        || q_regs_operand (operands[2], SImode))
17417    && !reg_overlap_mentioned_p (operands[0], operands[1])
17418    && !reg_overlap_mentioned_p (operands[0], operands[2])
17419    && ix86_match_ccmode (peep2_next_insn (3),
17420                          (GET_CODE (operands[3]) == PLUS
17421                           || GET_CODE (operands[3]) == MINUS)
17422                          ? CCGOCmode : CCNOmode)"
17423   [(parallel [(set (match_dup 4) (match_dup 5))
17424               (set (match_dup 1) (match_dup 6))])]
17426   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17427   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17428   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17429                                 copy_rtx (operands[1]), operands[2]);
17430   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17431                                  operands[5], const0_rtx);
17432   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17433                                 copy_rtx (operands[1]),
17434                                 copy_rtx (operands[2]));
17437 ;; Attempt to always use XOR for zeroing registers.
17438 (define_peephole2
17439   [(set (match_operand 0 "register_operand")
17440         (match_operand 1 "const0_operand"))]
17441   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17442    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17443    && GENERAL_REG_P (operands[0])
17444    && peep2_regno_dead_p (0, FLAGS_REG)"
17445   [(parallel [(set (match_dup 0) (const_int 0))
17446               (clobber (reg:CC FLAGS_REG))])]
17447   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17449 (define_peephole2
17450   [(set (strict_low_part (match_operand 0 "register_operand"))
17451         (const_int 0))]
17452   "(GET_MODE (operands[0]) == QImode
17453     || GET_MODE (operands[0]) == HImode)
17454    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17455    && peep2_regno_dead_p (0, FLAGS_REG)"
17456   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17457               (clobber (reg:CC FLAGS_REG))])])
17459 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17460 (define_peephole2
17461   [(set (match_operand:SWI248 0 "register_operand")
17462         (const_int -1))]
17463   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17464    && peep2_regno_dead_p (0, FLAGS_REG)"
17465   [(parallel [(set (match_dup 0) (const_int -1))
17466               (clobber (reg:CC FLAGS_REG))])]
17468   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17469     operands[0] = gen_lowpart (SImode, operands[0]);
17472 ;; Attempt to convert simple lea to add/shift.
17473 ;; These can be created by move expanders.
17474 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17475 ;; relevant lea instructions were already split.
17477 (define_peephole2
17478   [(set (match_operand:SWI48 0 "register_operand")
17479         (plus:SWI48 (match_dup 0)
17480                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
17481   "!TARGET_OPT_AGU
17482    && peep2_regno_dead_p (0, FLAGS_REG)"
17483   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17484               (clobber (reg:CC FLAGS_REG))])])
17486 (define_peephole2
17487   [(set (match_operand:SWI48 0 "register_operand")
17488         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17489                     (match_dup 0)))]
17490   "!TARGET_OPT_AGU
17491    && peep2_regno_dead_p (0, FLAGS_REG)"
17492   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17493               (clobber (reg:CC FLAGS_REG))])])
17495 (define_peephole2
17496   [(set (match_operand:DI 0 "register_operand")
17497         (zero_extend:DI
17498           (plus:SI (match_operand:SI 1 "register_operand")
17499                    (match_operand:SI 2 "nonmemory_operand"))))]
17500   "TARGET_64BIT && !TARGET_OPT_AGU
17501    && REGNO (operands[0]) == REGNO (operands[1])
17502    && peep2_regno_dead_p (0, FLAGS_REG)"
17503   [(parallel [(set (match_dup 0)
17504                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17505               (clobber (reg:CC FLAGS_REG))])])
17507 (define_peephole2
17508   [(set (match_operand:DI 0 "register_operand")
17509         (zero_extend:DI
17510           (plus:SI (match_operand:SI 1 "nonmemory_operand")
17511                    (match_operand:SI 2 "register_operand"))))]
17512   "TARGET_64BIT && !TARGET_OPT_AGU
17513    && REGNO (operands[0]) == REGNO (operands[2])
17514    && peep2_regno_dead_p (0, FLAGS_REG)"
17515   [(parallel [(set (match_dup 0)
17516                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17517               (clobber (reg:CC FLAGS_REG))])])
17519 (define_peephole2
17520   [(set (match_operand:SWI48 0 "register_operand")
17521         (mult:SWI48 (match_dup 0)
17522                     (match_operand:SWI48 1 "const_int_operand")))]
17523   "exact_log2 (INTVAL (operands[1])) >= 0
17524    && peep2_regno_dead_p (0, FLAGS_REG)"
17525   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17526               (clobber (reg:CC FLAGS_REG))])]
17527   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17529 (define_peephole2
17530   [(set (match_operand:DI 0 "register_operand")
17531         (zero_extend:DI
17532           (mult:SI (match_operand:SI 1 "register_operand")
17533                    (match_operand:SI 2 "const_int_operand"))))]
17534   "TARGET_64BIT
17535    && exact_log2 (INTVAL (operands[2])) >= 0
17536    && REGNO (operands[0]) == REGNO (operands[1])
17537    && peep2_regno_dead_p (0, FLAGS_REG)"
17538   [(parallel [(set (match_dup 0)
17539                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17540               (clobber (reg:CC FLAGS_REG))])]
17541   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17543 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17544 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17545 ;; On many CPUs it is also faster, since special hardware to avoid esp
17546 ;; dependencies is present.
17548 ;; While some of these conversions may be done using splitters, we use
17549 ;; peepholes in order to allow combine_stack_adjustments pass to see
17550 ;; nonobfuscated RTL.
17552 ;; Convert prologue esp subtractions to push.
17553 ;; We need register to push.  In order to keep verify_flow_info happy we have
17554 ;; two choices
17555 ;; - use scratch and clobber it in order to avoid dependencies
17556 ;; - use already live register
17557 ;; We can't use the second way right now, since there is no reliable way how to
17558 ;; verify that given register is live.  First choice will also most likely in
17559 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17560 ;; call clobbered registers are dead.  We may want to use base pointer as an
17561 ;; alternative when no register is available later.
17563 (define_peephole2
17564   [(match_scratch:W 1 "r")
17565    (parallel [(set (reg:P SP_REG)
17566                    (plus:P (reg:P SP_REG)
17567                            (match_operand:P 0 "const_int_operand")))
17568               (clobber (reg:CC FLAGS_REG))
17569               (clobber (mem:BLK (scratch)))])]
17570   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17571    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17572   [(clobber (match_dup 1))
17573    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17574               (clobber (mem:BLK (scratch)))])])
17576 (define_peephole2
17577   [(match_scratch:W 1 "r")
17578    (parallel [(set (reg:P SP_REG)
17579                    (plus:P (reg:P SP_REG)
17580                            (match_operand:P 0 "const_int_operand")))
17581               (clobber (reg:CC FLAGS_REG))
17582               (clobber (mem:BLK (scratch)))])]
17583   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17584    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17585   [(clobber (match_dup 1))
17586    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17587    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17588               (clobber (mem:BLK (scratch)))])])
17590 ;; Convert esp subtractions to push.
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   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17598    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17599   [(clobber (match_dup 1))
17600    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17602 (define_peephole2
17603   [(match_scratch:W 1 "r")
17604    (parallel [(set (reg:P SP_REG)
17605                    (plus:P (reg:P SP_REG)
17606                            (match_operand:P 0 "const_int_operand")))
17607               (clobber (reg:CC FLAGS_REG))])]
17608   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17609    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17610   [(clobber (match_dup 1))
17611    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17612    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17614 ;; Convert epilogue deallocator to pop.
17615 (define_peephole2
17616   [(match_scratch:W 1 "r")
17617    (parallel [(set (reg:P SP_REG)
17618                    (plus:P (reg:P SP_REG)
17619                            (match_operand:P 0 "const_int_operand")))
17620               (clobber (reg:CC FLAGS_REG))
17621               (clobber (mem:BLK (scratch)))])]
17622   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17623    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17624   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17625               (clobber (mem:BLK (scratch)))])])
17627 ;; Two pops case is tricky, since pop causes dependency
17628 ;; on destination register.  We use two registers if available.
17629 (define_peephole2
17630   [(match_scratch:W 1 "r")
17631    (match_scratch:W 2 "r")
17632    (parallel [(set (reg:P SP_REG)
17633                    (plus:P (reg:P SP_REG)
17634                            (match_operand:P 0 "const_int_operand")))
17635               (clobber (reg:CC FLAGS_REG))
17636               (clobber (mem:BLK (scratch)))])]
17637   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17638    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17639   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17640               (clobber (mem:BLK (scratch)))])
17641    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17643 (define_peephole2
17644   [(match_scratch:W 1 "r")
17645    (parallel [(set (reg:P SP_REG)
17646                    (plus:P (reg:P SP_REG)
17647                            (match_operand:P 0 "const_int_operand")))
17648               (clobber (reg:CC FLAGS_REG))
17649               (clobber (mem:BLK (scratch)))])]
17650   "optimize_insn_for_size_p ()
17651    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17652   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17653               (clobber (mem:BLK (scratch)))])
17654    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17656 ;; Convert esp additions to pop.
17657 (define_peephole2
17658   [(match_scratch:W 1 "r")
17659    (parallel [(set (reg:P SP_REG)
17660                    (plus:P (reg:P SP_REG)
17661                            (match_operand:P 0 "const_int_operand")))
17662               (clobber (reg:CC FLAGS_REG))])]
17663   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17664   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17666 ;; Two pops case is tricky, since pop causes dependency
17667 ;; on destination register.  We use two registers if available.
17668 (define_peephole2
17669   [(match_scratch:W 1 "r")
17670    (match_scratch:W 2 "r")
17671    (parallel [(set (reg:P SP_REG)
17672                    (plus:P (reg:P SP_REG)
17673                            (match_operand:P 0 "const_int_operand")))
17674               (clobber (reg:CC FLAGS_REG))])]
17675   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17676   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17677    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17679 (define_peephole2
17680   [(match_scratch:W 1 "r")
17681    (parallel [(set (reg:P SP_REG)
17682                    (plus:P (reg:P SP_REG)
17683                            (match_operand:P 0 "const_int_operand")))
17684               (clobber (reg:CC FLAGS_REG))])]
17685   "optimize_insn_for_size_p ()
17686    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17687   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17688    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17690 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17691 ;; required and register dies.  Similarly for 128 to -128.
17692 (define_peephole2
17693   [(set (match_operand 0 "flags_reg_operand")
17694         (match_operator 1 "compare_operator"
17695           [(match_operand 2 "register_operand")
17696            (match_operand 3 "const_int_operand")]))]
17697   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17698      && incdec_operand (operands[3], GET_MODE (operands[3])))
17699     || (!TARGET_FUSE_CMP_AND_BRANCH
17700         && INTVAL (operands[3]) == 128))
17701    && ix86_match_ccmode (insn, CCGCmode)
17702    && peep2_reg_dead_p (1, operands[2])"
17703   [(parallel [(set (match_dup 0)
17704                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17705               (clobber (match_dup 2))])])
17707 ;; Convert imul by three, five and nine into lea
17708 (define_peephole2
17709   [(parallel
17710     [(set (match_operand:SWI48 0 "register_operand")
17711           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17712                       (match_operand:SWI48 2 "const359_operand")))
17713      (clobber (reg:CC FLAGS_REG))])]
17714   "!TARGET_PARTIAL_REG_STALL
17715    || <MODE>mode == SImode
17716    || optimize_function_for_size_p (cfun)"
17717   [(set (match_dup 0)
17718         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17719                     (match_dup 1)))]
17720   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17722 (define_peephole2
17723   [(parallel
17724     [(set (match_operand:SWI48 0 "register_operand")
17725           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17726                       (match_operand:SWI48 2 "const359_operand")))
17727      (clobber (reg:CC FLAGS_REG))])]
17728   "optimize_insn_for_speed_p ()
17729    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17730   [(set (match_dup 0) (match_dup 1))
17731    (set (match_dup 0)
17732         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17733                     (match_dup 0)))]
17734   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17736 ;; imul $32bit_imm, mem, reg is vector decoded, while
17737 ;; imul $32bit_imm, reg, reg is direct decoded.
17738 (define_peephole2
17739   [(match_scratch:SWI48 3 "r")
17740    (parallel [(set (match_operand:SWI48 0 "register_operand")
17741                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17742                                (match_operand:SWI48 2 "immediate_operand")))
17743               (clobber (reg:CC FLAGS_REG))])]
17744   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17745    && !satisfies_constraint_K (operands[2])"
17746   [(set (match_dup 3) (match_dup 1))
17747    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17748               (clobber (reg:CC FLAGS_REG))])])
17750 (define_peephole2
17751   [(match_scratch:SI 3 "r")
17752    (parallel [(set (match_operand:DI 0 "register_operand")
17753                    (zero_extend:DI
17754                      (mult:SI (match_operand:SI 1 "memory_operand")
17755                               (match_operand:SI 2 "immediate_operand"))))
17756               (clobber (reg:CC FLAGS_REG))])]
17757   "TARGET_64BIT
17758    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17759    && !satisfies_constraint_K (operands[2])"
17760   [(set (match_dup 3) (match_dup 1))
17761    (parallel [(set (match_dup 0)
17762                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17763               (clobber (reg:CC FLAGS_REG))])])
17765 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17766 ;; Convert it into imul reg, reg
17767 ;; It would be better to force assembler to encode instruction using long
17768 ;; immediate, but there is apparently no way to do so.
17769 (define_peephole2
17770   [(parallel [(set (match_operand:SWI248 0 "register_operand")
17771                    (mult:SWI248
17772                     (match_operand:SWI248 1 "nonimmediate_operand")
17773                     (match_operand:SWI248 2 "const_int_operand")))
17774               (clobber (reg:CC FLAGS_REG))])
17775    (match_scratch:SWI248 3 "r")]
17776   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17777    && satisfies_constraint_K (operands[2])"
17778   [(set (match_dup 3) (match_dup 2))
17779    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17780               (clobber (reg:CC FLAGS_REG))])]
17782   if (!rtx_equal_p (operands[0], operands[1]))
17783     emit_move_insn (operands[0], operands[1]);
17786 ;; After splitting up read-modify operations, array accesses with memory
17787 ;; operands might end up in form:
17788 ;;  sall    $2, %eax
17789 ;;  movl    4(%esp), %edx
17790 ;;  addl    %edx, %eax
17791 ;; instead of pre-splitting:
17792 ;;  sall    $2, %eax
17793 ;;  addl    4(%esp), %eax
17794 ;; Turn it into:
17795 ;;  movl    4(%esp), %edx
17796 ;;  leal    (%edx,%eax,4), %eax
17798 (define_peephole2
17799   [(match_scratch:W 5 "r")
17800    (parallel [(set (match_operand 0 "register_operand")
17801                    (ashift (match_operand 1 "register_operand")
17802                            (match_operand 2 "const_int_operand")))
17803                (clobber (reg:CC FLAGS_REG))])
17804    (parallel [(set (match_operand 3 "register_operand")
17805                    (plus (match_dup 0)
17806                          (match_operand 4 "x86_64_general_operand")))
17807                    (clobber (reg:CC FLAGS_REG))])]
17808   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17809    /* Validate MODE for lea.  */
17810    && ((!TARGET_PARTIAL_REG_STALL
17811         && (GET_MODE (operands[0]) == QImode
17812             || GET_MODE (operands[0]) == HImode))
17813        || GET_MODE (operands[0]) == SImode
17814        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17815    && (rtx_equal_p (operands[0], operands[3])
17816        || peep2_reg_dead_p (2, operands[0]))
17817    /* We reorder load and the shift.  */
17818    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17819   [(set (match_dup 5) (match_dup 4))
17820    (set (match_dup 0) (match_dup 1))]
17822   enum machine_mode op1mode = GET_MODE (operands[1]);
17823   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17824   int scale = 1 << INTVAL (operands[2]);
17825   rtx index = gen_lowpart (word_mode, operands[1]);
17826   rtx base = gen_lowpart (word_mode, operands[5]);
17827   rtx dest = gen_lowpart (mode, operands[3]);
17829   operands[1] = gen_rtx_PLUS (word_mode, base,
17830                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17831   operands[5] = base;
17832   if (mode != word_mode)
17833     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17834   if (op1mode != word_mode)
17835     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17836   operands[0] = dest;
17839 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17840 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17841 ;; caught for use by garbage collectors and the like.  Using an insn that
17842 ;; maps to SIGILL makes it more likely the program will rightfully die.
17843 ;; Keeping with tradition, "6" is in honor of #UD.
17844 (define_insn "trap"
17845   [(trap_if (const_int 1) (const_int 6))]
17846   ""
17848 #ifdef HAVE_AS_IX86_UD2
17849   return "ud2";
17850 #else
17851   return ASM_SHORT "0x0b0f";
17852 #endif
17854   [(set_attr "length" "2")])
17856 (define_expand "prefetch"
17857   [(prefetch (match_operand 0 "address_operand")
17858              (match_operand:SI 1 "const_int_operand")
17859              (match_operand:SI 2 "const_int_operand"))]
17860   "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
17862   bool write = INTVAL (operands[1]) != 0;
17863   int locality = INTVAL (operands[2]);
17865   gcc_assert (IN_RANGE (locality, 0, 3));
17867   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17868      supported by SSE counterpart or the SSE prefetch is not available
17869      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17870      of locality.  */
17871   if (TARGET_PREFETCHWT1 && write && locality <= 2)
17872     operands[2] = const2_rtx;
17873   else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17874     operands[2] = GEN_INT (3);
17875   else
17876     operands[1] = const0_rtx;
17879 (define_insn "*prefetch_sse"
17880   [(prefetch (match_operand 0 "address_operand" "p")
17881              (const_int 0)
17882              (match_operand:SI 1 "const_int_operand"))]
17883   "TARGET_PREFETCH_SSE"
17885   static const char * const patterns[4] = {
17886    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17887   };
17889   int locality = INTVAL (operands[1]);
17890   gcc_assert (IN_RANGE (locality, 0, 3));
17892   return patterns[locality];
17894   [(set_attr "type" "sse")
17895    (set_attr "atom_sse_attr" "prefetch")
17896    (set (attr "length_address")
17897         (symbol_ref "memory_address_length (operands[0], false)"))
17898    (set_attr "memory" "none")])
17900 (define_insn "*prefetch_3dnow"
17901   [(prefetch (match_operand 0 "address_operand" "p")
17902              (match_operand:SI 1 "const_int_operand" "n")
17903              (const_int 3))]
17904   "TARGET_PRFCHW"
17906   if (INTVAL (operands[1]) == 0)
17907     return "prefetch\t%a0";
17908   else
17909     return "prefetchw\t%a0";
17911   [(set_attr "type" "mmx")
17912    (set (attr "length_address")
17913         (symbol_ref "memory_address_length (operands[0], false)"))
17914    (set_attr "memory" "none")])
17916 (define_insn "*prefetch_prefetchwt1_<mode>"
17917   [(prefetch (match_operand:P 0 "address_operand" "p")
17918              (const_int 1)
17919              (const_int 2))]
17920   "TARGET_PREFETCHWT1"
17921   "prefetchwt1\t%a0";
17922   [(set_attr "type" "sse")
17923    (set (attr "length_address")
17924         (symbol_ref "memory_address_length (operands[0], false)"))
17925    (set_attr "memory" "none")])
17927 (define_expand "stack_protect_set"
17928   [(match_operand 0 "memory_operand")
17929    (match_operand 1 "memory_operand")]
17930   "TARGET_SSP_TLS_GUARD"
17932   rtx (*insn)(rtx, rtx);
17934 #ifdef TARGET_THREAD_SSP_OFFSET
17935   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17936   insn = (TARGET_LP64
17937           ? gen_stack_tls_protect_set_di
17938           : gen_stack_tls_protect_set_si);
17939 #else
17940   insn = (TARGET_LP64
17941           ? gen_stack_protect_set_di
17942           : gen_stack_protect_set_si);
17943 #endif
17945   emit_insn (insn (operands[0], operands[1]));
17946   DONE;
17949 (define_insn "stack_protect_set_<mode>"
17950   [(set (match_operand:PTR 0 "memory_operand" "=m")
17951         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17952                     UNSPEC_SP_SET))
17953    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17954    (clobber (reg:CC FLAGS_REG))]
17955   "TARGET_SSP_TLS_GUARD"
17956   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17957   [(set_attr "type" "multi")])
17959 (define_insn "stack_tls_protect_set_<mode>"
17960   [(set (match_operand:PTR 0 "memory_operand" "=m")
17961         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17962                     UNSPEC_SP_TLS_SET))
17963    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17964    (clobber (reg:CC FLAGS_REG))]
17965   ""
17966   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17967   [(set_attr "type" "multi")])
17969 (define_expand "stack_protect_test"
17970   [(match_operand 0 "memory_operand")
17971    (match_operand 1 "memory_operand")
17972    (match_operand 2)]
17973   "TARGET_SSP_TLS_GUARD"
17975   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17977   rtx (*insn)(rtx, rtx, rtx);
17979 #ifdef TARGET_THREAD_SSP_OFFSET
17980   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17981   insn = (TARGET_LP64
17982           ? gen_stack_tls_protect_test_di
17983           : gen_stack_tls_protect_test_si);
17984 #else
17985   insn = (TARGET_LP64
17986           ? gen_stack_protect_test_di
17987           : gen_stack_protect_test_si);
17988 #endif
17990   emit_insn (insn (flags, operands[0], operands[1]));
17992   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17993                                   flags, const0_rtx, operands[2]));
17994   DONE;
17997 (define_insn "stack_protect_test_<mode>"
17998   [(set (match_operand:CCZ 0 "flags_reg_operand")
17999         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18000                      (match_operand:PTR 2 "memory_operand" "m")]
18001                     UNSPEC_SP_TEST))
18002    (clobber (match_scratch:PTR 3 "=&r"))]
18003   "TARGET_SSP_TLS_GUARD"
18004   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18005   [(set_attr "type" "multi")])
18007 (define_insn "stack_tls_protect_test_<mode>"
18008   [(set (match_operand:CCZ 0 "flags_reg_operand")
18009         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18010                      (match_operand:PTR 2 "const_int_operand" "i")]
18011                     UNSPEC_SP_TLS_TEST))
18012    (clobber (match_scratch:PTR 3 "=r"))]
18013   ""
18014   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18015   [(set_attr "type" "multi")])
18017 (define_insn "sse4_2_crc32<mode>"
18018   [(set (match_operand:SI 0 "register_operand" "=r")
18019         (unspec:SI
18020           [(match_operand:SI 1 "register_operand" "0")
18021            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18022           UNSPEC_CRC32))]
18023   "TARGET_SSE4_2 || TARGET_CRC32"
18024   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18025   [(set_attr "type" "sselog1")
18026    (set_attr "prefix_rep" "1")
18027    (set_attr "prefix_extra" "1")
18028    (set (attr "prefix_data16")
18029      (if_then_else (match_operand:HI 2)
18030        (const_string "1")
18031        (const_string "*")))
18032    (set (attr "prefix_rex")
18033      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18034        (const_string "1")
18035        (const_string "*")))
18036    (set_attr "mode" "SI")])
18038 (define_insn "sse4_2_crc32di"
18039   [(set (match_operand:DI 0 "register_operand" "=r")
18040         (unspec:DI
18041           [(match_operand:DI 1 "register_operand" "0")
18042            (match_operand:DI 2 "nonimmediate_operand" "rm")]
18043           UNSPEC_CRC32))]
18044   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18045   "crc32{q}\t{%2, %0|%0, %2}"
18046   [(set_attr "type" "sselog1")
18047    (set_attr "prefix_rep" "1")
18048    (set_attr "prefix_extra" "1")
18049    (set_attr "mode" "DI")])
18051 (define_insn "rdpmc"
18052   [(set (match_operand:DI 0 "register_operand" "=A")
18053         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18054                             UNSPECV_RDPMC))]
18055   "!TARGET_64BIT"
18056   "rdpmc"
18057   [(set_attr "type" "other")
18058    (set_attr "length" "2")])
18060 (define_insn "rdpmc_rex64"
18061   [(set (match_operand:DI 0 "register_operand" "=a")
18062         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18063                             UNSPECV_RDPMC))
18064    (set (match_operand:DI 1 "register_operand" "=d")
18065         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18066   "TARGET_64BIT"
18067   "rdpmc"
18068   [(set_attr "type" "other")
18069    (set_attr "length" "2")])
18071 (define_insn "rdtsc"
18072   [(set (match_operand:DI 0 "register_operand" "=A")
18073         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18074   "!TARGET_64BIT"
18075   "rdtsc"
18076   [(set_attr "type" "other")
18077    (set_attr "length" "2")])
18079 (define_insn "rdtsc_rex64"
18080   [(set (match_operand:DI 0 "register_operand" "=a")
18081         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18082    (set (match_operand:DI 1 "register_operand" "=d")
18083         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18084   "TARGET_64BIT"
18085   "rdtsc"
18086   [(set_attr "type" "other")
18087    (set_attr "length" "2")])
18089 (define_insn "rdtscp"
18090   [(set (match_operand:DI 0 "register_operand" "=A")
18091         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18092    (set (match_operand:SI 1 "register_operand" "=c")
18093         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18094   "!TARGET_64BIT"
18095   "rdtscp"
18096   [(set_attr "type" "other")
18097    (set_attr "length" "3")])
18099 (define_insn "rdtscp_rex64"
18100   [(set (match_operand:DI 0 "register_operand" "=a")
18101         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18102    (set (match_operand:DI 1 "register_operand" "=d")
18103         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18104    (set (match_operand:SI 2 "register_operand" "=c")
18105         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18106   "TARGET_64BIT"
18107   "rdtscp"
18108   [(set_attr "type" "other")
18109    (set_attr "length" "3")])
18111 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18113 ;; FXSR, XSAVE and XSAVEOPT instructions
18115 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18117 (define_insn "fxsave"
18118   [(set (match_operand:BLK 0 "memory_operand" "=m")
18119         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18120   "TARGET_FXSR"
18121   "fxsave\t%0"
18122   [(set_attr "type" "other")
18123    (set_attr "memory" "store")
18124    (set (attr "length")
18125         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18127 (define_insn "fxsave64"
18128   [(set (match_operand:BLK 0 "memory_operand" "=m")
18129         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18130   "TARGET_64BIT && TARGET_FXSR"
18131   "fxsave64\t%0"
18132   [(set_attr "type" "other")
18133    (set_attr "memory" "store")
18134    (set (attr "length")
18135         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18137 (define_insn "fxrstor"
18138   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18139                     UNSPECV_FXRSTOR)]
18140   "TARGET_FXSR"
18141   "fxrstor\t%0"
18142   [(set_attr "type" "other")
18143    (set_attr "memory" "load")
18144    (set (attr "length")
18145         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18147 (define_insn "fxrstor64"
18148   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18149                     UNSPECV_FXRSTOR64)]
18150   "TARGET_64BIT && TARGET_FXSR"
18151   "fxrstor64\t%0"
18152   [(set_attr "type" "other")
18153    (set_attr "memory" "load")
18154    (set (attr "length")
18155         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18157 (define_int_iterator ANY_XSAVE
18158         [UNSPECV_XSAVE
18159          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")])
18161 (define_int_iterator ANY_XSAVE64
18162         [UNSPECV_XSAVE64
18163          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")])
18165 (define_int_attr xsave
18166         [(UNSPECV_XSAVE "xsave")
18167          (UNSPECV_XSAVE64 "xsave64")
18168          (UNSPECV_XSAVEOPT "xsaveopt")
18169          (UNSPECV_XSAVEOPT64 "xsaveopt64")])
18171 (define_insn "<xsave>"
18172   [(set (match_operand:BLK 0 "memory_operand" "=m")
18173         (unspec_volatile:BLK
18174          [(match_operand:DI 1 "register_operand" "A")]
18175          ANY_XSAVE))]
18176   "!TARGET_64BIT && TARGET_XSAVE"
18177   "<xsave>\t%0"
18178   [(set_attr "type" "other")
18179    (set_attr "memory" "store")
18180    (set (attr "length")
18181         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18183 (define_insn "<xsave>_rex64"
18184   [(set (match_operand:BLK 0 "memory_operand" "=m")
18185         (unspec_volatile:BLK
18186          [(match_operand:SI 1 "register_operand" "a")
18187           (match_operand:SI 2 "register_operand" "d")]
18188          ANY_XSAVE))]
18189   "TARGET_64BIT && TARGET_XSAVE"
18190   "<xsave>\t%0"
18191   [(set_attr "type" "other")
18192    (set_attr "memory" "store")
18193    (set (attr "length")
18194         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18196 (define_insn "<xsave>"
18197   [(set (match_operand:BLK 0 "memory_operand" "=m")
18198         (unspec_volatile:BLK
18199          [(match_operand:SI 1 "register_operand" "a")
18200           (match_operand:SI 2 "register_operand" "d")]
18201          ANY_XSAVE64))]
18202   "TARGET_64BIT && TARGET_XSAVE"
18203   "<xsave>\t%0"
18204   [(set_attr "type" "other")
18205    (set_attr "memory" "store")
18206    (set (attr "length")
18207         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18209 (define_insn "xrstor"
18210    [(unspec_volatile:BLK
18211      [(match_operand:BLK 0 "memory_operand" "m")
18212       (match_operand:DI 1 "register_operand" "A")]
18213      UNSPECV_XRSTOR)]
18214   "!TARGET_64BIT && TARGET_XSAVE"
18215   "xrstor\t%0"
18216   [(set_attr "type" "other")
18217    (set_attr "memory" "load")
18218    (set (attr "length")
18219         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18221 (define_insn "xrstor_rex64"
18222    [(unspec_volatile:BLK
18223      [(match_operand:BLK 0 "memory_operand" "m")
18224       (match_operand:SI 1 "register_operand" "a")
18225       (match_operand:SI 2 "register_operand" "d")]
18226      UNSPECV_XRSTOR)]
18227   "TARGET_64BIT && TARGET_XSAVE"
18228   "xrstor\t%0"
18229   [(set_attr "type" "other")
18230    (set_attr "memory" "load")
18231    (set (attr "length")
18232         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18234 (define_insn "xrstor64"
18235    [(unspec_volatile:BLK
18236      [(match_operand:BLK 0 "memory_operand" "m")
18237       (match_operand:SI 1 "register_operand" "a")
18238       (match_operand:SI 2 "register_operand" "d")]
18239      UNSPECV_XRSTOR64)]
18240   "TARGET_64BIT && TARGET_XSAVE"
18241   "xrstor64\t%0"
18242   [(set_attr "type" "other")
18243    (set_attr "memory" "load")
18244    (set (attr "length")
18245         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18247 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18249 ;; Floating-point instructions for atomic compound assignments
18251 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18253 ; Clobber all floating-point registers on environment save and restore
18254 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18255 (define_insn "fnstenv"
18256   [(set (match_operand:BLK 0 "memory_operand" "=m")
18257         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18258    (clobber (reg:HI FPCR_REG))
18259    (clobber (reg:XF ST0_REG))
18260    (clobber (reg:XF ST1_REG))
18261    (clobber (reg:XF ST2_REG))
18262    (clobber (reg:XF ST3_REG))
18263    (clobber (reg:XF ST4_REG))
18264    (clobber (reg:XF ST5_REG))
18265    (clobber (reg:XF ST6_REG))
18266    (clobber (reg:XF ST7_REG))]
18267   "TARGET_80387"
18268   "fnstenv\t%0"
18269   [(set_attr "type" "other")
18270    (set_attr "memory" "store")
18271    (set (attr "length")
18272         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18274 (define_insn "fldenv"
18275   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18276                     UNSPECV_FLDENV)
18277    (clobber (reg:CCFP FPSR_REG))
18278    (clobber (reg:HI FPCR_REG))
18279    (clobber (reg:XF ST0_REG))
18280    (clobber (reg:XF ST1_REG))
18281    (clobber (reg:XF ST2_REG))
18282    (clobber (reg:XF ST3_REG))
18283    (clobber (reg:XF ST4_REG))
18284    (clobber (reg:XF ST5_REG))
18285    (clobber (reg:XF ST6_REG))
18286    (clobber (reg:XF ST7_REG))]
18287   "TARGET_80387"
18288   "fldenv\t%0"
18289   [(set_attr "type" "other")
18290    (set_attr "memory" "load")
18291    (set (attr "length")
18292         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18294 (define_insn "fnstsw"
18295   [(set (match_operand:HI 0 "memory_operand" "=m")
18296         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18297   "TARGET_80387"
18298   "fnstsw\t%0"
18299   [(set_attr "type" "other")
18300    (set_attr "memory" "store")
18301    (set (attr "length")
18302         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18304 (define_insn "fnclex"
18305   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18306   "TARGET_80387"
18307   "fnclex"
18308   [(set_attr "type" "other")
18309    (set_attr "memory" "none")
18310    (set_attr "length" "2")])
18312 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18314 ;; LWP instructions
18316 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18318 (define_expand "lwp_llwpcb"
18319   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18320                     UNSPECV_LLWP_INTRINSIC)]
18321   "TARGET_LWP")
18323 (define_insn "*lwp_llwpcb<mode>1"
18324   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18325                     UNSPECV_LLWP_INTRINSIC)]
18326   "TARGET_LWP"
18327   "llwpcb\t%0"
18328   [(set_attr "type" "lwp")
18329    (set_attr "mode" "<MODE>")
18330    (set_attr "length" "5")])
18332 (define_expand "lwp_slwpcb"
18333   [(set (match_operand 0 "register_operand" "=r")
18334         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18335   "TARGET_LWP"
18337   rtx (*insn)(rtx);
18339   insn = (Pmode == DImode
18340           ? gen_lwp_slwpcbdi
18341           : gen_lwp_slwpcbsi);
18343   emit_insn (insn (operands[0]));
18344   DONE;
18347 (define_insn "lwp_slwpcb<mode>"
18348   [(set (match_operand:P 0 "register_operand" "=r")
18349         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18350   "TARGET_LWP"
18351   "slwpcb\t%0"
18352   [(set_attr "type" "lwp")
18353    (set_attr "mode" "<MODE>")
18354    (set_attr "length" "5")])
18356 (define_expand "lwp_lwpval<mode>3"
18357   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18358                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18359                      (match_operand:SI 3 "const_int_operand" "i")]
18360                     UNSPECV_LWPVAL_INTRINSIC)]
18361   "TARGET_LWP"
18362   ;; Avoid unused variable warning.
18363   "(void) operands[0];")
18365 (define_insn "*lwp_lwpval<mode>3_1"
18366   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18367                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18368                      (match_operand:SI 2 "const_int_operand" "i")]
18369                     UNSPECV_LWPVAL_INTRINSIC)]
18370   "TARGET_LWP"
18371   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18372   [(set_attr "type" "lwp")
18373    (set_attr "mode" "<MODE>")
18374    (set (attr "length")
18375         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18377 (define_expand "lwp_lwpins<mode>3"
18378   [(set (reg:CCC FLAGS_REG)
18379         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18380                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18381                               (match_operand:SI 3 "const_int_operand" "i")]
18382                              UNSPECV_LWPINS_INTRINSIC))
18383    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18384         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18385   "TARGET_LWP")
18387 (define_insn "*lwp_lwpins<mode>3_1"
18388   [(set (reg:CCC FLAGS_REG)
18389         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18390                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18391                               (match_operand:SI 2 "const_int_operand" "i")]
18392                              UNSPECV_LWPINS_INTRINSIC))]
18393   "TARGET_LWP"
18394   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18395   [(set_attr "type" "lwp")
18396    (set_attr "mode" "<MODE>")
18397    (set (attr "length")
18398         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18400 (define_int_iterator RDFSGSBASE
18401         [UNSPECV_RDFSBASE
18402          UNSPECV_RDGSBASE])
18404 (define_int_iterator WRFSGSBASE
18405         [UNSPECV_WRFSBASE
18406          UNSPECV_WRGSBASE])
18408 (define_int_attr fsgs
18409         [(UNSPECV_RDFSBASE "fs")
18410          (UNSPECV_RDGSBASE "gs")
18411          (UNSPECV_WRFSBASE "fs")
18412          (UNSPECV_WRGSBASE "gs")])
18414 (define_insn "rd<fsgs>base<mode>"
18415   [(set (match_operand:SWI48 0 "register_operand" "=r")
18416         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18417   "TARGET_64BIT && TARGET_FSGSBASE"
18418   "rd<fsgs>base\t%0"
18419   [(set_attr "type" "other")
18420    (set_attr "prefix_extra" "2")])
18422 (define_insn "wr<fsgs>base<mode>"
18423   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18424                     WRFSGSBASE)]
18425   "TARGET_64BIT && TARGET_FSGSBASE"
18426   "wr<fsgs>base\t%0"
18427   [(set_attr "type" "other")
18428    (set_attr "prefix_extra" "2")])
18430 (define_insn "rdrand<mode>_1"
18431   [(set (match_operand:SWI248 0 "register_operand" "=r")
18432         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18433    (set (reg:CCC FLAGS_REG)
18434         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18435   "TARGET_RDRND"
18436   "rdrand\t%0"
18437   [(set_attr "type" "other")
18438    (set_attr "prefix_extra" "1")])
18440 (define_insn "rdseed<mode>_1"
18441   [(set (match_operand:SWI248 0 "register_operand" "=r")
18442         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18443    (set (reg:CCC FLAGS_REG)
18444         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18445   "TARGET_RDSEED"
18446   "rdseed\t%0"
18447   [(set_attr "type" "other")
18448    (set_attr "prefix_extra" "1")])
18450 (define_expand "pause"
18451   [(set (match_dup 0)
18452         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18453   ""
18455   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18456   MEM_VOLATILE_P (operands[0]) = 1;
18459 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18460 ;; They have the same encoding.
18461 (define_insn "*pause"
18462   [(set (match_operand:BLK 0)
18463         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18464   ""
18465   "rep%; nop"
18466   [(set_attr "length" "2")
18467    (set_attr "memory" "unknown")])
18469 (define_expand "xbegin"
18470   [(set (match_operand:SI 0 "register_operand")
18471         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18472   "TARGET_RTM"
18474   rtx label = gen_label_rtx ();
18476   /* xbegin is emitted as jump_insn, so reload won't be able
18477      to reload its operand.  Force the value into AX hard register.  */
18478   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18479   emit_move_insn (ax_reg, constm1_rtx);
18481   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18483   emit_label (label);
18484   LABEL_NUSES (label) = 1;
18486   emit_move_insn (operands[0], ax_reg);
18488   DONE;
18491 (define_insn "xbegin_1"
18492   [(set (pc)
18493         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18494                           (const_int 0))
18495                       (label_ref (match_operand 1))
18496                       (pc)))
18497    (set (match_operand:SI 0 "register_operand" "+a")
18498         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18499   "TARGET_RTM"
18500   "xbegin\t%l1"
18501   [(set_attr "type" "other")
18502    (set_attr "length" "6")])
18504 (define_insn "xend"
18505   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18506   "TARGET_RTM"
18507   "xend"
18508   [(set_attr "type" "other")
18509    (set_attr "length" "3")])
18511 (define_insn "xabort"
18512   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18513                     UNSPECV_XABORT)]
18514   "TARGET_RTM"
18515   "xabort\t%0"
18516   [(set_attr "type" "other")
18517    (set_attr "length" "3")])
18519 (define_expand "xtest"
18520   [(set (match_operand:QI 0 "register_operand")
18521         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18522   "TARGET_RTM"
18524   emit_insn (gen_xtest_1 ());
18526   ix86_expand_setcc (operands[0], NE,
18527                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18528   DONE;
18531 (define_insn "xtest_1"
18532   [(set (reg:CCZ FLAGS_REG)
18533         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18534   "TARGET_RTM"
18535   "xtest"
18536   [(set_attr "type" "other")
18537    (set_attr "length" "3")])
18539 (include "mmx.md")
18540 (include "sse.md")
18541 (include "sync.md")