* config/i386/constraints.md (B): New.
[official-gcc.git] / gcc / config / i386 / i386.md
blobbb2581bcfad52a2b923e36ef584ccd06c946d4f7
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2013 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
66 ;; ! -- print MPX prefix for jxx/call/ret instructions if required.
68 (define_c_enum "unspec" [
69   ;; Relocation specifiers
70   UNSPEC_GOT
71   UNSPEC_GOTOFF
72   UNSPEC_GOTPCREL
73   UNSPEC_GOTTPOFF
74   UNSPEC_TPOFF
75   UNSPEC_NTPOFF
76   UNSPEC_DTPOFF
77   UNSPEC_GOTNTPOFF
78   UNSPEC_INDNTPOFF
79   UNSPEC_PLTOFF
80   UNSPEC_MACHOPIC_OFFSET
81   UNSPEC_PCREL
83   ;; Prologue support
84   UNSPEC_STACK_ALLOC
85   UNSPEC_SET_GOT
86   UNSPEC_SET_RIP
87   UNSPEC_SET_GOT_OFFSET
88   UNSPEC_MEMORY_BLOCKAGE
89   UNSPEC_STACK_CHECK
91   ;; TLS support
92   UNSPEC_TP
93   UNSPEC_TLS_GD
94   UNSPEC_TLS_LD_BASE
95   UNSPEC_TLSDESC
96   UNSPEC_TLS_IE_SUN
98   ;; Other random patterns
99   UNSPEC_SCAS
100   UNSPEC_FNSTSW
101   UNSPEC_SAHF
102   UNSPEC_PARITY
103   UNSPEC_FSTCW
104   UNSPEC_ADD_CARRY
105   UNSPEC_FLDCW
106   UNSPEC_REP
107   UNSPEC_LD_MPIC        ; load_macho_picbase
108   UNSPEC_TRUNC_NOOP
109   UNSPEC_DIV_ALREADY_SPLIT
110   UNSPEC_MS_TO_SYSV_CALL
111   UNSPEC_PAUSE
112   UNSPEC_LEA_ADDR
113   UNSPEC_XBEGIN_ABORT
114   UNSPEC_STOS
116   ;; For SSE/MMX support:
117   UNSPEC_FIX_NOTRUNC
118   UNSPEC_MASKMOV
119   UNSPEC_MOVMSK
120   UNSPEC_RCP
121   UNSPEC_RSQRT
122   UNSPEC_PSADBW
124   ;; Generic math support
125   UNSPEC_COPYSIGN
126   UNSPEC_IEEE_MIN       ; not commutative
127   UNSPEC_IEEE_MAX       ; not commutative
129   ;; x87 Floating point
130   UNSPEC_SIN
131   UNSPEC_COS
132   UNSPEC_FPATAN
133   UNSPEC_FYL2X
134   UNSPEC_FYL2XP1
135   UNSPEC_FRNDINT
136   UNSPEC_FIST
137   UNSPEC_F2XM1
138   UNSPEC_TAN
139   UNSPEC_FXAM
141   ;; x87 Rounding
142   UNSPEC_FRNDINT_FLOOR
143   UNSPEC_FRNDINT_CEIL
144   UNSPEC_FRNDINT_TRUNC
145   UNSPEC_FRNDINT_MASK_PM
146   UNSPEC_FIST_FLOOR
147   UNSPEC_FIST_CEIL
149   ;; x87 Double output FP
150   UNSPEC_SINCOS_COS
151   UNSPEC_SINCOS_SIN
152   UNSPEC_XTRACT_FRACT
153   UNSPEC_XTRACT_EXP
154   UNSPEC_FSCALE_FRACT
155   UNSPEC_FSCALE_EXP
156   UNSPEC_FPREM_F
157   UNSPEC_FPREM_U
158   UNSPEC_FPREM1_F
159   UNSPEC_FPREM1_U
161   UNSPEC_C2_FLAG
162   UNSPEC_FXAM_MEM
164   ;; SSP patterns
165   UNSPEC_SP_SET
166   UNSPEC_SP_TEST
167   UNSPEC_SP_TLS_SET
168   UNSPEC_SP_TLS_TEST
170   ;; For ROUND support
171   UNSPEC_ROUND
173   ;; For CRC32 support
174   UNSPEC_CRC32
176   ;; For BMI support
177   UNSPEC_BEXTR
179   ;; For BMI2 support
180   UNSPEC_PDEP
181   UNSPEC_PEXT
183   UNSPEC_BNDMK
184   UNSPEC_BNDMK_ADDR
185   UNSPEC_BNDSTX
186   UNSPEC_BNDLDX
187   UNSPEC_BNDLDX_ADDR
188   UNSPEC_BNDCL
189   UNSPEC_BNDCU
190   UNSPEC_BNDCN
191   UNSPEC_MPX_FENCE
194 (define_c_enum "unspecv" [
195   UNSPECV_BLOCKAGE
196   UNSPECV_STACK_PROBE
197   UNSPECV_PROBE_STACK_RANGE
198   UNSPECV_ALIGN
199   UNSPECV_PROLOGUE_USE
200   UNSPECV_SPLIT_STACK_RETURN
201   UNSPECV_CLD
202   UNSPECV_NOPS
203   UNSPECV_RDTSC
204   UNSPECV_RDTSCP
205   UNSPECV_RDPMC
206   UNSPECV_LLWP_INTRINSIC
207   UNSPECV_SLWP_INTRINSIC
208   UNSPECV_LWPVAL_INTRINSIC
209   UNSPECV_LWPINS_INTRINSIC
210   UNSPECV_RDFSBASE
211   UNSPECV_RDGSBASE
212   UNSPECV_WRFSBASE
213   UNSPECV_WRGSBASE
214   UNSPECV_FXSAVE
215   UNSPECV_FXRSTOR
216   UNSPECV_FXSAVE64
217   UNSPECV_FXRSTOR64
218   UNSPECV_XSAVE
219   UNSPECV_XRSTOR
220   UNSPECV_XSAVE64
221   UNSPECV_XRSTOR64
222   UNSPECV_XSAVEOPT
223   UNSPECV_XSAVEOPT64
225   ;; For RDRAND support
226   UNSPECV_RDRAND
228   ;; For RDSEED support
229   UNSPECV_RDSEED
231   ;; For RTM support
232   UNSPECV_XBEGIN
233   UNSPECV_XEND
234   UNSPECV_XABORT
235   UNSPECV_XTEST
237   UNSPECV_NLGR
240 ;; Constants to represent rounding modes in the ROUND instruction
241 (define_constants
242   [(ROUND_FLOOR                 0x1)
243    (ROUND_CEIL                  0x2)
244    (ROUND_TRUNC                 0x3)
245    (ROUND_MXCSR                 0x4)
246    (ROUND_NO_EXC                0x8)
247   ])
249 ;; Constants to represent pcomtrue/pcomfalse variants
250 (define_constants
251   [(PCOM_FALSE                  0)
252    (PCOM_TRUE                   1)
253    (COM_FALSE_S                 2)
254    (COM_FALSE_P                 3)
255    (COM_TRUE_S                  4)
256    (COM_TRUE_P                  5)
257   ])
259 ;; Constants used in the XOP pperm instruction
260 (define_constants
261   [(PPERM_SRC                   0x00)   /* copy source */
262    (PPERM_INVERT                0x20)   /* invert source */
263    (PPERM_REVERSE               0x40)   /* bit reverse source */
264    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
265    (PPERM_ZERO                  0x80)   /* all 0's */
266    (PPERM_ONES                  0xa0)   /* all 1's */
267    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
268    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
269    (PPERM_SRC1                  0x00)   /* use first source byte */
270    (PPERM_SRC2                  0x10)   /* use second source byte */
271    ])
273 ;; Registers by name.
274 (define_constants
275   [(AX_REG                       0)
276    (DX_REG                       1)
277    (CX_REG                       2)
278    (BX_REG                       3)
279    (SI_REG                       4)
280    (DI_REG                       5)
281    (BP_REG                       6)
282    (SP_REG                       7)
283    (ST0_REG                      8)
284    (ST1_REG                      9)
285    (ST2_REG                     10)
286    (ST3_REG                     11)
287    (ST4_REG                     12)
288    (ST5_REG                     13)
289    (ST6_REG                     14)
290    (ST7_REG                     15)
291    (FLAGS_REG                   17)
292    (FPSR_REG                    18)
293    (FPCR_REG                    19)
294    (XMM0_REG                    21)
295    (XMM1_REG                    22)
296    (XMM2_REG                    23)
297    (XMM3_REG                    24)
298    (XMM4_REG                    25)
299    (XMM5_REG                    26)
300    (XMM6_REG                    27)
301    (XMM7_REG                    28)
302    (MM0_REG                     29)
303    (MM1_REG                     30)
304    (MM2_REG                     31)
305    (MM3_REG                     32)
306    (MM4_REG                     33)
307    (MM5_REG                     34)
308    (MM6_REG                     35)
309    (MM7_REG                     36)
310    (R8_REG                      37)
311    (R9_REG                      38)
312    (R10_REG                     39)
313    (R11_REG                     40)
314    (R12_REG                     41)
315    (R13_REG                     42)
316    (R14_REG                     43)
317    (R15_REG                     44)
318    (XMM8_REG                    45)
319    (XMM9_REG                    46)
320    (XMM10_REG                   47)
321    (XMM11_REG                   48)
322    (XMM12_REG                   49)
323    (XMM13_REG                   50)
324    (XMM14_REG                   51)
325    (XMM15_REG                   52)
326    (XMM16_REG                   53)
327    (XMM17_REG                   54)
328    (XMM18_REG                   55)
329    (XMM19_REG                   56)
330    (XMM20_REG                   57)
331    (XMM21_REG                   58)
332    (XMM22_REG                   59)
333    (XMM23_REG                   60)
334    (XMM24_REG                   61)
335    (XMM25_REG                   62)
336    (XMM26_REG                   63)
337    (XMM27_REG                   64)
338    (XMM28_REG                   65)
339    (XMM29_REG                   66)
340    (XMM30_REG                   67)
341    (XMM31_REG                   68)
342    (MASK0_REG                   69)
343    (MASK1_REG                   70)
344    (MASK2_REG                   71)
345    (MASK3_REG                   72)
346    (MASK4_REG                   73)
347    (MASK5_REG                   74)
348    (MASK6_REG                   75)
349    (MASK7_REG                   76)
350    (BND0_REG                    77)
351    (BND1_REG                    78)
352   ])
354 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
355 ;; from i386.c.
357 ;; In C guard expressions, put expressions which may be compile-time
358 ;; constants first.  This allows for better optimization.  For
359 ;; example, write "TARGET_64BIT && reload_completed", not
360 ;; "reload_completed && TARGET_64BIT".
363 ;; Processor type.
364 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
365                     atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,btver1,btver2"
366   (const (symbol_ref "ix86_schedule")))
368 ;; A basic instruction type.  Refinements due to arguments to be
369 ;; provided in other attributes.
370 (define_attr "type"
371   "other,multi,
372    alu,alu1,negnot,imov,imovx,lea,
373    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
374    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
375    push,pop,call,callv,leave,
376    str,bitmanip,
377    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
378    fxch,fistp,fisttp,frndint,
379    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
380    ssemul,sseimul,ssediv,sselog,sselog1,
381    sseishft,sseishft1,ssecmp,ssecomi,
382    ssecvt,ssecvt1,sseicvt,sseins,
383    sseshuf,sseshuf1,ssemuladd,sse4arg,
384    lwp,mskmov,msklog,
385    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
386    mpxmov,mpxmk,mpxchk,mpxld,mpxst"
387   (const_string "other"))
389 ;; Main data type used by the insn
390 (define_attr "mode"
391   "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
392   V2DF,V2SF,V1DF,V8DF"
393   (const_string "unknown"))
395 ;; The CPU unit operations uses.
396 (define_attr "unit" "integer,i387,sse,mmx,unknown"
397   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
398                           fxch,fistp,fisttp,frndint")
399            (const_string "i387")
400          (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
401                           ssemul,sseimul,ssediv,sselog,sselog1,
402                           sseishft,sseishft1,ssecmp,ssecomi,
403                           ssecvt,ssecvt1,sseicvt,sseins,
404                           sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
405            (const_string "sse")
406          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
407            (const_string "mmx")
408          (eq_attr "type" "other")
409            (const_string "unknown")]
410          (const_string "integer")))
412 ;; The (bounding maximum) length of an instruction immediate.
413 (define_attr "length_immediate" ""
414   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
415                           bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
416                           mpxld,mpxst")
417            (const_int 0)
418          (eq_attr "unit" "i387,sse,mmx")
419            (const_int 0)
420          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
421                           rotate,rotatex,rotate1,imul,icmp,push,pop")
422            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
423          (eq_attr "type" "imov,test")
424            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
425          (eq_attr "type" "call")
426            (if_then_else (match_operand 0 "constant_call_address_operand")
427              (const_int 4)
428              (const_int 0))
429          (eq_attr "type" "callv")
430            (if_then_else (match_operand 1 "constant_call_address_operand")
431              (const_int 4)
432              (const_int 0))
433          ;; We don't know the size before shorten_branches.  Expect
434          ;; the instruction to fit for better scheduling.
435          (eq_attr "type" "ibr")
436            (const_int 1)
437          ]
438          (symbol_ref "/* Update immediate_length and other attributes! */
439                       gcc_unreachable (),1")))
441 ;; The (bounding maximum) length of an instruction address.
442 (define_attr "length_address" ""
443   (cond [(eq_attr "type" "str,other,multi,fxch")
444            (const_int 0)
445          (and (eq_attr "type" "call")
446               (match_operand 0 "constant_call_address_operand"))
447              (const_int 0)
448          (and (eq_attr "type" "callv")
449               (match_operand 1 "constant_call_address_operand"))
450              (const_int 0)
451          ]
452          (symbol_ref "ix86_attr_length_address_default (insn)")))
454 ;; Set when length prefix is used.
455 (define_attr "prefix_data16" ""
456   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
457            (const_int 0)
458          (eq_attr "mode" "HI")
459            (const_int 1)
460          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
461            (const_int 1)
462         ]
463         (const_int 0)))
465 ;; Set when string REP prefix is used.
466 (define_attr "prefix_rep" ""
467   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
468            (const_int 0)
469          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
470            (const_int 1)
471          (and (eq_attr "type" "ibr,call,callv")
472               (match_test "ix86_bnd_prefixed_insn_p (insn)"))
473            (const_int 1)
474         ]
475         (const_int 0)))
477 ;; Set when 0f opcode prefix is used.
478 (define_attr "prefix_0f" ""
479   (if_then_else
480     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
481                           mpxmk,mpxmov,mpxchk,mpxld,mpxst")
482          (eq_attr "unit" "sse,mmx"))
483     (const_int 1)
484     (const_int 0)))
486 ;; Set when REX opcode prefix is used.
487 (define_attr "prefix_rex" ""
488   (cond [(not (match_test "TARGET_64BIT"))
489            (const_int 0)
490          (and (eq_attr "mode" "DI")
491               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
492                    (eq_attr "unit" "!mmx")))
493            (const_int 1)
494          (and (eq_attr "mode" "QI")
495               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
496            (const_int 1)
497          (match_test "x86_extended_reg_mentioned_p (insn)")
498            (const_int 1)
499          (and (eq_attr "type" "imovx")
500               (match_operand:QI 1 "ext_QIreg_operand"))
501            (const_int 1)
502         ]
503         (const_int 0)))
505 ;; There are also additional prefixes in 3DNOW, SSSE3.
506 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
507 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
508 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
509 (define_attr "prefix_extra" ""
510   (cond [(eq_attr "type" "ssemuladd,sse4arg")
511            (const_int 2)
512          (eq_attr "type" "sseiadd1,ssecvt1")
513            (const_int 1)
514         ]
515         (const_int 0)))
517 ;; Prefix used: original, VEX or maybe VEX.
518 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
519   (cond [(eq_attr "mode" "OI,V8SF,V4DF")
520            (const_string "vex")
521          (eq_attr "mode" "XI,V16SF,V8DF")
522            (const_string "evex")
523         ]
524         (const_string "orig")))
526 ;; VEX W bit is used.
527 (define_attr "prefix_vex_w" "" (const_int 0))
529 ;; The length of VEX prefix
530 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
531 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
532 ;; still prefix_0f 1, with prefix_extra 1.
533 (define_attr "length_vex" ""
534   (if_then_else (and (eq_attr "prefix_0f" "1")
535                      (eq_attr "prefix_extra" "0"))
536     (if_then_else (eq_attr "prefix_vex_w" "1")
537       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
538       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
539     (if_then_else (eq_attr "prefix_vex_w" "1")
540       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
541       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
543 ;; 4-bytes evex prefix and 1 byte opcode.
544 (define_attr "length_evex" "" (const_int 5))
546 ;; Set when modrm byte is used.
547 (define_attr "modrm" ""
548   (cond [(eq_attr "type" "str,leave")
549            (const_int 0)
550          (eq_attr "unit" "i387")
551            (const_int 0)
552          (and (eq_attr "type" "incdec")
553               (and (not (match_test "TARGET_64BIT"))
554                    (ior (match_operand:SI 1 "register_operand")
555                         (match_operand:HI 1 "register_operand"))))
556            (const_int 0)
557          (and (eq_attr "type" "push")
558               (not (match_operand 1 "memory_operand")))
559            (const_int 0)
560          (and (eq_attr "type" "pop")
561               (not (match_operand 0 "memory_operand")))
562            (const_int 0)
563          (and (eq_attr "type" "imov")
564               (and (not (eq_attr "mode" "DI"))
565                    (ior (and (match_operand 0 "register_operand")
566                              (match_operand 1 "immediate_operand"))
567                         (ior (and (match_operand 0 "ax_reg_operand")
568                                   (match_operand 1 "memory_displacement_only_operand"))
569                              (and (match_operand 0 "memory_displacement_only_operand")
570                                   (match_operand 1 "ax_reg_operand"))))))
571            (const_int 0)
572          (and (eq_attr "type" "call")
573               (match_operand 0 "constant_call_address_operand"))
574              (const_int 0)
575          (and (eq_attr "type" "callv")
576               (match_operand 1 "constant_call_address_operand"))
577              (const_int 0)
578          (and (eq_attr "type" "alu,alu1,icmp,test")
579               (match_operand 0 "ax_reg_operand"))
580              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
581          ]
582          (const_int 1)))
584 ;; When this attribute is set, calculate total insn length from
585 ;; length_nobnd attribute, prefixed with eventual bnd prefix byte
586 (define_attr "length_nobnd" "" (const_int 0))
588 ;; The (bounding maximum) length of an instruction in bytes.
589 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
590 ;; Later we may want to split them and compute proper length as for
591 ;; other insns.
592 (define_attr "length" ""
593   (cond [(eq_attr "length_nobnd" "!0")
594            (plus (symbol_ref ("ix86_bnd_prefixed_insn_p (insn)"))
595                  (attr "length_nobnd"))
596          (eq_attr "type" "other,multi,fistp,frndint")
597            (const_int 16)
598          (eq_attr "type" "fcmp")
599            (const_int 4)
600          (eq_attr "unit" "i387")
601            (plus (const_int 2)
602                  (plus (attr "prefix_data16")
603                        (attr "length_address")))
604          (ior (eq_attr "prefix" "evex")
605               (and (ior (eq_attr "prefix" "maybe_evex")
606                         (eq_attr "prefix" "maybe_vex"))
607                    (match_test "TARGET_AVX512F")))
608            (plus (attr "length_evex")
609                  (plus (attr "length_immediate")
610                        (plus (attr "modrm")
611                              (attr "length_address"))))
612          (ior (eq_attr "prefix" "vex")
613               (and (ior (eq_attr "prefix" "maybe_vex")
614                         (eq_attr "prefix" "maybe_evex"))
615                    (match_test "TARGET_AVX")))
616            (plus (attr "length_vex")
617                  (plus (attr "length_immediate")
618                        (plus (attr "modrm")
619                              (attr "length_address"))))]
620          (plus (plus (attr "modrm")
621                      (plus (attr "prefix_0f")
622                            (plus (attr "prefix_rex")
623                                  (plus (attr "prefix_extra")
624                                        (const_int 1)))))
625                (plus (attr "prefix_rep")
626                      (plus (attr "prefix_data16")
627                            (plus (attr "length_immediate")
628                                  (attr "length_address")))))))
630 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
631 ;; `store' if there is a simple memory reference therein, or `unknown'
632 ;; if the instruction is complex.
634 (define_attr "memory" "none,load,store,both,unknown"
635   (cond [(eq_attr "type" "other,multi,str,lwp")
636            (const_string "unknown")
637          (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
638            (const_string "none")
639          (eq_attr "type" "fistp,leave")
640            (const_string "both")
641          (eq_attr "type" "frndint")
642            (const_string "load")
643          (eq_attr "type" "mpxld")
644            (const_string "load")
645          (eq_attr "type" "mpxst")
646            (const_string "store")
647          (eq_attr "type" "push")
648            (if_then_else (match_operand 1 "memory_operand")
649              (const_string "both")
650              (const_string "store"))
651          (eq_attr "type" "pop")
652            (if_then_else (match_operand 0 "memory_operand")
653              (const_string "both")
654              (const_string "load"))
655          (eq_attr "type" "setcc")
656            (if_then_else (match_operand 0 "memory_operand")
657              (const_string "store")
658              (const_string "none"))
659          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
660            (if_then_else (ior (match_operand 0 "memory_operand")
661                               (match_operand 1 "memory_operand"))
662              (const_string "load")
663              (const_string "none"))
664          (eq_attr "type" "ibr")
665            (if_then_else (match_operand 0 "memory_operand")
666              (const_string "load")
667              (const_string "none"))
668          (eq_attr "type" "call")
669            (if_then_else (match_operand 0 "constant_call_address_operand")
670              (const_string "none")
671              (const_string "load"))
672          (eq_attr "type" "callv")
673            (if_then_else (match_operand 1 "constant_call_address_operand")
674              (const_string "none")
675              (const_string "load"))
676          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
677               (match_operand 1 "memory_operand"))
678            (const_string "both")
679          (and (match_operand 0 "memory_operand")
680               (match_operand 1 "memory_operand"))
681            (const_string "both")
682          (match_operand 0 "memory_operand")
683            (const_string "store")
684          (match_operand 1 "memory_operand")
685            (const_string "load")
686          (and (eq_attr "type"
687                  "!alu1,negnot,ishift1,
688                    imov,imovx,icmp,test,bitmanip,
689                    fmov,fcmp,fsgn,
690                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
691                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
692                    mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
693               (match_operand 2 "memory_operand"))
694            (const_string "load")
695          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
696               (match_operand 3 "memory_operand"))
697            (const_string "load")
698         ]
699         (const_string "none")))
701 ;; Indicates if an instruction has both an immediate and a displacement.
703 (define_attr "imm_disp" "false,true,unknown"
704   (cond [(eq_attr "type" "other,multi")
705            (const_string "unknown")
706          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
707               (and (match_operand 0 "memory_displacement_operand")
708                    (match_operand 1 "immediate_operand")))
709            (const_string "true")
710          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
711               (and (match_operand 0 "memory_displacement_operand")
712                    (match_operand 2 "immediate_operand")))
713            (const_string "true")
714         ]
715         (const_string "false")))
717 ;; Indicates if an FP operation has an integer source.
719 (define_attr "fp_int_src" "false,true"
720   (const_string "false"))
722 ;; Defines rounding mode of an FP operation.
724 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
725   (const_string "any"))
727 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
728 (define_attr "use_carry" "0,1" (const_string "0"))
730 ;; Define attribute to indicate unaligned ssemov insns
731 (define_attr "movu" "0,1" (const_string "0"))
733 ;; Used to control the "enabled" attribute on a per-instruction basis.
734 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
735                     sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
736                     avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,fma_avx512f"
737   (const_string "base"))
739 (define_attr "enabled" ""
740   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
741          (eq_attr "isa" "x64_sse4")
742            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
743          (eq_attr "isa" "x64_sse4_noavx")
744            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
745          (eq_attr "isa" "x64_avx")
746            (symbol_ref "TARGET_64BIT && TARGET_AVX")
747          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
748          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
749          (eq_attr "isa" "sse2_noavx")
750            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
751          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
752          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
753          (eq_attr "isa" "sse4_noavx")
754            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
755          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
756          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
757          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
758          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
759          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
760          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
761          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
762          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
763          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
764          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
765          (eq_attr "isa" "fma_avx512f")
766            (symbol_ref "TARGET_FMA || TARGET_AVX512F")
767         ]
768         (const_int 1)))
770 ;; Describe a user's asm statement.
771 (define_asm_attributes
772   [(set_attr "length" "128")
773    (set_attr "type" "multi")])
775 (define_code_iterator plusminus [plus minus])
777 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
779 (define_code_iterator multdiv [mult div])
781 ;; Base name for define_insn
782 (define_code_attr plusminus_insn
783   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
784    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
786 ;; Base name for insn mnemonic.
787 (define_code_attr plusminus_mnemonic
788   [(plus "add") (ss_plus "adds") (us_plus "addus")
789    (minus "sub") (ss_minus "subs") (us_minus "subus")])
790 (define_code_attr plusminus_carry_mnemonic
791   [(plus "adc") (minus "sbb")])
792 (define_code_attr multdiv_mnemonic
793   [(mult "mul") (div "div")])
795 ;; Mark commutative operators as such in constraints.
796 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
797                         (minus "") (ss_minus "") (us_minus "")])
799 ;; Mapping of max and min
800 (define_code_iterator maxmin [smax smin umax umin])
802 ;; Mapping of signed max and min
803 (define_code_iterator smaxmin [smax smin])
805 ;; Mapping of unsigned max and min
806 (define_code_iterator umaxmin [umax umin])
808 ;; Base name for integer and FP insn mnemonic
809 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
810                               (umax "maxu") (umin "minu")])
811 (define_code_attr maxmin_float [(smax "max") (smin "min")])
813 ;; Mapping of logic operators
814 (define_code_iterator any_logic [and ior xor])
815 (define_code_iterator any_or [ior xor])
816 (define_code_iterator fpint_logic [and xor])
818 ;; Base name for insn mnemonic.
819 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
821 ;; Mapping of logic-shift operators
822 (define_code_iterator any_lshift [ashift lshiftrt])
824 ;; Mapping of shift-right operators
825 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
827 ;; Mapping of all shift operators
828 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
830 ;; Base name for define_insn
831 (define_code_attr shift_insn
832   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
834 ;; Base name for insn mnemonic.
835 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
836 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
838 ;; Mapping of rotate operators
839 (define_code_iterator any_rotate [rotate rotatert])
841 ;; Base name for define_insn
842 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
844 ;; Base name for insn mnemonic.
845 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
847 ;; Mapping of abs neg operators
848 (define_code_iterator absneg [abs neg])
850 ;; Base name for x87 insn mnemonic.
851 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
853 ;; Used in signed and unsigned widening multiplications.
854 (define_code_iterator any_extend [sign_extend zero_extend])
856 ;; Prefix for insn menmonic.
857 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
859 ;; Prefix for define_insn
860 (define_code_attr u [(sign_extend "") (zero_extend "u")])
861 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
862 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
864 ;; Used in signed and unsigned fix.
865 (define_code_iterator any_fix [fix unsigned_fix])
866 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
868 ;; All integer modes.
869 (define_mode_iterator SWI1248x [QI HI SI DI])
871 ;; All integer modes without QImode.
872 (define_mode_iterator SWI248x [HI SI DI])
874 ;; All integer modes without QImode and HImode.
875 (define_mode_iterator SWI48x [SI DI])
877 ;; All integer modes without SImode and DImode.
878 (define_mode_iterator SWI12 [QI HI])
880 ;; All integer modes without DImode.
881 (define_mode_iterator SWI124 [QI HI SI])
883 ;; All integer modes without QImode and DImode.
884 (define_mode_iterator SWI24 [HI SI])
886 ;; Single word integer modes.
887 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
889 ;; Single word integer modes without QImode.
890 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
892 ;; Single word integer modes without QImode and HImode.
893 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
895 ;; All math-dependant single and double word integer modes.
896 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
897                              (HI "TARGET_HIMODE_MATH")
898                              SI DI (TI "TARGET_64BIT")])
900 ;; Math-dependant single word integer modes.
901 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
902                             (HI "TARGET_HIMODE_MATH")
903                             SI (DI "TARGET_64BIT")])
905 ;; Math-dependant integer modes without DImode.
906 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
907                                (HI "TARGET_HIMODE_MATH")
908                                SI])
910 ;; Math-dependant single word integer modes without QImode.
911 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
912                                SI (DI "TARGET_64BIT")])
914 ;; Double word integer modes.
915 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
916                            (TI "TARGET_64BIT")])
918 ;; Double word integer modes as mode attribute.
919 (define_mode_attr DWI [(SI "DI") (DI "TI")])
920 (define_mode_attr dwi [(SI "di") (DI "ti")])
922 ;; Half mode for double word integer modes.
923 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
924                             (DI "TARGET_64BIT")])
926 ;; Bound modes.
927 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
928                            (BND64 "TARGET_LP64")])
930 ;; Pointer mode corresponding to bound mode.
931 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
933 ;; MPX check types
934 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
936 ;; Check name
937 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
938                            (UNSPEC_BNDCU "cu")
939                            (UNSPEC_BNDCN "cn")])
941 ;; Instruction suffix for integer modes.
942 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
944 ;; Pointer size prefix for integer modes (Intel asm dialect)
945 (define_mode_attr iptrsize [(QI "BYTE")
946                             (HI "WORD")
947                             (SI "DWORD")
948                             (DI "QWORD")])
950 ;; Register class for integer modes.
951 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
953 ;; Immediate operand constraint for integer modes.
954 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
956 ;; General operand constraint for word modes.
957 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
959 ;; Immediate operand constraint for double integer modes.
960 (define_mode_attr di [(SI "nF") (DI "e")])
962 ;; Immediate operand constraint for shifts.
963 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
965 ;; General operand predicate for integer modes.
966 (define_mode_attr general_operand
967         [(QI "general_operand")
968          (HI "general_operand")
969          (SI "x86_64_general_operand")
970          (DI "x86_64_general_operand")
971          (TI "x86_64_general_operand")])
973 ;; General sign/zero extend operand predicate for integer modes.
974 (define_mode_attr general_szext_operand
975         [(QI "general_operand")
976          (HI "general_operand")
977          (SI "x86_64_szext_general_operand")
978          (DI "x86_64_szext_general_operand")])
980 ;; Immediate operand predicate for integer modes.
981 (define_mode_attr immediate_operand
982         [(QI "immediate_operand")
983          (HI "immediate_operand")
984          (SI "x86_64_immediate_operand")
985          (DI "x86_64_immediate_operand")])
987 ;; Nonmemory operand predicate for integer modes.
988 (define_mode_attr nonmemory_operand
989         [(QI "nonmemory_operand")
990          (HI "nonmemory_operand")
991          (SI "x86_64_nonmemory_operand")
992          (DI "x86_64_nonmemory_operand")])
994 ;; Operand predicate for shifts.
995 (define_mode_attr shift_operand
996         [(QI "nonimmediate_operand")
997          (HI "nonimmediate_operand")
998          (SI "nonimmediate_operand")
999          (DI "shiftdi_operand")
1000          (TI "register_operand")])
1002 ;; Operand predicate for shift argument.
1003 (define_mode_attr shift_immediate_operand
1004         [(QI "const_1_to_31_operand")
1005          (HI "const_1_to_31_operand")
1006          (SI "const_1_to_31_operand")
1007          (DI "const_1_to_63_operand")])
1009 ;; Input operand predicate for arithmetic left shifts.
1010 (define_mode_attr ashl_input_operand
1011         [(QI "nonimmediate_operand")
1012          (HI "nonimmediate_operand")
1013          (SI "nonimmediate_operand")
1014          (DI "ashldi_input_operand")
1015          (TI "reg_or_pm1_operand")])
1017 ;; SSE and x87 SFmode and DFmode floating point modes
1018 (define_mode_iterator MODEF [SF DF])
1020 ;; All x87 floating point modes
1021 (define_mode_iterator X87MODEF [SF DF XF])
1023 ;; SSE instruction suffix for various modes
1024 (define_mode_attr ssemodesuffix
1025   [(SF "ss") (DF "sd")
1026    (V16SF "ps") (V8DF "pd")
1027    (V8SF "ps") (V4DF "pd")
1028    (V4SF "ps") (V2DF "pd")
1029    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1030    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1031    (V64QI "b") (V16SI "d") (V8DI "q")])
1033 ;; SSE vector suffix for floating point modes
1034 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1036 ;; SSE vector mode corresponding to a scalar mode
1037 (define_mode_attr ssevecmode
1038   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1039 (define_mode_attr ssevecmodelower
1040   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1042 ;; Instruction suffix for REX 64bit operators.
1043 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1045 ;; This mode iterator allows :P to be used for patterns that operate on
1046 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1047 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1049 ;; This mode iterator allows :W to be used for patterns that operate on
1050 ;; word_mode sized quantities.
1051 (define_mode_iterator W
1052   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1054 ;; This mode iterator allows :PTR to be used for patterns that operate on
1055 ;; ptr_mode sized quantities.
1056 (define_mode_iterator PTR
1057   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1059 ;; Scheduling descriptions
1061 (include "pentium.md")
1062 (include "ppro.md")
1063 (include "k6.md")
1064 (include "athlon.md")
1065 (include "bdver1.md")
1066 (include "bdver3.md")
1067 (include "btver2.md")
1068 (include "geode.md")
1069 (include "atom.md")
1070 (include "slm.md")
1071 (include "core2.md")
1074 ;; Operand and operator predicates and constraints
1076 (include "predicates.md")
1077 (include "constraints.md")
1080 ;; Compare and branch/compare and store instructions.
1082 (define_expand "cbranch<mode>4"
1083   [(set (reg:CC FLAGS_REG)
1084         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1085                     (match_operand:SDWIM 2 "<general_operand>")))
1086    (set (pc) (if_then_else
1087                (match_operator 0 "ordered_comparison_operator"
1088                 [(reg:CC FLAGS_REG) (const_int 0)])
1089                (label_ref (match_operand 3))
1090                (pc)))]
1091   ""
1093   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1094     operands[1] = force_reg (<MODE>mode, operands[1]);
1095   ix86_expand_branch (GET_CODE (operands[0]),
1096                       operands[1], operands[2], operands[3]);
1097   DONE;
1100 (define_expand "cstore<mode>4"
1101   [(set (reg:CC FLAGS_REG)
1102         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1103                     (match_operand:SWIM 3 "<general_operand>")))
1104    (set (match_operand:QI 0 "register_operand")
1105         (match_operator 1 "ordered_comparison_operator"
1106           [(reg:CC FLAGS_REG) (const_int 0)]))]
1107   ""
1109   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1110     operands[2] = force_reg (<MODE>mode, operands[2]);
1111   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1112                      operands[2], operands[3]);
1113   DONE;
1116 (define_expand "cmp<mode>_1"
1117   [(set (reg:CC FLAGS_REG)
1118         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1119                     (match_operand:SWI48 1 "<general_operand>")))])
1121 (define_insn "*cmp<mode>_ccno_1"
1122   [(set (reg FLAGS_REG)
1123         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1124                  (match_operand:SWI 1 "const0_operand")))]
1125   "ix86_match_ccmode (insn, CCNOmode)"
1126   "@
1127    test{<imodesuffix>}\t%0, %0
1128    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1129   [(set_attr "type" "test,icmp")
1130    (set_attr "length_immediate" "0,1")
1131    (set_attr "mode" "<MODE>")])
1133 (define_insn "*cmp<mode>_1"
1134   [(set (reg FLAGS_REG)
1135         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1136                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1137   "ix86_match_ccmode (insn, CCmode)"
1138   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1139   [(set_attr "type" "icmp")
1140    (set_attr "mode" "<MODE>")])
1142 (define_insn "*cmp<mode>_minus_1"
1143   [(set (reg FLAGS_REG)
1144         (compare
1145           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1146                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1147           (const_int 0)))]
1148   "ix86_match_ccmode (insn, CCGOCmode)"
1149   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1150   [(set_attr "type" "icmp")
1151    (set_attr "mode" "<MODE>")])
1153 (define_insn "*cmpqi_ext_1"
1154   [(set (reg FLAGS_REG)
1155         (compare
1156           (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1157           (subreg:QI
1158             (zero_extract:SI
1159               (match_operand 1 "ext_register_operand" "Q,Q")
1160               (const_int 8)
1161               (const_int 8)) 0)))]
1162   "ix86_match_ccmode (insn, CCmode)"
1163   "cmp{b}\t{%h1, %0|%0, %h1}"
1164   [(set_attr "isa" "*,nox64")
1165    (set_attr "type" "icmp")
1166    (set_attr "mode" "QI")])
1168 (define_insn "*cmpqi_ext_2"
1169   [(set (reg FLAGS_REG)
1170         (compare
1171           (subreg:QI
1172             (zero_extract:SI
1173               (match_operand 0 "ext_register_operand" "Q")
1174               (const_int 8)
1175               (const_int 8)) 0)
1176           (match_operand:QI 1 "const0_operand")))]
1177   "ix86_match_ccmode (insn, CCNOmode)"
1178   "test{b}\t%h0, %h0"
1179   [(set_attr "type" "test")
1180    (set_attr "length_immediate" "0")
1181    (set_attr "mode" "QI")])
1183 (define_expand "cmpqi_ext_3"
1184   [(set (reg:CC FLAGS_REG)
1185         (compare:CC
1186           (subreg:QI
1187             (zero_extract:SI
1188               (match_operand 0 "ext_register_operand")
1189               (const_int 8)
1190               (const_int 8)) 0)
1191           (match_operand:QI 1 "const_int_operand")))])
1193 (define_insn "*cmpqi_ext_3"
1194   [(set (reg FLAGS_REG)
1195         (compare
1196           (subreg:QI
1197             (zero_extract:SI
1198               (match_operand 0 "ext_register_operand" "Q,Q")
1199               (const_int 8)
1200               (const_int 8)) 0)
1201           (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1202   "ix86_match_ccmode (insn, CCmode)"
1203   "cmp{b}\t{%1, %h0|%h0, %1}"
1204   [(set_attr "isa" "*,nox64")
1205    (set_attr "type" "icmp")
1206    (set_attr "modrm" "1")
1207    (set_attr "mode" "QI")])
1209 (define_insn "*cmpqi_ext_4"
1210   [(set (reg FLAGS_REG)
1211         (compare
1212           (subreg:QI
1213             (zero_extract:SI
1214               (match_operand 0 "ext_register_operand" "Q")
1215               (const_int 8)
1216               (const_int 8)) 0)
1217           (subreg:QI
1218             (zero_extract:SI
1219               (match_operand 1 "ext_register_operand" "Q")
1220               (const_int 8)
1221               (const_int 8)) 0)))]
1222   "ix86_match_ccmode (insn, CCmode)"
1223   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1224   [(set_attr "type" "icmp")
1225    (set_attr "mode" "QI")])
1227 ;; These implement float point compares.
1228 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1229 ;; which would allow mix and match FP modes on the compares.  Which is what
1230 ;; the old patterns did, but with many more of them.
1232 (define_expand "cbranchxf4"
1233   [(set (reg:CC FLAGS_REG)
1234         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1235                     (match_operand:XF 2 "nonmemory_operand")))
1236    (set (pc) (if_then_else
1237               (match_operator 0 "ix86_fp_comparison_operator"
1238                [(reg:CC FLAGS_REG)
1239                 (const_int 0)])
1240               (label_ref (match_operand 3))
1241               (pc)))]
1242   "TARGET_80387"
1244   ix86_expand_branch (GET_CODE (operands[0]),
1245                       operands[1], operands[2], operands[3]);
1246   DONE;
1249 (define_expand "cstorexf4"
1250   [(set (reg:CC FLAGS_REG)
1251         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1252                     (match_operand:XF 3 "nonmemory_operand")))
1253    (set (match_operand:QI 0 "register_operand")
1254               (match_operator 1 "ix86_fp_comparison_operator"
1255                [(reg:CC FLAGS_REG)
1256                 (const_int 0)]))]
1257   "TARGET_80387"
1259   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1260                      operands[2], operands[3]);
1261   DONE;
1264 (define_expand "cbranch<mode>4"
1265   [(set (reg:CC FLAGS_REG)
1266         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1267                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1268    (set (pc) (if_then_else
1269               (match_operator 0 "ix86_fp_comparison_operator"
1270                [(reg:CC FLAGS_REG)
1271                 (const_int 0)])
1272               (label_ref (match_operand 3))
1273               (pc)))]
1274   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1276   ix86_expand_branch (GET_CODE (operands[0]),
1277                       operands[1], operands[2], operands[3]);
1278   DONE;
1281 (define_expand "cstore<mode>4"
1282   [(set (reg:CC FLAGS_REG)
1283         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1284                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1285    (set (match_operand:QI 0 "register_operand")
1286               (match_operator 1 "ix86_fp_comparison_operator"
1287                [(reg:CC FLAGS_REG)
1288                 (const_int 0)]))]
1289   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1291   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1292                      operands[2], operands[3]);
1293   DONE;
1296 (define_expand "cbranchcc4"
1297   [(set (pc) (if_then_else
1298               (match_operator 0 "comparison_operator"
1299                [(match_operand 1 "flags_reg_operand")
1300                 (match_operand 2 "const0_operand")])
1301               (label_ref (match_operand 3))
1302               (pc)))]
1303   ""
1305   ix86_expand_branch (GET_CODE (operands[0]),
1306                       operands[1], operands[2], operands[3]);
1307   DONE;
1310 (define_expand "cstorecc4"
1311   [(set (match_operand:QI 0 "register_operand")
1312               (match_operator 1 "comparison_operator"
1313                [(match_operand 2 "flags_reg_operand")
1314                 (match_operand 3 "const0_operand")]))]
1315   ""
1317   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1318                      operands[2], operands[3]);
1319   DONE;
1323 ;; FP compares, step 1:
1324 ;; Set the FP condition codes.
1326 ;; CCFPmode     compare with exceptions
1327 ;; CCFPUmode    compare with no exceptions
1329 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1330 ;; used to manage the reg stack popping would not be preserved.
1332 (define_insn "*cmp<mode>_0_i387"
1333   [(set (match_operand:HI 0 "register_operand" "=a")
1334         (unspec:HI
1335           [(compare:CCFP
1336              (match_operand:X87MODEF 1 "register_operand" "f")
1337              (match_operand:X87MODEF 2 "const0_operand"))]
1338         UNSPEC_FNSTSW))]
1339   "TARGET_80387"
1340   "* return output_fp_compare (insn, operands, false, false);"
1341   [(set_attr "type" "multi")
1342    (set_attr "unit" "i387")
1343    (set_attr "mode" "<MODE>")])
1345 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1346   [(set (reg:CCFP FLAGS_REG)
1347         (compare:CCFP
1348           (match_operand:X87MODEF 1 "register_operand" "f")
1349           (match_operand:X87MODEF 2 "const0_operand")))
1350    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1351   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1352   "#"
1353   "&& reload_completed"
1354   [(set (match_dup 0)
1355         (unspec:HI
1356           [(compare:CCFP (match_dup 1)(match_dup 2))]
1357         UNSPEC_FNSTSW))
1358    (set (reg:CC FLAGS_REG)
1359         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1360   ""
1361   [(set_attr "type" "multi")
1362    (set_attr "unit" "i387")
1363    (set_attr "mode" "<MODE>")])
1365 (define_insn "*cmpxf_i387"
1366   [(set (match_operand:HI 0 "register_operand" "=a")
1367         (unspec:HI
1368           [(compare:CCFP
1369              (match_operand:XF 1 "register_operand" "f")
1370              (match_operand:XF 2 "register_operand" "f"))]
1371           UNSPEC_FNSTSW))]
1372   "TARGET_80387"
1373   "* return output_fp_compare (insn, operands, false, false);"
1374   [(set_attr "type" "multi")
1375    (set_attr "unit" "i387")
1376    (set_attr "mode" "XF")])
1378 (define_insn_and_split "*cmpxf_cc_i387"
1379   [(set (reg:CCFP FLAGS_REG)
1380         (compare:CCFP
1381           (match_operand:XF 1 "register_operand" "f")
1382           (match_operand:XF 2 "register_operand" "f")))
1383    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1384   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1385   "#"
1386   "&& reload_completed"
1387   [(set (match_dup 0)
1388         (unspec:HI
1389           [(compare:CCFP (match_dup 1)(match_dup 2))]
1390         UNSPEC_FNSTSW))
1391    (set (reg:CC FLAGS_REG)
1392         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1393   ""
1394   [(set_attr "type" "multi")
1395    (set_attr "unit" "i387")
1396    (set_attr "mode" "XF")])
1398 (define_insn "*cmp<mode>_i387"
1399   [(set (match_operand:HI 0 "register_operand" "=a")
1400         (unspec:HI
1401           [(compare:CCFP
1402              (match_operand:MODEF 1 "register_operand" "f")
1403              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1404           UNSPEC_FNSTSW))]
1405   "TARGET_80387"
1406   "* return output_fp_compare (insn, operands, false, false);"
1407   [(set_attr "type" "multi")
1408    (set_attr "unit" "i387")
1409    (set_attr "mode" "<MODE>")])
1411 (define_insn_and_split "*cmp<mode>_cc_i387"
1412   [(set (reg:CCFP FLAGS_REG)
1413         (compare:CCFP
1414           (match_operand:MODEF 1 "register_operand" "f")
1415           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1416    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1417   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1418   "#"
1419   "&& reload_completed"
1420   [(set (match_dup 0)
1421         (unspec:HI
1422           [(compare:CCFP (match_dup 1)(match_dup 2))]
1423         UNSPEC_FNSTSW))
1424    (set (reg:CC FLAGS_REG)
1425         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1426   ""
1427   [(set_attr "type" "multi")
1428    (set_attr "unit" "i387")
1429    (set_attr "mode" "<MODE>")])
1431 (define_insn "*cmpu<mode>_i387"
1432   [(set (match_operand:HI 0 "register_operand" "=a")
1433         (unspec:HI
1434           [(compare:CCFPU
1435              (match_operand:X87MODEF 1 "register_operand" "f")
1436              (match_operand:X87MODEF 2 "register_operand" "f"))]
1437           UNSPEC_FNSTSW))]
1438   "TARGET_80387"
1439   "* return output_fp_compare (insn, operands, false, true);"
1440   [(set_attr "type" "multi")
1441    (set_attr "unit" "i387")
1442    (set_attr "mode" "<MODE>")])
1444 (define_insn_and_split "*cmpu<mode>_cc_i387"
1445   [(set (reg:CCFPU FLAGS_REG)
1446         (compare:CCFPU
1447           (match_operand:X87MODEF 1 "register_operand" "f")
1448           (match_operand:X87MODEF 2 "register_operand" "f")))
1449    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1450   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1451   "#"
1452   "&& reload_completed"
1453   [(set (match_dup 0)
1454         (unspec:HI
1455           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1456         UNSPEC_FNSTSW))
1457    (set (reg:CC FLAGS_REG)
1458         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1459   ""
1460   [(set_attr "type" "multi")
1461    (set_attr "unit" "i387")
1462    (set_attr "mode" "<MODE>")])
1464 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1465   [(set (match_operand:HI 0 "register_operand" "=a")
1466         (unspec:HI
1467           [(compare:CCFP
1468              (match_operand:X87MODEF 1 "register_operand" "f")
1469              (match_operator:X87MODEF 3 "float_operator"
1470                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1471           UNSPEC_FNSTSW))]
1472   "TARGET_80387
1473    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1474        || optimize_function_for_size_p (cfun))"
1475   "* return output_fp_compare (insn, operands, false, false);"
1476   [(set_attr "type" "multi")
1477    (set_attr "unit" "i387")
1478    (set_attr "fp_int_src" "true")
1479    (set_attr "mode" "<SWI24:MODE>")])
1481 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1482   [(set (reg:CCFP FLAGS_REG)
1483         (compare:CCFP
1484           (match_operand:X87MODEF 1 "register_operand" "f")
1485           (match_operator:X87MODEF 3 "float_operator"
1486             [(match_operand:SWI24 2 "memory_operand" "m")])))
1487    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1488   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1489    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1490        || optimize_function_for_size_p (cfun))"
1491   "#"
1492   "&& reload_completed"
1493   [(set (match_dup 0)
1494         (unspec:HI
1495           [(compare:CCFP
1496              (match_dup 1)
1497              (match_op_dup 3 [(match_dup 2)]))]
1498         UNSPEC_FNSTSW))
1499    (set (reg:CC FLAGS_REG)
1500         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1501   ""
1502   [(set_attr "type" "multi")
1503    (set_attr "unit" "i387")
1504    (set_attr "fp_int_src" "true")
1505    (set_attr "mode" "<SWI24:MODE>")])
1507 ;; FP compares, step 2
1508 ;; Move the fpsw to ax.
1510 (define_insn "x86_fnstsw_1"
1511   [(set (match_operand:HI 0 "register_operand" "=a")
1512         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1513   "TARGET_80387"
1514   "fnstsw\t%0"
1515   [(set (attr "length")
1516         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1517    (set_attr "mode" "SI")
1518    (set_attr "unit" "i387")])
1520 ;; FP compares, step 3
1521 ;; Get ax into flags, general case.
1523 (define_insn "x86_sahf_1"
1524   [(set (reg:CC FLAGS_REG)
1525         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1526                    UNSPEC_SAHF))]
1527   "TARGET_SAHF"
1529 #ifndef HAVE_AS_IX86_SAHF
1530   if (TARGET_64BIT)
1531     return ASM_BYTE "0x9e";
1532   else
1533 #endif
1534   return "sahf";
1536   [(set_attr "length" "1")
1537    (set_attr "athlon_decode" "vector")
1538    (set_attr "amdfam10_decode" "direct")
1539    (set_attr "bdver1_decode" "direct")
1540    (set_attr "mode" "SI")])
1542 ;; Pentium Pro can do steps 1 through 3 in one go.
1543 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1544 ;; (these i387 instructions set flags directly)
1546 (define_mode_iterator FPCMP [CCFP CCFPU])
1547 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1549 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1550   [(set (reg:FPCMP FLAGS_REG)
1551         (compare:FPCMP
1552           (match_operand:MODEF 0 "register_operand" "f,x")
1553           (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1554   "TARGET_MIX_SSE_I387
1555    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1556   "* return output_fp_compare (insn, operands, true,
1557                                <FPCMP:MODE>mode == CCFPUmode);"
1558   [(set_attr "type" "fcmp,ssecomi")
1559    (set_attr "prefix" "orig,maybe_vex")
1560    (set_attr "mode" "<MODEF:MODE>")
1561    (set (attr "prefix_rep")
1562         (if_then_else (eq_attr "type" "ssecomi")
1563                       (const_string "0")
1564                       (const_string "*")))
1565    (set (attr "prefix_data16")
1566         (cond [(eq_attr "type" "fcmp")
1567                  (const_string "*")
1568                (eq_attr "mode" "DF")
1569                  (const_string "1")
1570               ]
1571               (const_string "0")))
1572    (set_attr "athlon_decode" "vector")
1573    (set_attr "amdfam10_decode" "direct")
1574    (set_attr "bdver1_decode" "double")])
1576 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1577   [(set (reg:FPCMP FLAGS_REG)
1578         (compare:FPCMP
1579           (match_operand:MODEF 0 "register_operand" "x")
1580           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1581   "TARGET_SSE_MATH
1582    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1583   "* return output_fp_compare (insn, operands, true,
1584                                <FPCMP:MODE>mode == CCFPUmode);"
1585   [(set_attr "type" "ssecomi")
1586    (set_attr "prefix" "maybe_vex")
1587    (set_attr "mode" "<MODEF:MODE>")
1588    (set_attr "prefix_rep" "0")
1589    (set (attr "prefix_data16")
1590         (if_then_else (eq_attr "mode" "DF")
1591                       (const_string "1")
1592                       (const_string "0")))
1593    (set_attr "athlon_decode" "vector")
1594    (set_attr "amdfam10_decode" "direct")
1595    (set_attr "bdver1_decode" "double")])
1597 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1598   [(set (reg:FPCMP FLAGS_REG)
1599         (compare:FPCMP
1600           (match_operand:X87MODEF 0 "register_operand" "f")
1601           (match_operand:X87MODEF 1 "register_operand" "f")))]
1602   "TARGET_80387 && TARGET_CMOVE
1603    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1604   "* return output_fp_compare (insn, operands, true,
1605                                <FPCMP:MODE>mode == CCFPUmode);"
1606   [(set_attr "type" "fcmp")
1607    (set_attr "mode" "<X87MODEF:MODE>")
1608    (set_attr "athlon_decode" "vector")
1609    (set_attr "amdfam10_decode" "direct")
1610    (set_attr "bdver1_decode" "double")])
1612 ;; Push/pop instructions.
1614 (define_insn "*push<mode>2"
1615   [(set (match_operand:DWI 0 "push_operand" "=<")
1616         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1617   ""
1618   "#"
1619   [(set_attr "type" "multi")
1620    (set_attr "mode" "<MODE>")])
1622 (define_split
1623   [(set (match_operand:TI 0 "push_operand")
1624         (match_operand:TI 1 "general_operand"))]
1625   "TARGET_64BIT && reload_completed
1626    && !SSE_REG_P (operands[1])"
1627   [(const_int 0)]
1628   "ix86_split_long_move (operands); DONE;")
1630 (define_insn "*pushdi2_rex64"
1631   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1632         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1633   "TARGET_64BIT"
1634   "@
1635    push{q}\t%1
1636    #"
1637   [(set_attr "type" "push,multi")
1638    (set_attr "mode" "DI")])
1640 ;; Convert impossible pushes of immediate to existing instructions.
1641 ;; First try to get scratch register and go through it.  In case this
1642 ;; fails, push sign extended lower part first and then overwrite
1643 ;; upper part by 32bit move.
1644 (define_peephole2
1645   [(match_scratch:DI 2 "r")
1646    (set (match_operand:DI 0 "push_operand")
1647         (match_operand:DI 1 "immediate_operand"))]
1648   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1649    && !x86_64_immediate_operand (operands[1], DImode)"
1650   [(set (match_dup 2) (match_dup 1))
1651    (set (match_dup 0) (match_dup 2))])
1653 ;; We need to define this as both peepholer and splitter for case
1654 ;; peephole2 pass is not run.
1655 ;; "&& 1" is needed to keep it from matching the previous pattern.
1656 (define_peephole2
1657   [(set (match_operand:DI 0 "push_operand")
1658         (match_operand:DI 1 "immediate_operand"))]
1659   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1660    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1661   [(set (match_dup 0) (match_dup 1))
1662    (set (match_dup 2) (match_dup 3))]
1664   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1666   operands[1] = gen_lowpart (DImode, operands[2]);
1667   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1668                                                    GEN_INT (4)));
1671 (define_split
1672   [(set (match_operand:DI 0 "push_operand")
1673         (match_operand:DI 1 "immediate_operand"))]
1674   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1675                     ? epilogue_completed : reload_completed)
1676    && !symbolic_operand (operands[1], DImode)
1677    && !x86_64_immediate_operand (operands[1], DImode)"
1678   [(set (match_dup 0) (match_dup 1))
1679    (set (match_dup 2) (match_dup 3))]
1681   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1683   operands[1] = gen_lowpart (DImode, operands[2]);
1684   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1685                                                    GEN_INT (4)));
1688 (define_split
1689   [(set (match_operand:DI 0 "push_operand")
1690         (match_operand:DI 1 "general_operand"))]
1691   "!TARGET_64BIT && reload_completed
1692    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1693   [(const_int 0)]
1694   "ix86_split_long_move (operands); DONE;")
1696 (define_insn "*pushsi2"
1697   [(set (match_operand:SI 0 "push_operand" "=<")
1698         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1699   "!TARGET_64BIT"
1700   "push{l}\t%1"
1701   [(set_attr "type" "push")
1702    (set_attr "mode" "SI")])
1704 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1705 ;; "push a byte/word".  But actually we use pushl, which has the effect
1706 ;; of rounding the amount pushed up to a word.
1708 ;; For TARGET_64BIT we always round up to 8 bytes.
1709 (define_insn "*push<mode>2_rex64"
1710   [(set (match_operand:SWI124 0 "push_operand" "=X")
1711         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1712   "TARGET_64BIT"
1713   "push{q}\t%q1"
1714   [(set_attr "type" "push")
1715    (set_attr "mode" "DI")])
1717 (define_insn "*push<mode>2"
1718   [(set (match_operand:SWI12 0 "push_operand" "=X")
1719         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1720   "!TARGET_64BIT"
1721   "push{l}\t%k1"
1722   [(set_attr "type" "push")
1723    (set_attr "mode" "SI")])
1725 (define_insn "*push<mode>2_prologue"
1726   [(set (match_operand:W 0 "push_operand" "=<")
1727         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1728    (clobber (mem:BLK (scratch)))]
1729   ""
1730   "push{<imodesuffix>}\t%1"
1731   [(set_attr "type" "push")
1732    (set_attr "mode" "<MODE>")])
1734 (define_insn "*pop<mode>1"
1735   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1736         (match_operand:W 1 "pop_operand" ">"))]
1737   ""
1738   "pop{<imodesuffix>}\t%0"
1739   [(set_attr "type" "pop")
1740    (set_attr "mode" "<MODE>")])
1742 (define_insn "*pop<mode>1_epilogue"
1743   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1744         (match_operand:W 1 "pop_operand" ">"))
1745    (clobber (mem:BLK (scratch)))]
1746   ""
1747   "pop{<imodesuffix>}\t%0"
1748   [(set_attr "type" "pop")
1749    (set_attr "mode" "<MODE>")])
1751 ;; Move instructions.
1753 (define_expand "movxi"
1754   [(set (match_operand:XI 0 "nonimmediate_operand")
1755         (match_operand:XI 1 "general_operand"))]
1756   "TARGET_AVX512F"
1757   "ix86_expand_move (XImode, operands); DONE;")
1759 ;; Reload patterns to support multi-word load/store
1760 ;; with non-offsetable address.
1761 (define_expand "reload_noff_store"
1762   [(parallel [(match_operand 0 "memory_operand" "=m")
1763               (match_operand 1 "register_operand" "r")
1764               (match_operand:DI 2 "register_operand" "=&r")])]
1765   "TARGET_64BIT"
1767   rtx mem = operands[0];
1768   rtx addr = XEXP (mem, 0);
1770   emit_move_insn (operands[2], addr);
1771   mem = replace_equiv_address_nv (mem, operands[2]);
1773   emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1774   DONE;
1777 (define_expand "reload_noff_load"
1778   [(parallel [(match_operand 0 "register_operand" "=r")
1779               (match_operand 1 "memory_operand" "m")
1780               (match_operand:DI 2 "register_operand" "=r")])]
1781   "TARGET_64BIT"
1783   rtx mem = operands[1];
1784   rtx addr = XEXP (mem, 0);
1786   emit_move_insn (operands[2], addr);
1787   mem = replace_equiv_address_nv (mem, operands[2]);
1789   emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1790   DONE;
1793 (define_expand "movoi"
1794   [(set (match_operand:OI 0 "nonimmediate_operand")
1795         (match_operand:OI 1 "general_operand"))]
1796   "TARGET_AVX"
1797   "ix86_expand_move (OImode, operands); DONE;")
1799 (define_expand "movti"
1800   [(set (match_operand:TI 0 "nonimmediate_operand")
1801         (match_operand:TI 1 "nonimmediate_operand"))]
1802   "TARGET_64BIT || TARGET_SSE"
1804   if (TARGET_64BIT)
1805     ix86_expand_move (TImode, operands);
1806   else if (push_operand (operands[0], TImode))
1807     ix86_expand_push (TImode, operands[1]);
1808   else
1809     ix86_expand_vector_move (TImode, operands);
1810   DONE;
1813 ;; This expands to what emit_move_complex would generate if we didn't
1814 ;; have a movti pattern.  Having this avoids problems with reload on
1815 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1816 ;; to have around all the time.
1817 (define_expand "movcdi"
1818   [(set (match_operand:CDI 0 "nonimmediate_operand")
1819         (match_operand:CDI 1 "general_operand"))]
1820   ""
1822   if (push_operand (operands[0], CDImode))
1823     emit_move_complex_push (CDImode, operands[0], operands[1]);
1824   else
1825     emit_move_complex_parts (operands[0], operands[1]);
1826   DONE;
1829 (define_expand "mov<mode>"
1830   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1831         (match_operand:SWI1248x 1 "general_operand"))]
1832   ""
1833   "ix86_expand_move (<MODE>mode, operands); DONE;")
1835 (define_insn "*mov<mode>_xor"
1836   [(set (match_operand:SWI48 0 "register_operand" "=r")
1837         (match_operand:SWI48 1 "const0_operand"))
1838    (clobber (reg:CC FLAGS_REG))]
1839   "reload_completed"
1840   "xor{l}\t%k0, %k0"
1841   [(set_attr "type" "alu1")
1842    (set_attr "mode" "SI")
1843    (set_attr "length_immediate" "0")])
1845 (define_insn "*mov<mode>_or"
1846   [(set (match_operand:SWI48 0 "register_operand" "=r")
1847         (match_operand:SWI48 1 "const_int_operand"))
1848    (clobber (reg:CC FLAGS_REG))]
1849   "reload_completed
1850    && operands[1] == constm1_rtx"
1851   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1852   [(set_attr "type" "alu1")
1853    (set_attr "mode" "<MODE>")
1854    (set_attr "length_immediate" "1")])
1856 (define_insn "*movxi_internal_avx512f"
1857   [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1858         (match_operand:XI 1 "vector_move_operand"  "C ,xm,x"))]
1859   "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1861   switch (which_alternative)
1862     {
1863     case 0:
1864       return standard_sse_constant_opcode (insn, operands[1]);
1865     case 1:
1866     case 2:
1867       if (misaligned_operand (operands[0], XImode)
1868           || misaligned_operand (operands[1], XImode))
1869         return "vmovdqu32\t{%1, %0|%0, %1}";
1870       else
1871         return "vmovdqa32\t{%1, %0|%0, %1}";
1872     default:
1873       gcc_unreachable ();
1874     }
1876   [(set_attr "type" "sselog1,ssemov,ssemov")
1877    (set_attr "prefix" "evex")
1878    (set_attr "mode" "XI")])
1880 (define_insn "*movoi_internal_avx"
1881   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1882         (match_operand:OI 1 "vector_move_operand"  "C ,xm,x"))]
1883   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1885   switch (get_attr_type (insn))
1886     {
1887     case TYPE_SSELOG1:
1888       return standard_sse_constant_opcode (insn, operands[1]);
1890     case TYPE_SSEMOV:
1891       if (misaligned_operand (operands[0], OImode)
1892           || misaligned_operand (operands[1], OImode))
1893         {
1894           if (get_attr_mode (insn) == MODE_V8SF)
1895             return "vmovups\t{%1, %0|%0, %1}";
1896           else
1897             return "vmovdqu\t{%1, %0|%0, %1}";
1898         }
1899       else
1900         {
1901           if (get_attr_mode (insn) == MODE_V8SF)
1902             return "vmovaps\t{%1, %0|%0, %1}";
1903           else
1904             return "vmovdqa\t{%1, %0|%0, %1}";
1905         }
1907     default:
1908       gcc_unreachable ();
1909     }
1911   [(set_attr "type" "sselog1,ssemov,ssemov")
1912    (set_attr "prefix" "vex")
1913    (set (attr "mode")
1914         (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1915                  (const_string "V8SF")
1916                (and (eq_attr "alternative" "2")
1917                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1918                  (const_string "V8SF")
1919               ]
1920               (const_string "OI")))])
1922 (define_insn "*movti_internal"
1923   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1924         (match_operand:TI 1 "general_operand"      "riFo,re,C,xm,x"))]
1925   "(TARGET_64BIT || TARGET_SSE)
1926    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1928   switch (get_attr_type (insn))
1929     {
1930     case TYPE_MULTI:
1931       return "#";
1933     case TYPE_SSELOG1:
1934       return standard_sse_constant_opcode (insn, operands[1]);
1936     case TYPE_SSEMOV:
1937       /* TDmode values are passed as TImode on the stack.  Moving them
1938          to stack may result in unaligned memory access.  */
1939       if (misaligned_operand (operands[0], TImode)
1940           || misaligned_operand (operands[1], TImode))
1941         {
1942           if (get_attr_mode (insn) == MODE_V4SF)
1943             return "%vmovups\t{%1, %0|%0, %1}";
1944           else
1945             return "%vmovdqu\t{%1, %0|%0, %1}";
1946         }
1947       else
1948         {
1949           if (get_attr_mode (insn) == MODE_V4SF)
1950             return "%vmovaps\t{%1, %0|%0, %1}";
1951           else
1952             return "%vmovdqa\t{%1, %0|%0, %1}";
1953         }
1955     default:
1956       gcc_unreachable ();
1957     }
1959   [(set_attr "isa" "x64,x64,*,*,*")
1960    (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
1961    (set (attr "prefix")
1962      (if_then_else (eq_attr "type" "sselog1,ssemov")
1963        (const_string "maybe_vex")
1964        (const_string "orig")))
1965    (set (attr "mode")
1966         (cond [(eq_attr "alternative" "0,1")
1967                  (const_string "DI")
1968                (ior (not (match_test "TARGET_SSE2"))
1969                     (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1970                  (const_string "V4SF")
1971                (and (eq_attr "alternative" "4")
1972                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1973                  (const_string "V4SF")
1974                (match_test "TARGET_AVX")
1975                  (const_string "TI")
1976                (match_test "optimize_function_for_size_p (cfun)")
1977                  (const_string "V4SF")
1978                ]
1979                (const_string "TI")))])
1981 (define_split
1982   [(set (match_operand:TI 0 "nonimmediate_operand")
1983         (match_operand:TI 1 "general_operand"))]
1984   "reload_completed
1985    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1986   [(const_int 0)]
1987   "ix86_split_long_move (operands); DONE;")
1989 (define_insn "*movdi_internal"
1990   [(set (match_operand:DI 0 "nonimmediate_operand"
1991     "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi")
1992         (match_operand:DI 1 "general_operand"
1993     "riFo,riF,Z,rem,i,re,C ,*y,m  ,*y,*Yn,r   ,C ,*v,m ,*v,*Yj,*v,r   ,*Yj ,*Yn"))]
1994   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1996   switch (get_attr_type (insn))
1997     {
1998     case TYPE_MULTI:
1999       return "#";
2001     case TYPE_MMX:
2002       return "pxor\t%0, %0";
2004     case TYPE_MMXMOV:
2005 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
2006       /* Handle broken assemblers that require movd instead of movq.  */
2007       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2008         return "movd\t{%1, %0|%0, %1}";
2009 #endif
2010       return "movq\t{%1, %0|%0, %1}";
2012     case TYPE_SSELOG1:
2013       if (GENERAL_REG_P (operands[0]))
2014         return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2016       return standard_sse_constant_opcode (insn, operands[1]);
2018     case TYPE_SSEMOV:
2019       switch (get_attr_mode (insn))
2020         {
2021         case MODE_DI:
2022 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
2023           /* Handle broken assemblers that require movd instead of movq.  */
2024           if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2025             return "%vmovd\t{%1, %0|%0, %1}";
2026 #endif
2027           return "%vmovq\t{%1, %0|%0, %1}";
2028         case MODE_TI:
2029           return "%vmovdqa\t{%1, %0|%0, %1}";
2030         case MODE_XI:
2031           return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2033         case MODE_V2SF:
2034           gcc_assert (!TARGET_AVX);
2035           return "movlps\t{%1, %0|%0, %1}";
2036         case MODE_V4SF:
2037           return "%vmovaps\t{%1, %0|%0, %1}";
2039         default:
2040           gcc_unreachable ();
2041         }
2043     case TYPE_SSECVT:
2044       if (SSE_REG_P (operands[0]))
2045         return "movq2dq\t{%1, %0|%0, %1}";
2046       else
2047         return "movdq2q\t{%1, %0|%0, %1}";
2049     case TYPE_LEA:
2050       return "lea{q}\t{%E1, %0|%0, %E1}";
2052     case TYPE_IMOV:
2053       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2054       if (get_attr_mode (insn) == MODE_SI)
2055         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2056       else if (which_alternative == 4)
2057         return "movabs{q}\t{%1, %0|%0, %1}";
2058       else if (ix86_use_lea_for_mov (insn, operands))
2059         return "lea{q}\t{%E1, %0|%0, %E1}";
2060       else
2061         return "mov{q}\t{%1, %0|%0, %1}";
2063     default:
2064       gcc_unreachable ();
2065     }
2067   [(set (attr "isa")
2068      (cond [(eq_attr "alternative" "0,1")
2069               (const_string "nox64")
2070             (eq_attr "alternative" "2,3,4,5,10,11,16,18")
2071               (const_string "x64")
2072             (eq_attr "alternative" "17")
2073               (const_string "x64_sse4")
2074            ]
2075            (const_string "*")))
2076    (set (attr "type")
2077      (cond [(eq_attr "alternative" "0,1")
2078               (const_string "multi")
2079             (eq_attr "alternative" "6")
2080               (const_string "mmx")
2081             (eq_attr "alternative" "7,8,9,10,11")
2082               (const_string "mmxmov")
2083             (eq_attr "alternative" "12,17")
2084               (const_string "sselog1")
2085             (eq_attr "alternative" "13,14,15,16,18")
2086               (const_string "ssemov")
2087             (eq_attr "alternative" "19,20")
2088               (const_string "ssecvt")
2089             (match_operand 1 "pic_32bit_operand")
2090               (const_string "lea")
2091            ]
2092            (const_string "imov")))
2093    (set (attr "modrm")
2094      (if_then_else
2095        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2096          (const_string "0")
2097          (const_string "*")))
2098    (set (attr "length_immediate")
2099      (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2100               (const_string "8")
2101             (eq_attr "alternative" "17")
2102               (const_string "1")
2103            ]
2104            (const_string "*")))
2105    (set (attr "prefix_rex")
2106      (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2107        (const_string "1")
2108        (const_string "*")))
2109    (set (attr "prefix_extra")
2110      (if_then_else (eq_attr "alternative" "17")
2111        (const_string "1")
2112        (const_string "*")))
2113    (set (attr "prefix")
2114      (if_then_else (eq_attr "type" "sselog1,ssemov")
2115        (const_string "maybe_vex")
2116        (const_string "orig")))
2117    (set (attr "prefix_data16")
2118      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2119        (const_string "1")
2120        (const_string "*")))
2121    (set (attr "mode")
2122      (cond [(eq_attr "alternative" "2")
2123               (const_string "SI")
2124             (eq_attr "alternative" "12,13")
2125               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2126                           (match_operand 1 "ext_sse_reg_operand"))
2127                        (const_string "XI")
2128                      (ior (not (match_test "TARGET_SSE2"))
2129                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2130                        (const_string "V4SF")
2131                      (match_test "TARGET_AVX")
2132                        (const_string "TI")
2133                      (match_test "optimize_function_for_size_p (cfun)")
2134                        (const_string "V4SF")
2135                     ]
2136                     (const_string "TI"))
2138             (and (eq_attr "alternative" "14,15")
2139                  (not (match_test "TARGET_SSE2")))
2140               (const_string "V2SF")
2141             (eq_attr "alternative" "17")
2142               (const_string "TI")
2143            ]
2144            (const_string "DI")))])
2146 (define_split
2147   [(set (match_operand:DI 0 "nonimmediate_operand")
2148         (match_operand:DI 1 "general_operand"))]
2149   "!TARGET_64BIT && reload_completed
2150    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2151    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2152   [(const_int 0)]
2153   "ix86_split_long_move (operands); DONE;")
2155 (define_insn "*movsi_internal"
2156   [(set (match_operand:SI 0 "nonimmediate_operand"
2157                         "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi")
2158         (match_operand:SI 1 "general_operand"
2159                         "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r"))]
2160   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2162   switch (get_attr_type (insn))
2163     {
2164     case TYPE_SSELOG1:
2165       if (GENERAL_REG_P (operands[0]))
2166         return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2168       return standard_sse_constant_opcode (insn, operands[1]);
2170     case TYPE_SSEMOV:
2171       switch (get_attr_mode (insn))
2172         {
2173         case MODE_SI:
2174           return "%vmovd\t{%1, %0|%0, %1}";
2175         case MODE_TI:
2176           return "%vmovdqa\t{%1, %0|%0, %1}";
2177         case MODE_XI:
2178           return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2180         case MODE_V4SF:
2181           return "%vmovaps\t{%1, %0|%0, %1}";
2183         case MODE_SF:
2184           gcc_assert (!TARGET_AVX);
2185           return "movss\t{%1, %0|%0, %1}";
2187         default:
2188           gcc_unreachable ();
2189         }
2191     case TYPE_MMX:
2192       return "pxor\t%0, %0";
2194     case TYPE_MMXMOV:
2195       switch (get_attr_mode (insn))
2196         {
2197         case MODE_DI:
2198           return "movq\t{%1, %0|%0, %1}";
2199         case MODE_SI:
2200           return "movd\t{%1, %0|%0, %1}";
2202         default:
2203           gcc_unreachable ();
2204         }
2206     case TYPE_LEA:
2207       return "lea{l}\t{%E1, %0|%0, %E1}";
2209     case TYPE_IMOV:
2210       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2211       if (ix86_use_lea_for_mov (insn, operands))
2212         return "lea{l}\t{%E1, %0|%0, %E1}";
2213       else
2214         return "mov{l}\t{%1, %0|%0, %1}";
2216     default:
2217       gcc_unreachable ();
2218     }
2220   [(set (attr "isa")
2221      (if_then_else (eq_attr "alternative" "11")
2222        (const_string "sse4")
2223        (const_string "*")))
2224    (set (attr "type")
2225      (cond [(eq_attr "alternative" "2")
2226               (const_string "mmx")
2227             (eq_attr "alternative" "3,4,5")
2228               (const_string "mmxmov")
2229             (eq_attr "alternative" "6,11")
2230               (const_string "sselog1")
2231             (eq_attr "alternative" "7,8,9,10,12")
2232               (const_string "ssemov")
2233             (match_operand 1 "pic_32bit_operand")
2234               (const_string "lea")
2235            ]
2236            (const_string "imov")))
2237    (set (attr "length_immediate")
2238      (if_then_else (eq_attr "alternative" "11")
2239        (const_string "1")
2240        (const_string "*")))
2241    (set (attr "prefix_extra")
2242      (if_then_else (eq_attr "alternative" "11")
2243        (const_string "1")
2244        (const_string "*")))
2245    (set (attr "prefix")
2246      (if_then_else (eq_attr "type" "sselog1,ssemov")
2247        (const_string "maybe_vex")
2248        (const_string "orig")))
2249    (set (attr "prefix_data16")
2250      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2251        (const_string "1")
2252        (const_string "*")))
2253    (set (attr "mode")
2254      (cond [(eq_attr "alternative" "2,3")
2255               (const_string "DI")
2256             (eq_attr "alternative" "6,7")
2257               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2258                           (match_operand 1 "ext_sse_reg_operand"))
2259                        (const_string "XI")
2260                      (ior (not (match_test "TARGET_SSE2"))
2261                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2262                        (const_string "V4SF")
2263                      (match_test "TARGET_AVX")
2264                        (const_string "TI")
2265                      (match_test "optimize_function_for_size_p (cfun)")
2266                        (const_string "V4SF")
2267                     ]
2268                     (const_string "TI"))
2270             (and (eq_attr "alternative" "8,9")
2271                  (not (match_test "TARGET_SSE2")))
2272               (const_string "SF")
2273             (eq_attr "alternative" "11")
2274               (const_string "TI")
2275            ]
2276            (const_string "SI")))])
2278 (define_insn "*movhi_internal"
2279   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,Yk,Yk,rm")
2280         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,rm,Yk,Yk"))]
2281   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2283   switch (get_attr_type (insn))
2284     {
2285     case TYPE_IMOVX:
2286       /* movzwl is faster than movw on p2 due to partial word stalls,
2287          though not as fast as an aligned movl.  */
2288       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2290     case TYPE_MSKMOV:
2291       switch (which_alternative)
2292         {
2293         case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2294         case 5: return "kmovw\t{%1, %0|%0, %1}";
2295         case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2296         default: gcc_unreachable ();
2297         }
2299     default:
2300       if (get_attr_mode (insn) == MODE_SI)
2301         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2302       else
2303         return "mov{w}\t{%1, %0|%0, %1}";
2304     }
2306   [(set (attr "type")
2307      (cond [(match_test "optimize_function_for_size_p (cfun)")
2308               (const_string "imov")
2309             (and (eq_attr "alternative" "0")
2310                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2311                       (not (match_test "TARGET_HIMODE_MATH"))))
2312               (const_string "imov")
2313             (and (eq_attr "alternative" "1,2")
2314                  (match_operand:HI 1 "aligned_operand"))
2315               (const_string "imov")
2316             (eq_attr "alternative" "4,5,6")
2317               (const_string "mskmov")
2318             (and (match_test "TARGET_MOVX")
2319                  (eq_attr "alternative" "0,2"))
2320               (const_string "imovx")
2321            ]
2322            (const_string "imov")))
2323     (set (attr "prefix")
2324       (if_then_else (eq_attr "alternative" "4,5,6")
2325         (const_string "vex")
2326         (const_string "orig")))
2327     (set (attr "mode")
2328       (cond [(eq_attr "type" "imovx")
2329                (const_string "SI")
2330              (and (eq_attr "alternative" "1,2")
2331                   (match_operand:HI 1 "aligned_operand"))
2332                (const_string "SI")
2333              (and (eq_attr "alternative" "0")
2334                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2335                        (not (match_test "TARGET_HIMODE_MATH"))))
2336                (const_string "SI")
2337             ]
2338             (const_string "HI")))])
2340 ;; Situation is quite tricky about when to choose full sized (SImode) move
2341 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2342 ;; partial register dependency machines (such as AMD Athlon), where QImode
2343 ;; moves issue extra dependency and for partial register stalls machines
2344 ;; that don't use QImode patterns (and QImode move cause stall on the next
2345 ;; instruction).
2347 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2348 ;; register stall machines with, where we use QImode instructions, since
2349 ;; partial register stall can be caused there.  Then we use movzx.
2351 (define_insn "*movqi_internal"
2352   [(set (match_operand:QI 0 "nonimmediate_operand"
2353                         "=q,q ,q ,r,r ,?r,m ,Yk,Yk,r")
2354         (match_operand:QI 1 "general_operand"
2355                         "q ,qn,qm,q,rn,qm,qn,r ,Yk,Yk"))]
2356   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2358   switch (get_attr_type (insn))
2359     {
2360     case TYPE_IMOVX:
2361       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2362       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2364     case TYPE_MSKMOV:
2365       switch (which_alternative)
2366         {
2367         case 7: return "kmovw\t{%k1, %0|%0, %k1}";
2368         case 8: return "kmovw\t{%1, %0|%0, %1}";
2369         case 9: return "kmovw\t{%1, %k0|%k0, %1}";
2370         default: gcc_unreachable ();
2371         }
2373     default:
2374       if (get_attr_mode (insn) == MODE_SI)
2375         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2376       else
2377         return "mov{b}\t{%1, %0|%0, %1}";
2378     }
2380   [(set (attr "type")
2381      (cond [(and (eq_attr "alternative" "5")
2382                  (not (match_operand:QI 1 "aligned_operand")))
2383               (const_string "imovx")
2384             (match_test "optimize_function_for_size_p (cfun)")
2385               (const_string "imov")
2386             (and (eq_attr "alternative" "3")
2387                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2388                       (not (match_test "TARGET_QIMODE_MATH"))))
2389               (const_string "imov")
2390             (eq_attr "alternative" "3,5")
2391               (const_string "imovx")
2392             (eq_attr "alternative" "7,8,9")
2393               (const_string "mskmov")
2394             (and (match_test "TARGET_MOVX")
2395                  (eq_attr "alternative" "2"))
2396               (const_string "imovx")
2397            ]
2398            (const_string "imov")))
2399    (set (attr "prefix")
2400      (if_then_else (eq_attr "alternative" "7,8,9")
2401        (const_string "vex")
2402        (const_string "orig")))
2403    (set (attr "mode")
2404       (cond [(eq_attr "alternative" "3,4,5")
2405                (const_string "SI")
2406              (eq_attr "alternative" "6")
2407                (const_string "QI")
2408              (eq_attr "type" "imovx")
2409                (const_string "SI")
2410              (and (eq_attr "type" "imov")
2411                   (and (eq_attr "alternative" "0,1")
2412                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2413                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2414                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2415                (const_string "SI")
2416              ;; Avoid partial register stalls when not using QImode arithmetic
2417              (and (eq_attr "type" "imov")
2418                   (and (eq_attr "alternative" "0,1")
2419                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2420                             (not (match_test "TARGET_QIMODE_MATH")))))
2421                (const_string "SI")
2422            ]
2423            (const_string "QI")))])
2425 ;; Stores and loads of ax to arbitrary constant address.
2426 ;; We fake an second form of instruction to force reload to load address
2427 ;; into register when rax is not available
2428 (define_insn "*movabs<mode>_1"
2429   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2430         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2431   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2432   "@
2433    movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2434    mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2435   [(set_attr "type" "imov")
2436    (set_attr "modrm" "0,*")
2437    (set_attr "length_address" "8,0")
2438    (set_attr "length_immediate" "0,*")
2439    (set_attr "memory" "store")
2440    (set_attr "mode" "<MODE>")])
2442 (define_insn "*movabs<mode>_2"
2443   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2444         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2445   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2446   "@
2447    movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2448    mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2449   [(set_attr "type" "imov")
2450    (set_attr "modrm" "0,*")
2451    (set_attr "length_address" "8,0")
2452    (set_attr "length_immediate" "0")
2453    (set_attr "memory" "load")
2454    (set_attr "mode" "<MODE>")])
2456 (define_insn "swap<mode>"
2457   [(set (match_operand:SWI48 0 "register_operand" "+r")
2458         (match_operand:SWI48 1 "register_operand" "+r"))
2459    (set (match_dup 1)
2460         (match_dup 0))]
2461   ""
2462   "xchg{<imodesuffix>}\t%1, %0"
2463   [(set_attr "type" "imov")
2464    (set_attr "mode" "<MODE>")
2465    (set_attr "pent_pair" "np")
2466    (set_attr "athlon_decode" "vector")
2467    (set_attr "amdfam10_decode" "double")
2468    (set_attr "bdver1_decode" "double")])
2470 (define_insn "*swap<mode>_1"
2471   [(set (match_operand:SWI12 0 "register_operand" "+r")
2472         (match_operand:SWI12 1 "register_operand" "+r"))
2473    (set (match_dup 1)
2474         (match_dup 0))]
2475   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2476   "xchg{l}\t%k1, %k0"
2477   [(set_attr "type" "imov")
2478    (set_attr "mode" "SI")
2479    (set_attr "pent_pair" "np")
2480    (set_attr "athlon_decode" "vector")
2481    (set_attr "amdfam10_decode" "double")
2482    (set_attr "bdver1_decode" "double")])
2484 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2485 ;; is disabled for AMDFAM10
2486 (define_insn "*swap<mode>_2"
2487   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2488         (match_operand:SWI12 1 "register_operand" "+<r>"))
2489    (set (match_dup 1)
2490         (match_dup 0))]
2491   "TARGET_PARTIAL_REG_STALL"
2492   "xchg{<imodesuffix>}\t%1, %0"
2493   [(set_attr "type" "imov")
2494    (set_attr "mode" "<MODE>")
2495    (set_attr "pent_pair" "np")
2496    (set_attr "athlon_decode" "vector")])
2498 (define_expand "movstrict<mode>"
2499   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2500         (match_operand:SWI12 1 "general_operand"))]
2501   ""
2503   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2504     FAIL;
2505   if (GET_CODE (operands[0]) == SUBREG
2506       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2507     FAIL;
2508   /* Don't generate memory->memory moves, go through a register */
2509   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2510     operands[1] = force_reg (<MODE>mode, operands[1]);
2513 (define_insn "*movstrict<mode>_1"
2514   [(set (strict_low_part
2515           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2516         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2517   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2518    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2519   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2520   [(set_attr "type" "imov")
2521    (set_attr "mode" "<MODE>")])
2523 (define_insn "*movstrict<mode>_xor"
2524   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2525         (match_operand:SWI12 1 "const0_operand"))
2526    (clobber (reg:CC FLAGS_REG))]
2527   "reload_completed"
2528   "xor{<imodesuffix>}\t%0, %0"
2529   [(set_attr "type" "alu1")
2530    (set_attr "mode" "<MODE>")
2531    (set_attr "length_immediate" "0")])
2533 (define_insn "*mov<mode>_extv_1"
2534   [(set (match_operand:SWI24 0 "register_operand" "=R")
2535         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2536                             (const_int 8)
2537                             (const_int 8)))]
2538   ""
2539   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2540   [(set_attr "type" "imovx")
2541    (set_attr "mode" "SI")])
2543 (define_insn "*movqi_extv_1"
2544   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2545         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2546                          (const_int 8)
2547                          (const_int 8)))]
2548   ""
2550   switch (get_attr_type (insn))
2551     {
2552     case TYPE_IMOVX:
2553       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2554     default:
2555       return "mov{b}\t{%h1, %0|%0, %h1}";
2556     }
2558   [(set_attr "isa" "*,*,nox64")
2559    (set (attr "type")
2560      (if_then_else (and (match_operand:QI 0 "register_operand")
2561                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2562                              (match_test "TARGET_MOVX")))
2563         (const_string "imovx")
2564         (const_string "imov")))
2565    (set (attr "mode")
2566      (if_then_else (eq_attr "type" "imovx")
2567         (const_string "SI")
2568         (const_string "QI")))])
2570 (define_insn "*mov<mode>_extzv_1"
2571   [(set (match_operand:SWI48 0 "register_operand" "=R")
2572         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2573                             (const_int 8)
2574                             (const_int 8)))]
2575   ""
2576   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2577   [(set_attr "type" "imovx")
2578    (set_attr "mode" "SI")])
2580 (define_insn "*movqi_extzv_2"
2581   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2582         (subreg:QI
2583           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2584                            (const_int 8)
2585                            (const_int 8)) 0))]
2586   ""
2588   switch (get_attr_type (insn))
2589     {
2590     case TYPE_IMOVX:
2591       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2592     default:
2593       return "mov{b}\t{%h1, %0|%0, %h1}";
2594     }
2596   [(set_attr "isa" "*,*,nox64")
2597    (set (attr "type")
2598      (if_then_else (and (match_operand:QI 0 "register_operand")
2599                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2600                              (match_test "TARGET_MOVX")))
2601         (const_string "imovx")
2602         (const_string "imov")))
2603    (set (attr "mode")
2604      (if_then_else (eq_attr "type" "imovx")
2605         (const_string "SI")
2606         (const_string "QI")))])
2608 (define_insn "mov<mode>_insv_1"
2609   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2610                              (const_int 8)
2611                              (const_int 8))
2612         (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2613   ""
2615   if (CONST_INT_P (operands[1]))
2616     operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2617   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2619   [(set_attr "isa" "*,nox64")
2620    (set_attr "type" "imov")
2621    (set_attr "mode" "QI")])
2623 (define_insn "*movqi_insv_2"
2624   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2625                          (const_int 8)
2626                          (const_int 8))
2627         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2628                      (const_int 8)))]
2629   ""
2630   "mov{b}\t{%h1, %h0|%h0, %h1}"
2631   [(set_attr "type" "imov")
2632    (set_attr "mode" "QI")])
2634 ;; Floating point push instructions.
2636 (define_insn "*pushtf"
2637   [(set (match_operand:TF 0 "push_operand" "=<,<")
2638         (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2639   "TARGET_64BIT || TARGET_SSE"
2641   /* This insn should be already split before reg-stack.  */
2642   gcc_unreachable ();
2644   [(set_attr "isa" "*,x64")
2645    (set_attr "type" "multi")
2646    (set_attr "unit" "sse,*")
2647    (set_attr "mode" "TF,DI")])
2649 ;; %%% Kill this when call knows how to work this out.
2650 (define_split
2651   [(set (match_operand:TF 0 "push_operand")
2652         (match_operand:TF 1 "sse_reg_operand"))]
2653   "TARGET_SSE && reload_completed"
2654   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2655    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2657 (define_insn "*pushxf"
2658   [(set (match_operand:XF 0 "push_operand" "=<,<")
2659         (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2660   ""
2662   /* This insn should be already split before reg-stack.  */
2663   gcc_unreachable ();
2665   [(set_attr "type" "multi")
2666    (set_attr "unit" "i387,*")
2667    (set (attr "mode")
2668         (cond [(eq_attr "alternative" "1")
2669                  (if_then_else (match_test "TARGET_64BIT")
2670                    (const_string "DI")
2671                    (const_string "SI"))
2672               ]
2673               (const_string "XF")))])
2675 ;; %%% Kill this when call knows how to work this out.
2676 (define_split
2677   [(set (match_operand:XF 0 "push_operand")
2678         (match_operand:XF 1 "fp_register_operand"))]
2679   "reload_completed"
2680   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2681    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2682   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2684 (define_insn "*pushdf"
2685   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2686         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2687   ""
2689   /* This insn should be already split before reg-stack.  */
2690   gcc_unreachable ();
2692   [(set_attr "isa" "*,nox64,x64,sse2")
2693    (set_attr "type" "multi")
2694    (set_attr "unit" "i387,*,*,sse")
2695    (set_attr "mode" "DF,SI,DI,DF")])
2697 ;; %%% Kill this when call knows how to work this out.
2698 (define_split
2699   [(set (match_operand:DF 0 "push_operand")
2700         (match_operand:DF 1 "any_fp_register_operand"))]
2701   "reload_completed"
2702   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2703    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2705 (define_insn "*pushsf_rex64"
2706   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2707         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2708   "TARGET_64BIT"
2710   /* Anything else should be already split before reg-stack.  */
2711   gcc_assert (which_alternative == 1);
2712   return "push{q}\t%q1";
2714   [(set_attr "type" "multi,push,multi")
2715    (set_attr "unit" "i387,*,*")
2716    (set_attr "mode" "SF,DI,SF")])
2718 (define_insn "*pushsf"
2719   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2720         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2721   "!TARGET_64BIT"
2723   /* Anything else should be already split before reg-stack.  */
2724   gcc_assert (which_alternative == 1);
2725   return "push{l}\t%1";
2727   [(set_attr "type" "multi,push,multi")
2728    (set_attr "unit" "i387,*,*")
2729    (set_attr "mode" "SF,SI,SF")])
2731 ;; %%% Kill this when call knows how to work this out.
2732 (define_split
2733   [(set (match_operand:SF 0 "push_operand")
2734         (match_operand:SF 1 "any_fp_register_operand"))]
2735   "reload_completed"
2736   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2737    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2738   "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2740 (define_split
2741   [(set (match_operand:SF 0 "push_operand")
2742         (match_operand:SF 1 "memory_operand"))]
2743   "reload_completed
2744    && (operands[2] = find_constant_src (insn))"
2745   [(set (match_dup 0) (match_dup 2))])
2747 (define_split
2748   [(set (match_operand 0 "push_operand")
2749         (match_operand 1 "general_operand"))]
2750   "reload_completed
2751    && (GET_MODE (operands[0]) == TFmode
2752        || GET_MODE (operands[0]) == XFmode
2753        || GET_MODE (operands[0]) == DFmode)
2754    && !ANY_FP_REG_P (operands[1])"
2755   [(const_int 0)]
2756   "ix86_split_long_move (operands); DONE;")
2758 ;; Floating point move instructions.
2760 (define_expand "movtf"
2761   [(set (match_operand:TF 0 "nonimmediate_operand")
2762         (match_operand:TF 1 "nonimmediate_operand"))]
2763   "TARGET_64BIT || TARGET_SSE"
2764   "ix86_expand_move (TFmode, operands); DONE;")
2766 (define_expand "mov<mode>"
2767   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2768         (match_operand:X87MODEF 1 "general_operand"))]
2769   ""
2770   "ix86_expand_move (<MODE>mode, operands); DONE;")
2772 (define_insn "*movtf_internal"
2773   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2774         (match_operand:TF 1 "general_operand"      "C ,xm,x,*roF,*rC"))]
2775   "(TARGET_64BIT || TARGET_SSE)
2776    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2777    && (!can_create_pseudo_p ()
2778        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2779        || GET_CODE (operands[1]) != CONST_DOUBLE
2780        || (optimize_function_for_size_p (cfun)
2781            && standard_sse_constant_p (operands[1])
2782            && !memory_operand (operands[0], TFmode))
2783        || (!TARGET_MEMORY_MISMATCH_STALL
2784            && memory_operand (operands[0], TFmode)))"
2786   switch (get_attr_type (insn))
2787     {
2788     case TYPE_SSELOG1:
2789       return standard_sse_constant_opcode (insn, operands[1]);
2791     case TYPE_SSEMOV:
2792       /* Handle misaligned load/store since we
2793          don't have movmisaligntf pattern. */
2794       if (misaligned_operand (operands[0], TFmode)
2795           || misaligned_operand (operands[1], TFmode))
2796         {
2797           if (get_attr_mode (insn) == MODE_V4SF)
2798             return "%vmovups\t{%1, %0|%0, %1}";
2799           else
2800             return "%vmovdqu\t{%1, %0|%0, %1}";
2801         }
2802       else
2803         {
2804           if (get_attr_mode (insn) == MODE_V4SF)
2805             return "%vmovaps\t{%1, %0|%0, %1}";
2806           else
2807             return "%vmovdqa\t{%1, %0|%0, %1}";
2808         }
2810     case TYPE_MULTI:
2811         return "#";
2813     default:
2814       gcc_unreachable ();
2815     }
2817   [(set_attr "isa" "*,*,*,x64,x64")
2818    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2819    (set (attr "prefix")
2820      (if_then_else (eq_attr "type" "sselog1,ssemov")
2821        (const_string "maybe_vex")
2822        (const_string "orig")))
2823    (set (attr "mode")
2824         (cond [(eq_attr "alternative" "3,4")
2825                  (const_string "DI")
2826                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2827                  (const_string "V4SF")
2828                (and (eq_attr "alternative" "2")
2829                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2830                  (const_string "V4SF")
2831                (match_test "TARGET_AVX")
2832                  (const_string "TI")
2833                (ior (not (match_test "TARGET_SSE2"))
2834                     (match_test "optimize_function_for_size_p (cfun)"))
2835                  (const_string "V4SF")
2836                ]
2837                (const_string "TI")))])
2839 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2840 (define_insn "*movxf_internal"
2841   [(set (match_operand:XF 0 "nonimmediate_operand"
2842          "=f,m,f,?Yx*r ,!o   ,!o")
2843         (match_operand:XF 1 "general_operand"
2844          "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2845   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2846    && (!can_create_pseudo_p ()
2847        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2848        || GET_CODE (operands[1]) != CONST_DOUBLE
2849        || (optimize_function_for_size_p (cfun)
2850            && standard_80387_constant_p (operands[1]) > 0
2851            && !memory_operand (operands[0], XFmode))
2852        || (!TARGET_MEMORY_MISMATCH_STALL
2853            && memory_operand (operands[0], XFmode)))"
2855   switch (get_attr_type (insn))
2856     {
2857     case TYPE_FMOV:
2858       if (which_alternative == 2)
2859         return standard_80387_constant_opcode (operands[1]);
2860       return output_387_reg_move (insn, operands);
2862     case TYPE_MULTI:
2863       return "#";
2865     default:
2866       gcc_unreachable ();
2867     }
2869   [(set_attr "isa" "*,*,*,*,nox64,x64")
2870    (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
2871    (set (attr "mode")
2872         (cond [(eq_attr "alternative" "3,4,5")
2873                  (if_then_else (match_test "TARGET_64BIT")
2874                    (const_string "DI")
2875                    (const_string "SI"))
2876               ]
2877               (const_string "XF")))])
2879 ;; Possible store forwarding (partial memory) stall in alternative 4.
2880 (define_insn "*movdf_internal"
2881   [(set (match_operand:DF 0 "nonimmediate_operand"
2882     "=Yf*f,m   ,Yf*f,?Yd*r ,!o   ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
2883         (match_operand:DF 1 "general_operand"
2884     "Yf*fm,Yf*f,G   ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
2885   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2886    && (!can_create_pseudo_p ()
2887        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2888        || GET_CODE (operands[1]) != CONST_DOUBLE
2889        || (optimize_function_for_size_p (cfun)
2890            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2891                 && standard_80387_constant_p (operands[1]) > 0)
2892                || (TARGET_SSE2 && TARGET_SSE_MATH
2893                    && standard_sse_constant_p (operands[1])))
2894            && !memory_operand (operands[0], DFmode))
2895        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
2896            && memory_operand (operands[0], DFmode)))"
2898   switch (get_attr_type (insn))
2899     {
2900     case TYPE_FMOV:
2901       if (which_alternative == 2)
2902         return standard_80387_constant_opcode (operands[1]);
2903       return output_387_reg_move (insn, operands);
2905     case TYPE_MULTI:
2906       return "#";
2908     case TYPE_IMOV:
2909       if (get_attr_mode (insn) == MODE_SI)
2910         return "mov{l}\t{%1, %k0|%k0, %1}";
2911       else if (which_alternative == 8)
2912         return "movabs{q}\t{%1, %0|%0, %1}";
2913       else
2914         return "mov{q}\t{%1, %0|%0, %1}";
2916     case TYPE_SSELOG1:
2917       return standard_sse_constant_opcode (insn, operands[1]);
2919     case TYPE_SSEMOV:
2920       switch (get_attr_mode (insn))
2921         {
2922         case MODE_DF:
2923           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2924             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2925           return "%vmovsd\t{%1, %0|%0, %1}";
2927         case MODE_V4SF:
2928           return "%vmovaps\t{%1, %0|%0, %1}";
2929         case MODE_V8DF:
2930           return "vmovapd\t{%g1, %g0|%g0, %g1}";
2931         case MODE_V2DF:
2932           return "%vmovapd\t{%1, %0|%0, %1}";
2934         case MODE_V2SF:
2935           gcc_assert (!TARGET_AVX);
2936           return "movlps\t{%1, %0|%0, %1}";
2937         case MODE_V1DF:
2938           gcc_assert (!TARGET_AVX);
2939           return "movlpd\t{%1, %0|%0, %1}";
2941         case MODE_DI:
2942 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
2943           /* Handle broken assemblers that require movd instead of movq.  */
2944           if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2945             return "%vmovd\t{%1, %0|%0, %1}";
2946 #endif
2947           return "%vmovq\t{%1, %0|%0, %1}";
2949         default:
2950           gcc_unreachable ();
2951         }
2953     default:
2954       gcc_unreachable ();
2955     }
2957   [(set (attr "isa")
2958         (cond [(eq_attr "alternative" "3,4")
2959                  (const_string "nox64")
2960                (eq_attr "alternative" "5,6,7,8,17,18")
2961                  (const_string "x64")
2962                (eq_attr "alternative" "9,10,11,12")
2963                  (const_string "sse2")
2964               ]
2965               (const_string "*")))
2966    (set (attr "type")
2967         (cond [(eq_attr "alternative" "0,1,2")
2968                  (const_string "fmov")
2969                (eq_attr "alternative" "3,4")
2970                  (const_string "multi")
2971                (eq_attr "alternative" "5,6,7,8")
2972                  (const_string "imov")
2973                (eq_attr "alternative" "9,13")
2974                  (const_string "sselog1")
2975               ]
2976               (const_string "ssemov")))
2977    (set (attr "modrm")
2978      (if_then_else (eq_attr "alternative" "8")
2979        (const_string "0")
2980        (const_string "*")))
2981    (set (attr "length_immediate")
2982      (if_then_else (eq_attr "alternative" "8")
2983        (const_string "8")
2984        (const_string "*")))
2985    (set (attr "prefix")
2986      (if_then_else (eq_attr "type" "sselog1,ssemov")
2987        (const_string "maybe_vex")
2988        (const_string "orig")))
2989    (set (attr "prefix_data16")
2990      (if_then_else
2991        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2992             (eq_attr "mode" "V1DF"))
2993        (const_string "1")
2994        (const_string "*")))
2995    (set (attr "mode")
2996         (cond [(eq_attr "alternative" "3,4,7")
2997                  (const_string "SI")
2998                (eq_attr "alternative" "5,6,8,17,18")
2999                  (const_string "DI")
3001                /* xorps is one byte shorter for non-AVX targets.  */
3002                (eq_attr "alternative" "9,13")
3003                  (cond [(not (match_test "TARGET_SSE2"))
3004                           (const_string "V4SF")
3005                         (match_test "TARGET_AVX512F")
3006                           (const_string "XI")
3007                         (match_test "TARGET_AVX")
3008                           (const_string "V2DF")
3009                         (match_test "optimize_function_for_size_p (cfun)")
3010                           (const_string "V4SF")
3011                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3012                           (const_string "TI")
3013                        ]
3014                        (const_string "V2DF"))
3016                /* For architectures resolving dependencies on
3017                   whole SSE registers use movapd to break dependency
3018                   chains, otherwise use short move to avoid extra work.  */
3020                /* movaps is one byte shorter for non-AVX targets.  */
3021                (eq_attr "alternative" "10,14")
3022                  (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3023                              (match_operand 1 "ext_sse_reg_operand"))
3024                           (const_string "V8DF")
3025                         (ior (not (match_test "TARGET_SSE2"))
3026                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3027                           (const_string "V4SF")
3028                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3029                           (const_string "V2DF")
3030                         (match_test "TARGET_AVX")
3031                           (const_string "DF")
3032                         (match_test "optimize_function_for_size_p (cfun)")
3033                           (const_string "V4SF")
3034                        ]
3035                        (const_string "DF"))
3037                /* For architectures resolving dependencies on register
3038                   parts we may avoid extra work to zero out upper part
3039                   of register.  */
3040                (eq_attr "alternative" "11,15")
3041                  (cond [(not (match_test "TARGET_SSE2"))
3042                           (const_string "V2SF")
3043                         (match_test "TARGET_AVX")
3044                           (const_string "DF")
3045                         (match_test "TARGET_SSE_SPLIT_REGS")
3046                           (const_string "V1DF")
3047                        ]
3048                        (const_string "DF"))
3050                (and (eq_attr "alternative" "12,16")
3051                     (not (match_test "TARGET_SSE2")))
3052                  (const_string "V2SF")
3053               ]
3054               (const_string "DF")))])
3056 (define_insn "*movsf_internal"
3057   [(set (match_operand:SF 0 "nonimmediate_operand"
3058           "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3059         (match_operand:SF 1 "general_operand"
3060           "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,Yj,r  ,*y ,m  ,*y,*Yn,r"))]
3061   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3062    && (!can_create_pseudo_p ()
3063        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3064        || GET_CODE (operands[1]) != CONST_DOUBLE
3065        || (optimize_function_for_size_p (cfun)
3066            && ((!TARGET_SSE_MATH
3067                 && standard_80387_constant_p (operands[1]) > 0)
3068                || (TARGET_SSE_MATH
3069                    && standard_sse_constant_p (operands[1]))))
3070        || memory_operand (operands[0], SFmode))"
3072   switch (get_attr_type (insn))
3073     {
3074     case TYPE_FMOV:
3075       if (which_alternative == 2)
3076         return standard_80387_constant_opcode (operands[1]);
3077       return output_387_reg_move (insn, operands);
3079     case TYPE_IMOV:
3080       return "mov{l}\t{%1, %0|%0, %1}";
3082     case TYPE_SSELOG1:
3083       return standard_sse_constant_opcode (insn, operands[1]);
3085     case TYPE_SSEMOV:
3086       switch (get_attr_mode (insn))
3087         {
3088         case MODE_SF:
3089           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3090             return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3091           return "%vmovss\t{%1, %0|%0, %1}";
3093         case MODE_V16SF:
3094           return "vmovaps\t{%g1, %g0|%g0, %g1}";
3095         case MODE_V4SF:
3096           return "%vmovaps\t{%1, %0|%0, %1}";
3098         case MODE_SI:
3099           return "%vmovd\t{%1, %0|%0, %1}";
3101         default:
3102           gcc_unreachable ();
3103         }
3105     case TYPE_MMXMOV:
3106       switch (get_attr_mode (insn))
3107         {
3108         case MODE_DI:
3109           return "movq\t{%1, %0|%0, %1}";
3110         case MODE_SI:
3111           return "movd\t{%1, %0|%0, %1}";
3113         default:
3114           gcc_unreachable ();
3115         }
3117     default:
3118       gcc_unreachable ();
3119     }
3121   [(set (attr "type")
3122         (cond [(eq_attr "alternative" "0,1,2")
3123                  (const_string "fmov")
3124                (eq_attr "alternative" "3,4")
3125                  (const_string "imov")
3126                (eq_attr "alternative" "5")
3127                  (const_string "sselog1")
3128                (eq_attr "alternative" "11,12,13,14,15")
3129                  (const_string "mmxmov")
3130               ]
3131               (const_string "ssemov")))
3132    (set (attr "prefix")
3133      (if_then_else (eq_attr "type" "sselog1,ssemov")
3134        (const_string "maybe_vex")
3135        (const_string "orig")))
3136    (set (attr "prefix_data16")
3137      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3138        (const_string "1")
3139        (const_string "*")))
3140    (set (attr "mode")
3141         (cond [(eq_attr "alternative" "3,4,9,10,14,15")
3142                  (const_string "SI")
3143                (eq_attr "alternative" "11")
3144                  (const_string "DI")
3145                (eq_attr "alternative" "5")
3146                  (cond [(not (match_test "TARGET_SSE2"))
3147                           (const_string "V4SF")
3148                         (match_test "TARGET_AVX512F")
3149                           (const_string "V16SF")
3150                         (match_test "TARGET_AVX")
3151                           (const_string "V4SF")
3152                         (match_test "optimize_function_for_size_p (cfun)")
3153                           (const_string "V4SF")
3154                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3155                           (const_string "TI")
3156                        ]
3157                        (const_string "V4SF"))
3159                /* For architectures resolving dependencies on
3160                   whole SSE registers use APS move to break dependency
3161                   chains, otherwise use short move to avoid extra work.
3163                   Do the same for architectures resolving dependencies on
3164                   the parts.  While in DF mode it is better to always handle
3165                   just register parts, the SF mode is different due to lack
3166                   of instructions to load just part of the register.  It is
3167                   better to maintain the whole registers in single format
3168                   to avoid problems on using packed logical operations.  */
3169                (eq_attr "alternative" "6")
3170                  (cond [(ior  (match_operand 0 "ext_sse_reg_operand")
3171                               (match_operand 1 "ext_sse_reg_operand"))
3172                           (const_string "V16SF")
3173                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3174                              (match_test "TARGET_SSE_SPLIT_REGS"))
3175                           (const_string "V4SF")
3176                        ]
3177                        (const_string "SF"))
3178               ]
3179               (const_string "SF")))])
3181 (define_split
3182   [(set (match_operand 0 "any_fp_register_operand")
3183         (match_operand 1 "memory_operand"))]
3184   "reload_completed
3185    && (GET_MODE (operands[0]) == TFmode
3186        || GET_MODE (operands[0]) == XFmode
3187        || GET_MODE (operands[0]) == DFmode
3188        || GET_MODE (operands[0]) == SFmode)
3189    && (operands[2] = find_constant_src (insn))"
3190   [(set (match_dup 0) (match_dup 2))]
3192   rtx c = operands[2];
3193   int r = REGNO (operands[0]);
3195   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3196       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3197     FAIL;
3200 (define_split
3201   [(set (match_operand 0 "any_fp_register_operand")
3202         (float_extend (match_operand 1 "memory_operand")))]
3203   "reload_completed
3204    && (GET_MODE (operands[0]) == TFmode
3205        || GET_MODE (operands[0]) == XFmode
3206        || GET_MODE (operands[0]) == DFmode)
3207    && (operands[2] = find_constant_src (insn))"
3208   [(set (match_dup 0) (match_dup 2))]
3210   rtx c = operands[2];
3211   int r = REGNO (operands[0]);
3213   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3214       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3215     FAIL;
3218 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3219 (define_split
3220   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3221         (match_operand:X87MODEF 1 "immediate_operand"))]
3222   "reload_completed
3223    && (standard_80387_constant_p (operands[1]) == 8
3224        || standard_80387_constant_p (operands[1]) == 9)"
3225   [(set (match_dup 0)(match_dup 1))
3226    (set (match_dup 0)
3227         (neg:X87MODEF (match_dup 0)))]
3229   REAL_VALUE_TYPE r;
3231   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3232   if (real_isnegzero (&r))
3233     operands[1] = CONST0_RTX (<MODE>mode);
3234   else
3235     operands[1] = CONST1_RTX (<MODE>mode);
3238 (define_split
3239   [(set (match_operand 0 "nonimmediate_operand")
3240         (match_operand 1 "general_operand"))]
3241   "reload_completed
3242    && (GET_MODE (operands[0]) == TFmode
3243        || GET_MODE (operands[0]) == XFmode
3244        || GET_MODE (operands[0]) == DFmode)
3245    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3246   [(const_int 0)]
3247   "ix86_split_long_move (operands); DONE;")
3249 (define_insn "swapxf"
3250   [(set (match_operand:XF 0 "register_operand" "+f")
3251         (match_operand:XF 1 "register_operand" "+f"))
3252    (set (match_dup 1)
3253         (match_dup 0))]
3254   "TARGET_80387"
3256   if (STACK_TOP_P (operands[0]))
3257     return "fxch\t%1";
3258   else
3259     return "fxch\t%0";
3261   [(set_attr "type" "fxch")
3262    (set_attr "mode" "XF")])
3264 (define_insn "*swap<mode>"
3265   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3266         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3267    (set (match_dup 1)
3268         (match_dup 0))]
3269   "TARGET_80387 || reload_completed"
3271   if (STACK_TOP_P (operands[0]))
3272     return "fxch\t%1";
3273   else
3274     return "fxch\t%0";
3276   [(set_attr "type" "fxch")
3277    (set_attr "mode" "<MODE>")])
3279 ;; Zero extension instructions
3281 (define_expand "zero_extendsidi2"
3282   [(set (match_operand:DI 0 "nonimmediate_operand")
3283         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3285 (define_insn "*zero_extendsidi2"
3286   [(set (match_operand:DI 0 "nonimmediate_operand"
3287                         "=r,?r,?o,r   ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3288         (zero_extend:DI
3289          (match_operand:SI 1 "x86_64_zext_operand"
3290                         "0 ,rm,r ,rmWz,0,r   ,m   ,*Yj,*x,r   ,m")))]
3291   ""
3293   switch (get_attr_type (insn))
3294     {
3295     case TYPE_IMOVX:
3296       if (ix86_use_lea_for_mov (insn, operands))
3297         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3298       else
3299         return "mov{l}\t{%1, %k0|%k0, %1}";
3301     case TYPE_MULTI:
3302       return "#";
3304     case TYPE_MMXMOV:
3305       return "movd\t{%1, %0|%0, %1}";
3307     case TYPE_SSELOG1:
3308       return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3310     case TYPE_SSEMOV:
3311       if (GENERAL_REG_P (operands[0]))
3312         return "%vmovd\t{%1, %k0|%k0, %1}";
3314       return "%vmovd\t{%1, %0|%0, %1}";
3316     default:
3317       gcc_unreachable ();
3318     }
3320   [(set (attr "isa")
3321      (cond [(eq_attr "alternative" "0,1,2")
3322               (const_string "nox64")
3323             (eq_attr "alternative" "3,7")
3324               (const_string "x64")
3325             (eq_attr "alternative" "8")
3326               (const_string "x64_sse4")
3327             (eq_attr "alternative" "10")
3328               (const_string "sse2")
3329            ]
3330            (const_string "*")))
3331    (set (attr "type")
3332      (cond [(eq_attr "alternative" "0,1,2,4")
3333               (const_string "multi")
3334             (eq_attr "alternative" "5,6")
3335               (const_string "mmxmov")
3336             (eq_attr "alternative" "7,9,10")
3337               (const_string "ssemov")
3338             (eq_attr "alternative" "8")
3339               (const_string "sselog1")
3340            ]
3341            (const_string "imovx")))
3342    (set (attr "prefix_extra")
3343      (if_then_else (eq_attr "alternative" "8")
3344        (const_string "1")
3345        (const_string "*")))
3346    (set (attr "length_immediate")
3347      (if_then_else (eq_attr "alternative" "8")
3348        (const_string "1")
3349        (const_string "*")))
3350    (set (attr "prefix")
3351      (if_then_else (eq_attr "type" "ssemov,sselog1")
3352        (const_string "maybe_vex")
3353        (const_string "orig")))
3354    (set (attr "prefix_0f")
3355      (if_then_else (eq_attr "type" "imovx")
3356        (const_string "0")
3357        (const_string "*")))
3358    (set (attr "mode")
3359      (cond [(eq_attr "alternative" "5,6")
3360               (const_string "DI")
3361             (eq_attr "alternative" "7,8,9")
3362               (const_string "TI")
3363            ]
3364            (const_string "SI")))])
3366 (define_split
3367   [(set (match_operand:DI 0 "memory_operand")
3368         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3369   "reload_completed"
3370   [(set (match_dup 4) (const_int 0))]
3371   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3373 (define_split
3374   [(set (match_operand:DI 0 "register_operand")
3375         (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3376   "!TARGET_64BIT && reload_completed
3377    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3378    && true_regnum (operands[0]) == true_regnum (operands[1])"
3379   [(set (match_dup 4) (const_int 0))]
3380   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3382 (define_split
3383   [(set (match_operand:DI 0 "nonimmediate_operand")
3384         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3385   "!TARGET_64BIT && reload_completed
3386    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3387    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3388   [(set (match_dup 3) (match_dup 1))
3389    (set (match_dup 4) (const_int 0))]
3390   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3392 (define_insn "zero_extend<mode>di2"
3393   [(set (match_operand:DI 0 "register_operand" "=r")
3394         (zero_extend:DI
3395          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3396   "TARGET_64BIT"
3397   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3398   [(set_attr "type" "imovx")
3399    (set_attr "mode" "SI")])
3401 (define_expand "zero_extend<mode>si2"
3402   [(set (match_operand:SI 0 "register_operand")
3403         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3404   ""
3406   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3407     {
3408       operands[1] = force_reg (<MODE>mode, operands[1]);
3409       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3410       DONE;
3411     }
3414 (define_insn_and_split "zero_extend<mode>si2_and"
3415   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3416         (zero_extend:SI
3417           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3418    (clobber (reg:CC FLAGS_REG))]
3419   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3420   "#"
3421   "&& reload_completed"
3422   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3423               (clobber (reg:CC FLAGS_REG))])]
3425   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3426     {
3427       ix86_expand_clear (operands[0]);
3429       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3430       emit_insn (gen_movstrict<mode>
3431                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3432       DONE;
3433     }
3435   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3437   [(set_attr "type" "alu1")
3438    (set_attr "mode" "SI")])
3440 (define_insn "*zero_extend<mode>si2"
3441   [(set (match_operand:SI 0 "register_operand" "=r")
3442         (zero_extend:SI
3443           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3444   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3445   "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3446   [(set_attr "type" "imovx")
3447    (set_attr "mode" "SI")])
3449 (define_expand "zero_extendqihi2"
3450   [(set (match_operand:HI 0 "register_operand")
3451         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3452   ""
3454   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3455     {
3456       operands[1] = force_reg (QImode, operands[1]);
3457       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3458       DONE;
3459     }
3462 (define_insn_and_split "zero_extendqihi2_and"
3463   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3464         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3465    (clobber (reg:CC FLAGS_REG))]
3466   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3467   "#"
3468   "&& reload_completed"
3469   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3470               (clobber (reg:CC FLAGS_REG))])]
3472   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3473     {
3474       ix86_expand_clear (operands[0]);
3476       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3477       emit_insn (gen_movstrictqi
3478                   (gen_lowpart (QImode, operands[0]), operands[1]));
3479       DONE;
3480     }
3482   operands[0] = gen_lowpart (SImode, operands[0]);
3484   [(set_attr "type" "alu1")
3485    (set_attr "mode" "SI")])
3487 ; zero extend to SImode to avoid partial register stalls
3488 (define_insn "*zero_extendqihi2"
3489   [(set (match_operand:HI 0 "register_operand" "=r")
3490         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3491   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3492   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3493   [(set_attr "type" "imovx")
3494    (set_attr "mode" "SI")])
3496 ;; Sign extension instructions
3498 (define_expand "extendsidi2"
3499   [(set (match_operand:DI 0 "register_operand")
3500         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3501   ""
3503   if (!TARGET_64BIT)
3504     {
3505       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3506       DONE;
3507     }
3510 (define_insn "*extendsidi2_rex64"
3511   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3512         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3513   "TARGET_64BIT"
3514   "@
3515    {cltq|cdqe}
3516    movs{lq|x}\t{%1, %0|%0, %1}"
3517   [(set_attr "type" "imovx")
3518    (set_attr "mode" "DI")
3519    (set_attr "prefix_0f" "0")
3520    (set_attr "modrm" "0,1")])
3522 (define_insn "extendsidi2_1"
3523   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3524         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3525    (clobber (reg:CC FLAGS_REG))
3526    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3527   "!TARGET_64BIT"
3528   "#")
3530 ;; Split the memory case.  If the source register doesn't die, it will stay
3531 ;; this way, if it does die, following peephole2s take care of it.
3532 (define_split
3533   [(set (match_operand:DI 0 "memory_operand")
3534         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3535    (clobber (reg:CC FLAGS_REG))
3536    (clobber (match_operand:SI 2 "register_operand"))]
3537   "reload_completed"
3538   [(const_int 0)]
3540   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3542   emit_move_insn (operands[3], operands[1]);
3544   /* Generate a cltd if possible and doing so it profitable.  */
3545   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3546       && true_regnum (operands[1]) == AX_REG
3547       && true_regnum (operands[2]) == DX_REG)
3548     {
3549       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3550     }
3551   else
3552     {
3553       emit_move_insn (operands[2], operands[1]);
3554       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3555     }
3556   emit_move_insn (operands[4], operands[2]);
3557   DONE;
3560 ;; Peepholes for the case where the source register does die, after
3561 ;; being split with the above splitter.
3562 (define_peephole2
3563   [(set (match_operand:SI 0 "memory_operand")
3564         (match_operand:SI 1 "register_operand"))
3565    (set (match_operand:SI 2 "register_operand") (match_dup 1))
3566    (parallel [(set (match_dup 2)
3567                    (ashiftrt:SI (match_dup 2) (const_int 31)))
3568                (clobber (reg:CC FLAGS_REG))])
3569    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3570   "REGNO (operands[1]) != REGNO (operands[2])
3571    && peep2_reg_dead_p (2, operands[1])
3572    && peep2_reg_dead_p (4, operands[2])
3573    && !reg_mentioned_p (operands[2], operands[3])"
3574   [(set (match_dup 0) (match_dup 1))
3575    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3576               (clobber (reg:CC FLAGS_REG))])
3577    (set (match_dup 3) (match_dup 1))])
3579 (define_peephole2
3580   [(set (match_operand:SI 0 "memory_operand")
3581         (match_operand:SI 1 "register_operand"))
3582    (parallel [(set (match_operand:SI 2 "register_operand")
3583                    (ashiftrt:SI (match_dup 1) (const_int 31)))
3584                (clobber (reg:CC FLAGS_REG))])
3585    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3586   "/* cltd is shorter than sarl $31, %eax */
3587    !optimize_function_for_size_p (cfun)
3588    && true_regnum (operands[1]) == AX_REG
3589    && true_regnum (operands[2]) == DX_REG
3590    && peep2_reg_dead_p (2, operands[1])
3591    && peep2_reg_dead_p (3, operands[2])
3592    && !reg_mentioned_p (operands[2], operands[3])"
3593   [(set (match_dup 0) (match_dup 1))
3594    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3595               (clobber (reg:CC FLAGS_REG))])
3596    (set (match_dup 3) (match_dup 1))])
3598 ;; Extend to register case.  Optimize case where source and destination
3599 ;; registers match and cases where we can use cltd.
3600 (define_split
3601   [(set (match_operand:DI 0 "register_operand")
3602         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3603    (clobber (reg:CC FLAGS_REG))
3604    (clobber (match_scratch:SI 2))]
3605   "reload_completed"
3606   [(const_int 0)]
3608   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3610   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3611     emit_move_insn (operands[3], operands[1]);
3613   /* Generate a cltd if possible and doing so it profitable.  */
3614   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3615       && true_regnum (operands[3]) == AX_REG
3616       && true_regnum (operands[4]) == DX_REG)
3617     {
3618       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3619       DONE;
3620     }
3622   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3623     emit_move_insn (operands[4], operands[1]);
3625   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3626   DONE;
3629 (define_insn "extend<mode>di2"
3630   [(set (match_operand:DI 0 "register_operand" "=r")
3631         (sign_extend:DI
3632          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3633   "TARGET_64BIT"
3634   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3635   [(set_attr "type" "imovx")
3636    (set_attr "mode" "DI")])
3638 (define_insn "extendhisi2"
3639   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3640         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3641   ""
3643   switch (get_attr_prefix_0f (insn))
3644     {
3645     case 0:
3646       return "{cwtl|cwde}";
3647     default:
3648       return "movs{wl|x}\t{%1, %0|%0, %1}";
3649     }
3651   [(set_attr "type" "imovx")
3652    (set_attr "mode" "SI")
3653    (set (attr "prefix_0f")
3654      ;; movsx is short decodable while cwtl is vector decoded.
3655      (if_then_else (and (eq_attr "cpu" "!k6")
3656                         (eq_attr "alternative" "0"))
3657         (const_string "0")
3658         (const_string "1")))
3659    (set (attr "modrm")
3660      (if_then_else (eq_attr "prefix_0f" "0")
3661         (const_string "0")
3662         (const_string "1")))])
3664 (define_insn "*extendhisi2_zext"
3665   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3666         (zero_extend:DI
3667          (sign_extend:SI
3668           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3669   "TARGET_64BIT"
3671   switch (get_attr_prefix_0f (insn))
3672     {
3673     case 0:
3674       return "{cwtl|cwde}";
3675     default:
3676       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3677     }
3679   [(set_attr "type" "imovx")
3680    (set_attr "mode" "SI")
3681    (set (attr "prefix_0f")
3682      ;; movsx is short decodable while cwtl is vector decoded.
3683      (if_then_else (and (eq_attr "cpu" "!k6")
3684                         (eq_attr "alternative" "0"))
3685         (const_string "0")
3686         (const_string "1")))
3687    (set (attr "modrm")
3688      (if_then_else (eq_attr "prefix_0f" "0")
3689         (const_string "0")
3690         (const_string "1")))])
3692 (define_insn "extendqisi2"
3693   [(set (match_operand:SI 0 "register_operand" "=r")
3694         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3695   ""
3696   "movs{bl|x}\t{%1, %0|%0, %1}"
3697    [(set_attr "type" "imovx")
3698     (set_attr "mode" "SI")])
3700 (define_insn "*extendqisi2_zext"
3701   [(set (match_operand:DI 0 "register_operand" "=r")
3702         (zero_extend:DI
3703           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3704   "TARGET_64BIT"
3705   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3706    [(set_attr "type" "imovx")
3707     (set_attr "mode" "SI")])
3709 (define_insn "extendqihi2"
3710   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3711         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3712   ""
3714   switch (get_attr_prefix_0f (insn))
3715     {
3716     case 0:
3717       return "{cbtw|cbw}";
3718     default:
3719       return "movs{bw|x}\t{%1, %0|%0, %1}";
3720     }
3722   [(set_attr "type" "imovx")
3723    (set_attr "mode" "HI")
3724    (set (attr "prefix_0f")
3725      ;; movsx is short decodable while cwtl is vector decoded.
3726      (if_then_else (and (eq_attr "cpu" "!k6")
3727                         (eq_attr "alternative" "0"))
3728         (const_string "0")
3729         (const_string "1")))
3730    (set (attr "modrm")
3731      (if_then_else (eq_attr "prefix_0f" "0")
3732         (const_string "0")
3733         (const_string "1")))])
3735 ;; Conversions between float and double.
3737 ;; These are all no-ops in the model used for the 80387.
3738 ;; So just emit moves.
3740 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3741 (define_split
3742   [(set (match_operand:DF 0 "push_operand")
3743         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3744   "reload_completed"
3745   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3746    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3748 (define_split
3749   [(set (match_operand:XF 0 "push_operand")
3750         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3751   "reload_completed"
3752   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3753    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3754   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3756 (define_expand "extendsfdf2"
3757   [(set (match_operand:DF 0 "nonimmediate_operand")
3758         (float_extend:DF (match_operand:SF 1 "general_operand")))]
3759   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3761   /* ??? Needed for compress_float_constant since all fp constants
3762      are TARGET_LEGITIMATE_CONSTANT_P.  */
3763   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3764     {
3765       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3766           && standard_80387_constant_p (operands[1]) > 0)
3767         {
3768           operands[1] = simplify_const_unary_operation
3769             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3770           emit_move_insn_1 (operands[0], operands[1]);
3771           DONE;
3772         }
3773       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3774     }
3777 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3778    cvtss2sd:
3779       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3780       cvtps2pd xmm2,xmm1
3781    We do the conversion post reload to avoid producing of 128bit spills
3782    that might lead to ICE on 32bit target.  The sequence unlikely combine
3783    anyway.  */
3784 (define_split
3785   [(set (match_operand:DF 0 "register_operand")
3786         (float_extend:DF
3787           (match_operand:SF 1 "nonimmediate_operand")))]
3788   "TARGET_USE_VECTOR_FP_CONVERTS
3789    && optimize_insn_for_speed_p ()
3790    && reload_completed && SSE_REG_P (operands[0])"
3791    [(set (match_dup 2)
3792          (float_extend:V2DF
3793            (vec_select:V2SF
3794              (match_dup 3)
3795              (parallel [(const_int 0) (const_int 1)]))))]
3797   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3798   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3799   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3800      Try to avoid move when unpacking can be done in source.  */
3801   if (REG_P (operands[1]))
3802     {
3803       /* If it is unsafe to overwrite upper half of source, we need
3804          to move to destination and unpack there.  */
3805       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3806            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3807           && true_regnum (operands[0]) != true_regnum (operands[1]))
3808         {
3809           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3810           emit_move_insn (tmp, operands[1]);
3811         }
3812       else
3813         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3814       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3815                                              operands[3]));
3816     }
3817   else
3818     emit_insn (gen_vec_setv4sf_0 (operands[3],
3819                                   CONST0_RTX (V4SFmode), operands[1]));
3822 ;; It's more profitable to split and then extend in the same register.
3823 (define_peephole2
3824   [(set (match_operand:DF 0 "register_operand")
3825         (float_extend:DF
3826           (match_operand:SF 1 "memory_operand")))]
3827   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3828    && optimize_insn_for_speed_p ()
3829    && SSE_REG_P (operands[0])"
3830   [(set (match_dup 2) (match_dup 1))
3831    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
3832   "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
3834 (define_insn "*extendsfdf2_mixed"
3835   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3836         (float_extend:DF
3837           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3838   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3840   switch (which_alternative)
3841     {
3842     case 0:
3843     case 1:
3844       return output_387_reg_move (insn, operands);
3846     case 2:
3847       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3849     default:
3850       gcc_unreachable ();
3851     }
3853   [(set_attr "type" "fmov,fmov,ssecvt")
3854    (set_attr "prefix" "orig,orig,maybe_vex")
3855    (set_attr "mode" "SF,XF,DF")])
3857 (define_insn "*extendsfdf2_sse"
3858   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3859         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3860   "TARGET_SSE2 && TARGET_SSE_MATH"
3861   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3862   [(set_attr "type" "ssecvt")
3863    (set_attr "prefix" "maybe_vex")
3864    (set_attr "mode" "DF")])
3866 (define_insn "*extendsfdf2_i387"
3867   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3868         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3869   "TARGET_80387"
3870   "* return output_387_reg_move (insn, operands);"
3871   [(set_attr "type" "fmov")
3872    (set_attr "mode" "SF,XF")])
3874 (define_expand "extend<mode>xf2"
3875   [(set (match_operand:XF 0 "nonimmediate_operand")
3876         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3877   "TARGET_80387"
3879   /* ??? Needed for compress_float_constant since all fp constants
3880      are TARGET_LEGITIMATE_CONSTANT_P.  */
3881   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3882     {
3883       if (standard_80387_constant_p (operands[1]) > 0)
3884         {
3885           operands[1] = simplify_const_unary_operation
3886             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3887           emit_move_insn_1 (operands[0], operands[1]);
3888           DONE;
3889         }
3890       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3891     }
3894 (define_insn "*extend<mode>xf2_i387"
3895   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3896         (float_extend:XF
3897           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3898   "TARGET_80387"
3899   "* return output_387_reg_move (insn, operands);"
3900   [(set_attr "type" "fmov")
3901    (set_attr "mode" "<MODE>,XF")])
3903 ;; %%% This seems bad bad news.
3904 ;; This cannot output into an f-reg because there is no way to be sure
3905 ;; of truncating in that case.  Otherwise this is just like a simple move
3906 ;; insn.  So we pretend we can output to a reg in order to get better
3907 ;; register preferencing, but we really use a stack slot.
3909 ;; Conversion from DFmode to SFmode.
3911 (define_expand "truncdfsf2"
3912   [(set (match_operand:SF 0 "nonimmediate_operand")
3913         (float_truncate:SF
3914           (match_operand:DF 1 "nonimmediate_operand")))]
3915   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3917   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3918     ;
3919   else if (flag_unsafe_math_optimizations)
3920     ;
3921   else
3922     {
3923       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3924       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3925       DONE;
3926     }
3929 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3930    cvtsd2ss:
3931       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3932       cvtpd2ps xmm2,xmm1
3933    We do the conversion post reload to avoid producing of 128bit spills
3934    that might lead to ICE on 32bit target.  The sequence unlikely combine
3935    anyway.  */
3936 (define_split
3937   [(set (match_operand:SF 0 "register_operand")
3938         (float_truncate:SF
3939           (match_operand:DF 1 "nonimmediate_operand")))]
3940   "TARGET_USE_VECTOR_FP_CONVERTS
3941    && optimize_insn_for_speed_p ()
3942    && reload_completed && SSE_REG_P (operands[0])"
3943    [(set (match_dup 2)
3944          (vec_concat:V4SF
3945            (float_truncate:V2SF
3946              (match_dup 4))
3947            (match_dup 3)))]
3949   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3950   operands[3] = CONST0_RTX (V2SFmode);
3951   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3952   /* Use movsd for loading from memory, unpcklpd for registers.
3953      Try to avoid move when unpacking can be done in source, or SSE3
3954      movddup is available.  */
3955   if (REG_P (operands[1]))
3956     {
3957       if (!TARGET_SSE3
3958           && true_regnum (operands[0]) != true_regnum (operands[1])
3959           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3960               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3961         {
3962           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3963           emit_move_insn (tmp, operands[1]);
3964           operands[1] = tmp;
3965         }
3966       else if (!TARGET_SSE3)
3967         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3968       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
3969     }
3970   else
3971     emit_insn (gen_sse2_loadlpd (operands[4],
3972                                  CONST0_RTX (V2DFmode), operands[1]));
3975 ;; It's more profitable to split and then extend in the same register.
3976 (define_peephole2
3977   [(set (match_operand:SF 0 "register_operand")
3978         (float_truncate:SF
3979           (match_operand:DF 1 "memory_operand")))]
3980   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3981    && optimize_insn_for_speed_p ()
3982    && SSE_REG_P (operands[0])"
3983   [(set (match_dup 2) (match_dup 1))
3984    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
3985   "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
3987 (define_expand "truncdfsf2_with_temp"
3988   [(parallel [(set (match_operand:SF 0)
3989                    (float_truncate:SF (match_operand:DF 1)))
3990               (clobber (match_operand:SF 2))])])
3992 (define_insn "*truncdfsf_fast_mixed"
3993   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
3994         (float_truncate:SF
3995           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
3996   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3998   switch (which_alternative)
3999     {
4000     case 0:
4001       return output_387_reg_move (insn, operands);
4002     case 1:
4003       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4004     default:
4005       gcc_unreachable ();
4006     }
4008   [(set_attr "type" "fmov,ssecvt")
4009    (set_attr "prefix" "orig,maybe_vex")
4010    (set_attr "mode" "SF")])
4012 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4013 ;; because nothing we do here is unsafe.
4014 (define_insn "*truncdfsf_fast_sse"
4015   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4016         (float_truncate:SF
4017           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4018   "TARGET_SSE2 && TARGET_SSE_MATH"
4019   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4020   [(set_attr "type" "ssecvt")
4021    (set_attr "prefix" "maybe_vex")
4022    (set_attr "mode" "SF")])
4024 (define_insn "*truncdfsf_fast_i387"
4025   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4026         (float_truncate:SF
4027           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4028   "TARGET_80387 && flag_unsafe_math_optimizations"
4029   "* return output_387_reg_move (insn, operands);"
4030   [(set_attr "type" "fmov")
4031    (set_attr "mode" "SF")])
4033 (define_insn "*truncdfsf_mixed"
4034   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4035         (float_truncate:SF
4036           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4037    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4038   "TARGET_MIX_SSE_I387"
4040   switch (which_alternative)
4041     {
4042     case 0:
4043       return output_387_reg_move (insn, operands);
4044     case 1:
4045       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4047     default:
4048       return "#";
4049     }
4051   [(set_attr "isa" "*,sse2,*,*,*")
4052    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4053    (set_attr "unit" "*,*,i387,i387,i387")
4054    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4055    (set_attr "mode" "SF")])
4057 (define_insn "*truncdfsf_i387"
4058   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4059         (float_truncate:SF
4060           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4061    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4062   "TARGET_80387"
4064   switch (which_alternative)
4065     {
4066     case 0:
4067       return output_387_reg_move (insn, operands);
4069     default:
4070       return "#";
4071     }
4073   [(set_attr "type" "fmov,multi,multi,multi")
4074    (set_attr "unit" "*,i387,i387,i387")
4075    (set_attr "mode" "SF")])
4077 (define_insn "*truncdfsf2_i387_1"
4078   [(set (match_operand:SF 0 "memory_operand" "=m")
4079         (float_truncate:SF
4080           (match_operand:DF 1 "register_operand" "f")))]
4081   "TARGET_80387
4082    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4083    && !TARGET_MIX_SSE_I387"
4084   "* return output_387_reg_move (insn, operands);"
4085   [(set_attr "type" "fmov")
4086    (set_attr "mode" "SF")])
4088 (define_split
4089   [(set (match_operand:SF 0 "register_operand")
4090         (float_truncate:SF
4091          (match_operand:DF 1 "fp_register_operand")))
4092    (clobber (match_operand 2))]
4093   "reload_completed"
4094   [(set (match_dup 2) (match_dup 1))
4095    (set (match_dup 0) (match_dup 2))]
4096   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4098 ;; Conversion from XFmode to {SF,DF}mode
4100 (define_expand "truncxf<mode>2"
4101   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4102                    (float_truncate:MODEF
4103                      (match_operand:XF 1 "register_operand")))
4104               (clobber (match_dup 2))])]
4105   "TARGET_80387"
4107   if (flag_unsafe_math_optimizations)
4108     {
4109       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4110       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4111       if (reg != operands[0])
4112         emit_move_insn (operands[0], reg);
4113       DONE;
4114     }
4115   else
4116     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4119 (define_insn "*truncxfsf2_mixed"
4120   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4121         (float_truncate:SF
4122           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4123    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4124   "TARGET_80387"
4126   gcc_assert (!which_alternative);
4127   return output_387_reg_move (insn, operands);
4129   [(set_attr "type" "fmov,multi,multi,multi")
4130    (set_attr "unit" "*,i387,i387,i387")
4131    (set_attr "mode" "SF")])
4133 (define_insn "*truncxfdf2_mixed"
4134   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4135         (float_truncate:DF
4136           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4137    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4138   "TARGET_80387"
4140   gcc_assert (!which_alternative);
4141   return output_387_reg_move (insn, operands);
4143   [(set_attr "isa" "*,*,sse2,*")
4144    (set_attr "type" "fmov,multi,multi,multi")
4145    (set_attr "unit" "*,i387,i387,i387")
4146    (set_attr "mode" "DF")])
4148 (define_insn "truncxf<mode>2_i387_noop"
4149   [(set (match_operand:MODEF 0 "register_operand" "=f")
4150         (float_truncate:MODEF
4151           (match_operand:XF 1 "register_operand" "f")))]
4152   "TARGET_80387 && flag_unsafe_math_optimizations"
4153   "* return output_387_reg_move (insn, operands);"
4154   [(set_attr "type" "fmov")
4155    (set_attr "mode" "<MODE>")])
4157 (define_insn "*truncxf<mode>2_i387"
4158   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4159         (float_truncate:MODEF
4160           (match_operand:XF 1 "register_operand" "f")))]
4161   "TARGET_80387"
4162   "* return output_387_reg_move (insn, operands);"
4163   [(set_attr "type" "fmov")
4164    (set_attr "mode" "<MODE>")])
4166 (define_split
4167   [(set (match_operand:MODEF 0 "register_operand")
4168         (float_truncate:MODEF
4169           (match_operand:XF 1 "register_operand")))
4170    (clobber (match_operand:MODEF 2 "memory_operand"))]
4171   "TARGET_80387 && reload_completed"
4172   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4173    (set (match_dup 0) (match_dup 2))])
4175 (define_split
4176   [(set (match_operand:MODEF 0 "memory_operand")
4177         (float_truncate:MODEF
4178           (match_operand:XF 1 "register_operand")))
4179    (clobber (match_operand:MODEF 2 "memory_operand"))]
4180   "TARGET_80387"
4181   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4183 ;; Signed conversion to DImode.
4185 (define_expand "fix_truncxfdi2"
4186   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4187                    (fix:DI (match_operand:XF 1 "register_operand")))
4188               (clobber (reg:CC FLAGS_REG))])]
4189   "TARGET_80387"
4191   if (TARGET_FISTTP)
4192    {
4193      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4194      DONE;
4195    }
4198 (define_expand "fix_trunc<mode>di2"
4199   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4200                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4201               (clobber (reg:CC FLAGS_REG))])]
4202   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4204   if (TARGET_FISTTP
4205       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4206    {
4207      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4208      DONE;
4209    }
4210   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4211    {
4212      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4213      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4214      if (out != operands[0])
4215         emit_move_insn (operands[0], out);
4216      DONE;
4217    }
4220 ;; Signed conversion to SImode.
4222 (define_expand "fix_truncxfsi2"
4223   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4224                    (fix:SI (match_operand:XF 1 "register_operand")))
4225               (clobber (reg:CC FLAGS_REG))])]
4226   "TARGET_80387"
4228   if (TARGET_FISTTP)
4229    {
4230      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4231      DONE;
4232    }
4235 (define_expand "fix_trunc<mode>si2"
4236   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4237                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4238               (clobber (reg:CC FLAGS_REG))])]
4239   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4241   if (TARGET_FISTTP
4242       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4243    {
4244      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4245      DONE;
4246    }
4247   if (SSE_FLOAT_MODE_P (<MODE>mode))
4248    {
4249      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4250      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4251      if (out != operands[0])
4252         emit_move_insn (operands[0], out);
4253      DONE;
4254    }
4257 ;; Signed conversion to HImode.
4259 (define_expand "fix_trunc<mode>hi2"
4260   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4261                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4262               (clobber (reg:CC FLAGS_REG))])]
4263   "TARGET_80387
4264    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4266   if (TARGET_FISTTP)
4267    {
4268      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4269      DONE;
4270    }
4273 ;; Unsigned conversion to SImode.
4275 (define_expand "fixuns_trunc<mode>si2"
4276   [(parallel
4277     [(set (match_operand:SI 0 "register_operand")
4278           (unsigned_fix:SI
4279             (match_operand:MODEF 1 "nonimmediate_operand")))
4280      (use (match_dup 2))
4281      (clobber (match_scratch:<ssevecmode> 3))
4282      (clobber (match_scratch:<ssevecmode> 4))])]
4283   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4285   enum machine_mode mode = <MODE>mode;
4286   enum machine_mode vecmode = <ssevecmode>mode;
4287   REAL_VALUE_TYPE TWO31r;
4288   rtx two31;
4290   if (optimize_insn_for_size_p ())
4291     FAIL;
4293   real_ldexp (&TWO31r, &dconst1, 31);
4294   two31 = const_double_from_real_value (TWO31r, mode);
4295   two31 = ix86_build_const_vector (vecmode, true, two31);
4296   operands[2] = force_reg (vecmode, two31);
4299 (define_insn_and_split "*fixuns_trunc<mode>_1"
4300   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4301         (unsigned_fix:SI
4302           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4303    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4304    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4305    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4306   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4307    && optimize_function_for_speed_p (cfun)"
4308   "#"
4309   "&& reload_completed"
4310   [(const_int 0)]
4312   ix86_split_convert_uns_si_sse (operands);
4313   DONE;
4316 ;; Unsigned conversion to HImode.
4317 ;; Without these patterns, we'll try the unsigned SI conversion which
4318 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4320 (define_expand "fixuns_trunc<mode>hi2"
4321   [(set (match_dup 2)
4322         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4323    (set (match_operand:HI 0 "nonimmediate_operand")
4324         (subreg:HI (match_dup 2) 0))]
4325   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4326   "operands[2] = gen_reg_rtx (SImode);")
4328 ;; When SSE is available, it is always faster to use it!
4329 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4330   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4331         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4332   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4333    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4334   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4335   [(set_attr "type" "sseicvt")
4336    (set_attr "prefix" "maybe_vex")
4337    (set (attr "prefix_rex")
4338         (if_then_else
4339           (match_test "<SWI48:MODE>mode == DImode")
4340           (const_string "1")
4341           (const_string "*")))
4342    (set_attr "mode" "<MODEF:MODE>")
4343    (set_attr "athlon_decode" "double,vector")
4344    (set_attr "amdfam10_decode" "double,double")
4345    (set_attr "bdver1_decode" "double,double")])
4347 ;; Avoid vector decoded forms of the instruction.
4348 (define_peephole2
4349   [(match_scratch:MODEF 2 "x")
4350    (set (match_operand:SWI48 0 "register_operand")
4351         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4352   "TARGET_AVOID_VECTOR_DECODE
4353    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4354    && optimize_insn_for_speed_p ()"
4355   [(set (match_dup 2) (match_dup 1))
4356    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4358 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4359   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4360         (fix:SWI248x (match_operand 1 "register_operand")))]
4361   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4362    && TARGET_FISTTP
4363    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4364          && (TARGET_64BIT || <MODE>mode != DImode))
4365         && TARGET_SSE_MATH)
4366    && can_create_pseudo_p ()"
4367   "#"
4368   "&& 1"
4369   [(const_int 0)]
4371   if (memory_operand (operands[0], VOIDmode))
4372     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4373   else
4374     {
4375       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4376       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4377                                                             operands[1],
4378                                                             operands[2]));
4379     }
4380   DONE;
4382   [(set_attr "type" "fisttp")
4383    (set_attr "mode" "<MODE>")])
4385 (define_insn "fix_trunc<mode>_i387_fisttp"
4386   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4387         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4388    (clobber (match_scratch:XF 2 "=&1f"))]
4389   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4390    && TARGET_FISTTP
4391    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4392          && (TARGET_64BIT || <MODE>mode != DImode))
4393         && TARGET_SSE_MATH)"
4394   "* return output_fix_trunc (insn, operands, true);"
4395   [(set_attr "type" "fisttp")
4396    (set_attr "mode" "<MODE>")])
4398 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4399   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4400         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4401    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4402    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4403   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4404    && TARGET_FISTTP
4405    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4406         && (TARGET_64BIT || <MODE>mode != DImode))
4407         && TARGET_SSE_MATH)"
4408   "#"
4409   [(set_attr "type" "fisttp")
4410    (set_attr "mode" "<MODE>")])
4412 (define_split
4413   [(set (match_operand:SWI248x 0 "register_operand")
4414         (fix:SWI248x (match_operand 1 "register_operand")))
4415    (clobber (match_operand:SWI248x 2 "memory_operand"))
4416    (clobber (match_scratch 3))]
4417   "reload_completed"
4418   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4419               (clobber (match_dup 3))])
4420    (set (match_dup 0) (match_dup 2))])
4422 (define_split
4423   [(set (match_operand:SWI248x 0 "memory_operand")
4424         (fix:SWI248x (match_operand 1 "register_operand")))
4425    (clobber (match_operand:SWI248x 2 "memory_operand"))
4426    (clobber (match_scratch 3))]
4427   "reload_completed"
4428   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4429               (clobber (match_dup 3))])])
4431 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4432 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4433 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4434 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4435 ;; function in i386.c.
4436 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4437   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4438         (fix:SWI248x (match_operand 1 "register_operand")))
4439    (clobber (reg:CC FLAGS_REG))]
4440   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4441    && !TARGET_FISTTP
4442    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4443          && (TARGET_64BIT || <MODE>mode != DImode))
4444    && can_create_pseudo_p ()"
4445   "#"
4446   "&& 1"
4447   [(const_int 0)]
4449   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4451   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4452   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4453   if (memory_operand (operands[0], VOIDmode))
4454     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4455                                          operands[2], operands[3]));
4456   else
4457     {
4458       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4459       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4460                                                      operands[2], operands[3],
4461                                                      operands[4]));
4462     }
4463   DONE;
4465   [(set_attr "type" "fistp")
4466    (set_attr "i387_cw" "trunc")
4467    (set_attr "mode" "<MODE>")])
4469 (define_insn "fix_truncdi_i387"
4470   [(set (match_operand:DI 0 "memory_operand" "=m")
4471         (fix:DI (match_operand 1 "register_operand" "f")))
4472    (use (match_operand:HI 2 "memory_operand" "m"))
4473    (use (match_operand:HI 3 "memory_operand" "m"))
4474    (clobber (match_scratch:XF 4 "=&1f"))]
4475   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4476    && !TARGET_FISTTP
4477    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4478   "* return output_fix_trunc (insn, operands, false);"
4479   [(set_attr "type" "fistp")
4480    (set_attr "i387_cw" "trunc")
4481    (set_attr "mode" "DI")])
4483 (define_insn "fix_truncdi_i387_with_temp"
4484   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4485         (fix:DI (match_operand 1 "register_operand" "f,f")))
4486    (use (match_operand:HI 2 "memory_operand" "m,m"))
4487    (use (match_operand:HI 3 "memory_operand" "m,m"))
4488    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4489    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4490   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4491    && !TARGET_FISTTP
4492    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4493   "#"
4494   [(set_attr "type" "fistp")
4495    (set_attr "i387_cw" "trunc")
4496    (set_attr "mode" "DI")])
4498 (define_split
4499   [(set (match_operand:DI 0 "register_operand")
4500         (fix:DI (match_operand 1 "register_operand")))
4501    (use (match_operand:HI 2 "memory_operand"))
4502    (use (match_operand:HI 3 "memory_operand"))
4503    (clobber (match_operand:DI 4 "memory_operand"))
4504    (clobber (match_scratch 5))]
4505   "reload_completed"
4506   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4507               (use (match_dup 2))
4508               (use (match_dup 3))
4509               (clobber (match_dup 5))])
4510    (set (match_dup 0) (match_dup 4))])
4512 (define_split
4513   [(set (match_operand:DI 0 "memory_operand")
4514         (fix:DI (match_operand 1 "register_operand")))
4515    (use (match_operand:HI 2 "memory_operand"))
4516    (use (match_operand:HI 3 "memory_operand"))
4517    (clobber (match_operand:DI 4 "memory_operand"))
4518    (clobber (match_scratch 5))]
4519   "reload_completed"
4520   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4521               (use (match_dup 2))
4522               (use (match_dup 3))
4523               (clobber (match_dup 5))])])
4525 (define_insn "fix_trunc<mode>_i387"
4526   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4527         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4528    (use (match_operand:HI 2 "memory_operand" "m"))
4529    (use (match_operand:HI 3 "memory_operand" "m"))]
4530   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4531    && !TARGET_FISTTP
4532    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4533   "* return output_fix_trunc (insn, operands, false);"
4534   [(set_attr "type" "fistp")
4535    (set_attr "i387_cw" "trunc")
4536    (set_attr "mode" "<MODE>")])
4538 (define_insn "fix_trunc<mode>_i387_with_temp"
4539   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4540         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4541    (use (match_operand:HI 2 "memory_operand" "m,m"))
4542    (use (match_operand:HI 3 "memory_operand" "m,m"))
4543    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4544   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4545    && !TARGET_FISTTP
4546    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4547   "#"
4548   [(set_attr "type" "fistp")
4549    (set_attr "i387_cw" "trunc")
4550    (set_attr "mode" "<MODE>")])
4552 (define_split
4553   [(set (match_operand:SWI24 0 "register_operand")
4554         (fix:SWI24 (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:SWI24 4 "memory_operand"))]
4558   "reload_completed"
4559   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4560               (use (match_dup 2))
4561               (use (match_dup 3))])
4562    (set (match_dup 0) (match_dup 4))])
4564 (define_split
4565   [(set (match_operand:SWI24 0 "memory_operand")
4566         (fix:SWI24 (match_operand 1 "register_operand")))
4567    (use (match_operand:HI 2 "memory_operand"))
4568    (use (match_operand:HI 3 "memory_operand"))
4569    (clobber (match_operand:SWI24 4 "memory_operand"))]
4570   "reload_completed"
4571   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4572               (use (match_dup 2))
4573               (use (match_dup 3))])])
4575 (define_insn "x86_fnstcw_1"
4576   [(set (match_operand:HI 0 "memory_operand" "=m")
4577         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4578   "TARGET_80387"
4579   "fnstcw\t%0"
4580   [(set (attr "length")
4581         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4582    (set_attr "mode" "HI")
4583    (set_attr "unit" "i387")
4584    (set_attr "bdver1_decode" "vector")])
4586 (define_insn "x86_fldcw_1"
4587   [(set (reg:HI FPCR_REG)
4588         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4589   "TARGET_80387"
4590   "fldcw\t%0"
4591   [(set (attr "length")
4592         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4593    (set_attr "mode" "HI")
4594    (set_attr "unit" "i387")
4595    (set_attr "athlon_decode" "vector")
4596    (set_attr "amdfam10_decode" "vector")
4597    (set_attr "bdver1_decode" "vector")])
4599 ;; Conversion between fixed point and floating point.
4601 ;; Even though we only accept memory inputs, the backend _really_
4602 ;; wants to be able to do this between registers.
4604 (define_expand "floathi<mode>2"
4605   [(set (match_operand:X87MODEF 0 "register_operand")
4606         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4607   "TARGET_80387
4608    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4609        || TARGET_MIX_SSE_I387)")
4611 ;; Pre-reload splitter to add memory clobber to the pattern.
4612 (define_insn_and_split "*floathi<mode>2_1"
4613   [(set (match_operand:X87MODEF 0 "register_operand")
4614         (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4615   "TARGET_80387
4616    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4617        || TARGET_MIX_SSE_I387)
4618    && can_create_pseudo_p ()"
4619   "#"
4620   "&& 1"
4621   [(parallel [(set (match_dup 0)
4622               (float:X87MODEF (match_dup 1)))
4623    (clobber (match_dup 2))])]
4624   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4626 (define_insn "*floathi<mode>2_i387_with_temp"
4627   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4628         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4629   (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4630   "TARGET_80387
4631    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4632        || TARGET_MIX_SSE_I387)"
4633   "#"
4634   [(set_attr "type" "fmov,multi")
4635    (set_attr "mode" "<MODE>")
4636    (set_attr "unit" "*,i387")
4637    (set_attr "fp_int_src" "true")])
4639 (define_insn "*floathi<mode>2_i387"
4640   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4641         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4642   "TARGET_80387
4643    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4644        || TARGET_MIX_SSE_I387)"
4645   "fild%Z1\t%1"
4646   [(set_attr "type" "fmov")
4647    (set_attr "mode" "<MODE>")
4648    (set_attr "fp_int_src" "true")])
4650 (define_split
4651   [(set (match_operand:X87MODEF 0 "register_operand")
4652         (float:X87MODEF (match_operand:HI 1 "register_operand")))
4653    (clobber (match_operand:HI 2 "memory_operand"))]
4654   "TARGET_80387
4655    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4656        || TARGET_MIX_SSE_I387)
4657    && reload_completed"
4658   [(set (match_dup 2) (match_dup 1))
4659    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4661 (define_split
4662   [(set (match_operand:X87MODEF 0 "register_operand")
4663         (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4664    (clobber (match_operand:HI 2 "memory_operand"))]
4665    "TARGET_80387
4666     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4667         || TARGET_MIX_SSE_I387)
4668     && reload_completed"
4669   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4671 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4672   [(set (match_operand:X87MODEF 0 "register_operand")
4673         (float:X87MODEF
4674           (match_operand:SWI48x 1 "nonimmediate_operand")))]
4675   "TARGET_80387
4676    || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4677        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4679   if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4680         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4681       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4682     {
4683       rtx reg = gen_reg_rtx (XFmode);
4684       rtx (*insn)(rtx, rtx);
4686       emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4688       if (<X87MODEF:MODE>mode == SFmode)
4689         insn = gen_truncxfsf2;
4690       else if (<X87MODEF:MODE>mode == DFmode)
4691         insn = gen_truncxfdf2;
4692       else
4693         gcc_unreachable ();
4695       emit_insn (insn (operands[0], reg));
4696       DONE;
4697     }
4700 ;; Pre-reload splitter to add memory clobber to the pattern.
4701 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4702   [(set (match_operand:X87MODEF 0 "register_operand")
4703         (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4704   "((TARGET_80387
4705      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4706      && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4707            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4708          || TARGET_MIX_SSE_I387))
4709     || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4710         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4711         && ((<SWI48x:MODE>mode == SImode
4712              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4713              && optimize_function_for_speed_p (cfun)
4714              && flag_trapping_math)
4715             || !(TARGET_INTER_UNIT_CONVERSIONS
4716                  || optimize_function_for_size_p (cfun)))))
4717    && can_create_pseudo_p ()"
4718   "#"
4719   "&& 1"
4720   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4721               (clobber (match_dup 2))])]
4723   operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4725   /* Avoid store forwarding (partial memory) stall penalty
4726      by passing DImode value through XMM registers.  */
4727   if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4728       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4729       && optimize_function_for_speed_p (cfun))
4730     {
4731       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4732                                                             operands[1],
4733                                                             operands[2]));
4734       DONE;
4735     }
4738 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4739   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4740         (float:MODEF
4741           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4742    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4743   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4744    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4745   "#"
4746   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4747    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4748    (set_attr "unit" "*,i387,*,*,*")
4749    (set_attr "athlon_decode" "*,*,double,direct,double")
4750    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4751    (set_attr "bdver1_decode" "*,*,double,direct,double")
4752    (set_attr "fp_int_src" "true")])
4754 (define_insn "*floatsi<mode>2_vector_mixed"
4755   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4756         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4757   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4758    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4759   "@
4760    fild%Z1\t%1
4761    #"
4762   [(set_attr "type" "fmov,sseicvt")
4763    (set_attr "mode" "<MODE>,<ssevecmode>")
4764    (set_attr "unit" "i387,*")
4765    (set_attr "athlon_decode" "*,direct")
4766    (set_attr "amdfam10_decode" "*,double")
4767    (set_attr "bdver1_decode" "*,direct")
4768    (set_attr "fp_int_src" "true")])
4770 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_with_temp"
4771   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4772         (float:MODEF
4773           (match_operand:SWI48 1 "nonimmediate_operand" "m,?r,r,m")))
4774    (clobber (match_operand:SWI48 2 "memory_operand" "=X,m,m,X"))]
4775   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4776   "#"
4777   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4778    (set_attr "mode" "<MODEF:MODE>")
4779    (set_attr "unit" "*,i387,*,*")
4780    (set_attr "athlon_decode" "*,*,double,direct")
4781    (set_attr "amdfam10_decode" "*,*,vector,double")
4782    (set_attr "bdver1_decode" "*,*,double,direct")
4783    (set_attr "fp_int_src" "true")])
4785 (define_split
4786   [(set (match_operand:MODEF 0 "register_operand")
4787         (float:MODEF (match_operand:SWI48 1 "register_operand")))
4788    (clobber (match_operand:SWI48 2 "memory_operand"))]
4789   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4790    && TARGET_INTER_UNIT_CONVERSIONS
4791    && reload_completed && SSE_REG_P (operands[0])"
4792   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4794 (define_split
4795   [(set (match_operand:MODEF 0 "register_operand")
4796         (float:MODEF (match_operand:SWI48 1 "register_operand")))
4797    (clobber (match_operand:SWI48 2 "memory_operand"))]
4798   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4799    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4800    && reload_completed && SSE_REG_P (operands[0])"
4801   [(set (match_dup 2) (match_dup 1))
4802    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4804 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_interunit"
4805   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4806         (float:MODEF
4807           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4808   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4809    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4810   "@
4811    fild%Z1\t%1
4812    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4813    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4814   [(set_attr "type" "fmov,sseicvt,sseicvt")
4815    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4816    (set_attr "mode" "<MODEF:MODE>")
4817    (set (attr "prefix_rex")
4818      (if_then_else
4819        (and (eq_attr "prefix" "maybe_vex")
4820             (match_test "<SWI48:MODE>mode == DImode"))
4821        (const_string "1")
4822        (const_string "*")))
4823    (set_attr "unit" "i387,*,*")
4824    (set_attr "athlon_decode" "*,double,direct")
4825    (set_attr "amdfam10_decode" "*,vector,double")
4826    (set_attr "bdver1_decode" "*,double,direct")
4827    (set_attr "fp_int_src" "true")])
4829 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_nointerunit"
4830   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4831         (float:MODEF
4832           (match_operand:SWI48 1 "memory_operand" "m,m")))]
4833   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4834    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4835   "@
4836    fild%Z1\t%1
4837    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4838   [(set_attr "type" "fmov,sseicvt")
4839    (set_attr "prefix" "orig,maybe_vex")
4840    (set_attr "mode" "<MODEF:MODE>")
4841    (set (attr "prefix_rex")
4842      (if_then_else
4843        (and (eq_attr "prefix" "maybe_vex")
4844             (match_test "<SWI48:MODE>mode == DImode"))
4845        (const_string "1")
4846        (const_string "*")))
4847    (set_attr "athlon_decode" "*,direct")
4848    (set_attr "amdfam10_decode" "*,double")
4849    (set_attr "bdver1_decode" "*,direct")
4850    (set_attr "fp_int_src" "true")])
4852 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4853   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4854         (float:MODEF
4855           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4856    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4857   "TARGET_SSE2 && TARGET_SSE_MATH
4858    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4859   "#"
4860   [(set_attr "type" "sseicvt")
4861    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4862    (set_attr "athlon_decode" "double,direct,double")
4863    (set_attr "amdfam10_decode" "vector,double,double")
4864    (set_attr "bdver1_decode" "double,direct,double")
4865    (set_attr "fp_int_src" "true")])
4867 (define_insn "*floatsi<mode>2_vector_sse"
4868   [(set (match_operand:MODEF 0 "register_operand" "=x")
4869         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4870   "TARGET_SSE2 && TARGET_SSE_MATH
4871    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4872   "#"
4873   [(set_attr "type" "sseicvt")
4874    (set_attr "mode" "<MODE>")
4875    (set_attr "athlon_decode" "direct")
4876    (set_attr "amdfam10_decode" "double")
4877    (set_attr "bdver1_decode" "direct")
4878    (set_attr "fp_int_src" "true")])
4880 (define_split
4881   [(set (match_operand:MODEF 0 "register_operand")
4882         (float:MODEF (match_operand:SI 1 "register_operand")))
4883    (clobber (match_operand:SI 2 "memory_operand"))]
4884   "TARGET_SSE2 && TARGET_SSE_MATH
4885    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4886    && reload_completed && SSE_REG_P (operands[0])"
4887   [(const_int 0)]
4889   rtx op1 = operands[1];
4891   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4892                                      <MODE>mode, 0);
4893   if (GET_CODE (op1) == SUBREG)
4894     op1 = SUBREG_REG (op1);
4896   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES_TO_VEC)
4897     {
4898       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4899       emit_insn (gen_sse2_loadld (operands[4],
4900                                   CONST0_RTX (V4SImode), operands[1]));
4901     }
4902   /* We can ignore possible trapping value in the
4903      high part of SSE register for non-trapping math. */
4904   else if (SSE_REG_P (op1) && !flag_trapping_math)
4905     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4906   else
4907     {
4908       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4909       emit_move_insn (operands[2], operands[1]);
4910       emit_insn (gen_sse2_loadld (operands[4],
4911                                   CONST0_RTX (V4SImode), operands[2]));
4912     }
4913   if (<ssevecmode>mode == V4SFmode)
4914     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4915   else
4916     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4917   DONE;
4920 (define_split
4921   [(set (match_operand:MODEF 0 "register_operand")
4922         (float:MODEF (match_operand:SI 1 "memory_operand")))
4923    (clobber (match_operand:SI 2 "memory_operand"))]
4924   "TARGET_SSE2 && TARGET_SSE_MATH
4925    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4926    && reload_completed && SSE_REG_P (operands[0])"
4927   [(const_int 0)]
4929   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4930                                      <MODE>mode, 0);
4931   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4933   emit_insn (gen_sse2_loadld (operands[4],
4934                               CONST0_RTX (V4SImode), operands[1]));
4935   if (<ssevecmode>mode == V4SFmode)
4936     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4937   else
4938     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4939   DONE;
4942 (define_split
4943   [(set (match_operand:MODEF 0 "register_operand")
4944         (float:MODEF (match_operand:SI 1 "register_operand")))]
4945   "TARGET_SSE2 && TARGET_SSE_MATH
4946    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4947    && reload_completed && SSE_REG_P (operands[0])"
4948   [(const_int 0)]
4950   rtx op1 = operands[1];
4952   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4953                                      <MODE>mode, 0);
4954   if (GET_CODE (op1) == SUBREG)
4955     op1 = SUBREG_REG (op1);
4957   if (GENERAL_REG_P (op1))
4958     {
4959       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4960       if (TARGET_INTER_UNIT_MOVES_TO_VEC)
4961         emit_insn (gen_sse2_loadld (operands[4],
4962                                     CONST0_RTX (V4SImode), operands[1]));
4963       else
4964         {
4965           operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
4966                                               operands[1]);
4967           emit_insn (gen_sse2_loadld (operands[4],
4968                                       CONST0_RTX (V4SImode), operands[5]));
4969           ix86_free_from_memory (GET_MODE (operands[1]));
4970         }
4971     }
4972   /* We can ignore possible trapping value in the
4973      high part of SSE register for non-trapping math. */
4974   else if (SSE_REG_P (op1) && !flag_trapping_math)
4975     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4976   else
4977     gcc_unreachable ();
4978   if (<ssevecmode>mode == V4SFmode)
4979     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4980   else
4981     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4982   DONE;
4985 (define_split
4986   [(set (match_operand:MODEF 0 "register_operand")
4987         (float:MODEF (match_operand:SI 1 "memory_operand")))]
4988   "TARGET_SSE2 && TARGET_SSE_MATH
4989    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4990    && reload_completed && SSE_REG_P (operands[0])"
4991   [(const_int 0)]
4993   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4994                                      <MODE>mode, 0);
4995   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4997   emit_insn (gen_sse2_loadld (operands[4],
4998                               CONST0_RTX (V4SImode), operands[1]));
4999   if (<ssevecmode>mode == V4SFmode)
5000     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5001   else
5002     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5003   DONE;
5006 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_with_temp"
5007   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5008         (float:MODEF
5009           (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))
5010   (clobber (match_operand:SWI48 2 "memory_operand" "=m,X"))]
5011   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5012   "#"
5013   [(set_attr "type" "sseicvt")
5014    (set_attr "mode" "<MODEF:MODE>")
5015    (set_attr "athlon_decode" "double,direct")
5016    (set_attr "amdfam10_decode" "vector,double")
5017    (set_attr "bdver1_decode" "double,direct")
5018    (set_attr "btver2_decode" "double,double")
5019    (set_attr "fp_int_src" "true")])
5021 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_interunit"
5022   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5023         (float:MODEF
5024           (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))]
5025   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5026    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5027   "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5028   [(set_attr "type" "sseicvt")
5029    (set_attr "prefix" "maybe_vex")
5030    (set_attr "mode" "<MODEF:MODE>")
5031    (set (attr "prefix_rex")
5032      (if_then_else
5033        (and (eq_attr "prefix" "maybe_vex")
5034             (match_test "<SWI48:MODE>mode == DImode"))
5035        (const_string "1")
5036        (const_string "*")))
5037    (set_attr "athlon_decode" "double,direct")
5038    (set_attr "amdfam10_decode" "vector,double")
5039    (set_attr "bdver1_decode" "double,direct")
5040    (set_attr "btver2_decode" "double,double")
5041    (set_attr "fp_int_src" "true")])
5043 (define_split
5044   [(set (match_operand:MODEF 0 "register_operand")
5045         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))
5046    (clobber (match_operand:SWI48 2 "memory_operand"))]
5047   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5048    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5049    && reload_completed && SSE_REG_P (operands[0])"
5050   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5052 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_nointerunit"
5053   [(set (match_operand:MODEF 0 "register_operand" "=x")
5054         (float:MODEF
5055           (match_operand:SWI48 1 "memory_operand" "m")))]
5056   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5057    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5058   "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5059   [(set_attr "type" "sseicvt")
5060    (set_attr "prefix" "maybe_vex")
5061    (set_attr "mode" "<MODEF:MODE>")
5062    (set (attr "prefix_rex")
5063      (if_then_else
5064        (and (eq_attr "prefix" "maybe_vex")
5065             (match_test "<SWI48:MODE>mode == DImode"))
5066        (const_string "1")
5067        (const_string "*")))
5068    (set_attr "athlon_decode" "direct")
5069    (set_attr "amdfam10_decode" "double")
5070    (set_attr "bdver1_decode" "direct")
5071    (set_attr "fp_int_src" "true")])
5073 (define_split
5074   [(set (match_operand:MODEF 0 "register_operand")
5075         (float:MODEF (match_operand:SWI48 1 "register_operand")))
5076    (clobber (match_operand:SWI48 2 "memory_operand"))]
5077   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5078    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5079    && reload_completed && SSE_REG_P (operands[0])"
5080   [(set (match_dup 2) (match_dup 1))
5081    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5083 (define_split
5084   [(set (match_operand:MODEF 0 "register_operand")
5085         (float:MODEF (match_operand:SWI48 1 "memory_operand")))
5086    (clobber (match_operand:SWI48 2 "memory_operand"))]
5087   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5088    && reload_completed && SSE_REG_P (operands[0])"
5089   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5091 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5092   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5093         (float:X87MODEF
5094           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5095   (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5096   "TARGET_80387
5097    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5098   "@
5099    fild%Z1\t%1
5100    #"
5101   [(set_attr "type" "fmov,multi")
5102    (set_attr "mode" "<X87MODEF:MODE>")
5103    (set_attr "unit" "*,i387")
5104    (set_attr "fp_int_src" "true")])
5106 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5107   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5108         (float:X87MODEF
5109           (match_operand:SWI48x 1 "memory_operand" "m")))]
5110   "TARGET_80387
5111    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5112   "fild%Z1\t%1"
5113   [(set_attr "type" "fmov")
5114    (set_attr "mode" "<X87MODEF:MODE>")
5115    (set_attr "fp_int_src" "true")])
5117 (define_split
5118   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5119         (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5120    (clobber (match_operand:SWI48x 2 "memory_operand"))]
5121   "TARGET_80387
5122    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5123    && reload_completed"
5124   [(set (match_dup 2) (match_dup 1))
5125    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5127 (define_split
5128   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5129         (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5130    (clobber (match_operand:SWI48x 2 "memory_operand"))]
5131   "TARGET_80387
5132    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5133    && reload_completed"
5134   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5136 ;; Avoid partial SSE register dependency stalls
5138 (define_split
5139   [(set (match_operand:MODEF 0 "register_operand")
5140         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5141   "TARGET_SSE2 && TARGET_SSE_MATH
5142    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5143    && optimize_function_for_speed_p (cfun)
5144    && reload_completed && SSE_REG_P (operands[0])"
5145   [(set (match_dup 0)
5146         (vec_merge:<ssevecmode>
5147           (vec_duplicate:<ssevecmode>
5148             (float:MODEF (match_dup 1)))
5149           (match_dup 0)
5150           (const_int 1)))]
5152   operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5153                                      <MODE>mode, 0);
5154   emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
5157 (define_split
5158   [(set (match_operand:MODEF 0 "register_operand")
5159         (float:MODEF (match_operand:DI 1 "nonimmediate_operand")))]
5160   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5161    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5162    && optimize_function_for_speed_p (cfun)
5163    && reload_completed && SSE_REG_P (operands[0])"
5164   [(set (match_dup 0)
5165         (vec_merge:<ssevecmode>
5166           (vec_duplicate:<ssevecmode>
5167             (float:MODEF (match_dup 1)))
5168           (match_dup 0)
5169           (const_int 1)))]
5171   operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5172                                      <MODE>mode, 0);
5173   emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
5176 ;; Break partial reg stall for cvtsd2ss.
5178 (define_peephole2
5179   [(set (match_operand:SF 0 "register_operand")
5180         (float_truncate:SF
5181           (match_operand:DF 1 "nonimmediate_operand")))]
5182   "TARGET_SSE2 && TARGET_SSE_MATH
5183    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5184    && optimize_function_for_speed_p (cfun)
5185    && SSE_REG_P (operands[0])
5186    && (!SSE_REG_P (operands[1])
5187        || REGNO (operands[0]) != REGNO (operands[1]))"
5188   [(set (match_dup 0)
5189         (vec_merge:V4SF
5190           (vec_duplicate:V4SF
5191             (float_truncate:V2SF
5192               (match_dup 1)))
5193           (match_dup 0)
5194           (const_int 1)))]
5196   operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
5197                                      SFmode, 0);
5198   operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
5199                                      DFmode, 0);
5200   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5203 ;; Break partial reg stall for cvtss2sd.
5205 (define_peephole2
5206   [(set (match_operand:DF 0 "register_operand")
5207         (float_extend:DF
5208           (match_operand:SF 1 "nonimmediate_operand")))]
5209   "TARGET_SSE2 && TARGET_SSE_MATH
5210    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5211    && optimize_function_for_speed_p (cfun)
5212    && SSE_REG_P (operands[0])
5213    && (!SSE_REG_P (operands[1])
5214        || REGNO (operands[0]) != REGNO (operands[1]))"
5215   [(set (match_dup 0)
5216         (vec_merge:V2DF
5217           (float_extend:V2DF
5218             (vec_select:V2SF
5219               (match_dup 1)
5220               (parallel [(const_int 0) (const_int 1)])))
5221           (match_dup 0)
5222           (const_int 1)))]
5224   operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
5225                                      DFmode, 0);
5226   operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5227                                      SFmode, 0);
5228   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5231 ;; Avoid store forwarding (partial memory) stall penalty
5232 ;; by passing DImode value through XMM registers.  */
5234 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5235   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5236         (float:X87MODEF
5237           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5238    (clobber (match_scratch:V4SI 3 "=X,x"))
5239    (clobber (match_scratch:V4SI 4 "=X,x"))
5240    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5241   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5242    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5243    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5244   "#"
5245   [(set_attr "type" "multi")
5246    (set_attr "mode" "<X87MODEF:MODE>")
5247    (set_attr "unit" "i387")
5248    (set_attr "fp_int_src" "true")])
5250 (define_split
5251   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5252         (float:X87MODEF (match_operand:DI 1 "register_operand")))
5253    (clobber (match_scratch:V4SI 3))
5254    (clobber (match_scratch:V4SI 4))
5255    (clobber (match_operand:DI 2 "memory_operand"))]
5256   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5257    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5258    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5259    && reload_completed"
5260   [(set (match_dup 2) (match_dup 3))
5261    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5263   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5264      Assemble the 64-bit DImode value in an xmm register.  */
5265   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5266                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5267   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5268                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5269   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5270                                          operands[4]));
5272   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5275 (define_split
5276   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5277         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5278    (clobber (match_scratch:V4SI 3))
5279    (clobber (match_scratch:V4SI 4))
5280    (clobber (match_operand:DI 2 "memory_operand"))]
5281   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5282    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5283    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5284    && reload_completed"
5285   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5287 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5288   [(set (match_operand:MODEF 0 "register_operand")
5289         (unsigned_float:MODEF
5290           (match_operand:SWI12 1 "nonimmediate_operand")))]
5291   "!TARGET_64BIT
5292    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5294   operands[1] = convert_to_mode (SImode, operands[1], 1);
5295   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5296   DONE;
5299 ;; Avoid store forwarding (partial memory) stall penalty by extending
5300 ;; SImode value to DImode through XMM register instead of pushing two
5301 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES_TO_VEC
5302 ;; targets benefit from this optimization. Also note that fild
5303 ;; loads from memory only.
5305 (define_insn "*floatunssi<mode>2_1"
5306   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5307         (unsigned_float:X87MODEF
5308           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5309    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5310    (clobber (match_scratch:SI 3 "=X,x"))]
5311   "!TARGET_64BIT
5312    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5313    && TARGET_SSE"
5314   "#"
5315   [(set_attr "type" "multi")
5316    (set_attr "mode" "<MODE>")])
5318 (define_split
5319   [(set (match_operand:X87MODEF 0 "register_operand")
5320         (unsigned_float:X87MODEF
5321           (match_operand:SI 1 "register_operand")))
5322    (clobber (match_operand:DI 2 "memory_operand"))
5323    (clobber (match_scratch:SI 3))]
5324   "!TARGET_64BIT
5325    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5326    && TARGET_SSE
5327    && reload_completed"
5328   [(set (match_dup 2) (match_dup 1))
5329    (set (match_dup 0)
5330         (float:X87MODEF (match_dup 2)))]
5331   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5333 (define_split
5334   [(set (match_operand:X87MODEF 0 "register_operand")
5335         (unsigned_float:X87MODEF
5336           (match_operand:SI 1 "memory_operand")))
5337    (clobber (match_operand:DI 2 "memory_operand"))
5338    (clobber (match_scratch:SI 3))]
5339   "!TARGET_64BIT
5340    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5341    && TARGET_SSE
5342    && reload_completed"
5343   [(set (match_dup 2) (match_dup 3))
5344    (set (match_dup 0)
5345         (float:X87MODEF (match_dup 2)))]
5347   emit_move_insn (operands[3], operands[1]);
5348   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5351 (define_expand "floatunssi<mode>2"
5352   [(parallel
5353      [(set (match_operand:X87MODEF 0 "register_operand")
5354            (unsigned_float:X87MODEF
5355              (match_operand:SI 1 "nonimmediate_operand")))
5356       (clobber (match_dup 2))
5357       (clobber (match_scratch:SI 3))])]
5358   "!TARGET_64BIT
5359    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5360         && TARGET_SSE)
5361        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5363   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5364     {
5365       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5366       DONE;
5367     }
5368   else
5369     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5372 (define_expand "floatunsdisf2"
5373   [(use (match_operand:SF 0 "register_operand"))
5374    (use (match_operand:DI 1 "nonimmediate_operand"))]
5375   "TARGET_64BIT && TARGET_SSE_MATH"
5376   "x86_emit_floatuns (operands); DONE;")
5378 (define_expand "floatunsdidf2"
5379   [(use (match_operand:DF 0 "register_operand"))
5380    (use (match_operand:DI 1 "nonimmediate_operand"))]
5381   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5382    && TARGET_SSE2 && TARGET_SSE_MATH"
5384   if (TARGET_64BIT)
5385     x86_emit_floatuns (operands);
5386   else
5387     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5388   DONE;
5391 ;; Load effective address instructions
5393 (define_insn_and_split "*lea<mode>"
5394   [(set (match_operand:SWI48 0 "register_operand" "=r")
5395         (match_operand:SWI48 1 "address_no_seg_operand" "p"))]
5396   ""
5398   if (SImode_address_operand (operands[1], VOIDmode))
5399     {
5400       gcc_assert (TARGET_64BIT);
5401       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5402     }
5403   else 
5404     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5406   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5407   [(const_int 0)]
5409   enum machine_mode mode = <MODE>mode;
5410   rtx pat;
5412   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5413      change operands[] array behind our back.  */
5414   pat = PATTERN (curr_insn);
5416   operands[0] = SET_DEST (pat);
5417   operands[1] = SET_SRC (pat);
5419   /* Emit all operations in SImode for zero-extended addresses.  Recall
5420      that x86_64 inheretly zero-extends SImode operations to DImode.  */
5421   if (SImode_address_operand (operands[1], VOIDmode))
5422     mode = SImode;
5424   ix86_split_lea_for_addr (curr_insn, operands, mode);
5425   DONE;
5427   [(set_attr "type" "lea")
5428    (set (attr "mode")
5429      (if_then_else
5430        (match_operand 1 "SImode_address_operand")
5431        (const_string "SI")
5432        (const_string "<MODE>")))])
5434 ;; Add instructions
5436 (define_expand "add<mode>3"
5437   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5438         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5439                     (match_operand:SDWIM 2 "<general_operand>")))]
5440   ""
5441   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5443 (define_insn_and_split "*add<dwi>3_doubleword"
5444   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5445         (plus:<DWI>
5446           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5447           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5448    (clobber (reg:CC FLAGS_REG))]
5449   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5450   "#"
5451   "reload_completed"
5452   [(parallel [(set (reg:CC FLAGS_REG)
5453                    (unspec:CC [(match_dup 1) (match_dup 2)]
5454                               UNSPEC_ADD_CARRY))
5455               (set (match_dup 0)
5456                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5457    (parallel [(set (match_dup 3)
5458                    (plus:DWIH
5459                      (match_dup 4)
5460                      (plus:DWIH
5461                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5462                        (match_dup 5))))
5463               (clobber (reg:CC FLAGS_REG))])]
5464   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5466 (define_insn "*add<mode>3_cc"
5467   [(set (reg:CC FLAGS_REG)
5468         (unspec:CC
5469           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5470            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5471           UNSPEC_ADD_CARRY))
5472    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5473         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5474   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5475   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5476   [(set_attr "type" "alu")
5477    (set_attr "mode" "<MODE>")])
5479 (define_insn "addqi3_cc"
5480   [(set (reg:CC FLAGS_REG)
5481         (unspec:CC
5482           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5483            (match_operand:QI 2 "general_operand" "qn,qm")]
5484           UNSPEC_ADD_CARRY))
5485    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5486         (plus:QI (match_dup 1) (match_dup 2)))]
5487   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5488   "add{b}\t{%2, %0|%0, %2}"
5489   [(set_attr "type" "alu")
5490    (set_attr "mode" "QI")])
5492 (define_insn "*add<mode>_1"
5493   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5494         (plus:SWI48
5495           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5496           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5497    (clobber (reg:CC FLAGS_REG))]
5498   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5500   switch (get_attr_type (insn))
5501     {
5502     case TYPE_LEA:
5503       return "#";
5505     case TYPE_INCDEC:
5506       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5507       if (operands[2] == const1_rtx)
5508         return "inc{<imodesuffix>}\t%0";
5509       else
5510         {
5511           gcc_assert (operands[2] == constm1_rtx);
5512           return "dec{<imodesuffix>}\t%0";
5513         }
5515     default:
5516       /* For most processors, ADD is faster than LEA.  This alternative
5517          was added to use ADD as much as possible.  */
5518       if (which_alternative == 2)
5519         {
5520           rtx tmp;
5521           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5522         }
5523         
5524       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5525       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5526         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5528       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5529     }
5531   [(set (attr "type")
5532      (cond [(eq_attr "alternative" "3")
5533               (const_string "lea")
5534             (match_operand:SWI48 2 "incdec_operand")
5535               (const_string "incdec")
5536            ]
5537            (const_string "alu")))
5538    (set (attr "length_immediate")
5539       (if_then_else
5540         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5541         (const_string "1")
5542         (const_string "*")))
5543    (set_attr "mode" "<MODE>")])
5545 ;; It may seem that nonimmediate operand is proper one for operand 1.
5546 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5547 ;; we take care in ix86_binary_operator_ok to not allow two memory
5548 ;; operands so proper swapping will be done in reload.  This allow
5549 ;; patterns constructed from addsi_1 to match.
5551 (define_insn "addsi_1_zext"
5552   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5553         (zero_extend:DI
5554           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5555                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5556    (clobber (reg:CC FLAGS_REG))]
5557   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5559   switch (get_attr_type (insn))
5560     {
5561     case TYPE_LEA:
5562       return "#";
5564     case TYPE_INCDEC:
5565       if (operands[2] == const1_rtx)
5566         return "inc{l}\t%k0";
5567       else
5568         {
5569           gcc_assert (operands[2] == constm1_rtx);
5570           return "dec{l}\t%k0";
5571         }
5573     default:
5574       /* For most processors, ADD is faster than LEA.  This alternative
5575          was added to use ADD as much as possible.  */
5576       if (which_alternative == 1)
5577         {
5578           rtx tmp;
5579           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5580         }
5582       if (x86_maybe_negate_const_int (&operands[2], SImode))
5583         return "sub{l}\t{%2, %k0|%k0, %2}";
5585       return "add{l}\t{%2, %k0|%k0, %2}";
5586     }
5588   [(set (attr "type")
5589      (cond [(eq_attr "alternative" "2")
5590               (const_string "lea")
5591             (match_operand:SI 2 "incdec_operand")
5592               (const_string "incdec")
5593            ]
5594            (const_string "alu")))
5595    (set (attr "length_immediate")
5596       (if_then_else
5597         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5598         (const_string "1")
5599         (const_string "*")))
5600    (set_attr "mode" "SI")])
5602 (define_insn "*addhi_1"
5603   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5604         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5605                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5606    (clobber (reg:CC FLAGS_REG))]
5607   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5609   switch (get_attr_type (insn))
5610     {
5611     case TYPE_LEA:
5612       return "#";
5614     case TYPE_INCDEC:
5615       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5616       if (operands[2] == const1_rtx)
5617         return "inc{w}\t%0";
5618       else
5619         {
5620           gcc_assert (operands[2] == constm1_rtx);
5621           return "dec{w}\t%0";
5622         }
5624     default:
5625       /* For most processors, ADD is faster than LEA.  This alternative
5626          was added to use ADD as much as possible.  */
5627       if (which_alternative == 2)
5628         {
5629           rtx tmp;
5630           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5631         }
5633       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5634       if (x86_maybe_negate_const_int (&operands[2], HImode))
5635         return "sub{w}\t{%2, %0|%0, %2}";
5637       return "add{w}\t{%2, %0|%0, %2}";
5638     }
5640   [(set (attr "type")
5641      (cond [(eq_attr "alternative" "3")
5642               (const_string "lea")
5643             (match_operand:HI 2 "incdec_operand")
5644               (const_string "incdec")
5645            ]
5646            (const_string "alu")))
5647    (set (attr "length_immediate")
5648       (if_then_else
5649         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5650         (const_string "1")
5651         (const_string "*")))
5652    (set_attr "mode" "HI,HI,HI,SI")])
5654 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5655 (define_insn "*addqi_1"
5656   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5657         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5658                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5659    (clobber (reg:CC FLAGS_REG))]
5660   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5662   bool widen = (which_alternative == 3 || which_alternative == 4);
5664   switch (get_attr_type (insn))
5665     {
5666     case TYPE_LEA:
5667       return "#";
5669     case TYPE_INCDEC:
5670       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5671       if (operands[2] == const1_rtx)
5672         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5673       else
5674         {
5675           gcc_assert (operands[2] == constm1_rtx);
5676           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5677         }
5679     default:
5680       /* For most processors, ADD is faster than LEA.  These alternatives
5681          were added to use ADD as much as possible.  */
5682       if (which_alternative == 2 || which_alternative == 4)
5683         {
5684           rtx tmp;
5685           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5686         }
5688       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5689       if (x86_maybe_negate_const_int (&operands[2], QImode))
5690         {
5691           if (widen)
5692             return "sub{l}\t{%2, %k0|%k0, %2}";
5693           else
5694             return "sub{b}\t{%2, %0|%0, %2}";
5695         }
5696       if (widen)
5697         return "add{l}\t{%k2, %k0|%k0, %k2}";
5698       else
5699         return "add{b}\t{%2, %0|%0, %2}";
5700     }
5702   [(set (attr "type")
5703      (cond [(eq_attr "alternative" "5")
5704               (const_string "lea")
5705             (match_operand:QI 2 "incdec_operand")
5706               (const_string "incdec")
5707            ]
5708            (const_string "alu")))
5709    (set (attr "length_immediate")
5710       (if_then_else
5711         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5712         (const_string "1")
5713         (const_string "*")))
5714    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5716 (define_insn "*addqi_1_slp"
5717   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5718         (plus:QI (match_dup 0)
5719                  (match_operand:QI 1 "general_operand" "qn,qm")))
5720    (clobber (reg:CC FLAGS_REG))]
5721   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5722    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5724   switch (get_attr_type (insn))
5725     {
5726     case TYPE_INCDEC:
5727       if (operands[1] == const1_rtx)
5728         return "inc{b}\t%0";
5729       else
5730         {
5731           gcc_assert (operands[1] == constm1_rtx);
5732           return "dec{b}\t%0";
5733         }
5735     default:
5736       if (x86_maybe_negate_const_int (&operands[1], QImode))
5737         return "sub{b}\t{%1, %0|%0, %1}";
5739       return "add{b}\t{%1, %0|%0, %1}";
5740     }
5742   [(set (attr "type")
5743      (if_then_else (match_operand:QI 1 "incdec_operand")
5744         (const_string "incdec")
5745         (const_string "alu1")))
5746    (set (attr "memory")
5747      (if_then_else (match_operand 1 "memory_operand")
5748         (const_string "load")
5749         (const_string "none")))
5750    (set_attr "mode" "QI")])
5752 ;; Split non destructive adds if we cannot use lea.
5753 (define_split
5754   [(set (match_operand:SWI48 0 "register_operand")
5755         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5756                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5757    (clobber (reg:CC FLAGS_REG))]
5758   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5759   [(set (match_dup 0) (match_dup 1))
5760    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5761               (clobber (reg:CC FLAGS_REG))])])
5763 ;; Convert add to the lea pattern to avoid flags dependency.
5764 (define_split
5765   [(set (match_operand:SWI 0 "register_operand")
5766         (plus:SWI (match_operand:SWI 1 "register_operand")
5767                   (match_operand:SWI 2 "<nonmemory_operand>")))
5768    (clobber (reg:CC FLAGS_REG))]
5769   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5770   [(const_int 0)]
5772   enum machine_mode mode = <MODE>mode;
5773   rtx pat;
5775   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5776     { 
5777       mode = SImode; 
5778       operands[0] = gen_lowpart (mode, operands[0]);
5779       operands[1] = gen_lowpart (mode, operands[1]);
5780       operands[2] = gen_lowpart (mode, operands[2]);
5781     }
5783   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5785   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5786   DONE;
5789 ;; Split non destructive adds if we cannot use lea.
5790 (define_split
5791   [(set (match_operand:DI 0 "register_operand")
5792         (zero_extend:DI
5793           (plus:SI (match_operand:SI 1 "register_operand")
5794                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5795    (clobber (reg:CC FLAGS_REG))]
5796   "TARGET_64BIT
5797    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5798   [(set (match_dup 3) (match_dup 1))
5799    (parallel [(set (match_dup 0)
5800                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5801               (clobber (reg:CC FLAGS_REG))])]
5802   "operands[3] = gen_lowpart (SImode, operands[0]);")
5804 ;; Convert add to the lea pattern to avoid flags dependency.
5805 (define_split
5806   [(set (match_operand:DI 0 "register_operand")
5807         (zero_extend:DI
5808           (plus:SI (match_operand:SI 1 "register_operand")
5809                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5810    (clobber (reg:CC FLAGS_REG))]
5811   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5812   [(set (match_dup 0)
5813         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5815 (define_insn "*add<mode>_2"
5816   [(set (reg FLAGS_REG)
5817         (compare
5818           (plus:SWI
5819             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5820             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5821           (const_int 0)))
5822    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5823         (plus:SWI (match_dup 1) (match_dup 2)))]
5824   "ix86_match_ccmode (insn, CCGOCmode)
5825    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5827   switch (get_attr_type (insn))
5828     {
5829     case TYPE_INCDEC:
5830       if (operands[2] == const1_rtx)
5831         return "inc{<imodesuffix>}\t%0";
5832       else
5833         {
5834           gcc_assert (operands[2] == constm1_rtx);
5835           return "dec{<imodesuffix>}\t%0";
5836         }
5838     default:
5839       if (which_alternative == 2)
5840         {
5841           rtx tmp;
5842           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5843         }
5844         
5845       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5846       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5847         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5849       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5850     }
5852   [(set (attr "type")
5853      (if_then_else (match_operand:SWI 2 "incdec_operand")
5854         (const_string "incdec")
5855         (const_string "alu")))
5856    (set (attr "length_immediate")
5857       (if_then_else
5858         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5859         (const_string "1")
5860         (const_string "*")))
5861    (set_attr "mode" "<MODE>")])
5863 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5864 (define_insn "*addsi_2_zext"
5865   [(set (reg FLAGS_REG)
5866         (compare
5867           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5868                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5869           (const_int 0)))
5870    (set (match_operand:DI 0 "register_operand" "=r,r")
5871         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5872   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5873    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5875   switch (get_attr_type (insn))
5876     {
5877     case TYPE_INCDEC:
5878       if (operands[2] == const1_rtx)
5879         return "inc{l}\t%k0";
5880       else
5881         {
5882           gcc_assert (operands[2] == constm1_rtx);
5883           return "dec{l}\t%k0";
5884         }
5886     default:
5887       if (which_alternative == 1)
5888         {
5889           rtx tmp;
5890           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5891         }
5893       if (x86_maybe_negate_const_int (&operands[2], SImode))
5894         return "sub{l}\t{%2, %k0|%k0, %2}";
5896       return "add{l}\t{%2, %k0|%k0, %2}";
5897     }
5899   [(set (attr "type")
5900      (if_then_else (match_operand:SI 2 "incdec_operand")
5901         (const_string "incdec")
5902         (const_string "alu")))
5903    (set (attr "length_immediate")
5904       (if_then_else
5905         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5906         (const_string "1")
5907         (const_string "*")))
5908    (set_attr "mode" "SI")])
5910 (define_insn "*add<mode>_3"
5911   [(set (reg FLAGS_REG)
5912         (compare
5913           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5914           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5915    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5916   "ix86_match_ccmode (insn, CCZmode)
5917    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5919   switch (get_attr_type (insn))
5920     {
5921     case TYPE_INCDEC:
5922       if (operands[2] == const1_rtx)
5923         return "inc{<imodesuffix>}\t%0";
5924       else
5925         {
5926           gcc_assert (operands[2] == constm1_rtx);
5927           return "dec{<imodesuffix>}\t%0";
5928         }
5930     default:
5931       if (which_alternative == 1)
5932         {
5933           rtx tmp;
5934           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5935         }
5937       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5938       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5939         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5941       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5942     }
5944   [(set (attr "type")
5945      (if_then_else (match_operand:SWI 2 "incdec_operand")
5946         (const_string "incdec")
5947         (const_string "alu")))
5948    (set (attr "length_immediate")
5949       (if_then_else
5950         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5951         (const_string "1")
5952         (const_string "*")))
5953    (set_attr "mode" "<MODE>")])
5955 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5956 (define_insn "*addsi_3_zext"
5957   [(set (reg FLAGS_REG)
5958         (compare
5959           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5960           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5961    (set (match_operand:DI 0 "register_operand" "=r,r")
5962         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5963   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5964    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5966   switch (get_attr_type (insn))
5967     {
5968     case TYPE_INCDEC:
5969       if (operands[2] == const1_rtx)
5970         return "inc{l}\t%k0";
5971       else
5972         {
5973           gcc_assert (operands[2] == constm1_rtx);
5974           return "dec{l}\t%k0";
5975         }
5977     default:
5978       if (which_alternative == 1)
5979         {
5980           rtx tmp;
5981           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5982         }
5984       if (x86_maybe_negate_const_int (&operands[2], SImode))
5985         return "sub{l}\t{%2, %k0|%k0, %2}";
5987       return "add{l}\t{%2, %k0|%k0, %2}";
5988     }
5990   [(set (attr "type")
5991      (if_then_else (match_operand:SI 2 "incdec_operand")
5992         (const_string "incdec")
5993         (const_string "alu")))
5994    (set (attr "length_immediate")
5995       (if_then_else
5996         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5997         (const_string "1")
5998         (const_string "*")))
5999    (set_attr "mode" "SI")])
6001 ; For comparisons against 1, -1 and 128, we may generate better code
6002 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6003 ; is matched then.  We can't accept general immediate, because for
6004 ; case of overflows,  the result is messed up.
6005 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6006 ; only for comparisons not depending on it.
6008 (define_insn "*adddi_4"
6009   [(set (reg FLAGS_REG)
6010         (compare
6011           (match_operand:DI 1 "nonimmediate_operand" "0")
6012           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6013    (clobber (match_scratch:DI 0 "=rm"))]
6014   "TARGET_64BIT
6015    && ix86_match_ccmode (insn, CCGCmode)"
6017   switch (get_attr_type (insn))
6018     {
6019     case TYPE_INCDEC:
6020       if (operands[2] == constm1_rtx)
6021         return "inc{q}\t%0";
6022       else
6023         {
6024           gcc_assert (operands[2] == const1_rtx);
6025           return "dec{q}\t%0";
6026         }
6028     default:
6029       if (x86_maybe_negate_const_int (&operands[2], DImode))
6030         return "add{q}\t{%2, %0|%0, %2}";
6032       return "sub{q}\t{%2, %0|%0, %2}";
6033     }
6035   [(set (attr "type")
6036      (if_then_else (match_operand:DI 2 "incdec_operand")
6037         (const_string "incdec")
6038         (const_string "alu")))
6039    (set (attr "length_immediate")
6040       (if_then_else
6041         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6042         (const_string "1")
6043         (const_string "*")))
6044    (set_attr "mode" "DI")])
6046 ; For comparisons against 1, -1 and 128, we may generate better code
6047 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6048 ; is matched then.  We can't accept general immediate, because for
6049 ; case of overflows,  the result is messed up.
6050 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6051 ; only for comparisons not depending on it.
6053 (define_insn "*add<mode>_4"
6054   [(set (reg FLAGS_REG)
6055         (compare
6056           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6057           (match_operand:SWI124 2 "const_int_operand" "n")))
6058    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6059   "ix86_match_ccmode (insn, CCGCmode)"
6061   switch (get_attr_type (insn))
6062     {
6063     case TYPE_INCDEC:
6064       if (operands[2] == constm1_rtx)
6065         return "inc{<imodesuffix>}\t%0";
6066       else
6067         {
6068           gcc_assert (operands[2] == const1_rtx);
6069           return "dec{<imodesuffix>}\t%0";
6070         }
6072     default:
6073       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6074         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6076       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6077     }
6079   [(set (attr "type")
6080      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6081         (const_string "incdec")
6082         (const_string "alu")))
6083    (set (attr "length_immediate")
6084       (if_then_else
6085         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6086         (const_string "1")
6087         (const_string "*")))
6088    (set_attr "mode" "<MODE>")])
6090 (define_insn "*add<mode>_5"
6091   [(set (reg FLAGS_REG)
6092         (compare
6093           (plus:SWI
6094             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6095             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6096           (const_int 0)))
6097    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6098   "ix86_match_ccmode (insn, CCGOCmode)
6099    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6101   switch (get_attr_type (insn))
6102     {
6103     case TYPE_INCDEC:
6104       if (operands[2] == const1_rtx)
6105         return "inc{<imodesuffix>}\t%0";
6106       else
6107         {
6108           gcc_assert (operands[2] == constm1_rtx);
6109           return "dec{<imodesuffix>}\t%0";
6110         }
6112     default:
6113       if (which_alternative == 1)
6114         {
6115           rtx tmp;
6116           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6117         }
6119       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6120       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6121         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6123       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6124     }
6126   [(set (attr "type")
6127      (if_then_else (match_operand:SWI 2 "incdec_operand")
6128         (const_string "incdec")
6129         (const_string "alu")))
6130    (set (attr "length_immediate")
6131       (if_then_else
6132         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6133         (const_string "1")
6134         (const_string "*")))
6135    (set_attr "mode" "<MODE>")])
6137 (define_insn "addqi_ext_1"
6138   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
6139                          (const_int 8)
6140                          (const_int 8))
6141         (plus:SI
6142           (zero_extract:SI
6143             (match_operand 1 "ext_register_operand" "0,0")
6144             (const_int 8)
6145             (const_int 8))
6146           (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
6147    (clobber (reg:CC FLAGS_REG))]
6148   ""
6150   switch (get_attr_type (insn))
6151     {
6152     case TYPE_INCDEC:
6153       if (operands[2] == const1_rtx)
6154         return "inc{b}\t%h0";
6155       else
6156         {
6157           gcc_assert (operands[2] == constm1_rtx);
6158           return "dec{b}\t%h0";
6159         }
6161     default:
6162       return "add{b}\t{%2, %h0|%h0, %2}";
6163     }
6165   [(set_attr "isa" "*,nox64")
6166    (set (attr "type")
6167      (if_then_else (match_operand:QI 2 "incdec_operand")
6168         (const_string "incdec")
6169         (const_string "alu")))
6170    (set_attr "modrm" "1")
6171    (set_attr "mode" "QI")])
6173 (define_insn "*addqi_ext_2"
6174   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6175                          (const_int 8)
6176                          (const_int 8))
6177         (plus:SI
6178           (zero_extract:SI
6179             (match_operand 1 "ext_register_operand" "%0")
6180             (const_int 8)
6181             (const_int 8))
6182           (zero_extract:SI
6183             (match_operand 2 "ext_register_operand" "Q")
6184             (const_int 8)
6185             (const_int 8))))
6186    (clobber (reg:CC FLAGS_REG))]
6187   ""
6188   "add{b}\t{%h2, %h0|%h0, %h2}"
6189   [(set_attr "type" "alu")
6190    (set_attr "mode" "QI")])
6192 ;; The lea patterns for modes less than 32 bits need to be matched by
6193 ;; several insns converted to real lea by splitters.
6195 (define_insn_and_split "*lea_general_1"
6196   [(set (match_operand 0 "register_operand" "=r")
6197         (plus (plus (match_operand 1 "index_register_operand" "l")
6198                     (match_operand 2 "register_operand" "r"))
6199               (match_operand 3 "immediate_operand" "i")))]
6200   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6201    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6202    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6203    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6204    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6205        || GET_MODE (operands[3]) == VOIDmode)"
6206   "#"
6207   "&& reload_completed"
6208   [(const_int 0)]
6210   enum machine_mode mode = SImode;
6211   rtx pat;
6213   operands[0] = gen_lowpart (mode, operands[0]);
6214   operands[1] = gen_lowpart (mode, operands[1]);
6215   operands[2] = gen_lowpart (mode, operands[2]);
6216   operands[3] = gen_lowpart (mode, operands[3]);
6218   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6219                       operands[3]);
6221   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6222   DONE;
6224   [(set_attr "type" "lea")
6225    (set_attr "mode" "SI")])
6227 (define_insn_and_split "*lea_general_2"
6228   [(set (match_operand 0 "register_operand" "=r")
6229         (plus (mult (match_operand 1 "index_register_operand" "l")
6230                     (match_operand 2 "const248_operand" "n"))
6231               (match_operand 3 "nonmemory_operand" "ri")))]
6232   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6233    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6234    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6235    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6236        || GET_MODE (operands[3]) == VOIDmode)"
6237   "#"
6238   "&& reload_completed"
6239   [(const_int 0)]
6241   enum machine_mode mode = SImode;
6242   rtx pat;
6244   operands[0] = gen_lowpart (mode, operands[0]);
6245   operands[1] = gen_lowpart (mode, operands[1]);
6246   operands[3] = gen_lowpart (mode, operands[3]);
6248   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6249                       operands[3]);
6251   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6252   DONE;
6254   [(set_attr "type" "lea")
6255    (set_attr "mode" "SI")])
6257 (define_insn_and_split "*lea_general_3"
6258   [(set (match_operand 0 "register_operand" "=r")
6259         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6260                           (match_operand 2 "const248_operand" "n"))
6261                     (match_operand 3 "register_operand" "r"))
6262               (match_operand 4 "immediate_operand" "i")))]
6263   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6264    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6265    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6266    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6267   "#"
6268   "&& reload_completed"
6269   [(const_int 0)]
6271   enum machine_mode mode = SImode;
6272   rtx pat;
6274   operands[0] = gen_lowpart (mode, operands[0]);
6275   operands[1] = gen_lowpart (mode, operands[1]);
6276   operands[3] = gen_lowpart (mode, operands[3]);
6277   operands[4] = gen_lowpart (mode, operands[4]);
6279   pat = gen_rtx_PLUS (mode,
6280                       gen_rtx_PLUS (mode,
6281                                     gen_rtx_MULT (mode, operands[1],
6282                                                         operands[2]),
6283                                     operands[3]),
6284                       operands[4]);
6286   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6287   DONE;
6289   [(set_attr "type" "lea")
6290    (set_attr "mode" "SI")])
6292 (define_insn_and_split "*lea_general_4"
6293   [(set (match_operand 0 "register_operand" "=r")
6294         (any_or (ashift
6295                   (match_operand 1 "index_register_operand" "l")
6296                   (match_operand 2 "const_int_operand" "n"))
6297                 (match_operand 3 "const_int_operand" "n")))]
6298   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6299       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6300     || GET_MODE (operands[0]) == SImode
6301     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6302    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6303    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6304    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6305        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6306   "#"
6307   "&& reload_completed"
6308   [(const_int 0)]
6310   enum machine_mode mode = GET_MODE (operands[0]);
6311   rtx pat;
6313   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6314     { 
6315       mode = SImode; 
6316       operands[0] = gen_lowpart (mode, operands[0]);
6317       operands[1] = gen_lowpart (mode, operands[1]);
6318     }
6320   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6322   pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6323                        INTVAL (operands[3]));
6325   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6326   DONE;
6328   [(set_attr "type" "lea")
6329    (set (attr "mode")
6330       (if_then_else (match_operand:DI 0)
6331         (const_string "DI")
6332         (const_string "SI")))])
6334 ;; Subtract instructions
6336 (define_expand "sub<mode>3"
6337   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6338         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6339                      (match_operand:SDWIM 2 "<general_operand>")))]
6340   ""
6341   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6343 (define_insn_and_split "*sub<dwi>3_doubleword"
6344   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6345         (minus:<DWI>
6346           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6347           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6348    (clobber (reg:CC FLAGS_REG))]
6349   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6350   "#"
6351   "reload_completed"
6352   [(parallel [(set (reg:CC FLAGS_REG)
6353                    (compare:CC (match_dup 1) (match_dup 2)))
6354               (set (match_dup 0)
6355                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6356    (parallel [(set (match_dup 3)
6357                    (minus:DWIH
6358                      (match_dup 4)
6359                      (plus:DWIH
6360                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6361                        (match_dup 5))))
6362               (clobber (reg:CC FLAGS_REG))])]
6363   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6365 (define_insn "*sub<mode>_1"
6366   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6367         (minus:SWI
6368           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6369           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6370    (clobber (reg:CC FLAGS_REG))]
6371   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6372   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6373   [(set_attr "type" "alu")
6374    (set_attr "mode" "<MODE>")])
6376 (define_insn "*subsi_1_zext"
6377   [(set (match_operand:DI 0 "register_operand" "=r")
6378         (zero_extend:DI
6379           (minus:SI (match_operand:SI 1 "register_operand" "0")
6380                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6381    (clobber (reg:CC FLAGS_REG))]
6382   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6383   "sub{l}\t{%2, %k0|%k0, %2}"
6384   [(set_attr "type" "alu")
6385    (set_attr "mode" "SI")])
6387 (define_insn "*subqi_1_slp"
6388   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6389         (minus:QI (match_dup 0)
6390                   (match_operand:QI 1 "general_operand" "qn,qm")))
6391    (clobber (reg:CC FLAGS_REG))]
6392   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6393    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6394   "sub{b}\t{%1, %0|%0, %1}"
6395   [(set_attr "type" "alu1")
6396    (set_attr "mode" "QI")])
6398 (define_insn "*sub<mode>_2"
6399   [(set (reg FLAGS_REG)
6400         (compare
6401           (minus:SWI
6402             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6403             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6404           (const_int 0)))
6405    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6406         (minus:SWI (match_dup 1) (match_dup 2)))]
6407   "ix86_match_ccmode (insn, CCGOCmode)
6408    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6409   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6410   [(set_attr "type" "alu")
6411    (set_attr "mode" "<MODE>")])
6413 (define_insn "*subsi_2_zext"
6414   [(set (reg FLAGS_REG)
6415         (compare
6416           (minus:SI (match_operand:SI 1 "register_operand" "0")
6417                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6418           (const_int 0)))
6419    (set (match_operand:DI 0 "register_operand" "=r")
6420         (zero_extend:DI
6421           (minus:SI (match_dup 1)
6422                     (match_dup 2))))]
6423   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6424    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6425   "sub{l}\t{%2, %k0|%k0, %2}"
6426   [(set_attr "type" "alu")
6427    (set_attr "mode" "SI")])
6429 (define_insn "*sub<mode>_3"
6430   [(set (reg FLAGS_REG)
6431         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6432                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6433    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6434         (minus:SWI (match_dup 1) (match_dup 2)))]
6435   "ix86_match_ccmode (insn, CCmode)
6436    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6437   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6438   [(set_attr "type" "alu")
6439    (set_attr "mode" "<MODE>")])
6441 (define_insn "*subsi_3_zext"
6442   [(set (reg FLAGS_REG)
6443         (compare (match_operand:SI 1 "register_operand" "0")
6444                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6445    (set (match_operand:DI 0 "register_operand" "=r")
6446         (zero_extend:DI
6447           (minus:SI (match_dup 1)
6448                     (match_dup 2))))]
6449   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6450    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6451   "sub{l}\t{%2, %1|%1, %2}"
6452   [(set_attr "type" "alu")
6453    (set_attr "mode" "SI")])
6455 ;; Add with carry and subtract with borrow
6457 (define_expand "<plusminus_insn><mode>3_carry"
6458   [(parallel
6459     [(set (match_operand:SWI 0 "nonimmediate_operand")
6460           (plusminus:SWI
6461             (match_operand:SWI 1 "nonimmediate_operand")
6462             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6463                        [(match_operand 3 "flags_reg_operand")
6464                         (const_int 0)])
6465                       (match_operand:SWI 2 "<general_operand>"))))
6466      (clobber (reg:CC FLAGS_REG))])]
6467   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6469 (define_insn "*<plusminus_insn><mode>3_carry"
6470   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6471         (plusminus:SWI
6472           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6473           (plus:SWI
6474             (match_operator 3 "ix86_carry_flag_operator"
6475              [(reg FLAGS_REG) (const_int 0)])
6476             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6477    (clobber (reg:CC FLAGS_REG))]
6478   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6479   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6480   [(set_attr "type" "alu")
6481    (set_attr "use_carry" "1")
6482    (set_attr "pent_pair" "pu")
6483    (set_attr "mode" "<MODE>")])
6485 (define_insn "*addsi3_carry_zext"
6486   [(set (match_operand:DI 0 "register_operand" "=r")
6487         (zero_extend:DI
6488           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6489                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6490                              [(reg FLAGS_REG) (const_int 0)])
6491                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6492    (clobber (reg:CC FLAGS_REG))]
6493   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6494   "adc{l}\t{%2, %k0|%k0, %2}"
6495   [(set_attr "type" "alu")
6496    (set_attr "use_carry" "1")
6497    (set_attr "pent_pair" "pu")
6498    (set_attr "mode" "SI")])
6500 (define_insn "*subsi3_carry_zext"
6501   [(set (match_operand:DI 0 "register_operand" "=r")
6502         (zero_extend:DI
6503           (minus:SI (match_operand:SI 1 "register_operand" "0")
6504                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6505                               [(reg FLAGS_REG) (const_int 0)])
6506                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6507    (clobber (reg:CC FLAGS_REG))]
6508   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6509   "sbb{l}\t{%2, %k0|%k0, %2}"
6510   [(set_attr "type" "alu")
6511    (set_attr "pent_pair" "pu")
6512    (set_attr "mode" "SI")])
6514 ;; ADCX instruction
6516 (define_insn "adcx<mode>3"
6517   [(set (reg:CCC FLAGS_REG)
6518         (compare:CCC
6519           (plus:SWI48
6520             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6521             (plus:SWI48
6522               (match_operator 4 "ix86_carry_flag_operator"
6523                [(match_operand 3 "flags_reg_operand") (const_int 0)])
6524               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6525           (const_int 0)))
6526    (set (match_operand:SWI48 0 "register_operand" "=r")
6527         (plus:SWI48 (match_dup 1)
6528                     (plus:SWI48 (match_op_dup 4
6529                                  [(match_dup 3) (const_int 0)])
6530                                 (match_dup 2))))]
6531   "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6532   "adcx\t{%2, %0|%0, %2}"
6533   [(set_attr "type" "alu")
6534    (set_attr "use_carry" "1")
6535    (set_attr "mode" "<MODE>")])
6537 ;; Overflow setting add instructions
6539 (define_insn "*add<mode>3_cconly_overflow"
6540   [(set (reg:CCC FLAGS_REG)
6541         (compare:CCC
6542           (plus:SWI
6543             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6544             (match_operand:SWI 2 "<general_operand>" "<g>"))
6545           (match_dup 1)))
6546    (clobber (match_scratch:SWI 0 "=<r>"))]
6547   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6548   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6549   [(set_attr "type" "alu")
6550    (set_attr "mode" "<MODE>")])
6552 (define_insn "*add<mode>3_cc_overflow"
6553   [(set (reg:CCC FLAGS_REG)
6554         (compare:CCC
6555             (plus:SWI
6556                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6557                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6558             (match_dup 1)))
6559    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6560         (plus:SWI (match_dup 1) (match_dup 2)))]
6561   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6562   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6563   [(set_attr "type" "alu")
6564    (set_attr "mode" "<MODE>")])
6566 (define_insn "*addsi3_zext_cc_overflow"
6567   [(set (reg:CCC FLAGS_REG)
6568         (compare:CCC
6569           (plus:SI
6570             (match_operand:SI 1 "nonimmediate_operand" "%0")
6571             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6572           (match_dup 1)))
6573    (set (match_operand:DI 0 "register_operand" "=r")
6574         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6575   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6576   "add{l}\t{%2, %k0|%k0, %2}"
6577   [(set_attr "type" "alu")
6578    (set_attr "mode" "SI")])
6580 ;; The patterns that match these are at the end of this file.
6582 (define_expand "<plusminus_insn>xf3"
6583   [(set (match_operand:XF 0 "register_operand")
6584         (plusminus:XF
6585           (match_operand:XF 1 "register_operand")
6586           (match_operand:XF 2 "register_operand")))]
6587   "TARGET_80387")
6589 (define_expand "<plusminus_insn><mode>3"
6590   [(set (match_operand:MODEF 0 "register_operand")
6591         (plusminus:MODEF
6592           (match_operand:MODEF 1 "register_operand")
6593           (match_operand:MODEF 2 "nonimmediate_operand")))]
6594   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6595     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6597 ;; Multiply instructions
6599 (define_expand "mul<mode>3"
6600   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6601                    (mult:SWIM248
6602                      (match_operand:SWIM248 1 "register_operand")
6603                      (match_operand:SWIM248 2 "<general_operand>")))
6604               (clobber (reg:CC FLAGS_REG))])])
6606 (define_expand "mulqi3"
6607   [(parallel [(set (match_operand:QI 0 "register_operand")
6608                    (mult:QI
6609                      (match_operand:QI 1 "register_operand")
6610                      (match_operand:QI 2 "nonimmediate_operand")))
6611               (clobber (reg:CC FLAGS_REG))])]
6612   "TARGET_QIMODE_MATH")
6614 ;; On AMDFAM10
6615 ;; IMUL reg32/64, reg32/64, imm8        Direct
6616 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6617 ;; IMUL reg32/64, reg32/64, imm32       Direct
6618 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6619 ;; IMUL reg32/64, reg32/64              Direct
6620 ;; IMUL reg32/64, mem32/64              Direct
6622 ;; On BDVER1, all above IMULs use DirectPath
6624 (define_insn "*mul<mode>3_1"
6625   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6626         (mult:SWI48
6627           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6628           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6629    (clobber (reg:CC FLAGS_REG))]
6630   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6631   "@
6632    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6633    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6634    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6635   [(set_attr "type" "imul")
6636    (set_attr "prefix_0f" "0,0,1")
6637    (set (attr "athlon_decode")
6638         (cond [(eq_attr "cpu" "athlon")
6639                   (const_string "vector")
6640                (eq_attr "alternative" "1")
6641                   (const_string "vector")
6642                (and (eq_attr "alternative" "2")
6643                     (match_operand 1 "memory_operand"))
6644                   (const_string "vector")]
6645               (const_string "direct")))
6646    (set (attr "amdfam10_decode")
6647         (cond [(and (eq_attr "alternative" "0,1")
6648                     (match_operand 1 "memory_operand"))
6649                   (const_string "vector")]
6650               (const_string "direct")))
6651    (set_attr "bdver1_decode" "direct")
6652    (set_attr "mode" "<MODE>")])
6654 (define_insn "*mulsi3_1_zext"
6655   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6656         (zero_extend:DI
6657           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6658                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6659    (clobber (reg:CC FLAGS_REG))]
6660   "TARGET_64BIT
6661    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6662   "@
6663    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6664    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6665    imul{l}\t{%2, %k0|%k0, %2}"
6666   [(set_attr "type" "imul")
6667    (set_attr "prefix_0f" "0,0,1")
6668    (set (attr "athlon_decode")
6669         (cond [(eq_attr "cpu" "athlon")
6670                   (const_string "vector")
6671                (eq_attr "alternative" "1")
6672                   (const_string "vector")
6673                (and (eq_attr "alternative" "2")
6674                     (match_operand 1 "memory_operand"))
6675                   (const_string "vector")]
6676               (const_string "direct")))
6677    (set (attr "amdfam10_decode")
6678         (cond [(and (eq_attr "alternative" "0,1")
6679                     (match_operand 1 "memory_operand"))
6680                   (const_string "vector")]
6681               (const_string "direct")))
6682    (set_attr "bdver1_decode" "direct")
6683    (set_attr "mode" "SI")])
6685 ;; On AMDFAM10
6686 ;; IMUL reg16, reg16, imm8      VectorPath
6687 ;; IMUL reg16, mem16, imm8      VectorPath
6688 ;; IMUL reg16, reg16, imm16     VectorPath
6689 ;; IMUL reg16, mem16, imm16     VectorPath
6690 ;; IMUL reg16, reg16            Direct
6691 ;; IMUL reg16, mem16            Direct
6693 ;; On BDVER1, all HI MULs use DoublePath
6695 (define_insn "*mulhi3_1"
6696   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6697         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6698                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6699    (clobber (reg:CC FLAGS_REG))]
6700   "TARGET_HIMODE_MATH
6701    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6702   "@
6703    imul{w}\t{%2, %1, %0|%0, %1, %2}
6704    imul{w}\t{%2, %1, %0|%0, %1, %2}
6705    imul{w}\t{%2, %0|%0, %2}"
6706   [(set_attr "type" "imul")
6707    (set_attr "prefix_0f" "0,0,1")
6708    (set (attr "athlon_decode")
6709         (cond [(eq_attr "cpu" "athlon")
6710                   (const_string "vector")
6711                (eq_attr "alternative" "1,2")
6712                   (const_string "vector")]
6713               (const_string "direct")))
6714    (set (attr "amdfam10_decode")
6715         (cond [(eq_attr "alternative" "0,1")
6716                   (const_string "vector")]
6717               (const_string "direct")))
6718    (set_attr "bdver1_decode" "double")
6719    (set_attr "mode" "HI")])
6721 ;;On AMDFAM10 and BDVER1
6722 ;; MUL reg8     Direct
6723 ;; MUL mem8     Direct
6725 (define_insn "*mulqi3_1"
6726   [(set (match_operand:QI 0 "register_operand" "=a")
6727         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6728                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6729    (clobber (reg:CC FLAGS_REG))]
6730   "TARGET_QIMODE_MATH
6731    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6732   "mul{b}\t%2"
6733   [(set_attr "type" "imul")
6734    (set_attr "length_immediate" "0")
6735    (set (attr "athlon_decode")
6736      (if_then_else (eq_attr "cpu" "athlon")
6737         (const_string "vector")
6738         (const_string "direct")))
6739    (set_attr "amdfam10_decode" "direct")
6740    (set_attr "bdver1_decode" "direct")
6741    (set_attr "mode" "QI")])
6743 (define_expand "<u>mul<mode><dwi>3"
6744   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6745                    (mult:<DWI>
6746                      (any_extend:<DWI>
6747                        (match_operand:DWIH 1 "nonimmediate_operand"))
6748                      (any_extend:<DWI>
6749                        (match_operand:DWIH 2 "register_operand"))))
6750               (clobber (reg:CC FLAGS_REG))])])
6752 (define_expand "<u>mulqihi3"
6753   [(parallel [(set (match_operand:HI 0 "register_operand")
6754                    (mult:HI
6755                      (any_extend:HI
6756                        (match_operand:QI 1 "nonimmediate_operand"))
6757                      (any_extend:HI
6758                        (match_operand:QI 2 "register_operand"))))
6759               (clobber (reg:CC FLAGS_REG))])]
6760   "TARGET_QIMODE_MATH")
6762 (define_insn "*bmi2_umulditi3_1"
6763   [(set (match_operand:DI 0 "register_operand" "=r")
6764         (mult:DI
6765           (match_operand:DI 2 "nonimmediate_operand" "%d")
6766           (match_operand:DI 3 "nonimmediate_operand" "rm")))
6767    (set (match_operand:DI 1 "register_operand" "=r")
6768         (truncate:DI
6769           (lshiftrt:TI
6770             (mult:TI (zero_extend:TI (match_dup 2))
6771                      (zero_extend:TI (match_dup 3)))
6772             (const_int 64))))]
6773   "TARGET_64BIT && TARGET_BMI2
6774    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6775   "mulx\t{%3, %0, %1|%1, %0, %3}"
6776   [(set_attr "type" "imulx")
6777    (set_attr "prefix" "vex")
6778    (set_attr "mode" "DI")])
6780 (define_insn "*bmi2_umulsidi3_1"
6781   [(set (match_operand:SI 0 "register_operand" "=r")
6782         (mult:SI
6783           (match_operand:SI 2 "nonimmediate_operand" "%d")
6784           (match_operand:SI 3 "nonimmediate_operand" "rm")))
6785    (set (match_operand:SI 1 "register_operand" "=r")
6786         (truncate:SI
6787           (lshiftrt:DI
6788             (mult:DI (zero_extend:DI (match_dup 2))
6789                      (zero_extend:DI (match_dup 3)))
6790             (const_int 32))))]
6791   "!TARGET_64BIT && TARGET_BMI2
6792    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6793   "mulx\t{%3, %0, %1|%1, %0, %3}"
6794   [(set_attr "type" "imulx")
6795    (set_attr "prefix" "vex")
6796    (set_attr "mode" "SI")])
6798 (define_insn "*umul<mode><dwi>3_1"
6799   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6800         (mult:<DWI>
6801           (zero_extend:<DWI>
6802             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6803           (zero_extend:<DWI>
6804             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6805    (clobber (reg:CC FLAGS_REG))]
6806   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6807   "@
6808    #
6809    mul{<imodesuffix>}\t%2"
6810   [(set_attr "isa" "bmi2,*")
6811    (set_attr "type" "imulx,imul")
6812    (set_attr "length_immediate" "*,0")
6813    (set (attr "athlon_decode")
6814         (cond [(eq_attr "alternative" "1")
6815                  (if_then_else (eq_attr "cpu" "athlon")
6816                    (const_string "vector")
6817                    (const_string "double"))]
6818               (const_string "*")))
6819    (set_attr "amdfam10_decode" "*,double")
6820    (set_attr "bdver1_decode" "*,direct")
6821    (set_attr "prefix" "vex,orig")
6822    (set_attr "mode" "<MODE>")])
6824 ;; Convert mul to the mulx pattern to avoid flags dependency.
6825 (define_split
6826  [(set (match_operand:<DWI> 0 "register_operand")
6827        (mult:<DWI>
6828          (zero_extend:<DWI>
6829            (match_operand:DWIH 1 "register_operand"))
6830          (zero_extend:<DWI>
6831            (match_operand:DWIH 2 "nonimmediate_operand"))))
6832   (clobber (reg:CC FLAGS_REG))]
6833  "TARGET_BMI2 && reload_completed
6834   && true_regnum (operands[1]) == DX_REG"
6835   [(parallel [(set (match_dup 3)
6836                    (mult:DWIH (match_dup 1) (match_dup 2)))
6837               (set (match_dup 4)
6838                    (truncate:DWIH
6839                      (lshiftrt:<DWI>
6840                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6841                                    (zero_extend:<DWI> (match_dup 2)))
6842                        (match_dup 5))))])]
6844   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6846   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6849 (define_insn "*mul<mode><dwi>3_1"
6850   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6851         (mult:<DWI>
6852           (sign_extend:<DWI>
6853             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6854           (sign_extend:<DWI>
6855             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6856    (clobber (reg:CC FLAGS_REG))]
6857   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6858   "imul{<imodesuffix>}\t%2"
6859   [(set_attr "type" "imul")
6860    (set_attr "length_immediate" "0")
6861    (set (attr "athlon_decode")
6862      (if_then_else (eq_attr "cpu" "athlon")
6863         (const_string "vector")
6864         (const_string "double")))
6865    (set_attr "amdfam10_decode" "double")
6866    (set_attr "bdver1_decode" "direct")
6867    (set_attr "mode" "<MODE>")])
6869 (define_insn "*<u>mulqihi3_1"
6870   [(set (match_operand:HI 0 "register_operand" "=a")
6871         (mult:HI
6872           (any_extend:HI
6873             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6874           (any_extend:HI
6875             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6876    (clobber (reg:CC FLAGS_REG))]
6877   "TARGET_QIMODE_MATH
6878    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6879   "<sgnprefix>mul{b}\t%2"
6880   [(set_attr "type" "imul")
6881    (set_attr "length_immediate" "0")
6882    (set (attr "athlon_decode")
6883      (if_then_else (eq_attr "cpu" "athlon")
6884         (const_string "vector")
6885         (const_string "direct")))
6886    (set_attr "amdfam10_decode" "direct")
6887    (set_attr "bdver1_decode" "direct")
6888    (set_attr "mode" "QI")])
6890 (define_expand "<s>mul<mode>3_highpart"
6891   [(parallel [(set (match_operand:SWI48 0 "register_operand")
6892                    (truncate:SWI48
6893                      (lshiftrt:<DWI>
6894                        (mult:<DWI>
6895                          (any_extend:<DWI>
6896                            (match_operand:SWI48 1 "nonimmediate_operand"))
6897                          (any_extend:<DWI>
6898                            (match_operand:SWI48 2 "register_operand")))
6899                        (match_dup 4))))
6900               (clobber (match_scratch:SWI48 3))
6901               (clobber (reg:CC FLAGS_REG))])]
6902   ""
6903   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6905 (define_insn "*<s>muldi3_highpart_1"
6906   [(set (match_operand:DI 0 "register_operand" "=d")
6907         (truncate:DI
6908           (lshiftrt:TI
6909             (mult:TI
6910               (any_extend:TI
6911                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6912               (any_extend:TI
6913                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6914             (const_int 64))))
6915    (clobber (match_scratch:DI 3 "=1"))
6916    (clobber (reg:CC FLAGS_REG))]
6917   "TARGET_64BIT
6918    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6919   "<sgnprefix>mul{q}\t%2"
6920   [(set_attr "type" "imul")
6921    (set_attr "length_immediate" "0")
6922    (set (attr "athlon_decode")
6923      (if_then_else (eq_attr "cpu" "athlon")
6924         (const_string "vector")
6925         (const_string "double")))
6926    (set_attr "amdfam10_decode" "double")
6927    (set_attr "bdver1_decode" "direct")
6928    (set_attr "mode" "DI")])
6930 (define_insn "*<s>mulsi3_highpart_1"
6931   [(set (match_operand:SI 0 "register_operand" "=d")
6932         (truncate:SI
6933           (lshiftrt:DI
6934             (mult:DI
6935               (any_extend:DI
6936                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6937               (any_extend:DI
6938                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6939             (const_int 32))))
6940    (clobber (match_scratch:SI 3 "=1"))
6941    (clobber (reg:CC FLAGS_REG))]
6942   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6943   "<sgnprefix>mul{l}\t%2"
6944   [(set_attr "type" "imul")
6945    (set_attr "length_immediate" "0")
6946    (set (attr "athlon_decode")
6947      (if_then_else (eq_attr "cpu" "athlon")
6948         (const_string "vector")
6949         (const_string "double")))
6950    (set_attr "amdfam10_decode" "double")
6951    (set_attr "bdver1_decode" "direct")
6952    (set_attr "mode" "SI")])
6954 (define_insn "*<s>mulsi3_highpart_zext"
6955   [(set (match_operand:DI 0 "register_operand" "=d")
6956         (zero_extend:DI (truncate:SI
6957           (lshiftrt:DI
6958             (mult:DI (any_extend:DI
6959                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6960                      (any_extend:DI
6961                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6962             (const_int 32)))))
6963    (clobber (match_scratch:SI 3 "=1"))
6964    (clobber (reg:CC FLAGS_REG))]
6965   "TARGET_64BIT
6966    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6967   "<sgnprefix>mul{l}\t%2"
6968   [(set_attr "type" "imul")
6969    (set_attr "length_immediate" "0")
6970    (set (attr "athlon_decode")
6971      (if_then_else (eq_attr "cpu" "athlon")
6972         (const_string "vector")
6973         (const_string "double")))
6974    (set_attr "amdfam10_decode" "double")
6975    (set_attr "bdver1_decode" "direct")
6976    (set_attr "mode" "SI")])
6978 ;; The patterns that match these are at the end of this file.
6980 (define_expand "mulxf3"
6981   [(set (match_operand:XF 0 "register_operand")
6982         (mult:XF (match_operand:XF 1 "register_operand")
6983                  (match_operand:XF 2 "register_operand")))]
6984   "TARGET_80387")
6986 (define_expand "mul<mode>3"
6987   [(set (match_operand:MODEF 0 "register_operand")
6988         (mult:MODEF (match_operand:MODEF 1 "register_operand")
6989                     (match_operand:MODEF 2 "nonimmediate_operand")))]
6990   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6991     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6993 ;; Divide instructions
6995 ;; The patterns that match these are at the end of this file.
6997 (define_expand "divxf3"
6998   [(set (match_operand:XF 0 "register_operand")
6999         (div:XF (match_operand:XF 1 "register_operand")
7000                 (match_operand:XF 2 "register_operand")))]
7001   "TARGET_80387")
7003 (define_expand "divdf3"
7004   [(set (match_operand:DF 0 "register_operand")
7005         (div:DF (match_operand:DF 1 "register_operand")
7006                 (match_operand:DF 2 "nonimmediate_operand")))]
7007    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7008     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7010 (define_expand "divsf3"
7011   [(set (match_operand:SF 0 "register_operand")
7012         (div:SF (match_operand:SF 1 "register_operand")
7013                 (match_operand:SF 2 "nonimmediate_operand")))]
7014   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7015     || TARGET_SSE_MATH"
7017   if (TARGET_SSE_MATH
7018       && TARGET_RECIP_DIV
7019       && optimize_insn_for_speed_p ()
7020       && flag_finite_math_only && !flag_trapping_math
7021       && flag_unsafe_math_optimizations)
7022     {
7023       ix86_emit_swdivsf (operands[0], operands[1],
7024                          operands[2], SFmode);
7025       DONE;
7026     }
7029 ;; Divmod instructions.
7031 (define_expand "divmod<mode>4"
7032   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7033                    (div:SWIM248
7034                      (match_operand:SWIM248 1 "register_operand")
7035                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7036               (set (match_operand:SWIM248 3 "register_operand")
7037                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7038               (clobber (reg:CC FLAGS_REG))])])
7040 ;; Split with 8bit unsigned divide:
7041 ;;      if (dividend an divisor are in [0-255])
7042 ;;         use 8bit unsigned integer divide
7043 ;;       else
7044 ;;         use original integer divide
7045 (define_split
7046   [(set (match_operand:SWI48 0 "register_operand")
7047         (div:SWI48 (match_operand:SWI48 2 "register_operand")
7048                     (match_operand:SWI48 3 "nonimmediate_operand")))
7049    (set (match_operand:SWI48 1 "register_operand")
7050         (mod:SWI48 (match_dup 2) (match_dup 3)))
7051    (clobber (reg:CC FLAGS_REG))]
7052   "TARGET_USE_8BIT_IDIV
7053    && TARGET_QIMODE_MATH
7054    && can_create_pseudo_p ()
7055    && !optimize_insn_for_size_p ()"
7056   [(const_int 0)]
7057   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7059 (define_insn_and_split "divmod<mode>4_1"
7060   [(set (match_operand:SWI48 0 "register_operand" "=a")
7061         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7062                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7063    (set (match_operand:SWI48 1 "register_operand" "=&d")
7064         (mod:SWI48 (match_dup 2) (match_dup 3)))
7065    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7066    (clobber (reg:CC FLAGS_REG))]
7067   ""
7068   "#"
7069   "reload_completed"
7070   [(parallel [(set (match_dup 1)
7071                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7072               (clobber (reg:CC FLAGS_REG))])
7073    (parallel [(set (match_dup 0)
7074                    (div:SWI48 (match_dup 2) (match_dup 3)))
7075               (set (match_dup 1)
7076                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7077               (use (match_dup 1))
7078               (clobber (reg:CC FLAGS_REG))])]
7080   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7082   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7083     operands[4] = operands[2];
7084   else
7085     {
7086       /* Avoid use of cltd in favor of a mov+shift.  */
7087       emit_move_insn (operands[1], operands[2]);
7088       operands[4] = operands[1];
7089     }
7091   [(set_attr "type" "multi")
7092    (set_attr "mode" "<MODE>")])
7094 (define_insn_and_split "*divmod<mode>4"
7095   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7096         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7097                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7098    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7099         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7100    (clobber (reg:CC FLAGS_REG))]
7101   ""
7102   "#"
7103   "reload_completed"
7104   [(parallel [(set (match_dup 1)
7105                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7106               (clobber (reg:CC FLAGS_REG))])
7107    (parallel [(set (match_dup 0)
7108                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7109               (set (match_dup 1)
7110                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7111               (use (match_dup 1))
7112               (clobber (reg:CC FLAGS_REG))])]
7114   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7116   if (<MODE>mode != HImode
7117       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7118     operands[4] = operands[2];
7119   else
7120     {
7121       /* Avoid use of cltd in favor of a mov+shift.  */
7122       emit_move_insn (operands[1], operands[2]);
7123       operands[4] = operands[1];
7124     }
7126   [(set_attr "type" "multi")
7127    (set_attr "mode" "<MODE>")])
7129 (define_insn "*divmod<mode>4_noext"
7130   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7131         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7132                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7133    (set (match_operand:SWIM248 1 "register_operand" "=d")
7134         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7135    (use (match_operand:SWIM248 4 "register_operand" "1"))
7136    (clobber (reg:CC FLAGS_REG))]
7137   ""
7138   "idiv{<imodesuffix>}\t%3"
7139   [(set_attr "type" "idiv")
7140    (set_attr "mode" "<MODE>")])
7142 (define_expand "divmodqi4"
7143   [(parallel [(set (match_operand:QI 0 "register_operand")
7144                    (div:QI
7145                      (match_operand:QI 1 "register_operand")
7146                      (match_operand:QI 2 "nonimmediate_operand")))
7147               (set (match_operand:QI 3 "register_operand")
7148                    (mod:QI (match_dup 1) (match_dup 2)))
7149               (clobber (reg:CC FLAGS_REG))])]
7150   "TARGET_QIMODE_MATH"
7152   rtx div, mod, insn;
7153   rtx tmp0, tmp1;
7154   
7155   tmp0 = gen_reg_rtx (HImode);
7156   tmp1 = gen_reg_rtx (HImode);
7158   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7159      in AX.  */
7160   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7161   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7163   /* Extract remainder from AH.  */
7164   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7165   insn = emit_move_insn (operands[3], tmp1);
7167   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7168   set_unique_reg_note (insn, REG_EQUAL, mod);
7170   /* Extract quotient from AL.  */
7171   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7173   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7174   set_unique_reg_note (insn, REG_EQUAL, div);
7176   DONE;
7179 ;; Divide AX by r/m8, with result stored in
7180 ;; AL <- Quotient
7181 ;; AH <- Remainder
7182 ;; Change div/mod to HImode and extend the second argument to HImode
7183 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7184 ;; combine may fail.
7185 (define_insn "divmodhiqi3"
7186   [(set (match_operand:HI 0 "register_operand" "=a")
7187         (ior:HI
7188           (ashift:HI
7189             (zero_extend:HI
7190               (truncate:QI
7191                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7192                         (sign_extend:HI
7193                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7194             (const_int 8))
7195           (zero_extend:HI
7196             (truncate:QI
7197               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7198    (clobber (reg:CC FLAGS_REG))]
7199   "TARGET_QIMODE_MATH"
7200   "idiv{b}\t%2"
7201   [(set_attr "type" "idiv")
7202    (set_attr "mode" "QI")])
7204 (define_expand "udivmod<mode>4"
7205   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7206                    (udiv:SWIM248
7207                      (match_operand:SWIM248 1 "register_operand")
7208                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7209               (set (match_operand:SWIM248 3 "register_operand")
7210                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7211               (clobber (reg:CC FLAGS_REG))])])
7213 ;; Split with 8bit unsigned divide:
7214 ;;      if (dividend an divisor are in [0-255])
7215 ;;         use 8bit unsigned integer divide
7216 ;;       else
7217 ;;         use original integer divide
7218 (define_split
7219   [(set (match_operand:SWI48 0 "register_operand")
7220         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7221                     (match_operand:SWI48 3 "nonimmediate_operand")))
7222    (set (match_operand:SWI48 1 "register_operand")
7223         (umod:SWI48 (match_dup 2) (match_dup 3)))
7224    (clobber (reg:CC FLAGS_REG))]
7225   "TARGET_USE_8BIT_IDIV
7226    && TARGET_QIMODE_MATH
7227    && can_create_pseudo_p ()
7228    && !optimize_insn_for_size_p ()"
7229   [(const_int 0)]
7230   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7232 (define_insn_and_split "udivmod<mode>4_1"
7233   [(set (match_operand:SWI48 0 "register_operand" "=a")
7234         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7235                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7236    (set (match_operand:SWI48 1 "register_operand" "=&d")
7237         (umod:SWI48 (match_dup 2) (match_dup 3)))
7238    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7239    (clobber (reg:CC FLAGS_REG))]
7240   ""
7241   "#"
7242   "reload_completed"
7243   [(set (match_dup 1) (const_int 0))
7244    (parallel [(set (match_dup 0)
7245                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7246               (set (match_dup 1)
7247                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7248               (use (match_dup 1))
7249               (clobber (reg:CC FLAGS_REG))])]
7250   ""
7251   [(set_attr "type" "multi")
7252    (set_attr "mode" "<MODE>")])
7254 (define_insn_and_split "*udivmod<mode>4"
7255   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7256         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7257                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7258    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7259         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7260    (clobber (reg:CC FLAGS_REG))]
7261   ""
7262   "#"
7263   "reload_completed"
7264   [(set (match_dup 1) (const_int 0))
7265    (parallel [(set (match_dup 0)
7266                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7267               (set (match_dup 1)
7268                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7269               (use (match_dup 1))
7270               (clobber (reg:CC FLAGS_REG))])]
7271   ""
7272   [(set_attr "type" "multi")
7273    (set_attr "mode" "<MODE>")])
7275 (define_insn "*udivmod<mode>4_noext"
7276   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7277         (udiv: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         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7281    (use (match_operand:SWIM248 4 "register_operand" "1"))
7282    (clobber (reg:CC FLAGS_REG))]
7283   ""
7284   "div{<imodesuffix>}\t%3"
7285   [(set_attr "type" "idiv")
7286    (set_attr "mode" "<MODE>")])
7288 (define_expand "udivmodqi4"
7289   [(parallel [(set (match_operand:QI 0 "register_operand")
7290                    (udiv:QI
7291                      (match_operand:QI 1 "register_operand")
7292                      (match_operand:QI 2 "nonimmediate_operand")))
7293               (set (match_operand:QI 3 "register_operand")
7294                    (umod:QI (match_dup 1) (match_dup 2)))
7295               (clobber (reg:CC FLAGS_REG))])]
7296   "TARGET_QIMODE_MATH"
7298   rtx div, mod, insn;
7299   rtx tmp0, tmp1;
7300   
7301   tmp0 = gen_reg_rtx (HImode);
7302   tmp1 = gen_reg_rtx (HImode);
7304   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7305      in AX.  */
7306   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7307   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7309   /* Extract remainder from AH.  */
7310   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7311   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7312   insn = emit_move_insn (operands[3], tmp1);
7314   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7315   set_unique_reg_note (insn, REG_EQUAL, mod);
7317   /* Extract quotient from AL.  */
7318   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7320   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7321   set_unique_reg_note (insn, REG_EQUAL, div);
7323   DONE;
7326 (define_insn "udivmodhiqi3"
7327   [(set (match_operand:HI 0 "register_operand" "=a")
7328         (ior:HI
7329           (ashift:HI
7330             (zero_extend:HI
7331               (truncate:QI
7332                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7333                         (zero_extend:HI
7334                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7335             (const_int 8))
7336           (zero_extend:HI
7337             (truncate:QI
7338               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7339    (clobber (reg:CC FLAGS_REG))]
7340   "TARGET_QIMODE_MATH"
7341   "div{b}\t%2"
7342   [(set_attr "type" "idiv")
7343    (set_attr "mode" "QI")])
7345 ;; We cannot use div/idiv for double division, because it causes
7346 ;; "division by zero" on the overflow and that's not what we expect
7347 ;; from truncate.  Because true (non truncating) double division is
7348 ;; never generated, we can't create this insn anyway.
7350 ;(define_insn ""
7351 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7352 ;       (truncate:SI
7353 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7354 ;                  (zero_extend:DI
7355 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7356 ;   (set (match_operand:SI 3 "register_operand" "=d")
7357 ;       (truncate:SI
7358 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7359 ;   (clobber (reg:CC FLAGS_REG))]
7360 ;  ""
7361 ;  "div{l}\t{%2, %0|%0, %2}"
7362 ;  [(set_attr "type" "idiv")])
7364 ;;- Logical AND instructions
7366 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7367 ;; Note that this excludes ah.
7369 (define_expand "testsi_ccno_1"
7370   [(set (reg:CCNO FLAGS_REG)
7371         (compare:CCNO
7372           (and:SI (match_operand:SI 0 "nonimmediate_operand")
7373                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
7374           (const_int 0)))])
7376 (define_expand "testqi_ccz_1"
7377   [(set (reg:CCZ FLAGS_REG)
7378         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7379                              (match_operand:QI 1 "nonmemory_operand"))
7380                  (const_int 0)))])
7382 (define_expand "testdi_ccno_1"
7383   [(set (reg:CCNO FLAGS_REG)
7384         (compare:CCNO
7385           (and:DI (match_operand:DI 0 "nonimmediate_operand")
7386                   (match_operand:DI 1 "x86_64_szext_general_operand"))
7387           (const_int 0)))]
7388   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7390 (define_insn "*testdi_1"
7391   [(set (reg FLAGS_REG)
7392         (compare
7393          (and:DI
7394           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7395           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7396          (const_int 0)))]
7397   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7398    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7399   "@
7400    test{l}\t{%k1, %k0|%k0, %k1}
7401    test{l}\t{%k1, %k0|%k0, %k1}
7402    test{q}\t{%1, %0|%0, %1}
7403    test{q}\t{%1, %0|%0, %1}
7404    test{q}\t{%1, %0|%0, %1}"
7405   [(set_attr "type" "test")
7406    (set_attr "modrm" "0,1,0,1,1")
7407    (set_attr "mode" "SI,SI,DI,DI,DI")])
7409 (define_insn "*testqi_1_maybe_si"
7410   [(set (reg FLAGS_REG)
7411         (compare
7412           (and:QI
7413             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7414             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7415           (const_int 0)))]
7416    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7417     && ix86_match_ccmode (insn,
7418                          CONST_INT_P (operands[1])
7419                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7421   if (which_alternative == 3)
7422     {
7423       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7424         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7425       return "test{l}\t{%1, %k0|%k0, %1}";
7426     }
7427   return "test{b}\t{%1, %0|%0, %1}";
7429   [(set_attr "type" "test")
7430    (set_attr "modrm" "0,1,1,1")
7431    (set_attr "mode" "QI,QI,QI,SI")
7432    (set_attr "pent_pair" "uv,np,uv,np")])
7434 (define_insn "*test<mode>_1"
7435   [(set (reg FLAGS_REG)
7436         (compare
7437          (and:SWI124
7438           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7439           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7440          (const_int 0)))]
7441   "ix86_match_ccmode (insn, CCNOmode)
7442    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7443   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7444   [(set_attr "type" "test")
7445    (set_attr "modrm" "0,1,1")
7446    (set_attr "mode" "<MODE>")
7447    (set_attr "pent_pair" "uv,np,uv")])
7449 (define_expand "testqi_ext_ccno_0"
7450   [(set (reg:CCNO FLAGS_REG)
7451         (compare:CCNO
7452           (and:SI
7453             (zero_extract:SI
7454               (match_operand 0 "ext_register_operand")
7455               (const_int 8)
7456               (const_int 8))
7457             (match_operand 1 "const_int_operand"))
7458           (const_int 0)))])
7460 (define_insn "*testqi_ext_0"
7461   [(set (reg FLAGS_REG)
7462         (compare
7463           (and:SI
7464             (zero_extract:SI
7465               (match_operand 0 "ext_register_operand" "Q")
7466               (const_int 8)
7467               (const_int 8))
7468             (match_operand 1 "const_int_operand" "n"))
7469           (const_int 0)))]
7470   "ix86_match_ccmode (insn, CCNOmode)"
7471   "test{b}\t{%1, %h0|%h0, %1}"
7472   [(set_attr "type" "test")
7473    (set_attr "mode" "QI")
7474    (set_attr "length_immediate" "1")
7475    (set_attr "modrm" "1")
7476    (set_attr "pent_pair" "np")])
7478 (define_insn "*testqi_ext_1"
7479   [(set (reg FLAGS_REG)
7480         (compare
7481           (and:SI
7482             (zero_extract:SI
7483               (match_operand 0 "ext_register_operand" "Q,Q")
7484               (const_int 8)
7485               (const_int 8))
7486             (zero_extend:SI
7487               (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7488           (const_int 0)))]
7489   "ix86_match_ccmode (insn, CCNOmode)"
7490   "test{b}\t{%1, %h0|%h0, %1}"
7491   [(set_attr "isa" "*,nox64")
7492    (set_attr "type" "test")
7493    (set_attr "mode" "QI")])
7495 (define_insn "*testqi_ext_2"
7496   [(set (reg FLAGS_REG)
7497         (compare
7498           (and:SI
7499             (zero_extract:SI
7500               (match_operand 0 "ext_register_operand" "Q")
7501               (const_int 8)
7502               (const_int 8))
7503             (zero_extract:SI
7504               (match_operand 1 "ext_register_operand" "Q")
7505               (const_int 8)
7506               (const_int 8)))
7507           (const_int 0)))]
7508   "ix86_match_ccmode (insn, CCNOmode)"
7509   "test{b}\t{%h1, %h0|%h0, %h1}"
7510   [(set_attr "type" "test")
7511    (set_attr "mode" "QI")])
7513 ;; Combine likes to form bit extractions for some tests.  Humor it.
7514 (define_insn "*testqi_ext_3"
7515   [(set (reg FLAGS_REG)
7516         (compare (zero_extract:SWI48
7517                    (match_operand 0 "nonimmediate_operand" "rm")
7518                    (match_operand:SWI48 1 "const_int_operand")
7519                    (match_operand:SWI48 2 "const_int_operand"))
7520                  (const_int 0)))]
7521   "ix86_match_ccmode (insn, CCNOmode)
7522    && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7523        || GET_MODE (operands[0]) == SImode
7524        || GET_MODE (operands[0]) == HImode
7525        || GET_MODE (operands[0]) == QImode)
7526    /* Ensure that resulting mask is zero or sign extended operand.  */
7527    && INTVAL (operands[2]) >= 0
7528    && ((INTVAL (operands[1]) > 0
7529         && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7530        || (<MODE>mode == DImode
7531            && INTVAL (operands[1]) > 32
7532            && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7533   "#")
7535 (define_split
7536   [(set (match_operand 0 "flags_reg_operand")
7537         (match_operator 1 "compare_operator"
7538           [(zero_extract
7539              (match_operand 2 "nonimmediate_operand")
7540              (match_operand 3 "const_int_operand")
7541              (match_operand 4 "const_int_operand"))
7542            (const_int 0)]))]
7543   "ix86_match_ccmode (insn, CCNOmode)"
7544   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7546   rtx val = operands[2];
7547   HOST_WIDE_INT len = INTVAL (operands[3]);
7548   HOST_WIDE_INT pos = INTVAL (operands[4]);
7549   HOST_WIDE_INT mask;
7550   enum machine_mode mode, submode;
7552   mode = GET_MODE (val);
7553   if (MEM_P (val))
7554     {
7555       /* ??? Combine likes to put non-volatile mem extractions in QImode
7556          no matter the size of the test.  So find a mode that works.  */
7557       if (! MEM_VOLATILE_P (val))
7558         {
7559           mode = smallest_mode_for_size (pos + len, MODE_INT);
7560           val = adjust_address (val, mode, 0);
7561         }
7562     }
7563   else if (GET_CODE (val) == SUBREG
7564            && (submode = GET_MODE (SUBREG_REG (val)),
7565                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7566            && pos + len <= GET_MODE_BITSIZE (submode)
7567            && GET_MODE_CLASS (submode) == MODE_INT)
7568     {
7569       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7570       mode = submode;
7571       val = SUBREG_REG (val);
7572     }
7573   else if (mode == HImode && pos + len <= 8)
7574     {
7575       /* Small HImode tests can be converted to QImode.  */
7576       mode = QImode;
7577       val = gen_lowpart (QImode, val);
7578     }
7580   if (len == HOST_BITS_PER_WIDE_INT)
7581     mask = -1;
7582   else
7583     mask = ((HOST_WIDE_INT)1 << len) - 1;
7584   mask <<= pos;
7586   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7589 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7590 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7591 ;; this is relatively important trick.
7592 ;; Do the conversion only post-reload to avoid limiting of the register class
7593 ;; to QI regs.
7594 (define_split
7595   [(set (match_operand 0 "flags_reg_operand")
7596         (match_operator 1 "compare_operator"
7597           [(and (match_operand 2 "register_operand")
7598                 (match_operand 3 "const_int_operand"))
7599            (const_int 0)]))]
7600    "reload_completed
7601     && QI_REG_P (operands[2])
7602     && GET_MODE (operands[2]) != QImode
7603     && ((ix86_match_ccmode (insn, CCZmode)
7604          && !(INTVAL (operands[3]) & ~(255 << 8)))
7605         || (ix86_match_ccmode (insn, CCNOmode)
7606             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7607   [(set (match_dup 0)
7608         (match_op_dup 1
7609           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7610                    (match_dup 3))
7611            (const_int 0)]))]
7613   operands[2] = gen_lowpart (SImode, operands[2]);
7614   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7617 (define_split
7618   [(set (match_operand 0 "flags_reg_operand")
7619         (match_operator 1 "compare_operator"
7620           [(and (match_operand 2 "nonimmediate_operand")
7621                 (match_operand 3 "const_int_operand"))
7622            (const_int 0)]))]
7623    "reload_completed
7624     && GET_MODE (operands[2]) != QImode
7625     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7626     && ((ix86_match_ccmode (insn, CCZmode)
7627          && !(INTVAL (operands[3]) & ~255))
7628         || (ix86_match_ccmode (insn, CCNOmode)
7629             && !(INTVAL (operands[3]) & ~127)))"
7630   [(set (match_dup 0)
7631         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7632                          (const_int 0)]))]
7634   operands[2] = gen_lowpart (QImode, operands[2]);
7635   operands[3] = gen_lowpart (QImode, operands[3]);
7638 (define_split
7639   [(set (match_operand:SWI12 0 "mask_reg_operand")
7640         (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand")
7641                          (match_operand:SWI12 2 "mask_reg_operand")))
7642    (clobber (reg:CC FLAGS_REG))]
7643   "TARGET_AVX512F && reload_completed"
7644   [(set (match_dup 0)
7645         (any_logic:SWI12 (match_dup 1)
7646                          (match_dup 2)))])
7648 (define_insn "*k<logic><mode>"
7649   [(set (match_operand:SWI12 0 "mask_reg_operand" "=Yk")
7650         (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand" "Yk")
7651                          (match_operand:SWI12 2 "mask_reg_operand" "Yk")))]
7652   "TARGET_AVX512F"
7653   "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7654   [(set_attr "mode" "<MODE>")
7655    (set_attr "type" "msklog")
7656    (set_attr "prefix" "vex")])
7658 ;; %%% This used to optimize known byte-wide and operations to memory,
7659 ;; and sometimes to QImode registers.  If this is considered useful,
7660 ;; it should be done with splitters.
7662 (define_expand "and<mode>3"
7663   [(set (match_operand:SWIM 0 "nonimmediate_operand")
7664         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7665                   (match_operand:SWIM 2 "<general_szext_operand>")))]
7666   ""
7668   enum machine_mode mode = <MODE>mode;
7669   rtx (*insn) (rtx, rtx);
7671   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7672     {
7673       HOST_WIDE_INT ival = INTVAL (operands[2]);
7675       if (ival == (HOST_WIDE_INT) 0xffffffff)
7676         mode = SImode;
7677       else if (ival == 0xffff)
7678         mode = HImode;
7679       else if (ival == 0xff)
7680         mode = QImode;
7681       }
7683   if (mode == <MODE>mode)
7684     {
7685       ix86_expand_binary_operator (AND, <MODE>mode, operands);
7686       DONE;
7687     }
7689   if (<MODE>mode == DImode)
7690     insn = (mode == SImode)
7691            ? gen_zero_extendsidi2
7692            : (mode == HImode)
7693            ? gen_zero_extendhidi2
7694            : gen_zero_extendqidi2;
7695   else if (<MODE>mode == SImode)
7696     insn = (mode == HImode)
7697            ? gen_zero_extendhisi2
7698            : gen_zero_extendqisi2;
7699   else if (<MODE>mode == HImode)
7700     insn = gen_zero_extendqihi2;
7701   else
7702     gcc_unreachable ();
7704   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7705   DONE;
7708 (define_insn "*anddi_1"
7709   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7710         (and:DI
7711          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7712          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7713    (clobber (reg:CC FLAGS_REG))]
7714   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7716   switch (get_attr_type (insn))
7717     {
7718     case TYPE_IMOVX:
7719       return "#";
7721     default:
7722       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7723       if (get_attr_mode (insn) == MODE_SI)
7724         return "and{l}\t{%k2, %k0|%k0, %k2}";
7725       else
7726         return "and{q}\t{%2, %0|%0, %2}";
7727     }
7729   [(set_attr "type" "alu,alu,alu,imovx")
7730    (set_attr "length_immediate" "*,*,*,0")
7731    (set (attr "prefix_rex")
7732      (if_then_else
7733        (and (eq_attr "type" "imovx")
7734             (and (match_test "INTVAL (operands[2]) == 0xff")
7735                  (match_operand 1 "ext_QIreg_operand")))
7736        (const_string "1")
7737        (const_string "*")))
7738    (set_attr "mode" "SI,DI,DI,SI")])
7740 (define_insn "*andsi_1"
7741   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7742         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7743                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7744    (clobber (reg:CC FLAGS_REG))]
7745   "ix86_binary_operator_ok (AND, SImode, operands)"
7747   switch (get_attr_type (insn))
7748     {
7749     case TYPE_IMOVX:
7750       return "#";
7752     default:
7753       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7754       return "and{l}\t{%2, %0|%0, %2}";
7755     }
7757   [(set_attr "type" "alu,alu,imovx")
7758    (set (attr "prefix_rex")
7759      (if_then_else
7760        (and (eq_attr "type" "imovx")
7761             (and (match_test "INTVAL (operands[2]) == 0xff")
7762                  (match_operand 1 "ext_QIreg_operand")))
7763        (const_string "1")
7764        (const_string "*")))
7765    (set_attr "length_immediate" "*,*,0")
7766    (set_attr "mode" "SI")])
7768 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7769 (define_insn "*andsi_1_zext"
7770   [(set (match_operand:DI 0 "register_operand" "=r")
7771         (zero_extend:DI
7772           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7773                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7774    (clobber (reg:CC FLAGS_REG))]
7775   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7776   "and{l}\t{%2, %k0|%k0, %2}"
7777   [(set_attr "type" "alu")
7778    (set_attr "mode" "SI")])
7780 (define_insn "*andhi_1"
7781   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!Yk")
7782         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,Yk")
7783                 (match_operand:HI 2 "general_operand" "rn,rm,L,Yk")))
7784    (clobber (reg:CC FLAGS_REG))]
7785   "ix86_binary_operator_ok (AND, HImode, operands)"
7787   switch (get_attr_type (insn))
7788     {
7789     case TYPE_IMOVX:
7790       return "#";
7792     case TYPE_MSKLOG:
7793       return "kandw\t{%2, %1, %0|%0, %1, %2}";
7795     default:
7796       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7797       return "and{w}\t{%2, %0|%0, %2}";
7798     }
7800   [(set_attr "type" "alu,alu,imovx,msklog")
7801    (set_attr "length_immediate" "*,*,0,*")
7802    (set (attr "prefix_rex")
7803      (if_then_else
7804        (and (eq_attr "type" "imovx")
7805             (match_operand 1 "ext_QIreg_operand"))
7806        (const_string "1")
7807        (const_string "*")))
7808    (set_attr "mode" "HI,HI,SI,HI")])
7810 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7811 (define_insn "*andqi_1"
7812   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!Yk")
7813         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,Yk")
7814                 (match_operand:QI 2 "general_operand" "qn,qmn,rn,Yk")))
7815    (clobber (reg:CC FLAGS_REG))]
7816   "ix86_binary_operator_ok (AND, QImode, operands)"
7817   "@
7818    and{b}\t{%2, %0|%0, %2}
7819    and{b}\t{%2, %0|%0, %2}
7820    and{l}\t{%k2, %k0|%k0, %k2}
7821    kandw\t{%2, %1, %0|%0, %1, %2}"
7822   [(set_attr "type" "alu,alu,alu,msklog")
7823    (set_attr "mode" "QI,QI,SI,HI")])
7825 (define_insn "*andqi_1_slp"
7826   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7827         (and:QI (match_dup 0)
7828                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7829    (clobber (reg:CC FLAGS_REG))]
7830   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7831    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7832   "and{b}\t{%1, %0|%0, %1}"
7833   [(set_attr "type" "alu1")
7834    (set_attr "mode" "QI")])
7836 (define_insn "kandn<mode>"
7837   [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!Yk")
7838         (and:SWI12
7839           (not:SWI12
7840             (match_operand:SWI12 1 "register_operand" "r,0,Yk"))
7841           (match_operand:SWI12 2 "register_operand" "r,r,Yk")))
7842    (clobber (reg:CC FLAGS_REG))]
7843   "TARGET_AVX512F"
7844   "@
7845    andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
7846    #
7847    kandnw\t{%2, %1, %0|%0, %1, %2}"
7848   [(set_attr "isa" "bmi,*,avx512f")
7849    (set_attr "type" "bitmanip,*,msklog")
7850    (set_attr "prefix" "*,*,vex")
7851    (set_attr "btver2_decode" "direct,*,*")
7852    (set_attr "mode" "<MODE>")])
7854 (define_split
7855   [(set (match_operand:SWI12 0 "general_reg_operand")
7856         (and:SWI12
7857           (not:SWI12
7858             (match_dup 0))
7859           (match_operand:SWI12 1 "general_reg_operand")))
7860    (clobber (reg:CC FLAGS_REG))]
7861   "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7862   [(set (match_dup 0)
7863         (not:HI (match_dup 0)))
7864    (parallel [(set (match_dup 0)
7865                    (and:HI (match_dup 0)
7866                            (match_dup 1)))
7867               (clobber (reg:CC FLAGS_REG))])])
7869 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7870 (define_split
7871   [(set (match_operand:DI 0 "register_operand")
7872         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7873                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7874    (clobber (reg:CC FLAGS_REG))]
7875   "TARGET_64BIT"
7876   [(parallel [(set (match_dup 0)
7877                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7878               (clobber (reg:CC FLAGS_REG))])]
7879   "operands[2] = gen_lowpart (SImode, operands[2]);")
7881 (define_split
7882   [(set (match_operand:SWI248 0 "register_operand")
7883         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7884                     (match_operand:SWI248 2 "const_int_operand")))
7885    (clobber (reg:CC FLAGS_REG))]
7886   "reload_completed
7887    && true_regnum (operands[0]) != true_regnum (operands[1])"
7888   [(const_int 0)]
7890   HOST_WIDE_INT ival = INTVAL (operands[2]);
7891   enum machine_mode mode;
7892   rtx (*insn) (rtx, rtx);
7894   if (ival == (HOST_WIDE_INT) 0xffffffff)
7895     mode = SImode;
7896   else if (ival == 0xffff)
7897     mode = HImode;
7898   else
7899     {
7900       gcc_assert (ival == 0xff);
7901       mode = QImode;
7902     }
7904   if (<MODE>mode == DImode)
7905     insn = (mode == SImode)
7906            ? gen_zero_extendsidi2
7907            : (mode == HImode)
7908            ? gen_zero_extendhidi2
7909            : gen_zero_extendqidi2;
7910   else
7911     {
7912       if (<MODE>mode != SImode)
7913         /* Zero extend to SImode to avoid partial register stalls.  */
7914         operands[0] = gen_lowpart (SImode, operands[0]);
7916       insn = (mode == HImode)
7917              ? gen_zero_extendhisi2
7918              : gen_zero_extendqisi2;
7919     }
7920   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7921   DONE;
7924 (define_split
7925   [(set (match_operand 0 "register_operand")
7926         (and (match_dup 0)
7927              (const_int -65536)))
7928    (clobber (reg:CC FLAGS_REG))]
7929   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7930     || optimize_function_for_size_p (cfun)"
7931   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7932   "operands[1] = gen_lowpart (HImode, operands[0]);")
7934 (define_split
7935   [(set (match_operand 0 "ext_register_operand")
7936         (and (match_dup 0)
7937              (const_int -256)))
7938    (clobber (reg:CC FLAGS_REG))]
7939   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7940    && reload_completed"
7941   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7942   "operands[1] = gen_lowpart (QImode, operands[0]);")
7944 (define_split
7945   [(set (match_operand 0 "ext_register_operand")
7946         (and (match_dup 0)
7947              (const_int -65281)))
7948    (clobber (reg:CC FLAGS_REG))]
7949   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7950    && reload_completed"
7951   [(parallel [(set (zero_extract:SI (match_dup 0)
7952                                     (const_int 8)
7953                                     (const_int 8))
7954                    (xor:SI
7955                      (zero_extract:SI (match_dup 0)
7956                                       (const_int 8)
7957                                       (const_int 8))
7958                      (zero_extract:SI (match_dup 0)
7959                                       (const_int 8)
7960                                       (const_int 8))))
7961               (clobber (reg:CC FLAGS_REG))])]
7962   "operands[0] = gen_lowpart (SImode, operands[0]);")
7964 (define_insn "*anddi_2"
7965   [(set (reg FLAGS_REG)
7966         (compare
7967          (and:DI
7968           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7969           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7970          (const_int 0)))
7971    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7972         (and:DI (match_dup 1) (match_dup 2)))]
7973   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7974    && ix86_binary_operator_ok (AND, DImode, operands)"
7975   "@
7976    and{l}\t{%k2, %k0|%k0, %k2}
7977    and{q}\t{%2, %0|%0, %2}
7978    and{q}\t{%2, %0|%0, %2}"
7979   [(set_attr "type" "alu")
7980    (set_attr "mode" "SI,DI,DI")])
7982 (define_insn "*andqi_2_maybe_si"
7983   [(set (reg FLAGS_REG)
7984         (compare (and:QI
7985                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7986                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7987                  (const_int 0)))
7988    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7989         (and:QI (match_dup 1) (match_dup 2)))]
7990   "ix86_binary_operator_ok (AND, QImode, operands)
7991    && ix86_match_ccmode (insn,
7992                          CONST_INT_P (operands[2])
7993                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7995   if (which_alternative == 2)
7996     {
7997       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7998         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7999       return "and{l}\t{%2, %k0|%k0, %2}";
8000     }
8001   return "and{b}\t{%2, %0|%0, %2}";
8003   [(set_attr "type" "alu")
8004    (set_attr "mode" "QI,QI,SI")])
8006 (define_insn "*and<mode>_2"
8007   [(set (reg FLAGS_REG)
8008         (compare (and:SWI124
8009                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8010                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8011                  (const_int 0)))
8012    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8013         (and:SWI124 (match_dup 1) (match_dup 2)))]
8014   "ix86_match_ccmode (insn, CCNOmode)
8015    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8016   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8017   [(set_attr "type" "alu")
8018    (set_attr "mode" "<MODE>")])
8020 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8021 (define_insn "*andsi_2_zext"
8022   [(set (reg FLAGS_REG)
8023         (compare (and:SI
8024                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8025                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
8026                  (const_int 0)))
8027    (set (match_operand:DI 0 "register_operand" "=r")
8028         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8029   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8030    && ix86_binary_operator_ok (AND, SImode, operands)"
8031   "and{l}\t{%2, %k0|%k0, %2}"
8032   [(set_attr "type" "alu")
8033    (set_attr "mode" "SI")])
8035 (define_insn "*andqi_2_slp"
8036   [(set (reg FLAGS_REG)
8037         (compare (and:QI
8038                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8039                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8040                  (const_int 0)))
8041    (set (strict_low_part (match_dup 0))
8042         (and:QI (match_dup 0) (match_dup 1)))]
8043   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8044    && ix86_match_ccmode (insn, CCNOmode)
8045    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8046   "and{b}\t{%1, %0|%0, %1}"
8047   [(set_attr "type" "alu1")
8048    (set_attr "mode" "QI")])
8050 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8051 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8052 ;; for a QImode operand, which of course failed.
8053 (define_insn "andqi_ext_0"
8054   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8055                          (const_int 8)
8056                          (const_int 8))
8057         (and:SI
8058           (zero_extract:SI
8059             (match_operand 1 "ext_register_operand" "0")
8060             (const_int 8)
8061             (const_int 8))
8062           (match_operand 2 "const_int_operand" "n")))
8063    (clobber (reg:CC FLAGS_REG))]
8064   ""
8065   "and{b}\t{%2, %h0|%h0, %2}"
8066   [(set_attr "type" "alu")
8067    (set_attr "length_immediate" "1")
8068    (set_attr "modrm" "1")
8069    (set_attr "mode" "QI")])
8071 ;; Generated by peephole translating test to and.  This shows up
8072 ;; often in fp comparisons.
8073 (define_insn "*andqi_ext_0_cc"
8074   [(set (reg FLAGS_REG)
8075         (compare
8076           (and:SI
8077             (zero_extract:SI
8078               (match_operand 1 "ext_register_operand" "0")
8079               (const_int 8)
8080               (const_int 8))
8081             (match_operand 2 "const_int_operand" "n"))
8082           (const_int 0)))
8083    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8084                          (const_int 8)
8085                          (const_int 8))
8086         (and:SI
8087           (zero_extract:SI
8088             (match_dup 1)
8089             (const_int 8)
8090             (const_int 8))
8091           (match_dup 2)))]
8092   "ix86_match_ccmode (insn, CCNOmode)"
8093   "and{b}\t{%2, %h0|%h0, %2}"
8094   [(set_attr "type" "alu")
8095    (set_attr "length_immediate" "1")
8096    (set_attr "modrm" "1")
8097    (set_attr "mode" "QI")])
8099 (define_insn "*andqi_ext_1"
8100   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8101                          (const_int 8)
8102                          (const_int 8))
8103         (and:SI
8104           (zero_extract:SI
8105             (match_operand 1 "ext_register_operand" "0,0")
8106             (const_int 8)
8107             (const_int 8))
8108           (zero_extend:SI
8109             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8110    (clobber (reg:CC FLAGS_REG))]
8111   ""
8112   "and{b}\t{%2, %h0|%h0, %2}"
8113   [(set_attr "isa" "*,nox64")
8114    (set_attr "type" "alu")
8115    (set_attr "length_immediate" "0")
8116    (set_attr "mode" "QI")])
8118 (define_insn "*andqi_ext_2"
8119   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8120                          (const_int 8)
8121                          (const_int 8))
8122         (and:SI
8123           (zero_extract:SI
8124             (match_operand 1 "ext_register_operand" "%0")
8125             (const_int 8)
8126             (const_int 8))
8127           (zero_extract:SI
8128             (match_operand 2 "ext_register_operand" "Q")
8129             (const_int 8)
8130             (const_int 8))))
8131    (clobber (reg:CC FLAGS_REG))]
8132   ""
8133   "and{b}\t{%h2, %h0|%h0, %h2}"
8134   [(set_attr "type" "alu")
8135    (set_attr "length_immediate" "0")
8136    (set_attr "mode" "QI")])
8138 ;; Convert wide AND instructions with immediate operand to shorter QImode
8139 ;; equivalents when possible.
8140 ;; Don't do the splitting with memory operands, since it introduces risk
8141 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8142 ;; for size, but that can (should?) be handled by generic code instead.
8143 (define_split
8144   [(set (match_operand 0 "register_operand")
8145         (and (match_operand 1 "register_operand")
8146              (match_operand 2 "const_int_operand")))
8147    (clobber (reg:CC FLAGS_REG))]
8148    "reload_completed
8149     && QI_REG_P (operands[0])
8150     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8151     && !(~INTVAL (operands[2]) & ~(255 << 8))
8152     && GET_MODE (operands[0]) != QImode"
8153   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8154                    (and:SI (zero_extract:SI (match_dup 1)
8155                                             (const_int 8) (const_int 8))
8156                            (match_dup 2)))
8157               (clobber (reg:CC FLAGS_REG))])]
8159   operands[0] = gen_lowpart (SImode, operands[0]);
8160   operands[1] = gen_lowpart (SImode, operands[1]);
8161   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8164 ;; Since AND can be encoded with sign extended immediate, this is only
8165 ;; profitable when 7th bit is not set.
8166 (define_split
8167   [(set (match_operand 0 "register_operand")
8168         (and (match_operand 1 "general_operand")
8169              (match_operand 2 "const_int_operand")))
8170    (clobber (reg:CC FLAGS_REG))]
8171    "reload_completed
8172     && ANY_QI_REG_P (operands[0])
8173     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8174     && !(~INTVAL (operands[2]) & ~255)
8175     && !(INTVAL (operands[2]) & 128)
8176     && GET_MODE (operands[0]) != QImode"
8177   [(parallel [(set (strict_low_part (match_dup 0))
8178                    (and:QI (match_dup 1)
8179                            (match_dup 2)))
8180               (clobber (reg:CC FLAGS_REG))])]
8182   operands[0] = gen_lowpart (QImode, operands[0]);
8183   operands[1] = gen_lowpart (QImode, operands[1]);
8184   operands[2] = gen_lowpart (QImode, operands[2]);
8187 ;; Logical inclusive and exclusive OR instructions
8189 ;; %%% This used to optimize known byte-wide and operations to memory.
8190 ;; If this is considered useful, it should be done with splitters.
8192 (define_expand "<code><mode>3"
8193   [(set (match_operand:SWIM 0 "nonimmediate_operand")
8194         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8195                      (match_operand:SWIM 2 "<general_operand>")))]
8196   ""
8197   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8199 (define_insn "*<code><mode>_1"
8200   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
8201         (any_or:SWI48
8202          (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
8203          (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>")))
8204    (clobber (reg:CC FLAGS_REG))]
8205   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8206   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8207   [(set_attr "type" "alu")
8208    (set_attr "mode" "<MODE>")])
8210 (define_insn "*<code>hi_1"
8211   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!Yk")
8212         (any_or:HI
8213          (match_operand:HI 1 "nonimmediate_operand" "%0,0,Yk")
8214          (match_operand:HI 2 "general_operand" "<g>,r<i>,Yk")))
8215    (clobber (reg:CC FLAGS_REG))]
8216   "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8217   "@
8218   <logic>{w}\t{%2, %0|%0, %2}
8219   <logic>{w}\t{%2, %0|%0, %2}
8220   k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8221   [(set_attr "type" "alu,alu,msklog")
8222    (set_attr "mode" "HI")])
8224 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8225 (define_insn "*<code>qi_1"
8226   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!Yk")
8227         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,Yk")
8228                    (match_operand:QI 2 "general_operand" "qmn,qn,rn,Yk")))
8229    (clobber (reg:CC FLAGS_REG))]
8230   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8231   "@
8232    <logic>{b}\t{%2, %0|%0, %2}
8233    <logic>{b}\t{%2, %0|%0, %2}
8234    <logic>{l}\t{%k2, %k0|%k0, %k2}
8235    k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8236   [(set_attr "type" "alu,alu,alu,msklog")
8237    (set_attr "mode" "QI,QI,SI,HI")])
8239 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8240 (define_insn "*<code>si_1_zext"
8241   [(set (match_operand:DI 0 "register_operand" "=r")
8242         (zero_extend:DI
8243          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8244                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8245    (clobber (reg:CC FLAGS_REG))]
8246   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8247   "<logic>{l}\t{%2, %k0|%k0, %2}"
8248   [(set_attr "type" "alu")
8249    (set_attr "mode" "SI")])
8251 (define_insn "*<code>si_1_zext_imm"
8252   [(set (match_operand:DI 0 "register_operand" "=r")
8253         (any_or:DI
8254          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8255          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8256    (clobber (reg:CC FLAGS_REG))]
8257   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8258   "<logic>{l}\t{%2, %k0|%k0, %2}"
8259   [(set_attr "type" "alu")
8260    (set_attr "mode" "SI")])
8262 (define_insn "*<code>qi_1_slp"
8263   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8264         (any_or:QI (match_dup 0)
8265                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8266    (clobber (reg:CC FLAGS_REG))]
8267   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8268    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8269   "<logic>{b}\t{%1, %0|%0, %1}"
8270   [(set_attr "type" "alu1")
8271    (set_attr "mode" "QI")])
8273 (define_insn "*<code><mode>_2"
8274   [(set (reg FLAGS_REG)
8275         (compare (any_or:SWI
8276                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8277                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8278                  (const_int 0)))
8279    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8280         (any_or:SWI (match_dup 1) (match_dup 2)))]
8281   "ix86_match_ccmode (insn, CCNOmode)
8282    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8283   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8284   [(set_attr "type" "alu")
8285    (set_attr "mode" "<MODE>")])
8287 (define_insn "kxnor<mode>"
8288   [(set (match_operand:SWI12 0 "register_operand" "=r,!Yk")
8289         (not:SWI12
8290           (xor:SWI12
8291             (match_operand:SWI12 1 "register_operand" "0,Yk")
8292             (match_operand:SWI12 2 "register_operand" "r,Yk"))))
8293    (clobber (reg:CC FLAGS_REG))]
8294   "TARGET_AVX512F"
8295   "@
8296    #
8297    kxnorw\t{%2, %1, %0|%0, %1, %2}"
8298   [(set_attr "type" "*,msklog")
8299    (set_attr "prefix" "*,vex")
8300    (set_attr "mode" "<MODE>")])
8302 (define_split
8303   [(set (match_operand:SWI12 0 "general_reg_operand")
8304         (not:SWI12
8305           (xor:SWI12
8306             (match_dup 0)
8307             (match_operand:SWI12 1 "general_reg_operand"))))
8308    (clobber (reg:CC FLAGS_REG))]
8309   "TARGET_AVX512F && reload_completed"
8310    [(parallel [(set (match_dup 0)
8311                     (xor:HI (match_dup 0)
8312                             (match_dup 1)))
8313                (clobber (reg:CC FLAGS_REG))])
8314     (set (match_dup 0)
8315          (not:HI (match_dup 0)))])
8317 (define_insn "kortestzhi"
8318   [(set (reg:CCZ FLAGS_REG)
8319         (compare:CCZ
8320           (ior:HI
8321             (match_operand:HI 0 "register_operand" "Yk")
8322             (match_operand:HI 1 "register_operand" "Yk"))
8323           (const_int 0)))]
8324   "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8325   "kortestw\t{%1, %0|%0, %1}"
8326   [(set_attr "mode" "HI")
8327    (set_attr "type" "msklog")
8328    (set_attr "prefix" "vex")])
8330 (define_insn "kortestchi"
8331   [(set (reg:CCC FLAGS_REG)
8332         (compare:CCC
8333           (ior:HI
8334             (match_operand:HI 0 "register_operand" "Yk")
8335             (match_operand:HI 1 "register_operand" "Yk"))
8336           (const_int -1)))]
8337   "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8338   "kortestw\t{%1, %0|%0, %1}"
8339   [(set_attr "mode" "HI")
8340    (set_attr "type" "msklog")
8341    (set_attr "prefix" "vex")])
8343 (define_insn "kunpckhi"
8344   [(set (match_operand:HI 0 "register_operand" "=Yk")
8345         (ior:HI
8346           (ashift:HI
8347             (match_operand:HI 1 "register_operand" "Yk")
8348             (const_int 8))
8349           (zero_extend:HI (match_operand:QI 2 "register_operand" "Yk"))))]
8350   "TARGET_AVX512F"
8351   "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8352   [(set_attr "mode" "HI")
8353    (set_attr "type" "msklog")
8354    (set_attr "prefix" "vex")])
8356 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8357 ;; ??? Special case for immediate operand is missing - it is tricky.
8358 (define_insn "*<code>si_2_zext"
8359   [(set (reg FLAGS_REG)
8360         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8361                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8362                  (const_int 0)))
8363    (set (match_operand:DI 0 "register_operand" "=r")
8364         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8365   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8366    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8367   "<logic>{l}\t{%2, %k0|%k0, %2}"
8368   [(set_attr "type" "alu")
8369    (set_attr "mode" "SI")])
8371 (define_insn "*<code>si_2_zext_imm"
8372   [(set (reg FLAGS_REG)
8373         (compare (any_or:SI
8374                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8375                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8376                  (const_int 0)))
8377    (set (match_operand:DI 0 "register_operand" "=r")
8378         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8379   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8380    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8381   "<logic>{l}\t{%2, %k0|%k0, %2}"
8382   [(set_attr "type" "alu")
8383    (set_attr "mode" "SI")])
8385 (define_insn "*<code>qi_2_slp"
8386   [(set (reg FLAGS_REG)
8387         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8388                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8389                  (const_int 0)))
8390    (set (strict_low_part (match_dup 0))
8391         (any_or:QI (match_dup 0) (match_dup 1)))]
8392   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8393    && ix86_match_ccmode (insn, CCNOmode)
8394    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8395   "<logic>{b}\t{%1, %0|%0, %1}"
8396   [(set_attr "type" "alu1")
8397    (set_attr "mode" "QI")])
8399 (define_insn "*<code><mode>_3"
8400   [(set (reg FLAGS_REG)
8401         (compare (any_or:SWI
8402                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8403                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8404                  (const_int 0)))
8405    (clobber (match_scratch:SWI 0 "=<r>"))]
8406   "ix86_match_ccmode (insn, CCNOmode)
8407    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8408   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8409   [(set_attr "type" "alu")
8410    (set_attr "mode" "<MODE>")])
8412 (define_insn "*<code>qi_ext_0"
8413   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8414                          (const_int 8)
8415                          (const_int 8))
8416         (any_or:SI
8417           (zero_extract:SI
8418             (match_operand 1 "ext_register_operand" "0")
8419             (const_int 8)
8420             (const_int 8))
8421           (match_operand 2 "const_int_operand" "n")))
8422    (clobber (reg:CC FLAGS_REG))]
8423   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8424   "<logic>{b}\t{%2, %h0|%h0, %2}"
8425   [(set_attr "type" "alu")
8426    (set_attr "length_immediate" "1")
8427    (set_attr "modrm" "1")
8428    (set_attr "mode" "QI")])
8430 (define_insn "*<code>qi_ext_1"
8431   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8432                          (const_int 8)
8433                          (const_int 8))
8434         (any_or:SI
8435           (zero_extract:SI
8436             (match_operand 1 "ext_register_operand" "0,0")
8437             (const_int 8)
8438             (const_int 8))
8439           (zero_extend:SI
8440             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8441    (clobber (reg:CC FLAGS_REG))]
8442   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8443   "<logic>{b}\t{%2, %h0|%h0, %2}"
8444   [(set_attr "isa" "*,nox64")
8445    (set_attr "type" "alu")
8446    (set_attr "length_immediate" "0")
8447    (set_attr "mode" "QI")])
8449 (define_insn "*<code>qi_ext_2"
8450   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8451                          (const_int 8)
8452                          (const_int 8))
8453         (any_or:SI
8454           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8455                            (const_int 8)
8456                            (const_int 8))
8457           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8458                            (const_int 8)
8459                            (const_int 8))))
8460    (clobber (reg:CC FLAGS_REG))]
8461   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8462   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8463   [(set_attr "type" "alu")
8464    (set_attr "length_immediate" "0")
8465    (set_attr "mode" "QI")])
8467 (define_split
8468   [(set (match_operand 0 "register_operand")
8469         (any_or (match_operand 1 "register_operand")
8470                 (match_operand 2 "const_int_operand")))
8471    (clobber (reg:CC FLAGS_REG))]
8472    "reload_completed
8473     && QI_REG_P (operands[0])
8474     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8475     && !(INTVAL (operands[2]) & ~(255 << 8))
8476     && GET_MODE (operands[0]) != QImode"
8477   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8478                    (any_or:SI (zero_extract:SI (match_dup 1)
8479                                                (const_int 8) (const_int 8))
8480                               (match_dup 2)))
8481               (clobber (reg:CC FLAGS_REG))])]
8483   operands[0] = gen_lowpart (SImode, operands[0]);
8484   operands[1] = gen_lowpart (SImode, operands[1]);
8485   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8488 ;; Since OR can be encoded with sign extended immediate, this is only
8489 ;; profitable when 7th bit is set.
8490 (define_split
8491   [(set (match_operand 0 "register_operand")
8492         (any_or (match_operand 1 "general_operand")
8493                 (match_operand 2 "const_int_operand")))
8494    (clobber (reg:CC FLAGS_REG))]
8495    "reload_completed
8496     && ANY_QI_REG_P (operands[0])
8497     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8498     && !(INTVAL (operands[2]) & ~255)
8499     && (INTVAL (operands[2]) & 128)
8500     && GET_MODE (operands[0]) != QImode"
8501   [(parallel [(set (strict_low_part (match_dup 0))
8502                    (any_or:QI (match_dup 1)
8503                               (match_dup 2)))
8504               (clobber (reg:CC FLAGS_REG))])]
8506   operands[0] = gen_lowpart (QImode, operands[0]);
8507   operands[1] = gen_lowpart (QImode, operands[1]);
8508   operands[2] = gen_lowpart (QImode, operands[2]);
8511 (define_expand "xorqi_cc_ext_1"
8512   [(parallel [
8513      (set (reg:CCNO FLAGS_REG)
8514           (compare:CCNO
8515             (xor:SI
8516               (zero_extract:SI
8517                 (match_operand 1 "ext_register_operand")
8518                 (const_int 8)
8519                 (const_int 8))
8520               (match_operand:QI 2 "const_int_operand"))
8521             (const_int 0)))
8522      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8523                            (const_int 8)
8524                            (const_int 8))
8525           (xor:SI
8526             (zero_extract:SI
8527              (match_dup 1)
8528              (const_int 8)
8529              (const_int 8))
8530             (match_dup 2)))])])
8532 (define_insn "*xorqi_cc_ext_1"
8533   [(set (reg FLAGS_REG)
8534         (compare
8535           (xor:SI
8536             (zero_extract:SI
8537               (match_operand 1 "ext_register_operand" "0,0")
8538               (const_int 8)
8539               (const_int 8))
8540             (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8541           (const_int 0)))
8542    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8543                          (const_int 8)
8544                          (const_int 8))
8545         (xor:SI
8546           (zero_extract:SI
8547            (match_dup 1)
8548            (const_int 8)
8549            (const_int 8))
8550           (match_dup 2)))]
8551   "ix86_match_ccmode (insn, CCNOmode)"
8552   "xor{b}\t{%2, %h0|%h0, %2}"
8553   [(set_attr "isa" "*,nox64")
8554    (set_attr "type" "alu")
8555    (set_attr "modrm" "1")
8556    (set_attr "mode" "QI")])
8558 ;; Negation instructions
8560 (define_expand "neg<mode>2"
8561   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8562         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8563   ""
8564   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8566 (define_insn_and_split "*neg<dwi>2_doubleword"
8567   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8568         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8569    (clobber (reg:CC FLAGS_REG))]
8570   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8571   "#"
8572   "reload_completed"
8573   [(parallel
8574     [(set (reg:CCZ FLAGS_REG)
8575           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8576      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8577    (parallel
8578     [(set (match_dup 2)
8579           (plus:DWIH (match_dup 3)
8580                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8581                                 (const_int 0))))
8582      (clobber (reg:CC FLAGS_REG))])
8583    (parallel
8584     [(set (match_dup 2)
8585           (neg:DWIH (match_dup 2)))
8586      (clobber (reg:CC FLAGS_REG))])]
8587   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8589 (define_insn "*neg<mode>2_1"
8590   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8591         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8592    (clobber (reg:CC FLAGS_REG))]
8593   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8594   "neg{<imodesuffix>}\t%0"
8595   [(set_attr "type" "negnot")
8596    (set_attr "mode" "<MODE>")])
8598 ;; Combine is quite creative about this pattern.
8599 (define_insn "*negsi2_1_zext"
8600   [(set (match_operand:DI 0 "register_operand" "=r")
8601         (lshiftrt:DI
8602           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8603                              (const_int 32)))
8604         (const_int 32)))
8605    (clobber (reg:CC FLAGS_REG))]
8606   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8607   "neg{l}\t%k0"
8608   [(set_attr "type" "negnot")
8609    (set_attr "mode" "SI")])
8611 ;; The problem with neg is that it does not perform (compare x 0),
8612 ;; it really performs (compare 0 x), which leaves us with the zero
8613 ;; flag being the only useful item.
8615 (define_insn "*neg<mode>2_cmpz"
8616   [(set (reg:CCZ FLAGS_REG)
8617         (compare:CCZ
8618           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8619                    (const_int 0)))
8620    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8621         (neg:SWI (match_dup 1)))]
8622   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8623   "neg{<imodesuffix>}\t%0"
8624   [(set_attr "type" "negnot")
8625    (set_attr "mode" "<MODE>")])
8627 (define_insn "*negsi2_cmpz_zext"
8628   [(set (reg:CCZ FLAGS_REG)
8629         (compare:CCZ
8630           (lshiftrt:DI
8631             (neg:DI (ashift:DI
8632                       (match_operand:DI 1 "register_operand" "0")
8633                       (const_int 32)))
8634             (const_int 32))
8635           (const_int 0)))
8636    (set (match_operand:DI 0 "register_operand" "=r")
8637         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8638                                         (const_int 32)))
8639                      (const_int 32)))]
8640   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8641   "neg{l}\t%k0"
8642   [(set_attr "type" "negnot")
8643    (set_attr "mode" "SI")])
8645 ;; Changing of sign for FP values is doable using integer unit too.
8647 (define_expand "<code><mode>2"
8648   [(set (match_operand:X87MODEF 0 "register_operand")
8649         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8650   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8651   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8653 (define_insn "*absneg<mode>2_mixed"
8654   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8655         (match_operator:MODEF 3 "absneg_operator"
8656           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8657    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8658    (clobber (reg:CC FLAGS_REG))]
8659   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8660   "#")
8662 (define_insn "*absneg<mode>2_sse"
8663   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8664         (match_operator:MODEF 3 "absneg_operator"
8665           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8666    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8667    (clobber (reg:CC FLAGS_REG))]
8668   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8669   "#")
8671 (define_insn "*absneg<mode>2_i387"
8672   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8673         (match_operator:X87MODEF 3 "absneg_operator"
8674           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8675    (use (match_operand 2))
8676    (clobber (reg:CC FLAGS_REG))]
8677   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8678   "#")
8680 (define_expand "<code>tf2"
8681   [(set (match_operand:TF 0 "register_operand")
8682         (absneg:TF (match_operand:TF 1 "register_operand")))]
8683   "TARGET_SSE"
8684   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8686 (define_insn "*absnegtf2_sse"
8687   [(set (match_operand:TF 0 "register_operand" "=x,x")
8688         (match_operator:TF 3 "absneg_operator"
8689           [(match_operand:TF 1 "register_operand" "0,x")]))
8690    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8691    (clobber (reg:CC FLAGS_REG))]
8692   "TARGET_SSE"
8693   "#")
8695 ;; Splitters for fp abs and neg.
8697 (define_split
8698   [(set (match_operand 0 "fp_register_operand")
8699         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8700    (use (match_operand 2))
8701    (clobber (reg:CC FLAGS_REG))]
8702   "reload_completed"
8703   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8705 (define_split
8706   [(set (match_operand 0 "register_operand")
8707         (match_operator 3 "absneg_operator"
8708           [(match_operand 1 "register_operand")]))
8709    (use (match_operand 2 "nonimmediate_operand"))
8710    (clobber (reg:CC FLAGS_REG))]
8711   "reload_completed && SSE_REG_P (operands[0])"
8712   [(set (match_dup 0) (match_dup 3))]
8714   enum machine_mode mode = GET_MODE (operands[0]);
8715   enum machine_mode vmode = GET_MODE (operands[2]);
8716   rtx tmp;
8718   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8719   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8720   if (operands_match_p (operands[0], operands[2]))
8721     {
8722       tmp = operands[1];
8723       operands[1] = operands[2];
8724       operands[2] = tmp;
8725     }
8726   if (GET_CODE (operands[3]) == ABS)
8727     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8728   else
8729     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8730   operands[3] = tmp;
8733 (define_split
8734   [(set (match_operand:SF 0 "register_operand")
8735         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8736    (use (match_operand:V4SF 2))
8737    (clobber (reg:CC FLAGS_REG))]
8738   "reload_completed"
8739   [(parallel [(set (match_dup 0) (match_dup 1))
8740               (clobber (reg:CC FLAGS_REG))])]
8742   rtx tmp;
8743   operands[0] = gen_lowpart (SImode, operands[0]);
8744   if (GET_CODE (operands[1]) == ABS)
8745     {
8746       tmp = gen_int_mode (0x7fffffff, SImode);
8747       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8748     }
8749   else
8750     {
8751       tmp = gen_int_mode (0x80000000, SImode);
8752       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8753     }
8754   operands[1] = tmp;
8757 (define_split
8758   [(set (match_operand:DF 0 "register_operand")
8759         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8760    (use (match_operand 2))
8761    (clobber (reg:CC FLAGS_REG))]
8762   "reload_completed"
8763   [(parallel [(set (match_dup 0) (match_dup 1))
8764               (clobber (reg:CC FLAGS_REG))])]
8766   rtx tmp;
8767   if (TARGET_64BIT)
8768     {
8769       tmp = gen_lowpart (DImode, operands[0]);
8770       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8771       operands[0] = tmp;
8773       if (GET_CODE (operands[1]) == ABS)
8774         tmp = const0_rtx;
8775       else
8776         tmp = gen_rtx_NOT (DImode, tmp);
8777     }
8778   else
8779     {
8780       operands[0] = gen_highpart (SImode, operands[0]);
8781       if (GET_CODE (operands[1]) == ABS)
8782         {
8783           tmp = gen_int_mode (0x7fffffff, SImode);
8784           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8785         }
8786       else
8787         {
8788           tmp = gen_int_mode (0x80000000, SImode);
8789           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8790         }
8791     }
8792   operands[1] = tmp;
8795 (define_split
8796   [(set (match_operand:XF 0 "register_operand")
8797         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8798    (use (match_operand 2))
8799    (clobber (reg:CC FLAGS_REG))]
8800   "reload_completed"
8801   [(parallel [(set (match_dup 0) (match_dup 1))
8802               (clobber (reg:CC FLAGS_REG))])]
8804   rtx tmp;
8805   operands[0] = gen_rtx_REG (SImode,
8806                              true_regnum (operands[0])
8807                              + (TARGET_64BIT ? 1 : 2));
8808   if (GET_CODE (operands[1]) == ABS)
8809     {
8810       tmp = GEN_INT (0x7fff);
8811       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8812     }
8813   else
8814     {
8815       tmp = GEN_INT (0x8000);
8816       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8817     }
8818   operands[1] = tmp;
8821 ;; Conditionalize these after reload. If they match before reload, we
8822 ;; lose the clobber and ability to use integer instructions.
8824 (define_insn "*<code><mode>2_1"
8825   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8826         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8827   "TARGET_80387
8828    && (reload_completed
8829        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8830   "f<absneg_mnemonic>"
8831   [(set_attr "type" "fsgn")
8832    (set_attr "mode" "<MODE>")])
8834 (define_insn "*<code>extendsfdf2"
8835   [(set (match_operand:DF 0 "register_operand" "=f")
8836         (absneg:DF (float_extend:DF
8837                      (match_operand:SF 1 "register_operand" "0"))))]
8838   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8839   "f<absneg_mnemonic>"
8840   [(set_attr "type" "fsgn")
8841    (set_attr "mode" "DF")])
8843 (define_insn "*<code>extendsfxf2"
8844   [(set (match_operand:XF 0 "register_operand" "=f")
8845         (absneg:XF (float_extend:XF
8846                      (match_operand:SF 1 "register_operand" "0"))))]
8847   "TARGET_80387"
8848   "f<absneg_mnemonic>"
8849   [(set_attr "type" "fsgn")
8850    (set_attr "mode" "XF")])
8852 (define_insn "*<code>extenddfxf2"
8853   [(set (match_operand:XF 0 "register_operand" "=f")
8854         (absneg:XF (float_extend:XF
8855                      (match_operand:DF 1 "register_operand" "0"))))]
8856   "TARGET_80387"
8857   "f<absneg_mnemonic>"
8858   [(set_attr "type" "fsgn")
8859    (set_attr "mode" "XF")])
8861 ;; Copysign instructions
8863 (define_mode_iterator CSGNMODE [SF DF TF])
8864 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8866 (define_expand "copysign<mode>3"
8867   [(match_operand:CSGNMODE 0 "register_operand")
8868    (match_operand:CSGNMODE 1 "nonmemory_operand")
8869    (match_operand:CSGNMODE 2 "register_operand")]
8870   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8871    || (TARGET_SSE && (<MODE>mode == TFmode))"
8872   "ix86_expand_copysign (operands); DONE;")
8874 (define_insn_and_split "copysign<mode>3_const"
8875   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8876         (unspec:CSGNMODE
8877           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8878            (match_operand:CSGNMODE 2 "register_operand" "0")
8879            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8880           UNSPEC_COPYSIGN))]
8881   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8882    || (TARGET_SSE && (<MODE>mode == TFmode))"
8883   "#"
8884   "&& reload_completed"
8885   [(const_int 0)]
8886   "ix86_split_copysign_const (operands); DONE;")
8888 (define_insn "copysign<mode>3_var"
8889   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8890         (unspec:CSGNMODE
8891           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8892            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8893            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8894            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8895           UNSPEC_COPYSIGN))
8896    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8897   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8898    || (TARGET_SSE && (<MODE>mode == TFmode))"
8899   "#")
8901 (define_split
8902   [(set (match_operand:CSGNMODE 0 "register_operand")
8903         (unspec:CSGNMODE
8904           [(match_operand:CSGNMODE 2 "register_operand")
8905            (match_operand:CSGNMODE 3 "register_operand")
8906            (match_operand:<CSGNVMODE> 4)
8907            (match_operand:<CSGNVMODE> 5)]
8908           UNSPEC_COPYSIGN))
8909    (clobber (match_scratch:<CSGNVMODE> 1))]
8910   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8911     || (TARGET_SSE && (<MODE>mode == TFmode)))
8912    && reload_completed"
8913   [(const_int 0)]
8914   "ix86_split_copysign_var (operands); DONE;")
8916 ;; One complement instructions
8918 (define_expand "one_cmpl<mode>2"
8919   [(set (match_operand:SWIM 0 "nonimmediate_operand")
8920         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8921   ""
8922   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8924 (define_insn "*one_cmpl<mode>2_1"
8925   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8926         (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0")))]
8927   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8928   "not{<imodesuffix>}\t%0"
8929   [(set_attr "type" "negnot")
8930    (set_attr "mode" "<MODE>")])
8932 (define_insn "*one_cmplhi2_1"
8933   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!Yk")
8934         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,Yk")))]
8935   "ix86_unary_operator_ok (NOT, HImode, operands)"
8936   "@
8937    not{w}\t%0
8938    knotw\t{%1, %0|%0, %1}"
8939   [(set_attr "isa" "*,avx512f")
8940    (set_attr "type" "negnot,msklog")
8941    (set_attr "prefix" "*,vex")
8942    (set_attr "mode" "HI")])
8944 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8945 (define_insn "*one_cmplqi2_1"
8946   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!Yk")
8947         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,Yk")))]
8948   "ix86_unary_operator_ok (NOT, QImode, operands)"
8949   "@
8950    not{b}\t%0
8951    not{l}\t%k0
8952    knotw\t{%1, %0|%0, %1}"
8953   [(set_attr "isa" "*,*,avx512f")
8954    (set_attr "type" "negnot,negnot,msklog")
8955    (set_attr "prefix" "*,*,vex")
8956    (set_attr "mode" "QI,SI,QI")])
8958 ;; ??? Currently never generated - xor is used instead.
8959 (define_insn "*one_cmplsi2_1_zext"
8960   [(set (match_operand:DI 0 "register_operand" "=r")
8961         (zero_extend:DI
8962           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8963   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8964   "not{l}\t%k0"
8965   [(set_attr "type" "negnot")
8966    (set_attr "mode" "SI")])
8968 (define_insn "*one_cmpl<mode>2_2"
8969   [(set (reg FLAGS_REG)
8970         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8971                  (const_int 0)))
8972    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8973         (not:SWI (match_dup 1)))]
8974   "ix86_match_ccmode (insn, CCNOmode)
8975    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8976   "#"
8977   [(set_attr "type" "alu1")
8978    (set_attr "mode" "<MODE>")])
8980 (define_split
8981   [(set (match_operand 0 "flags_reg_operand")
8982         (match_operator 2 "compare_operator"
8983           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
8984            (const_int 0)]))
8985    (set (match_operand:SWI 1 "nonimmediate_operand")
8986         (not:SWI (match_dup 3)))]
8987   "ix86_match_ccmode (insn, CCNOmode)"
8988   [(parallel [(set (match_dup 0)
8989                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8990                                     (const_int 0)]))
8991               (set (match_dup 1)
8992                    (xor:SWI (match_dup 3) (const_int -1)))])])
8994 ;; ??? Currently never generated - xor is used instead.
8995 (define_insn "*one_cmplsi2_2_zext"
8996   [(set (reg FLAGS_REG)
8997         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8998                  (const_int 0)))
8999    (set (match_operand:DI 0 "register_operand" "=r")
9000         (zero_extend:DI (not:SI (match_dup 1))))]
9001   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9002    && ix86_unary_operator_ok (NOT, SImode, operands)"
9003   "#"
9004   [(set_attr "type" "alu1")
9005    (set_attr "mode" "SI")])
9007 (define_split
9008   [(set (match_operand 0 "flags_reg_operand")
9009         (match_operator 2 "compare_operator"
9010           [(not:SI (match_operand:SI 3 "register_operand"))
9011            (const_int 0)]))
9012    (set (match_operand:DI 1 "register_operand")
9013         (zero_extend:DI (not:SI (match_dup 3))))]
9014   "ix86_match_ccmode (insn, CCNOmode)"
9015   [(parallel [(set (match_dup 0)
9016                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9017                                     (const_int 0)]))
9018               (set (match_dup 1)
9019                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9021 ;; Shift instructions
9023 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9024 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9025 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9026 ;; from the assembler input.
9028 ;; This instruction shifts the target reg/mem as usual, but instead of
9029 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9030 ;; is a left shift double, bits are taken from the high order bits of
9031 ;; reg, else if the insn is a shift right double, bits are taken from the
9032 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9033 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9035 ;; Since sh[lr]d does not change the `reg' operand, that is done
9036 ;; separately, making all shifts emit pairs of shift double and normal
9037 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9038 ;; support a 63 bit shift, each shift where the count is in a reg expands
9039 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9041 ;; If the shift count is a constant, we need never emit more than one
9042 ;; shift pair, instead using moves and sign extension for counts greater
9043 ;; than 31.
9045 (define_expand "ashl<mode>3"
9046   [(set (match_operand:SDWIM 0 "<shift_operand>")
9047         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9048                       (match_operand:QI 2 "nonmemory_operand")))]
9049   ""
9050   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9052 (define_insn "*ashl<mode>3_doubleword"
9053   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9054         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9055                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9056    (clobber (reg:CC FLAGS_REG))]
9057   ""
9058   "#"
9059   [(set_attr "type" "multi")])
9061 (define_split
9062   [(set (match_operand:DWI 0 "register_operand")
9063         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9064                     (match_operand:QI 2 "nonmemory_operand")))
9065    (clobber (reg:CC FLAGS_REG))]
9066   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9067   [(const_int 0)]
9068   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9070 ;; By default we don't ask for a scratch register, because when DWImode
9071 ;; values are manipulated, registers are already at a premium.  But if
9072 ;; we have one handy, we won't turn it away.
9074 (define_peephole2
9075   [(match_scratch:DWIH 3 "r")
9076    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9077                    (ashift:<DWI>
9078                      (match_operand:<DWI> 1 "nonmemory_operand")
9079                      (match_operand:QI 2 "nonmemory_operand")))
9080               (clobber (reg:CC FLAGS_REG))])
9081    (match_dup 3)]
9082   "TARGET_CMOVE"
9083   [(const_int 0)]
9084   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9086 (define_insn "x86_64_shld"
9087   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9088         (ior:DI (ashift:DI (match_dup 0)
9089                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9090                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9091                   (minus:QI (const_int 64) (match_dup 2)))))
9092    (clobber (reg:CC FLAGS_REG))]
9093   "TARGET_64BIT"
9094   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9095   [(set_attr "type" "ishift")
9096    (set_attr "prefix_0f" "1")
9097    (set_attr "mode" "DI")
9098    (set_attr "athlon_decode" "vector")
9099    (set_attr "amdfam10_decode" "vector")
9100    (set_attr "bdver1_decode" "vector")])
9102 (define_insn "x86_shld"
9103   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9104         (ior:SI (ashift:SI (match_dup 0)
9105                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9106                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9107                   (minus:QI (const_int 32) (match_dup 2)))))
9108    (clobber (reg:CC FLAGS_REG))]
9109   ""
9110   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9111   [(set_attr "type" "ishift")
9112    (set_attr "prefix_0f" "1")
9113    (set_attr "mode" "SI")
9114    (set_attr "pent_pair" "np")
9115    (set_attr "athlon_decode" "vector")
9116    (set_attr "amdfam10_decode" "vector")
9117    (set_attr "bdver1_decode" "vector")])
9119 (define_expand "x86_shift<mode>_adj_1"
9120   [(set (reg:CCZ FLAGS_REG)
9121         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9122                              (match_dup 4))
9123                      (const_int 0)))
9124    (set (match_operand:SWI48 0 "register_operand")
9125         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9126                             (match_operand:SWI48 1 "register_operand")
9127                             (match_dup 0)))
9128    (set (match_dup 1)
9129         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9130                             (match_operand:SWI48 3 "register_operand")
9131                             (match_dup 1)))]
9132   "TARGET_CMOVE"
9133   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9135 (define_expand "x86_shift<mode>_adj_2"
9136   [(use (match_operand:SWI48 0 "register_operand"))
9137    (use (match_operand:SWI48 1 "register_operand"))
9138    (use (match_operand:QI 2 "register_operand"))]
9139   ""
9141   rtx label = gen_label_rtx ();
9142   rtx tmp;
9144   emit_insn (gen_testqi_ccz_1 (operands[2],
9145                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9147   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9148   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9149   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9150                               gen_rtx_LABEL_REF (VOIDmode, label),
9151                               pc_rtx);
9152   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9153   JUMP_LABEL (tmp) = label;
9155   emit_move_insn (operands[0], operands[1]);
9156   ix86_expand_clear (operands[1]);
9158   emit_label (label);
9159   LABEL_NUSES (label) = 1;
9161   DONE;
9164 ;; Avoid useless masking of count operand.
9165 (define_insn "*ashl<mode>3_mask"
9166   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9167         (ashift:SWI48
9168           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9169           (subreg:QI
9170             (and:SI
9171               (match_operand:SI 2 "register_operand" "c")
9172               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9173    (clobber (reg:CC FLAGS_REG))]
9174   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9175    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9176       == GET_MODE_BITSIZE (<MODE>mode)-1"
9178   return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9180   [(set_attr "type" "ishift")
9181    (set_attr "mode" "<MODE>")])
9183 (define_insn "*bmi2_ashl<mode>3_1"
9184   [(set (match_operand:SWI48 0 "register_operand" "=r")
9185         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9186                       (match_operand:SWI48 2 "register_operand" "r")))]
9187   "TARGET_BMI2"
9188   "shlx\t{%2, %1, %0|%0, %1, %2}"
9189   [(set_attr "type" "ishiftx")
9190    (set_attr "mode" "<MODE>")])
9192 (define_insn "*ashl<mode>3_1"
9193   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9194         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9195                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9196    (clobber (reg:CC FLAGS_REG))]
9197   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9199   switch (get_attr_type (insn))
9200     {
9201     case TYPE_LEA:
9202     case TYPE_ISHIFTX:
9203       return "#";
9205     case TYPE_ALU:
9206       gcc_assert (operands[2] == const1_rtx);
9207       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9208       return "add{<imodesuffix>}\t%0, %0";
9210     default:
9211       if (operands[2] == const1_rtx
9212           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9213         return "sal{<imodesuffix>}\t%0";
9214       else
9215         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9216     }
9218   [(set_attr "isa" "*,*,bmi2")
9219    (set (attr "type")
9220      (cond [(eq_attr "alternative" "1")
9221               (const_string "lea")
9222             (eq_attr "alternative" "2")
9223               (const_string "ishiftx")
9224             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9225                       (match_operand 0 "register_operand"))
9226                  (match_operand 2 "const1_operand"))
9227               (const_string "alu")
9228            ]
9229            (const_string "ishift")))
9230    (set (attr "length_immediate")
9231      (if_then_else
9232        (ior (eq_attr "type" "alu")
9233             (and (eq_attr "type" "ishift")
9234                  (and (match_operand 2 "const1_operand")
9235                       (ior (match_test "TARGET_SHIFT1")
9236                            (match_test "optimize_function_for_size_p (cfun)")))))
9237        (const_string "0")
9238        (const_string "*")))
9239    (set_attr "mode" "<MODE>")])
9241 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9242 (define_split
9243   [(set (match_operand:SWI48 0 "register_operand")
9244         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9245                       (match_operand:QI 2 "register_operand")))
9246    (clobber (reg:CC FLAGS_REG))]
9247   "TARGET_BMI2 && reload_completed"
9248   [(set (match_dup 0)
9249         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9250   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9252 (define_insn "*bmi2_ashlsi3_1_zext"
9253   [(set (match_operand:DI 0 "register_operand" "=r")
9254         (zero_extend:DI
9255           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9256                      (match_operand:SI 2 "register_operand" "r"))))]
9257   "TARGET_64BIT && TARGET_BMI2"
9258   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9259   [(set_attr "type" "ishiftx")
9260    (set_attr "mode" "SI")])
9262 (define_insn "*ashlsi3_1_zext"
9263   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9264         (zero_extend:DI
9265           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9266                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9267    (clobber (reg:CC FLAGS_REG))]
9268   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9270   switch (get_attr_type (insn))
9271     {
9272     case TYPE_LEA:
9273     case TYPE_ISHIFTX:
9274       return "#";
9276     case TYPE_ALU:
9277       gcc_assert (operands[2] == const1_rtx);
9278       return "add{l}\t%k0, %k0";
9280     default:
9281       if (operands[2] == const1_rtx
9282           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9283         return "sal{l}\t%k0";
9284       else
9285         return "sal{l}\t{%2, %k0|%k0, %2}";
9286     }
9288   [(set_attr "isa" "*,*,bmi2")
9289    (set (attr "type")
9290      (cond [(eq_attr "alternative" "1")
9291               (const_string "lea")
9292             (eq_attr "alternative" "2")
9293               (const_string "ishiftx")
9294             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9295                  (match_operand 2 "const1_operand"))
9296               (const_string "alu")
9297            ]
9298            (const_string "ishift")))
9299    (set (attr "length_immediate")
9300      (if_then_else
9301        (ior (eq_attr "type" "alu")
9302             (and (eq_attr "type" "ishift")
9303                  (and (match_operand 2 "const1_operand")
9304                       (ior (match_test "TARGET_SHIFT1")
9305                            (match_test "optimize_function_for_size_p (cfun)")))))
9306        (const_string "0")
9307        (const_string "*")))
9308    (set_attr "mode" "SI")])
9310 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9311 (define_split
9312   [(set (match_operand:DI 0 "register_operand")
9313         (zero_extend:DI
9314           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9315                      (match_operand:QI 2 "register_operand"))))
9316    (clobber (reg:CC FLAGS_REG))]
9317   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9318   [(set (match_dup 0)
9319         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9320   "operands[2] = gen_lowpart (SImode, operands[2]);")
9322 (define_insn "*ashlhi3_1"
9323   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9324         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9325                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9326    (clobber (reg:CC FLAGS_REG))]
9327   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9329   switch (get_attr_type (insn))
9330     {
9331     case TYPE_LEA:
9332       return "#";
9334     case TYPE_ALU:
9335       gcc_assert (operands[2] == const1_rtx);
9336       return "add{w}\t%0, %0";
9338     default:
9339       if (operands[2] == const1_rtx
9340           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9341         return "sal{w}\t%0";
9342       else
9343         return "sal{w}\t{%2, %0|%0, %2}";
9344     }
9346   [(set (attr "type")
9347      (cond [(eq_attr "alternative" "1")
9348               (const_string "lea")
9349             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9350                       (match_operand 0 "register_operand"))
9351                  (match_operand 2 "const1_operand"))
9352               (const_string "alu")
9353            ]
9354            (const_string "ishift")))
9355    (set (attr "length_immediate")
9356      (if_then_else
9357        (ior (eq_attr "type" "alu")
9358             (and (eq_attr "type" "ishift")
9359                  (and (match_operand 2 "const1_operand")
9360                       (ior (match_test "TARGET_SHIFT1")
9361                            (match_test "optimize_function_for_size_p (cfun)")))))
9362        (const_string "0")
9363        (const_string "*")))
9364    (set_attr "mode" "HI,SI")])
9366 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9367 (define_insn "*ashlqi3_1"
9368   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9369         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9370                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9371    (clobber (reg:CC FLAGS_REG))]
9372   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9374   switch (get_attr_type (insn))
9375     {
9376     case TYPE_LEA:
9377       return "#";
9379     case TYPE_ALU:
9380       gcc_assert (operands[2] == const1_rtx);
9381       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9382         return "add{l}\t%k0, %k0";
9383       else
9384         return "add{b}\t%0, %0";
9386     default:
9387       if (operands[2] == const1_rtx
9388           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9389         {
9390           if (get_attr_mode (insn) == MODE_SI)
9391             return "sal{l}\t%k0";
9392           else
9393             return "sal{b}\t%0";
9394         }
9395       else
9396         {
9397           if (get_attr_mode (insn) == MODE_SI)
9398             return "sal{l}\t{%2, %k0|%k0, %2}";
9399           else
9400             return "sal{b}\t{%2, %0|%0, %2}";
9401         }
9402     }
9404   [(set (attr "type")
9405      (cond [(eq_attr "alternative" "2")
9406               (const_string "lea")
9407             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9408                       (match_operand 0 "register_operand"))
9409                  (match_operand 2 "const1_operand"))
9410               (const_string "alu")
9411            ]
9412            (const_string "ishift")))
9413    (set (attr "length_immediate")
9414      (if_then_else
9415        (ior (eq_attr "type" "alu")
9416             (and (eq_attr "type" "ishift")
9417                  (and (match_operand 2 "const1_operand")
9418                       (ior (match_test "TARGET_SHIFT1")
9419                            (match_test "optimize_function_for_size_p (cfun)")))))
9420        (const_string "0")
9421        (const_string "*")))
9422    (set_attr "mode" "QI,SI,SI")])
9424 (define_insn "*ashlqi3_1_slp"
9425   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9426         (ashift:QI (match_dup 0)
9427                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9428    (clobber (reg:CC FLAGS_REG))]
9429   "(optimize_function_for_size_p (cfun)
9430     || !TARGET_PARTIAL_FLAG_REG_STALL
9431     || (operands[1] == const1_rtx
9432         && (TARGET_SHIFT1
9433             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9435   switch (get_attr_type (insn))
9436     {
9437     case TYPE_ALU:
9438       gcc_assert (operands[1] == const1_rtx);
9439       return "add{b}\t%0, %0";
9441     default:
9442       if (operands[1] == const1_rtx
9443           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9444         return "sal{b}\t%0";
9445       else
9446         return "sal{b}\t{%1, %0|%0, %1}";
9447     }
9449   [(set (attr "type")
9450      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9451                       (match_operand 0 "register_operand"))
9452                  (match_operand 1 "const1_operand"))
9453               (const_string "alu")
9454            ]
9455            (const_string "ishift1")))
9456    (set (attr "length_immediate")
9457      (if_then_else
9458        (ior (eq_attr "type" "alu")
9459             (and (eq_attr "type" "ishift1")
9460                  (and (match_operand 1 "const1_operand")
9461                       (ior (match_test "TARGET_SHIFT1")
9462                            (match_test "optimize_function_for_size_p (cfun)")))))
9463        (const_string "0")
9464        (const_string "*")))
9465    (set_attr "mode" "QI")])
9467 ;; Convert ashift to the lea pattern to avoid flags dependency.
9468 (define_split
9469   [(set (match_operand 0 "register_operand")
9470         (ashift (match_operand 1 "index_register_operand")
9471                 (match_operand:QI 2 "const_int_operand")))
9472    (clobber (reg:CC FLAGS_REG))]
9473   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9474    && reload_completed
9475    && true_regnum (operands[0]) != true_regnum (operands[1])"
9476   [(const_int 0)]
9478   enum machine_mode mode = GET_MODE (operands[0]);
9479   rtx pat;
9481   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9482     { 
9483       mode = SImode; 
9484       operands[0] = gen_lowpart (mode, operands[0]);
9485       operands[1] = gen_lowpart (mode, operands[1]);
9486     }
9488   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9490   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9492   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9493   DONE;
9496 ;; Convert ashift to the lea pattern to avoid flags dependency.
9497 (define_split
9498   [(set (match_operand:DI 0 "register_operand")
9499         (zero_extend:DI
9500           (ashift:SI (match_operand:SI 1 "index_register_operand")
9501                      (match_operand:QI 2 "const_int_operand"))))
9502    (clobber (reg:CC FLAGS_REG))]
9503   "TARGET_64BIT && reload_completed
9504    && true_regnum (operands[0]) != true_regnum (operands[1])"
9505   [(set (match_dup 0)
9506         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9508   operands[1] = gen_lowpart (SImode, operands[1]);
9509   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9512 ;; This pattern can't accept a variable shift count, since shifts by
9513 ;; zero don't affect the flags.  We assume that shifts by constant
9514 ;; zero are optimized away.
9515 (define_insn "*ashl<mode>3_cmp"
9516   [(set (reg FLAGS_REG)
9517         (compare
9518           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9519                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9520           (const_int 0)))
9521    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9522         (ashift:SWI (match_dup 1) (match_dup 2)))]
9523   "(optimize_function_for_size_p (cfun)
9524     || !TARGET_PARTIAL_FLAG_REG_STALL
9525     || (operands[2] == const1_rtx
9526         && (TARGET_SHIFT1
9527             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9528    && ix86_match_ccmode (insn, CCGOCmode)
9529    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9531   switch (get_attr_type (insn))
9532     {
9533     case TYPE_ALU:
9534       gcc_assert (operands[2] == const1_rtx);
9535       return "add{<imodesuffix>}\t%0, %0";
9537     default:
9538       if (operands[2] == const1_rtx
9539           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9540         return "sal{<imodesuffix>}\t%0";
9541       else
9542         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9543     }
9545   [(set (attr "type")
9546      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9547                       (match_operand 0 "register_operand"))
9548                  (match_operand 2 "const1_operand"))
9549               (const_string "alu")
9550            ]
9551            (const_string "ishift")))
9552    (set (attr "length_immediate")
9553      (if_then_else
9554        (ior (eq_attr "type" "alu")
9555             (and (eq_attr "type" "ishift")
9556                  (and (match_operand 2 "const1_operand")
9557                       (ior (match_test "TARGET_SHIFT1")
9558                            (match_test "optimize_function_for_size_p (cfun)")))))
9559        (const_string "0")
9560        (const_string "*")))
9561    (set_attr "mode" "<MODE>")])
9563 (define_insn "*ashlsi3_cmp_zext"
9564   [(set (reg FLAGS_REG)
9565         (compare
9566           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9567                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9568           (const_int 0)))
9569    (set (match_operand:DI 0 "register_operand" "=r")
9570         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9571   "TARGET_64BIT
9572    && (optimize_function_for_size_p (cfun)
9573        || !TARGET_PARTIAL_FLAG_REG_STALL
9574        || (operands[2] == const1_rtx
9575            && (TARGET_SHIFT1
9576                || TARGET_DOUBLE_WITH_ADD)))
9577    && ix86_match_ccmode (insn, CCGOCmode)
9578    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9580   switch (get_attr_type (insn))
9581     {
9582     case TYPE_ALU:
9583       gcc_assert (operands[2] == const1_rtx);
9584       return "add{l}\t%k0, %k0";
9586     default:
9587       if (operands[2] == const1_rtx
9588           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9589         return "sal{l}\t%k0";
9590       else
9591         return "sal{l}\t{%2, %k0|%k0, %2}";
9592     }
9594   [(set (attr "type")
9595      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9596                  (match_operand 2 "const1_operand"))
9597               (const_string "alu")
9598            ]
9599            (const_string "ishift")))
9600    (set (attr "length_immediate")
9601      (if_then_else
9602        (ior (eq_attr "type" "alu")
9603             (and (eq_attr "type" "ishift")
9604                  (and (match_operand 2 "const1_operand")
9605                       (ior (match_test "TARGET_SHIFT1")
9606                            (match_test "optimize_function_for_size_p (cfun)")))))
9607        (const_string "0")
9608        (const_string "*")))
9609    (set_attr "mode" "SI")])
9611 (define_insn "*ashl<mode>3_cconly"
9612   [(set (reg FLAGS_REG)
9613         (compare
9614           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9615                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9616           (const_int 0)))
9617    (clobber (match_scratch:SWI 0 "=<r>"))]
9618   "(optimize_function_for_size_p (cfun)
9619     || !TARGET_PARTIAL_FLAG_REG_STALL
9620     || (operands[2] == const1_rtx
9621         && (TARGET_SHIFT1
9622             || TARGET_DOUBLE_WITH_ADD)))
9623    && ix86_match_ccmode (insn, CCGOCmode)"
9625   switch (get_attr_type (insn))
9626     {
9627     case TYPE_ALU:
9628       gcc_assert (operands[2] == const1_rtx);
9629       return "add{<imodesuffix>}\t%0, %0";
9631     default:
9632       if (operands[2] == const1_rtx
9633           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9634         return "sal{<imodesuffix>}\t%0";
9635       else
9636         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9637     }
9639   [(set (attr "type")
9640      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9641                       (match_operand 0 "register_operand"))
9642                  (match_operand 2 "const1_operand"))
9643               (const_string "alu")
9644            ]
9645            (const_string "ishift")))
9646    (set (attr "length_immediate")
9647      (if_then_else
9648        (ior (eq_attr "type" "alu")
9649             (and (eq_attr "type" "ishift")
9650                  (and (match_operand 2 "const1_operand")
9651                       (ior (match_test "TARGET_SHIFT1")
9652                            (match_test "optimize_function_for_size_p (cfun)")))))
9653        (const_string "0")
9654        (const_string "*")))
9655    (set_attr "mode" "<MODE>")])
9657 ;; See comment above `ashl<mode>3' about how this works.
9659 (define_expand "<shift_insn><mode>3"
9660   [(set (match_operand:SDWIM 0 "<shift_operand>")
9661         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9662                            (match_operand:QI 2 "nonmemory_operand")))]
9663   ""
9664   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9666 ;; Avoid useless masking of count operand.
9667 (define_insn "*<shift_insn><mode>3_mask"
9668   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9669         (any_shiftrt:SWI48
9670           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9671           (subreg:QI
9672             (and:SI
9673               (match_operand:SI 2 "register_operand" "c")
9674               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9675    (clobber (reg:CC FLAGS_REG))]
9676   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9677    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9678       == GET_MODE_BITSIZE (<MODE>mode)-1"
9680   return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9682   [(set_attr "type" "ishift")
9683    (set_attr "mode" "<MODE>")])
9685 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9686   [(set (match_operand:DWI 0 "register_operand" "=r")
9687         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9688                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9689    (clobber (reg:CC FLAGS_REG))]
9690   ""
9691   "#"
9692   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9693   [(const_int 0)]
9694   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9695   [(set_attr "type" "multi")])
9697 ;; By default we don't ask for a scratch register, because when DWImode
9698 ;; values are manipulated, registers are already at a premium.  But if
9699 ;; we have one handy, we won't turn it away.
9701 (define_peephole2
9702   [(match_scratch:DWIH 3 "r")
9703    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9704                    (any_shiftrt:<DWI>
9705                      (match_operand:<DWI> 1 "register_operand")
9706                      (match_operand:QI 2 "nonmemory_operand")))
9707               (clobber (reg:CC FLAGS_REG))])
9708    (match_dup 3)]
9709   "TARGET_CMOVE"
9710   [(const_int 0)]
9711   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9713 (define_insn "x86_64_shrd"
9714   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9715         (ior:DI (ashiftrt:DI (match_dup 0)
9716                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9717                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9718                   (minus:QI (const_int 64) (match_dup 2)))))
9719    (clobber (reg:CC FLAGS_REG))]
9720   "TARGET_64BIT"
9721   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9722   [(set_attr "type" "ishift")
9723    (set_attr "prefix_0f" "1")
9724    (set_attr "mode" "DI")
9725    (set_attr "athlon_decode" "vector")
9726    (set_attr "amdfam10_decode" "vector")
9727    (set_attr "bdver1_decode" "vector")])
9729 (define_insn "x86_shrd"
9730   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9731         (ior:SI (ashiftrt:SI (match_dup 0)
9732                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9733                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9734                   (minus:QI (const_int 32) (match_dup 2)))))
9735    (clobber (reg:CC FLAGS_REG))]
9736   ""
9737   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9738   [(set_attr "type" "ishift")
9739    (set_attr "prefix_0f" "1")
9740    (set_attr "mode" "SI")
9741    (set_attr "pent_pair" "np")
9742    (set_attr "athlon_decode" "vector")
9743    (set_attr "amdfam10_decode" "vector")
9744    (set_attr "bdver1_decode" "vector")])
9746 (define_insn "ashrdi3_cvt"
9747   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9748         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9749                      (match_operand:QI 2 "const_int_operand")))
9750    (clobber (reg:CC FLAGS_REG))]
9751   "TARGET_64BIT && INTVAL (operands[2]) == 63
9752    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9753    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9754   "@
9755    {cqto|cqo}
9756    sar{q}\t{%2, %0|%0, %2}"
9757   [(set_attr "type" "imovx,ishift")
9758    (set_attr "prefix_0f" "0,*")
9759    (set_attr "length_immediate" "0,*")
9760    (set_attr "modrm" "0,1")
9761    (set_attr "mode" "DI")])
9763 (define_insn "ashrsi3_cvt"
9764   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9765         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9766                      (match_operand:QI 2 "const_int_operand")))
9767    (clobber (reg:CC FLAGS_REG))]
9768   "INTVAL (operands[2]) == 31
9769    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9770    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9771   "@
9772    {cltd|cdq}
9773    sar{l}\t{%2, %0|%0, %2}"
9774   [(set_attr "type" "imovx,ishift")
9775    (set_attr "prefix_0f" "0,*")
9776    (set_attr "length_immediate" "0,*")
9777    (set_attr "modrm" "0,1")
9778    (set_attr "mode" "SI")])
9780 (define_insn "*ashrsi3_cvt_zext"
9781   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9782         (zero_extend:DI
9783           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9784                        (match_operand:QI 2 "const_int_operand"))))
9785    (clobber (reg:CC FLAGS_REG))]
9786   "TARGET_64BIT && INTVAL (operands[2]) == 31
9787    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9788    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9789   "@
9790    {cltd|cdq}
9791    sar{l}\t{%2, %k0|%k0, %2}"
9792   [(set_attr "type" "imovx,ishift")
9793    (set_attr "prefix_0f" "0,*")
9794    (set_attr "length_immediate" "0,*")
9795    (set_attr "modrm" "0,1")
9796    (set_attr "mode" "SI")])
9798 (define_expand "x86_shift<mode>_adj_3"
9799   [(use (match_operand:SWI48 0 "register_operand"))
9800    (use (match_operand:SWI48 1 "register_operand"))
9801    (use (match_operand:QI 2 "register_operand"))]
9802   ""
9804   rtx label = gen_label_rtx ();
9805   rtx tmp;
9807   emit_insn (gen_testqi_ccz_1 (operands[2],
9808                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9810   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9811   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9812   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9813                               gen_rtx_LABEL_REF (VOIDmode, label),
9814                               pc_rtx);
9815   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9816   JUMP_LABEL (tmp) = label;
9818   emit_move_insn (operands[0], operands[1]);
9819   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9820                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9821   emit_label (label);
9822   LABEL_NUSES (label) = 1;
9824   DONE;
9827 (define_insn "*bmi2_<shift_insn><mode>3_1"
9828   [(set (match_operand:SWI48 0 "register_operand" "=r")
9829         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9830                            (match_operand:SWI48 2 "register_operand" "r")))]
9831   "TARGET_BMI2"
9832   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9833   [(set_attr "type" "ishiftx")
9834    (set_attr "mode" "<MODE>")])
9836 (define_insn "*<shift_insn><mode>3_1"
9837   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9838         (any_shiftrt:SWI48
9839           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9840           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9841    (clobber (reg:CC FLAGS_REG))]
9842   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9844   switch (get_attr_type (insn))
9845     {
9846     case TYPE_ISHIFTX:
9847       return "#";
9849     default:
9850       if (operands[2] == const1_rtx
9851           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9852         return "<shift>{<imodesuffix>}\t%0";
9853       else
9854         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9855     }
9857   [(set_attr "isa" "*,bmi2")
9858    (set_attr "type" "ishift,ishiftx")
9859    (set (attr "length_immediate")
9860      (if_then_else
9861        (and (match_operand 2 "const1_operand")
9862             (ior (match_test "TARGET_SHIFT1")
9863                  (match_test "optimize_function_for_size_p (cfun)")))
9864        (const_string "0")
9865        (const_string "*")))
9866    (set_attr "mode" "<MODE>")])
9868 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9869 (define_split
9870   [(set (match_operand:SWI48 0 "register_operand")
9871         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9872                            (match_operand:QI 2 "register_operand")))
9873    (clobber (reg:CC FLAGS_REG))]
9874   "TARGET_BMI2 && reload_completed"
9875   [(set (match_dup 0)
9876         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9877   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9879 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9880   [(set (match_operand:DI 0 "register_operand" "=r")
9881         (zero_extend:DI
9882           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9883                           (match_operand:SI 2 "register_operand" "r"))))]
9884   "TARGET_64BIT && TARGET_BMI2"
9885   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9886   [(set_attr "type" "ishiftx")
9887    (set_attr "mode" "SI")])
9889 (define_insn "*<shift_insn>si3_1_zext"
9890   [(set (match_operand:DI 0 "register_operand" "=r,r")
9891         (zero_extend:DI
9892           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9893                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9894    (clobber (reg:CC FLAGS_REG))]
9895   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9897   switch (get_attr_type (insn))
9898     {
9899     case TYPE_ISHIFTX:
9900       return "#";
9902     default:
9903       if (operands[2] == const1_rtx
9904           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9905         return "<shift>{l}\t%k0";
9906       else
9907         return "<shift>{l}\t{%2, %k0|%k0, %2}";
9908     }
9910   [(set_attr "isa" "*,bmi2")
9911    (set_attr "type" "ishift,ishiftx")
9912    (set (attr "length_immediate")
9913      (if_then_else
9914        (and (match_operand 2 "const1_operand")
9915             (ior (match_test "TARGET_SHIFT1")
9916                  (match_test "optimize_function_for_size_p (cfun)")))
9917        (const_string "0")
9918        (const_string "*")))
9919    (set_attr "mode" "SI")])
9921 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9922 (define_split
9923   [(set (match_operand:DI 0 "register_operand")
9924         (zero_extend:DI
9925           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9926                           (match_operand:QI 2 "register_operand"))))
9927    (clobber (reg:CC FLAGS_REG))]
9928   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9929   [(set (match_dup 0)
9930         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9931   "operands[2] = gen_lowpart (SImode, operands[2]);")
9933 (define_insn "*<shift_insn><mode>3_1"
9934   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9935         (any_shiftrt:SWI12
9936           (match_operand:SWI12 1 "nonimmediate_operand" "0")
9937           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9938    (clobber (reg:CC FLAGS_REG))]
9939   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9941   if (operands[2] == const1_rtx
9942       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9943     return "<shift>{<imodesuffix>}\t%0";
9944   else
9945     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9947   [(set_attr "type" "ishift")
9948    (set (attr "length_immediate")
9949      (if_then_else
9950        (and (match_operand 2 "const1_operand")
9951             (ior (match_test "TARGET_SHIFT1")
9952                  (match_test "optimize_function_for_size_p (cfun)")))
9953        (const_string "0")
9954        (const_string "*")))
9955    (set_attr "mode" "<MODE>")])
9957 (define_insn "*<shift_insn>qi3_1_slp"
9958   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9959         (any_shiftrt:QI (match_dup 0)
9960                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9961    (clobber (reg:CC FLAGS_REG))]
9962   "(optimize_function_for_size_p (cfun)
9963     || !TARGET_PARTIAL_REG_STALL
9964     || (operands[1] == const1_rtx
9965         && TARGET_SHIFT1))"
9967   if (operands[1] == const1_rtx
9968       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9969     return "<shift>{b}\t%0";
9970   else
9971     return "<shift>{b}\t{%1, %0|%0, %1}";
9973   [(set_attr "type" "ishift1")
9974    (set (attr "length_immediate")
9975      (if_then_else
9976        (and (match_operand 1 "const1_operand")
9977             (ior (match_test "TARGET_SHIFT1")
9978                  (match_test "optimize_function_for_size_p (cfun)")))
9979        (const_string "0")
9980        (const_string "*")))
9981    (set_attr "mode" "QI")])
9983 ;; This pattern can't accept a variable shift count, since shifts by
9984 ;; zero don't affect the flags.  We assume that shifts by constant
9985 ;; zero are optimized away.
9986 (define_insn "*<shift_insn><mode>3_cmp"
9987   [(set (reg FLAGS_REG)
9988         (compare
9989           (any_shiftrt:SWI
9990             (match_operand:SWI 1 "nonimmediate_operand" "0")
9991             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9992           (const_int 0)))
9993    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9994         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9995   "(optimize_function_for_size_p (cfun)
9996     || !TARGET_PARTIAL_FLAG_REG_STALL
9997     || (operands[2] == const1_rtx
9998         && TARGET_SHIFT1))
9999    && ix86_match_ccmode (insn, CCGOCmode)
10000    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10002   if (operands[2] == const1_rtx
10003       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10004     return "<shift>{<imodesuffix>}\t%0";
10005   else
10006     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10008   [(set_attr "type" "ishift")
10009    (set (attr "length_immediate")
10010      (if_then_else
10011        (and (match_operand 2 "const1_operand")
10012             (ior (match_test "TARGET_SHIFT1")
10013                  (match_test "optimize_function_for_size_p (cfun)")))
10014        (const_string "0")
10015        (const_string "*")))
10016    (set_attr "mode" "<MODE>")])
10018 (define_insn "*<shift_insn>si3_cmp_zext"
10019   [(set (reg FLAGS_REG)
10020         (compare
10021           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10022                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10023           (const_int 0)))
10024    (set (match_operand:DI 0 "register_operand" "=r")
10025         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10026   "TARGET_64BIT
10027    && (optimize_function_for_size_p (cfun)
10028        || !TARGET_PARTIAL_FLAG_REG_STALL
10029        || (operands[2] == const1_rtx
10030            && TARGET_SHIFT1))
10031    && ix86_match_ccmode (insn, CCGOCmode)
10032    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10034   if (operands[2] == const1_rtx
10035       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10036     return "<shift>{l}\t%k0";
10037   else
10038     return "<shift>{l}\t{%2, %k0|%k0, %2}";
10040   [(set_attr "type" "ishift")
10041    (set (attr "length_immediate")
10042      (if_then_else
10043        (and (match_operand 2 "const1_operand")
10044             (ior (match_test "TARGET_SHIFT1")
10045                  (match_test "optimize_function_for_size_p (cfun)")))
10046        (const_string "0")
10047        (const_string "*")))
10048    (set_attr "mode" "SI")])
10050 (define_insn "*<shift_insn><mode>3_cconly"
10051   [(set (reg FLAGS_REG)
10052         (compare
10053           (any_shiftrt:SWI
10054             (match_operand:SWI 1 "register_operand" "0")
10055             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10056           (const_int 0)))
10057    (clobber (match_scratch:SWI 0 "=<r>"))]
10058   "(optimize_function_for_size_p (cfun)
10059     || !TARGET_PARTIAL_FLAG_REG_STALL
10060     || (operands[2] == const1_rtx
10061         && TARGET_SHIFT1))
10062    && ix86_match_ccmode (insn, CCGOCmode)"
10064   if (operands[2] == const1_rtx
10065       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10066     return "<shift>{<imodesuffix>}\t%0";
10067   else
10068     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10070   [(set_attr "type" "ishift")
10071    (set (attr "length_immediate")
10072      (if_then_else
10073        (and (match_operand 2 "const1_operand")
10074             (ior (match_test "TARGET_SHIFT1")
10075                  (match_test "optimize_function_for_size_p (cfun)")))
10076        (const_string "0")
10077        (const_string "*")))
10078    (set_attr "mode" "<MODE>")])
10080 ;; Rotate instructions
10082 (define_expand "<rotate_insn>ti3"
10083   [(set (match_operand:TI 0 "register_operand")
10084         (any_rotate:TI (match_operand:TI 1 "register_operand")
10085                        (match_operand:QI 2 "nonmemory_operand")))]
10086   "TARGET_64BIT"
10088   if (const_1_to_63_operand (operands[2], VOIDmode))
10089     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10090                 (operands[0], operands[1], operands[2]));
10091   else
10092     FAIL;
10094   DONE;
10097 (define_expand "<rotate_insn>di3"
10098   [(set (match_operand:DI 0 "shiftdi_operand")
10099         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10100                        (match_operand:QI 2 "nonmemory_operand")))]
10101  ""
10103   if (TARGET_64BIT)
10104     ix86_expand_binary_operator (<CODE>, DImode, operands);
10105   else if (const_1_to_31_operand (operands[2], VOIDmode))
10106     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10107                 (operands[0], operands[1], operands[2]));
10108   else
10109     FAIL;
10111   DONE;
10114 (define_expand "<rotate_insn><mode>3"
10115   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10116         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10117                             (match_operand:QI 2 "nonmemory_operand")))]
10118   ""
10119   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10121 ;; Avoid useless masking of count operand.
10122 (define_insn "*<rotate_insn><mode>3_mask"
10123   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10124         (any_rotate:SWI48
10125           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10126           (subreg:QI
10127             (and:SI
10128               (match_operand:SI 2 "register_operand" "c")
10129               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10130    (clobber (reg:CC FLAGS_REG))]
10131   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10132    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10133       == GET_MODE_BITSIZE (<MODE>mode)-1"
10135   return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10137   [(set_attr "type" "rotate")
10138    (set_attr "mode" "<MODE>")])
10140 ;; Implement rotation using two double-precision
10141 ;; shift instructions and a scratch register.
10143 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10144  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10145        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10146                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10147   (clobber (reg:CC FLAGS_REG))
10148   (clobber (match_scratch:DWIH 3 "=&r"))]
10149  ""
10150  "#"
10151  "reload_completed"
10152  [(set (match_dup 3) (match_dup 4))
10153   (parallel
10154    [(set (match_dup 4)
10155          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10156                    (lshiftrt:DWIH (match_dup 5)
10157                                   (minus:QI (match_dup 6) (match_dup 2)))))
10158     (clobber (reg:CC FLAGS_REG))])
10159   (parallel
10160    [(set (match_dup 5)
10161          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10162                    (lshiftrt:DWIH (match_dup 3)
10163                                   (minus:QI (match_dup 6) (match_dup 2)))))
10164     (clobber (reg:CC FLAGS_REG))])]
10166   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10168   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10171 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10172  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10173        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10174                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10175   (clobber (reg:CC FLAGS_REG))
10176   (clobber (match_scratch:DWIH 3 "=&r"))]
10177  ""
10178  "#"
10179  "reload_completed"
10180  [(set (match_dup 3) (match_dup 4))
10181   (parallel
10182    [(set (match_dup 4)
10183          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10184                    (ashift:DWIH (match_dup 5)
10185                                 (minus:QI (match_dup 6) (match_dup 2)))))
10186     (clobber (reg:CC FLAGS_REG))])
10187   (parallel
10188    [(set (match_dup 5)
10189          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10190                    (ashift:DWIH (match_dup 3)
10191                                 (minus:QI (match_dup 6) (match_dup 2)))))
10192     (clobber (reg:CC FLAGS_REG))])]
10194   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10196   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10199 (define_insn "*bmi2_rorx<mode>3_1"
10200   [(set (match_operand:SWI48 0 "register_operand" "=r")
10201         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10202                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10203   "TARGET_BMI2"
10204   "rorx\t{%2, %1, %0|%0, %1, %2}"
10205   [(set_attr "type" "rotatex")
10206    (set_attr "mode" "<MODE>")])
10208 (define_insn "*<rotate_insn><mode>3_1"
10209   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10210         (any_rotate:SWI48
10211           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10212           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10213    (clobber (reg:CC FLAGS_REG))]
10214   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10216   switch (get_attr_type (insn))
10217     {
10218     case TYPE_ROTATEX:
10219       return "#";
10221     default:
10222       if (operands[2] == const1_rtx
10223           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10224         return "<rotate>{<imodesuffix>}\t%0";
10225       else
10226         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10227     }
10229   [(set_attr "isa" "*,bmi2")
10230    (set_attr "type" "rotate,rotatex")
10231    (set (attr "length_immediate")
10232      (if_then_else
10233        (and (eq_attr "type" "rotate")
10234             (and (match_operand 2 "const1_operand")
10235                  (ior (match_test "TARGET_SHIFT1")
10236                       (match_test "optimize_function_for_size_p (cfun)"))))
10237        (const_string "0")
10238        (const_string "*")))
10239    (set_attr "mode" "<MODE>")])
10241 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10242 (define_split
10243   [(set (match_operand:SWI48 0 "register_operand")
10244         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10245                       (match_operand:QI 2 "immediate_operand")))
10246    (clobber (reg:CC FLAGS_REG))]
10247   "TARGET_BMI2 && reload_completed"
10248   [(set (match_dup 0)
10249         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10251   operands[2]
10252     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10255 (define_split
10256   [(set (match_operand:SWI48 0 "register_operand")
10257         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10258                         (match_operand:QI 2 "immediate_operand")))
10259    (clobber (reg:CC FLAGS_REG))]
10260   "TARGET_BMI2 && reload_completed"
10261   [(set (match_dup 0)
10262         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10264 (define_insn "*bmi2_rorxsi3_1_zext"
10265   [(set (match_operand:DI 0 "register_operand" "=r")
10266         (zero_extend:DI
10267           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10268                        (match_operand:QI 2 "immediate_operand" "I"))))]
10269   "TARGET_64BIT && TARGET_BMI2"
10270   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10271   [(set_attr "type" "rotatex")
10272    (set_attr "mode" "SI")])
10274 (define_insn "*<rotate_insn>si3_1_zext"
10275   [(set (match_operand:DI 0 "register_operand" "=r,r")
10276         (zero_extend:DI
10277           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10278                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10279    (clobber (reg:CC FLAGS_REG))]
10280   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10282   switch (get_attr_type (insn))
10283     {
10284     case TYPE_ROTATEX:
10285       return "#";
10287     default:
10288       if (operands[2] == const1_rtx
10289           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10290         return "<rotate>{l}\t%k0";
10291       else
10292         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10293     }
10295   [(set_attr "isa" "*,bmi2")
10296    (set_attr "type" "rotate,rotatex")
10297    (set (attr "length_immediate")
10298      (if_then_else
10299        (and (eq_attr "type" "rotate")
10300             (and (match_operand 2 "const1_operand")
10301                  (ior (match_test "TARGET_SHIFT1")
10302                       (match_test "optimize_function_for_size_p (cfun)"))))
10303        (const_string "0")
10304        (const_string "*")))
10305    (set_attr "mode" "SI")])
10307 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10308 (define_split
10309   [(set (match_operand:DI 0 "register_operand")
10310         (zero_extend:DI
10311           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10312                      (match_operand:QI 2 "immediate_operand"))))
10313    (clobber (reg:CC FLAGS_REG))]
10314   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10315   [(set (match_dup 0)
10316         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10318   operands[2]
10319     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10322 (define_split
10323   [(set (match_operand:DI 0 "register_operand")
10324         (zero_extend:DI
10325           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10326                        (match_operand:QI 2 "immediate_operand"))))
10327    (clobber (reg:CC FLAGS_REG))]
10328   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10329   [(set (match_dup 0)
10330         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10332 (define_insn "*<rotate_insn><mode>3_1"
10333   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10334         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10335                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10336    (clobber (reg:CC FLAGS_REG))]
10337   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10339   if (operands[2] == const1_rtx
10340       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10341     return "<rotate>{<imodesuffix>}\t%0";
10342   else
10343     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10345   [(set_attr "type" "rotate")
10346    (set (attr "length_immediate")
10347      (if_then_else
10348        (and (match_operand 2 "const1_operand")
10349             (ior (match_test "TARGET_SHIFT1")
10350                  (match_test "optimize_function_for_size_p (cfun)")))
10351        (const_string "0")
10352        (const_string "*")))
10353    (set_attr "mode" "<MODE>")])
10355 (define_insn "*<rotate_insn>qi3_1_slp"
10356   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10357         (any_rotate:QI (match_dup 0)
10358                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10359    (clobber (reg:CC FLAGS_REG))]
10360   "(optimize_function_for_size_p (cfun)
10361     || !TARGET_PARTIAL_REG_STALL
10362     || (operands[1] == const1_rtx
10363         && TARGET_SHIFT1))"
10365   if (operands[1] == const1_rtx
10366       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10367     return "<rotate>{b}\t%0";
10368   else
10369     return "<rotate>{b}\t{%1, %0|%0, %1}";
10371   [(set_attr "type" "rotate1")
10372    (set (attr "length_immediate")
10373      (if_then_else
10374        (and (match_operand 1 "const1_operand")
10375             (ior (match_test "TARGET_SHIFT1")
10376                  (match_test "optimize_function_for_size_p (cfun)")))
10377        (const_string "0")
10378        (const_string "*")))
10379    (set_attr "mode" "QI")])
10381 (define_split
10382  [(set (match_operand:HI 0 "register_operand")
10383        (any_rotate:HI (match_dup 0) (const_int 8)))
10384   (clobber (reg:CC FLAGS_REG))]
10385  "reload_completed
10386   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10387  [(parallel [(set (strict_low_part (match_dup 0))
10388                   (bswap:HI (match_dup 0)))
10389              (clobber (reg:CC FLAGS_REG))])])
10391 ;; Bit set / bit test instructions
10393 (define_expand "extv"
10394   [(set (match_operand:SI 0 "register_operand")
10395         (sign_extract:SI (match_operand:SI 1 "register_operand")
10396                          (match_operand:SI 2 "const8_operand")
10397                          (match_operand:SI 3 "const8_operand")))]
10398   ""
10400   /* Handle extractions from %ah et al.  */
10401   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10402     FAIL;
10404   /* From mips.md: extract_bit_field doesn't verify that our source
10405      matches the predicate, so check it again here.  */
10406   if (! ext_register_operand (operands[1], VOIDmode))
10407     FAIL;
10410 (define_expand "extzv"
10411   [(set (match_operand:SI 0 "register_operand")
10412         (zero_extract:SI (match_operand 1 "ext_register_operand")
10413                          (match_operand:SI 2 "const8_operand")
10414                          (match_operand:SI 3 "const8_operand")))]
10415   ""
10417   /* Handle extractions from %ah et al.  */
10418   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10419     FAIL;
10421   /* From mips.md: extract_bit_field doesn't verify that our source
10422      matches the predicate, so check it again here.  */
10423   if (! ext_register_operand (operands[1], VOIDmode))
10424     FAIL;
10427 (define_expand "insv"
10428   [(set (zero_extract (match_operand 0 "register_operand")
10429                       (match_operand 1 "const_int_operand")
10430                       (match_operand 2 "const_int_operand"))
10431         (match_operand 3 "register_operand"))]
10432   ""
10434   rtx (*gen_mov_insv_1) (rtx, rtx);
10436   if (ix86_expand_pinsr (operands))
10437     DONE;
10439   /* Handle insertions to %ah et al.  */
10440   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10441     FAIL;
10443   /* From mips.md: insert_bit_field doesn't verify that our source
10444      matches the predicate, so check it again here.  */
10445   if (! ext_register_operand (operands[0], VOIDmode))
10446     FAIL;
10448   gen_mov_insv_1 = (TARGET_64BIT
10449                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10451   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10452   DONE;
10455 ;; %%% bts, btr, btc, bt.
10456 ;; In general these instructions are *slow* when applied to memory,
10457 ;; since they enforce atomic operation.  When applied to registers,
10458 ;; it depends on the cpu implementation.  They're never faster than
10459 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10460 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10461 ;; within the instruction itself, so operating on bits in the high
10462 ;; 32-bits of a register becomes easier.
10464 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10465 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10466 ;; negdf respectively, so they can never be disabled entirely.
10468 (define_insn "*btsq"
10469   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10470                          (const_int 1)
10471                          (match_operand:DI 1 "const_0_to_63_operand"))
10472         (const_int 1))
10473    (clobber (reg:CC FLAGS_REG))]
10474   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10475   "bts{q}\t{%1, %0|%0, %1}"
10476   [(set_attr "type" "alu1")
10477    (set_attr "prefix_0f" "1")
10478    (set_attr "mode" "DI")])
10480 (define_insn "*btrq"
10481   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10482                          (const_int 1)
10483                          (match_operand:DI 1 "const_0_to_63_operand"))
10484         (const_int 0))
10485    (clobber (reg:CC FLAGS_REG))]
10486   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10487   "btr{q}\t{%1, %0|%0, %1}"
10488   [(set_attr "type" "alu1")
10489    (set_attr "prefix_0f" "1")
10490    (set_attr "mode" "DI")])
10492 (define_insn "*btcq"
10493   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10494                          (const_int 1)
10495                          (match_operand:DI 1 "const_0_to_63_operand"))
10496         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10497    (clobber (reg:CC FLAGS_REG))]
10498   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10499   "btc{q}\t{%1, %0|%0, %1}"
10500   [(set_attr "type" "alu1")
10501    (set_attr "prefix_0f" "1")
10502    (set_attr "mode" "DI")])
10504 ;; Allow Nocona to avoid these instructions if a register is available.
10506 (define_peephole2
10507   [(match_scratch:DI 2 "r")
10508    (parallel [(set (zero_extract:DI
10509                      (match_operand:DI 0 "register_operand")
10510                      (const_int 1)
10511                      (match_operand:DI 1 "const_0_to_63_operand"))
10512                    (const_int 1))
10513               (clobber (reg:CC FLAGS_REG))])]
10514   "TARGET_64BIT && !TARGET_USE_BT"
10515   [(const_int 0)]
10517   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10518   rtx op1;
10520   if (HOST_BITS_PER_WIDE_INT >= 64)
10521     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10522   else if (i < HOST_BITS_PER_WIDE_INT)
10523     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10524   else
10525     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10527   op1 = immed_double_const (lo, hi, DImode);
10528   if (i >= 31)
10529     {
10530       emit_move_insn (operands[2], op1);
10531       op1 = operands[2];
10532     }
10534   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10535   DONE;
10538 (define_peephole2
10539   [(match_scratch:DI 2 "r")
10540    (parallel [(set (zero_extract:DI
10541                      (match_operand:DI 0 "register_operand")
10542                      (const_int 1)
10543                      (match_operand:DI 1 "const_0_to_63_operand"))
10544                    (const_int 0))
10545               (clobber (reg:CC FLAGS_REG))])]
10546   "TARGET_64BIT && !TARGET_USE_BT"
10547   [(const_int 0)]
10549   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10550   rtx op1;
10552   if (HOST_BITS_PER_WIDE_INT >= 64)
10553     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10554   else if (i < HOST_BITS_PER_WIDE_INT)
10555     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10556   else
10557     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10559   op1 = immed_double_const (~lo, ~hi, DImode);
10560   if (i >= 32)
10561     {
10562       emit_move_insn (operands[2], op1);
10563       op1 = operands[2];
10564     }
10566   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10567   DONE;
10570 (define_peephole2
10571   [(match_scratch:DI 2 "r")
10572    (parallel [(set (zero_extract:DI
10573                      (match_operand:DI 0 "register_operand")
10574                      (const_int 1)
10575                      (match_operand:DI 1 "const_0_to_63_operand"))
10576               (not:DI (zero_extract:DI
10577                         (match_dup 0) (const_int 1) (match_dup 1))))
10578               (clobber (reg:CC FLAGS_REG))])]
10579   "TARGET_64BIT && !TARGET_USE_BT"
10580   [(const_int 0)]
10582   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10583   rtx op1;
10585   if (HOST_BITS_PER_WIDE_INT >= 64)
10586     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10587   else if (i < HOST_BITS_PER_WIDE_INT)
10588     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10589   else
10590     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10592   op1 = immed_double_const (lo, hi, DImode);
10593   if (i >= 31)
10594     {
10595       emit_move_insn (operands[2], op1);
10596       op1 = operands[2];
10597     }
10599   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10600   DONE;
10603 (define_insn "*bt<mode>"
10604   [(set (reg:CCC FLAGS_REG)
10605         (compare:CCC
10606           (zero_extract:SWI48
10607             (match_operand:SWI48 0 "register_operand" "r")
10608             (const_int 1)
10609             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10610           (const_int 0)))]
10611   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10612   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10613   [(set_attr "type" "alu1")
10614    (set_attr "prefix_0f" "1")
10615    (set_attr "mode" "<MODE>")])
10617 ;; Store-flag instructions.
10619 ;; For all sCOND expanders, also expand the compare or test insn that
10620 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10622 (define_insn_and_split "*setcc_di_1"
10623   [(set (match_operand:DI 0 "register_operand" "=q")
10624         (match_operator:DI 1 "ix86_comparison_operator"
10625           [(reg FLAGS_REG) (const_int 0)]))]
10626   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10627   "#"
10628   "&& reload_completed"
10629   [(set (match_dup 2) (match_dup 1))
10630    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10632   PUT_MODE (operands[1], QImode);
10633   operands[2] = gen_lowpart (QImode, operands[0]);
10636 (define_insn_and_split "*setcc_si_1_and"
10637   [(set (match_operand:SI 0 "register_operand" "=q")
10638         (match_operator:SI 1 "ix86_comparison_operator"
10639           [(reg FLAGS_REG) (const_int 0)]))
10640    (clobber (reg:CC FLAGS_REG))]
10641   "!TARGET_PARTIAL_REG_STALL
10642    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10643   "#"
10644   "&& reload_completed"
10645   [(set (match_dup 2) (match_dup 1))
10646    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10647               (clobber (reg:CC FLAGS_REG))])]
10649   PUT_MODE (operands[1], QImode);
10650   operands[2] = gen_lowpart (QImode, operands[0]);
10653 (define_insn_and_split "*setcc_si_1_movzbl"
10654   [(set (match_operand:SI 0 "register_operand" "=q")
10655         (match_operator:SI 1 "ix86_comparison_operator"
10656           [(reg FLAGS_REG) (const_int 0)]))]
10657   "!TARGET_PARTIAL_REG_STALL
10658    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10659   "#"
10660   "&& reload_completed"
10661   [(set (match_dup 2) (match_dup 1))
10662    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10664   PUT_MODE (operands[1], QImode);
10665   operands[2] = gen_lowpart (QImode, operands[0]);
10668 (define_insn "*setcc_qi"
10669   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10670         (match_operator:QI 1 "ix86_comparison_operator"
10671           [(reg FLAGS_REG) (const_int 0)]))]
10672   ""
10673   "set%C1\t%0"
10674   [(set_attr "type" "setcc")
10675    (set_attr "mode" "QI")])
10677 (define_insn "*setcc_qi_slp"
10678   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10679         (match_operator:QI 1 "ix86_comparison_operator"
10680           [(reg FLAGS_REG) (const_int 0)]))]
10681   ""
10682   "set%C1\t%0"
10683   [(set_attr "type" "setcc")
10684    (set_attr "mode" "QI")])
10686 ;; In general it is not safe to assume too much about CCmode registers,
10687 ;; so simplify-rtx stops when it sees a second one.  Under certain
10688 ;; conditions this is safe on x86, so help combine not create
10690 ;;      seta    %al
10691 ;;      testb   %al, %al
10692 ;;      sete    %al
10694 (define_split
10695   [(set (match_operand:QI 0 "nonimmediate_operand")
10696         (ne:QI (match_operator 1 "ix86_comparison_operator"
10697                  [(reg FLAGS_REG) (const_int 0)])
10698             (const_int 0)))]
10699   ""
10700   [(set (match_dup 0) (match_dup 1))]
10701   "PUT_MODE (operands[1], QImode);")
10703 (define_split
10704   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10705         (ne:QI (match_operator 1 "ix86_comparison_operator"
10706                  [(reg FLAGS_REG) (const_int 0)])
10707             (const_int 0)))]
10708   ""
10709   [(set (match_dup 0) (match_dup 1))]
10710   "PUT_MODE (operands[1], QImode);")
10712 (define_split
10713   [(set (match_operand:QI 0 "nonimmediate_operand")
10714         (eq:QI (match_operator 1 "ix86_comparison_operator"
10715                  [(reg FLAGS_REG) (const_int 0)])
10716             (const_int 0)))]
10717   ""
10718   [(set (match_dup 0) (match_dup 1))]
10720   rtx new_op1 = copy_rtx (operands[1]);
10721   operands[1] = new_op1;
10722   PUT_MODE (new_op1, QImode);
10723   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10724                                              GET_MODE (XEXP (new_op1, 0))));
10726   /* Make sure that (a) the CCmode we have for the flags is strong
10727      enough for the reversed compare or (b) we have a valid FP compare.  */
10728   if (! ix86_comparison_operator (new_op1, VOIDmode))
10729     FAIL;
10732 (define_split
10733   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10734         (eq:QI (match_operator 1 "ix86_comparison_operator"
10735                  [(reg FLAGS_REG) (const_int 0)])
10736             (const_int 0)))]
10737   ""
10738   [(set (match_dup 0) (match_dup 1))]
10740   rtx new_op1 = copy_rtx (operands[1]);
10741   operands[1] = new_op1;
10742   PUT_MODE (new_op1, QImode);
10743   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10744                                              GET_MODE (XEXP (new_op1, 0))));
10746   /* Make sure that (a) the CCmode we have for the flags is strong
10747      enough for the reversed compare or (b) we have a valid FP compare.  */
10748   if (! ix86_comparison_operator (new_op1, VOIDmode))
10749     FAIL;
10752 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10753 ;; subsequent logical operations are used to imitate conditional moves.
10754 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10755 ;; it directly.
10757 (define_insn "setcc_<mode>_sse"
10758   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10759         (match_operator:MODEF 3 "sse_comparison_operator"
10760           [(match_operand:MODEF 1 "register_operand" "0,x")
10761            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10762   "SSE_FLOAT_MODE_P (<MODE>mode)"
10763   "@
10764    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10765    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10766   [(set_attr "isa" "noavx,avx")
10767    (set_attr "type" "ssecmp")
10768    (set_attr "length_immediate" "1")
10769    (set_attr "prefix" "orig,vex")
10770    (set_attr "mode" "<MODE>")])
10772 ;; Basic conditional jump instructions.
10773 ;; We ignore the overflow flag for signed branch instructions.
10775 (define_insn "*jcc_1"
10776   [(set (pc)
10777         (if_then_else (match_operator 1 "ix86_comparison_operator"
10778                                       [(reg FLAGS_REG) (const_int 0)])
10779                       (label_ref (match_operand 0))
10780                       (pc)))]
10781   ""
10782   "%!%+j%C1\t%l0"
10783   [(set_attr "type" "ibr")
10784    (set_attr "modrm" "0")
10785    (set (attr "length_nobnd")
10786            (if_then_else (and (ge (minus (match_dup 0) (pc))
10787                                   (const_int -126))
10788                               (lt (minus (match_dup 0) (pc))
10789                                   (const_int 128)))
10790              (const_int 2)
10791              (const_int 6)))])
10793 (define_insn "*jcc_2"
10794   [(set (pc)
10795         (if_then_else (match_operator 1 "ix86_comparison_operator"
10796                                       [(reg FLAGS_REG) (const_int 0)])
10797                       (pc)
10798                       (label_ref (match_operand 0))))]
10799   ""
10800   "%!%+j%c1\t%l0"
10801   [(set_attr "type" "ibr")
10802    (set_attr "modrm" "0")
10803    (set (attr "length_nobnd")
10804            (if_then_else (and (ge (minus (match_dup 0) (pc))
10805                                   (const_int -126))
10806                               (lt (minus (match_dup 0) (pc))
10807                                   (const_int 128)))
10808              (const_int 2)
10809              (const_int 6)))])
10811 ;; In general it is not safe to assume too much about CCmode registers,
10812 ;; so simplify-rtx stops when it sees a second one.  Under certain
10813 ;; conditions this is safe on x86, so help combine not create
10815 ;;      seta    %al
10816 ;;      testb   %al, %al
10817 ;;      je      Lfoo
10819 (define_split
10820   [(set (pc)
10821         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10822                                       [(reg FLAGS_REG) (const_int 0)])
10823                           (const_int 0))
10824                       (label_ref (match_operand 1))
10825                       (pc)))]
10826   ""
10827   [(set (pc)
10828         (if_then_else (match_dup 0)
10829                       (label_ref (match_dup 1))
10830                       (pc)))]
10831   "PUT_MODE (operands[0], VOIDmode);")
10833 (define_split
10834   [(set (pc)
10835         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10836                                       [(reg FLAGS_REG) (const_int 0)])
10837                           (const_int 0))
10838                       (label_ref (match_operand 1))
10839                       (pc)))]
10840   ""
10841   [(set (pc)
10842         (if_then_else (match_dup 0)
10843                       (label_ref (match_dup 1))
10844                       (pc)))]
10846   rtx new_op0 = copy_rtx (operands[0]);
10847   operands[0] = new_op0;
10848   PUT_MODE (new_op0, VOIDmode);
10849   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10850                                              GET_MODE (XEXP (new_op0, 0))));
10852   /* Make sure that (a) the CCmode we have for the flags is strong
10853      enough for the reversed compare or (b) we have a valid FP compare.  */
10854   if (! ix86_comparison_operator (new_op0, VOIDmode))
10855     FAIL;
10858 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10859 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10860 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10861 ;; appropriate modulo of the bit offset value.
10863 (define_insn_and_split "*jcc_bt<mode>"
10864   [(set (pc)
10865         (if_then_else (match_operator 0 "bt_comparison_operator"
10866                         [(zero_extract:SWI48
10867                            (match_operand:SWI48 1 "register_operand" "r")
10868                            (const_int 1)
10869                            (zero_extend:SI
10870                              (match_operand:QI 2 "register_operand" "r")))
10871                          (const_int 0)])
10872                       (label_ref (match_operand 3))
10873                       (pc)))
10874    (clobber (reg:CC FLAGS_REG))]
10875   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10876   "#"
10877   "&& 1"
10878   [(set (reg:CCC FLAGS_REG)
10879         (compare:CCC
10880           (zero_extract:SWI48
10881             (match_dup 1)
10882             (const_int 1)
10883             (match_dup 2))
10884           (const_int 0)))
10885    (set (pc)
10886         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10887                       (label_ref (match_dup 3))
10888                       (pc)))]
10890   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10892   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10895 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
10896 ;; zero extended to SImode.
10897 (define_insn_and_split "*jcc_bt<mode>_1"
10898   [(set (pc)
10899         (if_then_else (match_operator 0 "bt_comparison_operator"
10900                         [(zero_extract:SWI48
10901                            (match_operand:SWI48 1 "register_operand" "r")
10902                            (const_int 1)
10903                            (match_operand:SI 2 "register_operand" "r"))
10904                          (const_int 0)])
10905                       (label_ref (match_operand 3))
10906                       (pc)))
10907    (clobber (reg:CC FLAGS_REG))]
10908   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10909   "#"
10910   "&& 1"
10911   [(set (reg:CCC FLAGS_REG)
10912         (compare:CCC
10913           (zero_extract:SWI48
10914             (match_dup 1)
10915             (const_int 1)
10916             (match_dup 2))
10917           (const_int 0)))
10918    (set (pc)
10919         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10920                       (label_ref (match_dup 3))
10921                       (pc)))]
10923   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10925   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10928 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10929 ;; also for DImode, this is what combine produces.
10930 (define_insn_and_split "*jcc_bt<mode>_mask"
10931   [(set (pc)
10932         (if_then_else (match_operator 0 "bt_comparison_operator"
10933                         [(zero_extract:SWI48
10934                            (match_operand:SWI48 1 "register_operand" "r")
10935                            (const_int 1)
10936                            (and:SI
10937                              (match_operand:SI 2 "register_operand" "r")
10938                              (match_operand:SI 3 "const_int_operand" "n")))])
10939                       (label_ref (match_operand 4))
10940                       (pc)))
10941    (clobber (reg:CC FLAGS_REG))]
10942   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10943    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10944       == GET_MODE_BITSIZE (<MODE>mode)-1"
10945   "#"
10946   "&& 1"
10947   [(set (reg:CCC FLAGS_REG)
10948         (compare:CCC
10949           (zero_extract:SWI48
10950             (match_dup 1)
10951             (const_int 1)
10952             (match_dup 2))
10953           (const_int 0)))
10954    (set (pc)
10955         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10956                       (label_ref (match_dup 4))
10957                       (pc)))]
10959   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10961   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10964 (define_insn_and_split "*jcc_btsi_1"
10965   [(set (pc)
10966         (if_then_else (match_operator 0 "bt_comparison_operator"
10967                         [(and:SI
10968                            (lshiftrt:SI
10969                              (match_operand:SI 1 "register_operand" "r")
10970                              (match_operand:QI 2 "register_operand" "r"))
10971                            (const_int 1))
10972                          (const_int 0)])
10973                       (label_ref (match_operand 3))
10974                       (pc)))
10975    (clobber (reg:CC FLAGS_REG))]
10976   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10977   "#"
10978   "&& 1"
10979   [(set (reg:CCC FLAGS_REG)
10980         (compare:CCC
10981           (zero_extract:SI
10982             (match_dup 1)
10983             (const_int 1)
10984             (match_dup 2))
10985           (const_int 0)))
10986    (set (pc)
10987         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10988                       (label_ref (match_dup 3))
10989                       (pc)))]
10991   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10993   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10996 ;; avoid useless masking of bit offset operand
10997 (define_insn_and_split "*jcc_btsi_mask_1"
10998   [(set (pc)
10999         (if_then_else
11000           (match_operator 0 "bt_comparison_operator"
11001             [(and:SI
11002                (lshiftrt:SI
11003                  (match_operand:SI 1 "register_operand" "r")
11004                  (subreg:QI
11005                    (and:SI
11006                      (match_operand:SI 2 "register_operand" "r")
11007                      (match_operand:SI 3 "const_int_operand" "n")) 0))
11008                (const_int 1))
11009              (const_int 0)])
11010           (label_ref (match_operand 4))
11011           (pc)))
11012    (clobber (reg:CC FLAGS_REG))]
11013   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11014    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11015   "#"
11016   "&& 1"
11017   [(set (reg:CCC FLAGS_REG)
11018         (compare:CCC
11019           (zero_extract:SI
11020             (match_dup 1)
11021             (const_int 1)
11022             (match_dup 2))
11023           (const_int 0)))
11024    (set (pc)
11025         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11026                       (label_ref (match_dup 4))
11027                       (pc)))]
11028   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11030 ;; Define combination compare-and-branch fp compare instructions to help
11031 ;; combine.
11033 (define_insn "*jcc<mode>_0_i387"
11034   [(set (pc)
11035         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11036                         [(match_operand:X87MODEF 1 "register_operand" "f")
11037                          (match_operand:X87MODEF 2 "const0_operand")])
11038           (label_ref (match_operand 3))
11039           (pc)))
11040    (clobber (reg:CCFP FPSR_REG))
11041    (clobber (reg:CCFP FLAGS_REG))
11042    (clobber (match_scratch:HI 4 "=a"))]
11043   "TARGET_80387 && !TARGET_CMOVE"
11044   "#")
11046 (define_insn "*jcc<mode>_0_r_i387"
11047   [(set (pc)
11048         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11049                         [(match_operand:X87MODEF 1 "register_operand" "f")
11050                          (match_operand:X87MODEF 2 "const0_operand")])
11051           (pc)
11052           (label_ref (match_operand 3))))
11053    (clobber (reg:CCFP FPSR_REG))
11054    (clobber (reg:CCFP FLAGS_REG))
11055    (clobber (match_scratch:HI 4 "=a"))]
11056   "TARGET_80387 && !TARGET_CMOVE"
11057   "#")
11059 (define_insn "*jccxf_i387"
11060   [(set (pc)
11061         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11062                         [(match_operand:XF 1 "register_operand" "f")
11063                          (match_operand:XF 2 "register_operand" "f")])
11064           (label_ref (match_operand 3))
11065           (pc)))
11066    (clobber (reg:CCFP FPSR_REG))
11067    (clobber (reg:CCFP FLAGS_REG))
11068    (clobber (match_scratch:HI 4 "=a"))]
11069   "TARGET_80387 && !TARGET_CMOVE"
11070   "#")
11072 (define_insn "*jccxf_r_i387"
11073   [(set (pc)
11074         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11075                         [(match_operand:XF 1 "register_operand" "f")
11076                          (match_operand:XF 2 "register_operand" "f")])
11077           (pc)
11078           (label_ref (match_operand 3))))
11079    (clobber (reg:CCFP FPSR_REG))
11080    (clobber (reg:CCFP FLAGS_REG))
11081    (clobber (match_scratch:HI 4 "=a"))]
11082   "TARGET_80387 && !TARGET_CMOVE"
11083   "#")
11085 (define_insn "*jcc<mode>_i387"
11086   [(set (pc)
11087         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11088                         [(match_operand:MODEF 1 "register_operand" "f")
11089                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11090           (label_ref (match_operand 3))
11091           (pc)))
11092    (clobber (reg:CCFP FPSR_REG))
11093    (clobber (reg:CCFP FLAGS_REG))
11094    (clobber (match_scratch:HI 4 "=a"))]
11095   "TARGET_80387 && !TARGET_CMOVE"
11096   "#")
11098 (define_insn "*jcc<mode>_r_i387"
11099   [(set (pc)
11100         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11101                         [(match_operand:MODEF 1 "register_operand" "f")
11102                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11103           (pc)
11104           (label_ref (match_operand 3))))
11105    (clobber (reg:CCFP FPSR_REG))
11106    (clobber (reg:CCFP FLAGS_REG))
11107    (clobber (match_scratch:HI 4 "=a"))]
11108   "TARGET_80387 && !TARGET_CMOVE"
11109   "#")
11111 (define_insn "*jccu<mode>_i387"
11112   [(set (pc)
11113         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11114                         [(match_operand:X87MODEF 1 "register_operand" "f")
11115                          (match_operand:X87MODEF 2 "register_operand" "f")])
11116           (label_ref (match_operand 3))
11117           (pc)))
11118    (clobber (reg:CCFP FPSR_REG))
11119    (clobber (reg:CCFP FLAGS_REG))
11120    (clobber (match_scratch:HI 4 "=a"))]
11121   "TARGET_80387 && !TARGET_CMOVE"
11122   "#")
11124 (define_insn "*jccu<mode>_r_i387"
11125   [(set (pc)
11126         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11127                         [(match_operand:X87MODEF 1 "register_operand" "f")
11128                          (match_operand:X87MODEF 2 "register_operand" "f")])
11129           (pc)
11130           (label_ref (match_operand 3))))
11131    (clobber (reg:CCFP FPSR_REG))
11132    (clobber (reg:CCFP FLAGS_REG))
11133    (clobber (match_scratch:HI 4 "=a"))]
11134   "TARGET_80387 && !TARGET_CMOVE"
11135   "#")
11137 (define_split
11138   [(set (pc)
11139         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11140                         [(match_operand:X87MODEF 1 "register_operand")
11141                          (match_operand:X87MODEF 2 "nonimmediate_operand")])
11142           (match_operand 3)
11143           (match_operand 4)))
11144    (clobber (reg:CCFP FPSR_REG))
11145    (clobber (reg:CCFP FLAGS_REG))]
11146   "TARGET_80387 && !TARGET_CMOVE
11147    && reload_completed"
11148   [(const_int 0)]
11150   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11151                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11152   DONE;
11155 (define_split
11156   [(set (pc)
11157         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11158                         [(match_operand:X87MODEF 1 "register_operand")
11159                          (match_operand:X87MODEF 2 "general_operand")])
11160           (match_operand 3)
11161           (match_operand 4)))
11162    (clobber (reg:CCFP FPSR_REG))
11163    (clobber (reg:CCFP FLAGS_REG))
11164    (clobber (match_scratch:HI 5))]
11165   "TARGET_80387 && !TARGET_CMOVE
11166    && reload_completed"
11167   [(const_int 0)]
11169   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11170                         operands[3], operands[4], operands[5], NULL_RTX);
11171   DONE;
11174 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11175 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11176 ;; with a precedence over other operators and is always put in the first
11177 ;; place. Swap condition and operands to match ficom instruction.
11179 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11180   [(set (pc)
11181         (if_then_else
11182           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11183             [(match_operator:X87MODEF 1 "float_operator"
11184               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11185              (match_operand:X87MODEF 3 "register_operand" "f,f")])
11186           (label_ref (match_operand 4))
11187           (pc)))
11188    (clobber (reg:CCFP FPSR_REG))
11189    (clobber (reg:CCFP FLAGS_REG))
11190    (clobber (match_scratch:HI 5 "=a,a"))]
11191   "TARGET_80387 && !TARGET_CMOVE
11192    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11193        || optimize_function_for_size_p (cfun))"
11194   "#")
11196 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11197   [(set (pc)
11198         (if_then_else
11199           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11200             [(match_operator:X87MODEF 1 "float_operator"
11201               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11202              (match_operand:X87MODEF 3 "register_operand" "f,f")])
11203           (pc)
11204           (label_ref (match_operand 4))))
11205    (clobber (reg:CCFP FPSR_REG))
11206    (clobber (reg:CCFP FLAGS_REG))
11207    (clobber (match_scratch:HI 5 "=a,a"))]
11208   "TARGET_80387 && !TARGET_CMOVE
11209    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11210        || optimize_function_for_size_p (cfun))"
11211   "#")
11213 (define_split
11214   [(set (pc)
11215         (if_then_else
11216           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11217             [(match_operator:X87MODEF 1 "float_operator"
11218               [(match_operand:SWI24 2 "memory_operand")])
11219              (match_operand:X87MODEF 3 "register_operand")])
11220           (match_operand 4)
11221           (match_operand 5)))
11222    (clobber (reg:CCFP FPSR_REG))
11223    (clobber (reg:CCFP FLAGS_REG))
11224    (clobber (match_scratch:HI 6))]
11225   "TARGET_80387 && !TARGET_CMOVE
11226    && reload_completed"
11227   [(const_int 0)]
11229   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11230                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11231                         operands[4], operands[5], operands[6], NULL_RTX);
11232   DONE;
11235 ;; %%% Kill this when reload knows how to do it.
11236 (define_split
11237   [(set (pc)
11238         (if_then_else
11239           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11240             [(match_operator:X87MODEF 1 "float_operator"
11241               [(match_operand:SWI24 2 "register_operand")])
11242              (match_operand:X87MODEF 3 "register_operand")])
11243           (match_operand 4)
11244           (match_operand 5)))
11245    (clobber (reg:CCFP FPSR_REG))
11246    (clobber (reg:CCFP FLAGS_REG))
11247    (clobber (match_scratch:HI 6))]
11248   "TARGET_80387 && !TARGET_CMOVE
11249    && reload_completed"
11250   [(const_int 0)]
11252   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11254   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11255                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]),
11256                         operands[4], operands[5], operands[6], operands[2]);
11257   DONE;
11260 ;; Unconditional and other jump instructions
11262 (define_insn "jump"
11263   [(set (pc)
11264         (label_ref (match_operand 0)))]
11265   ""
11266   "%!jmp\t%l0"
11267   [(set_attr "type" "ibr")
11268    (set (attr "length_nobnd")
11269            (if_then_else (and (ge (minus (match_dup 0) (pc))
11270                                   (const_int -126))
11271                               (lt (minus (match_dup 0) (pc))
11272                                   (const_int 128)))
11273              (const_int 2)
11274              (const_int 5)))
11275    (set_attr "modrm" "0")])
11277 (define_expand "indirect_jump"
11278   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11279   ""
11281   if (TARGET_X32)
11282     operands[0] = convert_memory_address (word_mode, operands[0]);
11285 (define_insn "*indirect_jump"
11286   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11287   ""
11288   "%!jmp\t%A0"
11289   [(set_attr "type" "ibr")
11290    (set_attr "length_immediate" "0")])
11292 (define_expand "tablejump"
11293   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11294               (use (label_ref (match_operand 1)))])]
11295   ""
11297   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11298      relative.  Convert the relative address to an absolute address.  */
11299   if (flag_pic)
11300     {
11301       rtx op0, op1;
11302       enum rtx_code code;
11304       /* We can't use @GOTOFF for text labels on VxWorks;
11305          see gotoff_operand.  */
11306       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11307         {
11308           code = PLUS;
11309           op0 = operands[0];
11310           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11311         }
11312       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11313         {
11314           code = PLUS;
11315           op0 = operands[0];
11316           op1 = pic_offset_table_rtx;
11317         }
11318       else
11319         {
11320           code = MINUS;
11321           op0 = pic_offset_table_rtx;
11322           op1 = operands[0];
11323         }
11325       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11326                                          OPTAB_DIRECT);
11327     }
11329   if (TARGET_X32)
11330     operands[0] = convert_memory_address (word_mode, operands[0]);
11333 (define_insn "*tablejump_1"
11334   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11335    (use (label_ref (match_operand 1)))]
11336   ""
11337   "%!jmp\t%A0"
11338   [(set_attr "type" "ibr")
11339    (set_attr "length_immediate" "0")])
11341 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11343 (define_peephole2
11344   [(set (reg FLAGS_REG) (match_operand 0))
11345    (set (match_operand:QI 1 "register_operand")
11346         (match_operator:QI 2 "ix86_comparison_operator"
11347           [(reg FLAGS_REG) (const_int 0)]))
11348    (set (match_operand 3 "q_regs_operand")
11349         (zero_extend (match_dup 1)))]
11350   "(peep2_reg_dead_p (3, operands[1])
11351     || operands_match_p (operands[1], operands[3]))
11352    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11353   [(set (match_dup 4) (match_dup 0))
11354    (set (strict_low_part (match_dup 5))
11355         (match_dup 2))]
11357   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11358   operands[5] = gen_lowpart (QImode, operands[3]);
11359   ix86_expand_clear (operands[3]);
11362 (define_peephole2
11363   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11364               (match_operand 4)])
11365    (set (match_operand:QI 1 "register_operand")
11366         (match_operator:QI 2 "ix86_comparison_operator"
11367           [(reg FLAGS_REG) (const_int 0)]))
11368    (set (match_operand 3 "q_regs_operand")
11369         (zero_extend (match_dup 1)))]
11370   "(peep2_reg_dead_p (3, operands[1])
11371     || operands_match_p (operands[1], operands[3]))
11372    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11373   [(parallel [(set (match_dup 5) (match_dup 0))
11374               (match_dup 4)])
11375    (set (strict_low_part (match_dup 6))
11376         (match_dup 2))]
11378   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11379   operands[6] = gen_lowpart (QImode, operands[3]);
11380   ix86_expand_clear (operands[3]);
11383 ;; Similar, but match zero extend with andsi3.
11385 (define_peephole2
11386   [(set (reg FLAGS_REG) (match_operand 0))
11387    (set (match_operand:QI 1 "register_operand")
11388         (match_operator:QI 2 "ix86_comparison_operator"
11389           [(reg FLAGS_REG) (const_int 0)]))
11390    (parallel [(set (match_operand:SI 3 "q_regs_operand")
11391                    (and:SI (match_dup 3) (const_int 255)))
11392               (clobber (reg:CC FLAGS_REG))])]
11393   "REGNO (operands[1]) == REGNO (operands[3])
11394    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11395   [(set (match_dup 4) (match_dup 0))
11396    (set (strict_low_part (match_dup 5))
11397         (match_dup 2))]
11399   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11400   operands[5] = gen_lowpart (QImode, operands[3]);
11401   ix86_expand_clear (operands[3]);
11404 (define_peephole2
11405   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11406               (match_operand 4)])
11407    (set (match_operand:QI 1 "register_operand")
11408         (match_operator:QI 2 "ix86_comparison_operator"
11409           [(reg FLAGS_REG) (const_int 0)]))
11410    (parallel [(set (match_operand 3 "q_regs_operand")
11411                    (zero_extend (match_dup 1)))
11412               (clobber (reg:CC FLAGS_REG))])]
11413   "(peep2_reg_dead_p (3, operands[1])
11414     || operands_match_p (operands[1], operands[3]))
11415    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11416   [(parallel [(set (match_dup 5) (match_dup 0))
11417               (match_dup 4)])
11418    (set (strict_low_part (match_dup 6))
11419         (match_dup 2))]
11421   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11422   operands[6] = gen_lowpart (QImode, operands[3]);
11423   ix86_expand_clear (operands[3]);
11426 ;; Call instructions.
11428 ;; The predicates normally associated with named expanders are not properly
11429 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11430 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11432 ;; P6 processors will jump to the address after the decrement when %esp
11433 ;; is used as a call operand, so they will execute return address as a code.
11434 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11436 ;; Register constraint for call instruction.
11437 (define_mode_attr c [(SI "l") (DI "r")])
11439 ;; Call subroutine returning no value.
11441 (define_expand "call"
11442   [(call (match_operand:QI 0)
11443          (match_operand 1))
11444    (use (match_operand 2))]
11445   ""
11447   ix86_expand_call (NULL, operands[0], operands[1],
11448                     operands[2], NULL, false);
11449   DONE;
11452 (define_expand "sibcall"
11453   [(call (match_operand:QI 0)
11454          (match_operand 1))
11455    (use (match_operand 2))]
11456   ""
11458   ix86_expand_call (NULL, operands[0], operands[1],
11459                     operands[2], NULL, true);
11460   DONE;
11463 (define_insn "*call"
11464   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11465          (match_operand 1))]
11466   "!SIBLING_CALL_P (insn)"
11467   "* return ix86_output_call_insn (insn, operands[0]);"
11468   [(set_attr "type" "call")])
11470 (define_insn "*call_rex64_ms_sysv"
11471   [(match_parallel 2 "call_rex64_ms_sysv_operation"
11472     [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11473            (match_operand 1))
11474      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11475   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11476   "* return ix86_output_call_insn (insn, operands[0]);"
11477   [(set_attr "type" "call")])
11479 (define_insn "*sibcall"
11480   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11481          (match_operand 1))]
11482   "SIBLING_CALL_P (insn)"
11483   "* return ix86_output_call_insn (insn, operands[0]);"
11484   [(set_attr "type" "call")])
11486 (define_expand "call_pop"
11487   [(parallel [(call (match_operand:QI 0)
11488                     (match_operand:SI 1))
11489               (set (reg:SI SP_REG)
11490                    (plus:SI (reg:SI SP_REG)
11491                             (match_operand:SI 3)))])]
11492   "!TARGET_64BIT"
11494   ix86_expand_call (NULL, operands[0], operands[1],
11495                     operands[2], operands[3], false);
11496   DONE;
11499 (define_insn "*call_pop"
11500   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11501          (match_operand 1))
11502    (set (reg:SI SP_REG)
11503         (plus:SI (reg:SI SP_REG)
11504                  (match_operand:SI 2 "immediate_operand" "i")))]
11505   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11506   "* return ix86_output_call_insn (insn, operands[0]);"
11507   [(set_attr "type" "call")])
11509 (define_insn "*sibcall_pop"
11510   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11511          (match_operand 1))
11512    (set (reg:SI SP_REG)
11513         (plus:SI (reg:SI SP_REG)
11514                  (match_operand:SI 2 "immediate_operand" "i")))]
11515   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11516   "* return ix86_output_call_insn (insn, operands[0]);"
11517   [(set_attr "type" "call")])
11519 ;; Call subroutine, returning value in operand 0
11521 (define_expand "call_value"
11522   [(set (match_operand 0)
11523         (call (match_operand:QI 1)
11524               (match_operand 2)))
11525    (use (match_operand 3))]
11526   ""
11528   ix86_expand_call (operands[0], operands[1], operands[2],
11529                     operands[3], NULL, false);
11530   DONE;
11533 (define_expand "sibcall_value"
11534   [(set (match_operand 0)
11535         (call (match_operand:QI 1)
11536               (match_operand 2)))
11537    (use (match_operand 3))]
11538   ""
11540   ix86_expand_call (operands[0], operands[1], operands[2],
11541                     operands[3], NULL, true);
11542   DONE;
11545 (define_insn "*call_value"
11546   [(set (match_operand 0)
11547         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11548               (match_operand 2)))]
11549   "!SIBLING_CALL_P (insn)"
11550   "* return ix86_output_call_insn (insn, operands[1]);"
11551   [(set_attr "type" "callv")])
11553 (define_insn "*sibcall_value"
11554   [(set (match_operand 0)
11555         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11556               (match_operand 2)))]
11557   "SIBLING_CALL_P (insn)"
11558   "* return ix86_output_call_insn (insn, operands[1]);"
11559   [(set_attr "type" "callv")])
11561 (define_insn "*call_value_rex64_ms_sysv"
11562   [(match_parallel 3 "call_rex64_ms_sysv_operation"
11563     [(set (match_operand 0)
11564           (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11565                 (match_operand 2)))
11566      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11567  "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11568   "* return ix86_output_call_insn (insn, operands[1]);"
11569   [(set_attr "type" "callv")])
11571 (define_expand "call_value_pop"
11572   [(parallel [(set (match_operand 0)
11573                    (call (match_operand:QI 1)
11574                          (match_operand:SI 2)))
11575               (set (reg:SI SP_REG)
11576                    (plus:SI (reg:SI SP_REG)
11577                             (match_operand:SI 4)))])]
11578   "!TARGET_64BIT"
11580   ix86_expand_call (operands[0], operands[1], operands[2],
11581                     operands[3], operands[4], false);
11582   DONE;
11585 (define_insn "*call_value_pop"
11586   [(set (match_operand 0)
11587         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11588               (match_operand 2)))
11589    (set (reg:SI SP_REG)
11590         (plus:SI (reg:SI SP_REG)
11591                  (match_operand:SI 3 "immediate_operand" "i")))]
11592   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11593   "* return ix86_output_call_insn (insn, operands[1]);"
11594   [(set_attr "type" "callv")])
11596 (define_insn "*sibcall_value_pop"
11597   [(set (match_operand 0)
11598         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11599               (match_operand 2)))
11600    (set (reg:SI SP_REG)
11601         (plus:SI (reg:SI SP_REG)
11602                  (match_operand:SI 3 "immediate_operand" "i")))]
11603   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11604   "* return ix86_output_call_insn (insn, operands[1]);"
11605   [(set_attr "type" "callv")])
11607 ;; Call subroutine returning any type.
11609 (define_expand "untyped_call"
11610   [(parallel [(call (match_operand 0)
11611                     (const_int 0))
11612               (match_operand 1)
11613               (match_operand 2)])]
11614   ""
11616   int i;
11618   /* In order to give reg-stack an easier job in validating two
11619      coprocessor registers as containing a possible return value,
11620      simply pretend the untyped call returns a complex long double
11621      value. 
11623      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11624      and should have the default ABI.  */
11626   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11627                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11628                     operands[0], const0_rtx,
11629                     GEN_INT ((TARGET_64BIT
11630                               ? (ix86_abi == SYSV_ABI
11631                                  ? X86_64_SSE_REGPARM_MAX
11632                                  : X86_64_MS_SSE_REGPARM_MAX)
11633                               : X86_32_SSE_REGPARM_MAX)
11634                              - 1),
11635                     NULL, false);
11637   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11638     {
11639       rtx set = XVECEXP (operands[2], 0, i);
11640       emit_move_insn (SET_DEST (set), SET_SRC (set));
11641     }
11643   /* The optimizer does not know that the call sets the function value
11644      registers we stored in the result block.  We avoid problems by
11645      claiming that all hard registers are used and clobbered at this
11646      point.  */
11647   emit_insn (gen_blockage ());
11649   DONE;
11652 ;; Prologue and epilogue instructions
11654 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11655 ;; all of memory.  This blocks insns from being moved across this point.
11657 (define_insn "blockage"
11658   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11659   ""
11660   ""
11661   [(set_attr "length" "0")])
11663 ;; Do not schedule instructions accessing memory across this point.
11665 (define_expand "memory_blockage"
11666   [(set (match_dup 0)
11667         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11668   ""
11670   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11671   MEM_VOLATILE_P (operands[0]) = 1;
11674 (define_insn "*memory_blockage"
11675   [(set (match_operand:BLK 0)
11676         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11677   ""
11678   ""
11679   [(set_attr "length" "0")])
11681 ;; As USE insns aren't meaningful after reload, this is used instead
11682 ;; to prevent deleting instructions setting registers for PIC code
11683 (define_insn "prologue_use"
11684   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11685   ""
11686   ""
11687   [(set_attr "length" "0")])
11689 ;; Insn emitted into the body of a function to return from a function.
11690 ;; This is only done if the function's epilogue is known to be simple.
11691 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11693 (define_expand "return"
11694   [(simple_return)]
11695   "ix86_can_use_return_insn_p ()"
11697   if (crtl->args.pops_args)
11698     {
11699       rtx popc = GEN_INT (crtl->args.pops_args);
11700       emit_jump_insn (gen_simple_return_pop_internal (popc));
11701       DONE;
11702     }
11705 ;; We need to disable this for TARGET_SEH, as otherwise
11706 ;; shrink-wrapped prologue gets enabled too.  This might exceed
11707 ;; the maximum size of prologue in unwind information.
11709 (define_expand "simple_return"
11710   [(simple_return)]
11711   "!TARGET_SEH"
11713   if (crtl->args.pops_args)
11714     {
11715       rtx popc = GEN_INT (crtl->args.pops_args);
11716       emit_jump_insn (gen_simple_return_pop_internal (popc));
11717       DONE;
11718     }
11721 (define_insn "simple_return_internal"
11722   [(simple_return)]
11723   "reload_completed"
11724   "%!ret"
11725   [(set_attr "length_nobnd" "1")
11726    (set_attr "atom_unit" "jeu")
11727    (set_attr "length_immediate" "0")
11728    (set_attr "modrm" "0")])
11730 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11731 ;; instruction Athlon and K8 have.
11733 (define_insn "simple_return_internal_long"
11734   [(simple_return)
11735    (unspec [(const_int 0)] UNSPEC_REP)]
11736   "reload_completed"
11738   if (ix86_bnd_prefixed_insn_p (insn))
11739     return "%!ret";
11741   return "rep%; ret";
11743   [(set_attr "length" "2")
11744    (set_attr "atom_unit" "jeu")
11745    (set_attr "length_immediate" "0")
11746    (set_attr "prefix_rep" "1")
11747    (set_attr "modrm" "0")])
11749 (define_insn "simple_return_pop_internal"
11750   [(simple_return)
11751    (use (match_operand:SI 0 "const_int_operand"))]
11752   "reload_completed"
11753   "%!ret\t%0"
11754   [(set_attr "length_nobnd" "3")
11755    (set_attr "atom_unit" "jeu")
11756    (set_attr "length_immediate" "2")
11757    (set_attr "modrm" "0")])
11759 (define_insn "simple_return_indirect_internal"
11760   [(simple_return)
11761    (use (match_operand:SI 0 "register_operand" "r"))]
11762   "reload_completed"
11763   "%!jmp\t%A0"
11764   [(set_attr "type" "ibr")
11765    (set_attr "length_immediate" "0")])
11767 (define_insn "nop"
11768   [(const_int 0)]
11769   ""
11770   "nop"
11771   [(set_attr "length" "1")
11772    (set_attr "length_immediate" "0")
11773    (set_attr "modrm" "0")])
11775 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11776 (define_insn "nops"
11777   [(unspec_volatile [(match_operand 0 "const_int_operand")]
11778                     UNSPECV_NOPS)]
11779   "reload_completed"
11781   int num = INTVAL (operands[0]);
11783   gcc_assert (IN_RANGE (num, 1, 8));
11785   while (num--)
11786     fputs ("\tnop\n", asm_out_file);
11788   return "";
11790   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11791    (set_attr "length_immediate" "0")
11792    (set_attr "modrm" "0")])
11794 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11795 ;; branch prediction penalty for the third jump in a 16-byte
11796 ;; block on K8.
11798 (define_insn "pad"
11799   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11800   ""
11802 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11803   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11804 #else
11805   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11806      The align insn is used to avoid 3 jump instructions in the row to improve
11807      branch prediction and the benefits hardly outweigh the cost of extra 8
11808      nops on the average inserted by full alignment pseudo operation.  */
11809 #endif
11810   return "";
11812   [(set_attr "length" "16")])
11814 (define_expand "prologue"
11815   [(const_int 0)]
11816   ""
11817   "ix86_expand_prologue (); DONE;")
11819 (define_insn "set_got"
11820   [(set (match_operand:SI 0 "register_operand" "=r")
11821         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11822    (clobber (reg:CC FLAGS_REG))]
11823   "!TARGET_64BIT"
11824   "* return output_set_got (operands[0], NULL_RTX);"
11825   [(set_attr "type" "multi")
11826    (set_attr "length" "12")])
11828 (define_insn "set_got_labelled"
11829   [(set (match_operand:SI 0 "register_operand" "=r")
11830         (unspec:SI [(label_ref (match_operand 1))]
11831          UNSPEC_SET_GOT))
11832    (clobber (reg:CC FLAGS_REG))]
11833   "!TARGET_64BIT"
11834   "* return output_set_got (operands[0], operands[1]);"
11835   [(set_attr "type" "multi")
11836    (set_attr "length" "12")])
11838 (define_insn "set_got_rex64"
11839   [(set (match_operand:DI 0 "register_operand" "=r")
11840         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11841   "TARGET_64BIT"
11842   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11843   [(set_attr "type" "lea")
11844    (set_attr "length_address" "4")
11845    (set_attr "mode" "DI")])
11847 (define_insn "set_rip_rex64"
11848   [(set (match_operand:DI 0 "register_operand" "=r")
11849         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
11850   "TARGET_64BIT"
11851   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11852   [(set_attr "type" "lea")
11853    (set_attr "length_address" "4")
11854    (set_attr "mode" "DI")])
11856 (define_insn "set_got_offset_rex64"
11857   [(set (match_operand:DI 0 "register_operand" "=r")
11858         (unspec:DI
11859           [(label_ref (match_operand 1))]
11860           UNSPEC_SET_GOT_OFFSET))]
11861   "TARGET_LP64"
11862   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11863   [(set_attr "type" "imov")
11864    (set_attr "length_immediate" "0")
11865    (set_attr "length_address" "8")
11866    (set_attr "mode" "DI")])
11868 (define_expand "epilogue"
11869   [(const_int 0)]
11870   ""
11871   "ix86_expand_epilogue (1); DONE;")
11873 (define_expand "sibcall_epilogue"
11874   [(const_int 0)]
11875   ""
11876   "ix86_expand_epilogue (0); DONE;")
11878 (define_expand "eh_return"
11879   [(use (match_operand 0 "register_operand"))]
11880   ""
11882   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11884   /* Tricky bit: we write the address of the handler to which we will
11885      be returning into someone else's stack frame, one word below the
11886      stack address we wish to restore.  */
11887   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11888   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
11889   tmp = gen_rtx_MEM (Pmode, tmp);
11890   emit_move_insn (tmp, ra);
11892   emit_jump_insn (gen_eh_return_internal ());
11893   emit_barrier ();
11894   DONE;
11897 (define_insn_and_split "eh_return_internal"
11898   [(eh_return)]
11899   ""
11900   "#"
11901   "epilogue_completed"
11902   [(const_int 0)]
11903   "ix86_expand_epilogue (2); DONE;")
11905 (define_insn "leave"
11906   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11907    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11908    (clobber (mem:BLK (scratch)))]
11909   "!TARGET_64BIT"
11910   "leave"
11911   [(set_attr "type" "leave")])
11913 (define_insn "leave_rex64"
11914   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11915    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11916    (clobber (mem:BLK (scratch)))]
11917   "TARGET_64BIT"
11918   "leave"
11919   [(set_attr "type" "leave")])
11921 ;; Handle -fsplit-stack.
11923 (define_expand "split_stack_prologue"
11924   [(const_int 0)]
11925   ""
11927   ix86_expand_split_stack_prologue ();
11928   DONE;
11931 ;; In order to support the call/return predictor, we use a return
11932 ;; instruction which the middle-end doesn't see.
11933 (define_insn "split_stack_return"
11934   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
11935                      UNSPECV_SPLIT_STACK_RETURN)]
11936   ""
11938   if (operands[0] == const0_rtx)
11939     return "ret";
11940   else
11941     return "ret\t%0";
11943   [(set_attr "atom_unit" "jeu")
11944    (set_attr "modrm" "0")
11945    (set (attr "length")
11946         (if_then_else (match_operand:SI 0 "const0_operand")
11947                       (const_int 1)
11948                       (const_int 3)))
11949    (set (attr "length_immediate")
11950         (if_then_else (match_operand:SI 0 "const0_operand")
11951                       (const_int 0)
11952                       (const_int 2)))])
11954 ;; If there are operand 0 bytes available on the stack, jump to
11955 ;; operand 1.
11957 (define_expand "split_stack_space_check"
11958   [(set (pc) (if_then_else
11959               (ltu (minus (reg SP_REG)
11960                           (match_operand 0 "register_operand"))
11961                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11962               (label_ref (match_operand 1))
11963               (pc)))]
11964   ""
11966   rtx reg, size, limit;
11968   reg = gen_reg_rtx (Pmode);
11969   size = force_reg (Pmode, operands[0]);
11970   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11971   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11972                           UNSPEC_STACK_CHECK);
11973   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11974   ix86_expand_branch (GEU, reg, limit, operands[1]);
11976   DONE;
11979 ;; Bit manipulation instructions.
11981 (define_expand "ffs<mode>2"
11982   [(set (match_dup 2) (const_int -1))
11983    (parallel [(set (match_dup 3) (match_dup 4))
11984               (set (match_operand:SWI48 0 "register_operand")
11985                    (ctz:SWI48
11986                      (match_operand:SWI48 1 "nonimmediate_operand")))])
11987    (set (match_dup 0) (if_then_else:SWI48
11988                         (eq (match_dup 3) (const_int 0))
11989                         (match_dup 2)
11990                         (match_dup 0)))
11991    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11992               (clobber (reg:CC FLAGS_REG))])]
11993   ""
11995   enum machine_mode flags_mode;
11997   if (<MODE>mode == SImode && !TARGET_CMOVE)
11998     {
11999       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12000       DONE;
12001     }
12003   flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12005   operands[2] = gen_reg_rtx (<MODE>mode);
12006   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12007   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12010 (define_insn_and_split "ffssi2_no_cmove"
12011   [(set (match_operand:SI 0 "register_operand" "=r")
12012         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12013    (clobber (match_scratch:SI 2 "=&q"))
12014    (clobber (reg:CC FLAGS_REG))]
12015   "!TARGET_CMOVE"
12016   "#"
12017   "&& reload_completed"
12018   [(parallel [(set (match_dup 4) (match_dup 5))
12019               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12020    (set (strict_low_part (match_dup 3))
12021         (eq:QI (match_dup 4) (const_int 0)))
12022    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12023               (clobber (reg:CC FLAGS_REG))])
12024    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12025               (clobber (reg:CC FLAGS_REG))])
12026    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12027               (clobber (reg:CC FLAGS_REG))])]
12029   enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12031   operands[3] = gen_lowpart (QImode, operands[2]);
12032   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12033   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12035   ix86_expand_clear (operands[2]);
12038 (define_insn "*tzcnt<mode>_1"
12039   [(set (reg:CCC FLAGS_REG)
12040         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12041                      (const_int 0)))
12042    (set (match_operand:SWI48 0 "register_operand" "=r")
12043         (ctz:SWI48 (match_dup 1)))]
12044   "TARGET_BMI"
12045   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12046   [(set_attr "type" "alu1")
12047    (set_attr "prefix_0f" "1")
12048    (set_attr "prefix_rep" "1")
12049    (set_attr "btver2_decode" "double")
12050    (set_attr "mode" "<MODE>")])
12052 (define_insn "*bsf<mode>_1"
12053   [(set (reg:CCZ FLAGS_REG)
12054         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12055                      (const_int 0)))
12056    (set (match_operand:SWI48 0 "register_operand" "=r")
12057         (ctz:SWI48 (match_dup 1)))]
12058   ""
12059   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12060   [(set_attr "type" "alu1")
12061    (set_attr "prefix_0f" "1")
12062    (set_attr "btver2_decode" "double")
12063    (set_attr "mode" "<MODE>")])
12065 (define_insn "ctz<mode>2"
12066   [(set (match_operand:SWI248 0 "register_operand" "=r")
12067         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12068    (clobber (reg:CC FLAGS_REG))]
12069   ""
12071   if (TARGET_BMI)
12072     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12073   else if (optimize_function_for_size_p (cfun))
12074     ;
12075   else if (TARGET_GENERIC)
12076     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12077     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12079   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12081   [(set_attr "type" "alu1")
12082    (set_attr "prefix_0f" "1")
12083    (set (attr "prefix_rep")
12084      (if_then_else
12085        (ior (match_test "TARGET_BMI")
12086             (and (not (match_test "optimize_function_for_size_p (cfun)"))
12087                  (match_test "TARGET_GENERIC")))
12088        (const_string "1")
12089        (const_string "0")))
12090    (set_attr "mode" "<MODE>")])
12092 (define_expand "clz<mode>2"
12093   [(parallel
12094      [(set (match_operand:SWI248 0 "register_operand")
12095            (minus:SWI248
12096              (match_dup 2)
12097              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12098       (clobber (reg:CC FLAGS_REG))])
12099    (parallel
12100      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12101       (clobber (reg:CC FLAGS_REG))])]
12102   ""
12104   if (TARGET_LZCNT)
12105     {
12106       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12107       DONE;
12108     }
12109   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12112 (define_insn "clz<mode>2_lzcnt"
12113   [(set (match_operand:SWI248 0 "register_operand" "=r")
12114         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12115    (clobber (reg:CC FLAGS_REG))]
12116   "TARGET_LZCNT"
12117   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12118   [(set_attr "prefix_rep" "1")
12119    (set_attr "type" "bitmanip")
12120    (set_attr "mode" "<MODE>")])
12122 ;; BMI instructions.
12123 (define_insn "*bmi_andn_<mode>"
12124   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12125         (and:SWI48
12126           (not:SWI48
12127             (match_operand:SWI48 1 "register_operand" "r,r"))
12128             (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12129    (clobber (reg:CC FLAGS_REG))]
12130   "TARGET_BMI"
12131   "andn\t{%2, %1, %0|%0, %1, %2}"
12132   [(set_attr "type" "bitmanip")
12133    (set_attr "btver2_decode" "direct, double")
12134    (set_attr "mode" "<MODE>")])
12136 (define_insn "bmi_bextr_<mode>"
12137   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12138         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12139                        (match_operand:SWI48 2 "register_operand" "r,r")]
12140                        UNSPEC_BEXTR))
12141    (clobber (reg:CC FLAGS_REG))]
12142   "TARGET_BMI"
12143   "bextr\t{%2, %1, %0|%0, %1, %2}"
12144   [(set_attr "type" "bitmanip")
12145    (set_attr "btver2_decode" "direct, double")
12146    (set_attr "mode" "<MODE>")])
12148 (define_insn "*bmi_blsi_<mode>"
12149   [(set (match_operand:SWI48 0 "register_operand" "=r")
12150         (and:SWI48
12151           (neg:SWI48
12152             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12153           (match_dup 1)))
12154    (clobber (reg:CC FLAGS_REG))]
12155   "TARGET_BMI"
12156   "blsi\t{%1, %0|%0, %1}"
12157   [(set_attr "type" "bitmanip")
12158    (set_attr "btver2_decode" "double")
12159    (set_attr "mode" "<MODE>")])
12161 (define_insn "*bmi_blsmsk_<mode>"
12162   [(set (match_operand:SWI48 0 "register_operand" "=r")
12163         (xor:SWI48
12164           (plus:SWI48
12165             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12166             (const_int -1))
12167           (match_dup 1)))
12168    (clobber (reg:CC FLAGS_REG))]
12169   "TARGET_BMI"
12170   "blsmsk\t{%1, %0|%0, %1}"
12171   [(set_attr "type" "bitmanip")
12172    (set_attr "btver2_decode" "double")
12173    (set_attr "mode" "<MODE>")])
12175 (define_insn "*bmi_blsr_<mode>"
12176   [(set (match_operand:SWI48 0 "register_operand" "=r")
12177         (and:SWI48
12178           (plus:SWI48
12179             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12180             (const_int -1))
12181           (match_dup 1)))
12182    (clobber (reg:CC FLAGS_REG))]
12183    "TARGET_BMI"
12184    "blsr\t{%1, %0|%0, %1}"
12185   [(set_attr "type" "bitmanip")
12186    (set_attr "btver2_decode" "double")
12187    (set_attr "mode" "<MODE>")])
12189 ;; BMI2 instructions.
12190 (define_insn "bmi2_bzhi_<mode>3"
12191   [(set (match_operand:SWI48 0 "register_operand" "=r")
12192         (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12193                                    (match_operand:SWI48 2 "register_operand" "r"))
12194                    (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12195    (clobber (reg:CC FLAGS_REG))]
12196   "TARGET_BMI2"
12197   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12198   [(set_attr "type" "bitmanip")
12199    (set_attr "prefix" "vex")
12200    (set_attr "mode" "<MODE>")])
12202 (define_insn "bmi2_pdep_<mode>3"
12203   [(set (match_operand:SWI48 0 "register_operand" "=r")
12204         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12205                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12206                        UNSPEC_PDEP))]
12207   "TARGET_BMI2"
12208   "pdep\t{%2, %1, %0|%0, %1, %2}"
12209   [(set_attr "type" "bitmanip")
12210    (set_attr "prefix" "vex")
12211    (set_attr "mode" "<MODE>")])
12213 (define_insn "bmi2_pext_<mode>3"
12214   [(set (match_operand:SWI48 0 "register_operand" "=r")
12215         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12216                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12217                        UNSPEC_PEXT))]
12218   "TARGET_BMI2"
12219   "pext\t{%2, %1, %0|%0, %1, %2}"
12220   [(set_attr "type" "bitmanip")
12221    (set_attr "prefix" "vex")
12222    (set_attr "mode" "<MODE>")])
12224 ;; TBM instructions.
12225 (define_insn "tbm_bextri_<mode>"
12226   [(set (match_operand:SWI48 0 "register_operand" "=r")
12227         (zero_extract:SWI48
12228           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12229           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12230           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12231    (clobber (reg:CC FLAGS_REG))]
12232    "TARGET_TBM"
12234   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12235   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12237   [(set_attr "type" "bitmanip")
12238    (set_attr "mode" "<MODE>")])
12240 (define_insn "*tbm_blcfill_<mode>"
12241   [(set (match_operand:SWI48 0 "register_operand" "=r")
12242         (and:SWI48
12243           (plus:SWI48
12244             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12245             (const_int 1))
12246           (match_dup 1)))
12247    (clobber (reg:CC FLAGS_REG))]
12248    "TARGET_TBM"
12249    "blcfill\t{%1, %0|%0, %1}"
12250   [(set_attr "type" "bitmanip")
12251    (set_attr "mode" "<MODE>")])
12253 (define_insn "*tbm_blci_<mode>"
12254   [(set (match_operand:SWI48 0 "register_operand" "=r")
12255         (ior:SWI48
12256           (not:SWI48
12257             (plus:SWI48
12258               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12259               (const_int 1)))
12260           (match_dup 1)))
12261    (clobber (reg:CC FLAGS_REG))]
12262    "TARGET_TBM"
12263    "blci\t{%1, %0|%0, %1}"
12264   [(set_attr "type" "bitmanip")
12265    (set_attr "mode" "<MODE>")])
12267 (define_insn "*tbm_blcic_<mode>"
12268   [(set (match_operand:SWI48 0 "register_operand" "=r")
12269         (and:SWI48
12270           (plus:SWI48
12271             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12272             (const_int 1))
12273           (not:SWI48
12274             (match_dup 1))))
12275    (clobber (reg:CC FLAGS_REG))]
12276    "TARGET_TBM"
12277    "blcic\t{%1, %0|%0, %1}"
12278   [(set_attr "type" "bitmanip")
12279    (set_attr "mode" "<MODE>")])
12281 (define_insn "*tbm_blcmsk_<mode>"
12282   [(set (match_operand:SWI48 0 "register_operand" "=r")
12283         (xor:SWI48
12284           (plus:SWI48
12285             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12286             (const_int 1))
12287           (match_dup 1)))
12288    (clobber (reg:CC FLAGS_REG))]
12289    "TARGET_TBM"
12290    "blcmsk\t{%1, %0|%0, %1}"
12291   [(set_attr "type" "bitmanip")
12292    (set_attr "mode" "<MODE>")])
12294 (define_insn "*tbm_blcs_<mode>"
12295   [(set (match_operand:SWI48 0 "register_operand" "=r")
12296         (ior:SWI48
12297           (plus:SWI48
12298             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12299             (const_int 1))
12300           (match_dup 1)))
12301    (clobber (reg:CC FLAGS_REG))]
12302    "TARGET_TBM"
12303    "blcs\t{%1, %0|%0, %1}"
12304   [(set_attr "type" "bitmanip")
12305    (set_attr "mode" "<MODE>")])
12307 (define_insn "*tbm_blsfill_<mode>"
12308   [(set (match_operand:SWI48 0 "register_operand" "=r")
12309         (ior:SWI48
12310           (plus:SWI48
12311             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12312             (const_int -1))
12313           (match_dup 1)))
12314    (clobber (reg:CC FLAGS_REG))]
12315    "TARGET_TBM"
12316    "blsfill\t{%1, %0|%0, %1}"
12317   [(set_attr "type" "bitmanip")
12318    (set_attr "mode" "<MODE>")])
12320 (define_insn "*tbm_blsic_<mode>"
12321   [(set (match_operand:SWI48 0 "register_operand" "=r")
12322         (ior:SWI48
12323           (plus:SWI48
12324             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12325             (const_int -1))
12326           (not:SWI48
12327             (match_dup 1))))
12328    (clobber (reg:CC FLAGS_REG))]
12329    "TARGET_TBM"
12330    "blsic\t{%1, %0|%0, %1}"
12331   [(set_attr "type" "bitmanip")
12332    (set_attr "mode" "<MODE>")])
12334 (define_insn "*tbm_t1mskc_<mode>"
12335   [(set (match_operand:SWI48 0 "register_operand" "=r")
12336         (ior:SWI48
12337           (plus:SWI48
12338             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12339             (const_int 1))
12340           (not:SWI48
12341             (match_dup 1))))
12342    (clobber (reg:CC FLAGS_REG))]
12343    "TARGET_TBM"
12344    "t1mskc\t{%1, %0|%0, %1}"
12345   [(set_attr "type" "bitmanip")
12346    (set_attr "mode" "<MODE>")])
12348 (define_insn "*tbm_tzmsk_<mode>"
12349   [(set (match_operand:SWI48 0 "register_operand" "=r")
12350         (and:SWI48
12351           (plus:SWI48
12352             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12353             (const_int -1))
12354           (not:SWI48
12355             (match_dup 1))))
12356    (clobber (reg:CC FLAGS_REG))]
12357    "TARGET_TBM"
12358    "tzmsk\t{%1, %0|%0, %1}"
12359   [(set_attr "type" "bitmanip")
12360    (set_attr "mode" "<MODE>")])
12362 (define_insn "bsr_rex64"
12363   [(set (match_operand:DI 0 "register_operand" "=r")
12364         (minus:DI (const_int 63)
12365                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12366    (clobber (reg:CC FLAGS_REG))]
12367   "TARGET_64BIT"
12368   "bsr{q}\t{%1, %0|%0, %1}"
12369   [(set_attr "type" "alu1")
12370    (set_attr "prefix_0f" "1")
12371    (set_attr "mode" "DI")])
12373 (define_insn "bsr"
12374   [(set (match_operand:SI 0 "register_operand" "=r")
12375         (minus:SI (const_int 31)
12376                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12377    (clobber (reg:CC FLAGS_REG))]
12378   ""
12379   "bsr{l}\t{%1, %0|%0, %1}"
12380   [(set_attr "type" "alu1")
12381    (set_attr "prefix_0f" "1")
12382    (set_attr "mode" "SI")])
12384 (define_insn "*bsrhi"
12385   [(set (match_operand:HI 0 "register_operand" "=r")
12386         (minus:HI (const_int 15)
12387                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12388    (clobber (reg:CC FLAGS_REG))]
12389   ""
12390   "bsr{w}\t{%1, %0|%0, %1}"
12391   [(set_attr "type" "alu1")
12392    (set_attr "prefix_0f" "1")
12393    (set_attr "mode" "HI")])
12395 (define_insn "popcount<mode>2"
12396   [(set (match_operand:SWI248 0 "register_operand" "=r")
12397         (popcount:SWI248
12398           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12399    (clobber (reg:CC FLAGS_REG))]
12400   "TARGET_POPCNT"
12402 #if TARGET_MACHO
12403   return "popcnt\t{%1, %0|%0, %1}";
12404 #else
12405   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12406 #endif
12408   [(set_attr "prefix_rep" "1")
12409    (set_attr "type" "bitmanip")
12410    (set_attr "mode" "<MODE>")])
12412 (define_insn "*popcount<mode>2_cmp"
12413   [(set (reg FLAGS_REG)
12414         (compare
12415           (popcount:SWI248
12416             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12417           (const_int 0)))
12418    (set (match_operand:SWI248 0 "register_operand" "=r")
12419         (popcount:SWI248 (match_dup 1)))]
12420   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12422 #if TARGET_MACHO
12423   return "popcnt\t{%1, %0|%0, %1}";
12424 #else
12425   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12426 #endif
12428   [(set_attr "prefix_rep" "1")
12429    (set_attr "type" "bitmanip")
12430    (set_attr "mode" "<MODE>")])
12432 (define_insn "*popcountsi2_cmp_zext"
12433   [(set (reg FLAGS_REG)
12434         (compare
12435           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12436           (const_int 0)))
12437    (set (match_operand:DI 0 "register_operand" "=r")
12438         (zero_extend:DI(popcount:SI (match_dup 1))))]
12439   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12441 #if TARGET_MACHO
12442   return "popcnt\t{%1, %0|%0, %1}";
12443 #else
12444   return "popcnt{l}\t{%1, %0|%0, %1}";
12445 #endif
12447   [(set_attr "prefix_rep" "1")
12448    (set_attr "type" "bitmanip")
12449    (set_attr "mode" "SI")])
12451 (define_expand "bswapdi2"
12452   [(set (match_operand:DI 0 "register_operand")
12453         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12454   "TARGET_64BIT"
12456   if (!TARGET_MOVBE)
12457     operands[1] = force_reg (DImode, operands[1]);
12460 (define_expand "bswapsi2"
12461   [(set (match_operand:SI 0 "register_operand")
12462         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12463   ""
12465   if (TARGET_MOVBE)
12466     ;
12467   else if (TARGET_BSWAP)
12468     operands[1] = force_reg (SImode, operands[1]);
12469   else
12470     {
12471       rtx x = operands[0];
12473       emit_move_insn (x, operands[1]);
12474       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12475       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12476       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12477       DONE;
12478     }
12481 (define_insn "*bswap<mode>2_movbe"
12482   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12483         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12484   "TARGET_MOVBE
12485    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12486   "@
12487     bswap\t%0
12488     movbe\t{%1, %0|%0, %1}
12489     movbe\t{%1, %0|%0, %1}"
12490   [(set_attr "type" "bitmanip,imov,imov")
12491    (set_attr "modrm" "0,1,1")
12492    (set_attr "prefix_0f" "*,1,1")
12493    (set_attr "prefix_extra" "*,1,1")
12494    (set_attr "mode" "<MODE>")])
12496 (define_insn "*bswap<mode>2"
12497   [(set (match_operand:SWI48 0 "register_operand" "=r")
12498         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12499   "TARGET_BSWAP"
12500   "bswap\t%0"
12501   [(set_attr "type" "bitmanip")
12502    (set_attr "modrm" "0")
12503    (set_attr "mode" "<MODE>")])
12505 (define_insn "*bswaphi_lowpart_1"
12506   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12507         (bswap:HI (match_dup 0)))
12508    (clobber (reg:CC FLAGS_REG))]
12509   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12510   "@
12511     xchg{b}\t{%h0, %b0|%b0, %h0}
12512     rol{w}\t{$8, %0|%0, 8}"
12513   [(set_attr "length" "2,4")
12514    (set_attr "mode" "QI,HI")])
12516 (define_insn "bswaphi_lowpart"
12517   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12518         (bswap:HI (match_dup 0)))
12519    (clobber (reg:CC FLAGS_REG))]
12520   ""
12521   "rol{w}\t{$8, %0|%0, 8}"
12522   [(set_attr "length" "4")
12523    (set_attr "mode" "HI")])
12525 (define_expand "paritydi2"
12526   [(set (match_operand:DI 0 "register_operand")
12527         (parity:DI (match_operand:DI 1 "register_operand")))]
12528   "! TARGET_POPCNT"
12530   rtx scratch = gen_reg_rtx (QImode);
12531   rtx cond;
12533   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12534                                 NULL_RTX, operands[1]));
12536   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12537                          gen_rtx_REG (CCmode, FLAGS_REG),
12538                          const0_rtx);
12539   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12541   if (TARGET_64BIT)
12542     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12543   else
12544     {
12545       rtx tmp = gen_reg_rtx (SImode);
12547       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12548       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12549     }
12550   DONE;
12553 (define_expand "paritysi2"
12554   [(set (match_operand:SI 0 "register_operand")
12555         (parity:SI (match_operand:SI 1 "register_operand")))]
12556   "! TARGET_POPCNT"
12558   rtx scratch = gen_reg_rtx (QImode);
12559   rtx cond;
12561   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12563   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12564                          gen_rtx_REG (CCmode, FLAGS_REG),
12565                          const0_rtx);
12566   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12568   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12569   DONE;
12572 (define_insn_and_split "paritydi2_cmp"
12573   [(set (reg:CC FLAGS_REG)
12574         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12575                    UNSPEC_PARITY))
12576    (clobber (match_scratch:DI 0 "=r"))
12577    (clobber (match_scratch:SI 1 "=&r"))
12578    (clobber (match_scratch:HI 2 "=Q"))]
12579   "! TARGET_POPCNT"
12580   "#"
12581   "&& reload_completed"
12582   [(parallel
12583      [(set (match_dup 1)
12584            (xor:SI (match_dup 1) (match_dup 4)))
12585       (clobber (reg:CC FLAGS_REG))])
12586    (parallel
12587      [(set (reg:CC FLAGS_REG)
12588            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12589       (clobber (match_dup 1))
12590       (clobber (match_dup 2))])]
12592   operands[4] = gen_lowpart (SImode, operands[3]);
12594   if (TARGET_64BIT)
12595     {
12596       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12597       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12598     }
12599   else
12600     operands[1] = gen_highpart (SImode, operands[3]);
12603 (define_insn_and_split "paritysi2_cmp"
12604   [(set (reg:CC FLAGS_REG)
12605         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12606                    UNSPEC_PARITY))
12607    (clobber (match_scratch:SI 0 "=r"))
12608    (clobber (match_scratch:HI 1 "=&Q"))]
12609   "! TARGET_POPCNT"
12610   "#"
12611   "&& reload_completed"
12612   [(parallel
12613      [(set (match_dup 1)
12614            (xor:HI (match_dup 1) (match_dup 3)))
12615       (clobber (reg:CC FLAGS_REG))])
12616    (parallel
12617      [(set (reg:CC FLAGS_REG)
12618            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12619       (clobber (match_dup 1))])]
12621   operands[3] = gen_lowpart (HImode, operands[2]);
12623   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12624   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12627 (define_insn "*parityhi2_cmp"
12628   [(set (reg:CC FLAGS_REG)
12629         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12630                    UNSPEC_PARITY))
12631    (clobber (match_scratch:HI 0 "=Q"))]
12632   "! TARGET_POPCNT"
12633   "xor{b}\t{%h0, %b0|%b0, %h0}"
12634   [(set_attr "length" "2")
12635    (set_attr "mode" "HI")])
12638 ;; Thread-local storage patterns for ELF.
12640 ;; Note that these code sequences must appear exactly as shown
12641 ;; in order to allow linker relaxation.
12643 (define_insn "*tls_global_dynamic_32_gnu"
12644   [(set (match_operand:SI 0 "register_operand" "=a")
12645         (unspec:SI
12646          [(match_operand:SI 1 "register_operand" "b")
12647           (match_operand 2 "tls_symbolic_operand")
12648           (match_operand 3 "constant_call_address_operand" "z")]
12649          UNSPEC_TLS_GD))
12650    (clobber (match_scratch:SI 4 "=d"))
12651    (clobber (match_scratch:SI 5 "=c"))
12652    (clobber (reg:CC FLAGS_REG))]
12653   "!TARGET_64BIT && TARGET_GNU_TLS"
12655   output_asm_insn
12656     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12657   if (TARGET_SUN_TLS)
12658 #ifdef HAVE_AS_IX86_TLSGDPLT
12659     return "call\t%a2@tlsgdplt";
12660 #else
12661     return "call\t%p3@plt";
12662 #endif
12663   return "call\t%P3";
12665   [(set_attr "type" "multi")
12666    (set_attr "length" "12")])
12668 (define_expand "tls_global_dynamic_32"
12669   [(parallel
12670     [(set (match_operand:SI 0 "register_operand")
12671           (unspec:SI [(match_operand:SI 2 "register_operand")
12672                       (match_operand 1 "tls_symbolic_operand")
12673                       (match_operand 3 "constant_call_address_operand")]
12674                      UNSPEC_TLS_GD))
12675      (clobber (match_scratch:SI 4))
12676      (clobber (match_scratch:SI 5))
12677      (clobber (reg:CC FLAGS_REG))])])
12679 (define_insn "*tls_global_dynamic_64_<mode>"
12680   [(set (match_operand:P 0 "register_operand" "=a")
12681         (call:P
12682          (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12683          (match_operand 3)))
12684    (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12685              UNSPEC_TLS_GD)]
12686   "TARGET_64BIT"
12688   if (!TARGET_X32)
12689     fputs (ASM_BYTE "0x66\n", asm_out_file);
12690   output_asm_insn
12691     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12692   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12693   fputs ("\trex64\n", asm_out_file);
12694   if (TARGET_SUN_TLS)
12695     return "call\t%p2@plt";
12696   return "call\t%P2";
12698   [(set_attr "type" "multi")
12699    (set (attr "length")
12700         (symbol_ref "TARGET_X32 ? 15 : 16"))])
12702 (define_insn "*tls_global_dynamic_64_largepic"
12703   [(set (match_operand:DI 0 "register_operand" "=a")
12704         (call:DI
12705          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
12706                           (match_operand:DI 3 "immediate_operand" "i")))
12707          (match_operand 4)))
12708    (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12709              UNSPEC_TLS_GD)]
12710   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12711    && GET_CODE (operands[3]) == CONST
12712    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
12713    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
12715   output_asm_insn
12716     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12717   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
12718   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
12719   return "call\t{*%%rax|rax}";
12721   [(set_attr "type" "multi")
12722    (set_attr "length" "22")])
12724 (define_expand "tls_global_dynamic_64_<mode>"
12725   [(parallel
12726     [(set (match_operand:P 0 "register_operand")
12727           (call:P
12728            (mem:QI (match_operand 2))
12729            (const_int 0)))
12730      (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12731                UNSPEC_TLS_GD)])]
12732   "TARGET_64BIT")
12734 (define_insn "*tls_local_dynamic_base_32_gnu"
12735   [(set (match_operand:SI 0 "register_operand" "=a")
12736         (unspec:SI
12737          [(match_operand:SI 1 "register_operand" "b")
12738           (match_operand 2 "constant_call_address_operand" "z")]
12739          UNSPEC_TLS_LD_BASE))
12740    (clobber (match_scratch:SI 3 "=d"))
12741    (clobber (match_scratch:SI 4 "=c"))
12742    (clobber (reg:CC FLAGS_REG))]
12743   "!TARGET_64BIT && TARGET_GNU_TLS"
12745   output_asm_insn
12746     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12747   if (TARGET_SUN_TLS)
12748 #ifdef HAVE_AS_IX86_TLSLDMPLT
12749     return "call\t%&@tlsldmplt";
12750 #else
12751     return "call\t%p2@plt";
12752 #endif
12753   return "call\t%P2";
12755   [(set_attr "type" "multi")
12756    (set_attr "length" "11")])
12758 (define_expand "tls_local_dynamic_base_32"
12759   [(parallel
12760      [(set (match_operand:SI 0 "register_operand")
12761            (unspec:SI
12762             [(match_operand:SI 1 "register_operand")
12763              (match_operand 2 "constant_call_address_operand")]
12764             UNSPEC_TLS_LD_BASE))
12765       (clobber (match_scratch:SI 3))
12766       (clobber (match_scratch:SI 4))
12767       (clobber (reg:CC FLAGS_REG))])])
12769 (define_insn "*tls_local_dynamic_base_64_<mode>"
12770   [(set (match_operand:P 0 "register_operand" "=a")
12771         (call:P
12772          (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12773          (match_operand 2)))
12774    (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12775   "TARGET_64BIT"
12777   output_asm_insn
12778     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12779   if (TARGET_SUN_TLS)
12780     return "call\t%p1@plt";
12781   return "call\t%P1";
12783   [(set_attr "type" "multi")
12784    (set_attr "length" "12")])
12786 (define_insn "*tls_local_dynamic_base_64_largepic"
12787   [(set (match_operand:DI 0 "register_operand" "=a")
12788         (call:DI
12789          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
12790                           (match_operand:DI 2 "immediate_operand" "i")))
12791          (match_operand 3)))
12792    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12793   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12794    && GET_CODE (operands[2]) == CONST
12795    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
12796    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
12798   output_asm_insn
12799     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12800   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
12801   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
12802   return "call\t{*%%rax|rax}";
12804   [(set_attr "type" "multi")
12805    (set_attr "length" "22")])
12807 (define_expand "tls_local_dynamic_base_64_<mode>"
12808   [(parallel
12809      [(set (match_operand:P 0 "register_operand")
12810            (call:P
12811             (mem:QI (match_operand 1))
12812             (const_int 0)))
12813       (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12814   "TARGET_64BIT")
12816 ;; Local dynamic of a single variable is a lose.  Show combine how
12817 ;; to convert that back to global dynamic.
12819 (define_insn_and_split "*tls_local_dynamic_32_once"
12820   [(set (match_operand:SI 0 "register_operand" "=a")
12821         (plus:SI
12822          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12823                      (match_operand 2 "constant_call_address_operand" "z")]
12824                     UNSPEC_TLS_LD_BASE)
12825          (const:SI (unspec:SI
12826                     [(match_operand 3 "tls_symbolic_operand")]
12827                     UNSPEC_DTPOFF))))
12828    (clobber (match_scratch:SI 4 "=d"))
12829    (clobber (match_scratch:SI 5 "=c"))
12830    (clobber (reg:CC FLAGS_REG))]
12831   ""
12832   "#"
12833   ""
12834   [(parallel
12835      [(set (match_dup 0)
12836            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12837                       UNSPEC_TLS_GD))
12838       (clobber (match_dup 4))
12839       (clobber (match_dup 5))
12840       (clobber (reg:CC FLAGS_REG))])])
12842 ;; Segment register for the thread base ptr load
12843 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12845 ;; Load and add the thread base pointer from %<tp_seg>:0.
12846 (define_insn "*load_tp_x32"
12847   [(set (match_operand:SI 0 "register_operand" "=r")
12848         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12849   "TARGET_X32"
12850   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12851   [(set_attr "type" "imov")
12852    (set_attr "modrm" "0")
12853    (set_attr "length" "7")
12854    (set_attr "memory" "load")
12855    (set_attr "imm_disp" "false")])
12857 (define_insn "*load_tp_x32_zext"
12858   [(set (match_operand:DI 0 "register_operand" "=r")
12859         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12860   "TARGET_X32"
12861   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12862   [(set_attr "type" "imov")
12863    (set_attr "modrm" "0")
12864    (set_attr "length" "7")
12865    (set_attr "memory" "load")
12866    (set_attr "imm_disp" "false")])
12868 (define_insn "*load_tp_<mode>"
12869   [(set (match_operand:P 0 "register_operand" "=r")
12870         (unspec:P [(const_int 0)] UNSPEC_TP))]
12871   "!TARGET_X32"
12872   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12873   [(set_attr "type" "imov")
12874    (set_attr "modrm" "0")
12875    (set_attr "length" "7")
12876    (set_attr "memory" "load")
12877    (set_attr "imm_disp" "false")])
12879 (define_insn "*add_tp_x32"
12880   [(set (match_operand:SI 0 "register_operand" "=r")
12881         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12882                  (match_operand:SI 1 "register_operand" "0")))
12883    (clobber (reg:CC FLAGS_REG))]
12884   "TARGET_X32"
12885   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12886   [(set_attr "type" "alu")
12887    (set_attr "modrm" "0")
12888    (set_attr "length" "7")
12889    (set_attr "memory" "load")
12890    (set_attr "imm_disp" "false")])
12892 (define_insn "*add_tp_x32_zext"
12893   [(set (match_operand:DI 0 "register_operand" "=r")
12894         (zero_extend:DI
12895           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12896                    (match_operand:SI 1 "register_operand" "0"))))
12897    (clobber (reg:CC FLAGS_REG))]
12898   "TARGET_X32"
12899   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12900   [(set_attr "type" "alu")
12901    (set_attr "modrm" "0")
12902    (set_attr "length" "7")
12903    (set_attr "memory" "load")
12904    (set_attr "imm_disp" "false")])
12906 (define_insn "*add_tp_<mode>"
12907   [(set (match_operand:P 0 "register_operand" "=r")
12908         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12909                 (match_operand:P 1 "register_operand" "0")))
12910    (clobber (reg:CC FLAGS_REG))]
12911   "!TARGET_X32"
12912   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12913   [(set_attr "type" "alu")
12914    (set_attr "modrm" "0")
12915    (set_attr "length" "7")
12916    (set_attr "memory" "load")
12917    (set_attr "imm_disp" "false")])
12919 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12920 ;; %rax as destination of the initial executable code sequence.
12921 (define_insn "tls_initial_exec_64_sun"
12922   [(set (match_operand:DI 0 "register_operand" "=a")
12923         (unspec:DI
12924          [(match_operand 1 "tls_symbolic_operand")]
12925          UNSPEC_TLS_IE_SUN))
12926    (clobber (reg:CC FLAGS_REG))]
12927   "TARGET_64BIT && TARGET_SUN_TLS"
12929   output_asm_insn
12930     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12931   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12933   [(set_attr "type" "multi")])
12935 ;; GNU2 TLS patterns can be split.
12937 (define_expand "tls_dynamic_gnu2_32"
12938   [(set (match_dup 3)
12939         (plus:SI (match_operand:SI 2 "register_operand")
12940                  (const:SI
12941                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
12942                              UNSPEC_TLSDESC))))
12943    (parallel
12944     [(set (match_operand:SI 0 "register_operand")
12945           (unspec:SI [(match_dup 1) (match_dup 3)
12946                       (match_dup 2) (reg:SI SP_REG)]
12947                       UNSPEC_TLSDESC))
12948      (clobber (reg:CC FLAGS_REG))])]
12949   "!TARGET_64BIT && TARGET_GNU2_TLS"
12951   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12952   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12955 (define_insn "*tls_dynamic_gnu2_lea_32"
12956   [(set (match_operand:SI 0 "register_operand" "=r")
12957         (plus:SI (match_operand:SI 1 "register_operand" "b")
12958                  (const:SI
12959                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
12960                               UNSPEC_TLSDESC))))]
12961   "!TARGET_64BIT && TARGET_GNU2_TLS"
12962   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12963   [(set_attr "type" "lea")
12964    (set_attr "mode" "SI")
12965    (set_attr "length" "6")
12966    (set_attr "length_address" "4")])
12968 (define_insn "*tls_dynamic_gnu2_call_32"
12969   [(set (match_operand:SI 0 "register_operand" "=a")
12970         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
12971                     (match_operand:SI 2 "register_operand" "0")
12972                     ;; we have to make sure %ebx still points to the GOT
12973                     (match_operand:SI 3 "register_operand" "b")
12974                     (reg:SI SP_REG)]
12975                    UNSPEC_TLSDESC))
12976    (clobber (reg:CC FLAGS_REG))]
12977   "!TARGET_64BIT && TARGET_GNU2_TLS"
12978   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12979   [(set_attr "type" "call")
12980    (set_attr "length" "2")
12981    (set_attr "length_address" "0")])
12983 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12984   [(set (match_operand:SI 0 "register_operand" "=&a")
12985         (plus:SI
12986          (unspec:SI [(match_operand 3 "tls_modbase_operand")
12987                      (match_operand:SI 4)
12988                      (match_operand:SI 2 "register_operand" "b")
12989                      (reg:SI SP_REG)]
12990                     UNSPEC_TLSDESC)
12991          (const:SI (unspec:SI
12992                     [(match_operand 1 "tls_symbolic_operand")]
12993                     UNSPEC_DTPOFF))))
12994    (clobber (reg:CC FLAGS_REG))]
12995   "!TARGET_64BIT && TARGET_GNU2_TLS"
12996   "#"
12997   ""
12998   [(set (match_dup 0) (match_dup 5))]
13000   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13001   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13004 (define_expand "tls_dynamic_gnu2_64"
13005   [(set (match_dup 2)
13006         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13007                    UNSPEC_TLSDESC))
13008    (parallel
13009     [(set (match_operand:DI 0 "register_operand")
13010           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13011                      UNSPEC_TLSDESC))
13012      (clobber (reg:CC FLAGS_REG))])]
13013   "TARGET_64BIT && TARGET_GNU2_TLS"
13015   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13016   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13019 (define_insn "*tls_dynamic_gnu2_lea_64"
13020   [(set (match_operand:DI 0 "register_operand" "=r")
13021         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13022                    UNSPEC_TLSDESC))]
13023   "TARGET_64BIT && TARGET_GNU2_TLS"
13024   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13025   [(set_attr "type" "lea")
13026    (set_attr "mode" "DI")
13027    (set_attr "length" "7")
13028    (set_attr "length_address" "4")])
13030 (define_insn "*tls_dynamic_gnu2_call_64"
13031   [(set (match_operand:DI 0 "register_operand" "=a")
13032         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13033                     (match_operand:DI 2 "register_operand" "0")
13034                     (reg:DI SP_REG)]
13035                    UNSPEC_TLSDESC))
13036    (clobber (reg:CC FLAGS_REG))]
13037   "TARGET_64BIT && TARGET_GNU2_TLS"
13038   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13039   [(set_attr "type" "call")
13040    (set_attr "length" "2")
13041    (set_attr "length_address" "0")])
13043 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13044   [(set (match_operand:DI 0 "register_operand" "=&a")
13045         (plus:DI
13046          (unspec:DI [(match_operand 2 "tls_modbase_operand")
13047                      (match_operand:DI 3)
13048                      (reg:DI SP_REG)]
13049                     UNSPEC_TLSDESC)
13050          (const:DI (unspec:DI
13051                     [(match_operand 1 "tls_symbolic_operand")]
13052                     UNSPEC_DTPOFF))))
13053    (clobber (reg:CC FLAGS_REG))]
13054   "TARGET_64BIT && TARGET_GNU2_TLS"
13055   "#"
13056   ""
13057   [(set (match_dup 0) (match_dup 4))]
13059   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13060   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13063 ;; These patterns match the binary 387 instructions for addM3, subM3,
13064 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13065 ;; SFmode.  The first is the normal insn, the second the same insn but
13066 ;; with one operand a conversion, and the third the same insn but with
13067 ;; the other operand a conversion.  The conversion may be SFmode or
13068 ;; SImode if the target mode DFmode, but only SImode if the target mode
13069 ;; is SFmode.
13071 ;; Gcc is slightly more smart about handling normal two address instructions
13072 ;; so use special patterns for add and mull.
13074 (define_insn "*fop_<mode>_comm_mixed"
13075   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13076         (match_operator:MODEF 3 "binary_fp_operator"
13077           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13078            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13079   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13080    && COMMUTATIVE_ARITH_P (operands[3])
13081    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13082   "* return output_387_binary_op (insn, operands);"
13083   [(set (attr "type")
13084         (if_then_else (eq_attr "alternative" "1,2")
13085            (if_then_else (match_operand:MODEF 3 "mult_operator")
13086               (const_string "ssemul")
13087               (const_string "sseadd"))
13088            (if_then_else (match_operand:MODEF 3 "mult_operator")
13089               (const_string "fmul")
13090               (const_string "fop"))))
13091    (set_attr "isa" "*,noavx,avx")
13092    (set_attr "prefix" "orig,orig,vex")
13093    (set_attr "mode" "<MODE>")])
13095 (define_insn "*fop_<mode>_comm_sse"
13096   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13097         (match_operator:MODEF 3 "binary_fp_operator"
13098           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13099            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13100   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13101    && COMMUTATIVE_ARITH_P (operands[3])
13102    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13103   "* return output_387_binary_op (insn, operands);"
13104   [(set (attr "type")
13105         (if_then_else (match_operand:MODEF 3 "mult_operator")
13106            (const_string "ssemul")
13107            (const_string "sseadd")))
13108    (set_attr "isa" "noavx,avx")
13109    (set_attr "prefix" "orig,vex")
13110    (set_attr "mode" "<MODE>")])
13112 (define_insn "*fop_<mode>_comm_i387"
13113   [(set (match_operand:MODEF 0 "register_operand" "=f")
13114         (match_operator:MODEF 3 "binary_fp_operator"
13115           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13116            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13117   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13118    && COMMUTATIVE_ARITH_P (operands[3])
13119    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13120   "* return output_387_binary_op (insn, operands);"
13121   [(set (attr "type")
13122         (if_then_else (match_operand:MODEF 3 "mult_operator")
13123            (const_string "fmul")
13124            (const_string "fop")))
13125    (set_attr "mode" "<MODE>")])
13127 (define_insn "*fop_<mode>_1_mixed"
13128   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13129         (match_operator:MODEF 3 "binary_fp_operator"
13130           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13131            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13132   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13133    && !COMMUTATIVE_ARITH_P (operands[3])
13134    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13135   "* return output_387_binary_op (insn, operands);"
13136   [(set (attr "type")
13137         (cond [(and (eq_attr "alternative" "2,3")
13138                     (match_operand:MODEF 3 "mult_operator"))
13139                  (const_string "ssemul")
13140                (and (eq_attr "alternative" "2,3")
13141                     (match_operand:MODEF 3 "div_operator"))
13142                  (const_string "ssediv")
13143                (eq_attr "alternative" "2,3")
13144                  (const_string "sseadd")
13145                (match_operand:MODEF 3 "mult_operator")
13146                  (const_string "fmul")
13147                (match_operand:MODEF 3 "div_operator")
13148                  (const_string "fdiv")
13149               ]
13150               (const_string "fop")))
13151    (set_attr "isa" "*,*,noavx,avx")
13152    (set_attr "prefix" "orig,orig,orig,vex")
13153    (set_attr "mode" "<MODE>")])
13155 (define_insn "*rcpsf2_sse"
13156   [(set (match_operand:SF 0 "register_operand" "=x")
13157         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13158                    UNSPEC_RCP))]
13159   "TARGET_SSE_MATH"
13160   "%vrcpss\t{%1, %d0|%d0, %1}"
13161   [(set_attr "type" "sse")
13162    (set_attr "atom_sse_attr" "rcp")
13163    (set_attr "btver2_sse_attr" "rcp")
13164    (set_attr "prefix" "maybe_vex")
13165    (set_attr "mode" "SF")])
13167 (define_insn "*fop_<mode>_1_sse"
13168   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13169         (match_operator:MODEF 3 "binary_fp_operator"
13170           [(match_operand:MODEF 1 "register_operand" "0,x")
13171            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13172   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13173    && !COMMUTATIVE_ARITH_P (operands[3])"
13174   "* return output_387_binary_op (insn, operands);"
13175   [(set (attr "type")
13176         (cond [(match_operand:MODEF 3 "mult_operator")
13177                  (const_string "ssemul")
13178                (match_operand:MODEF 3 "div_operator")
13179                  (const_string "ssediv")
13180               ]
13181               (const_string "sseadd")))
13182    (set_attr "isa" "noavx,avx")
13183    (set_attr "prefix" "orig,vex")
13184    (set_attr "mode" "<MODE>")])
13186 ;; This pattern is not fully shadowed by the pattern above.
13187 (define_insn "*fop_<mode>_1_i387"
13188   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13189         (match_operator:MODEF 3 "binary_fp_operator"
13190           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13191            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13192   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13193    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13194    && !COMMUTATIVE_ARITH_P (operands[3])
13195    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13196   "* return output_387_binary_op (insn, operands);"
13197   [(set (attr "type")
13198         (cond [(match_operand:MODEF 3 "mult_operator")
13199                  (const_string "fmul")
13200                (match_operand:MODEF 3 "div_operator")
13201                  (const_string "fdiv")
13202               ]
13203               (const_string "fop")))
13204    (set_attr "mode" "<MODE>")])
13206 ;; ??? Add SSE splitters for these!
13207 (define_insn "*fop_<MODEF:mode>_2_i387"
13208   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13209         (match_operator:MODEF 3 "binary_fp_operator"
13210           [(float:MODEF
13211              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13212            (match_operand:MODEF 2 "register_operand" "0,0")]))]
13213   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13214    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13215    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13216   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13217   [(set (attr "type")
13218         (cond [(match_operand:MODEF 3 "mult_operator")
13219                  (const_string "fmul")
13220                (match_operand:MODEF 3 "div_operator")
13221                  (const_string "fdiv")
13222               ]
13223               (const_string "fop")))
13224    (set_attr "fp_int_src" "true")
13225    (set_attr "mode" "<SWI24:MODE>")])
13227 (define_insn "*fop_<MODEF:mode>_3_i387"
13228   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13229         (match_operator:MODEF 3 "binary_fp_operator"
13230           [(match_operand:MODEF 1 "register_operand" "0,0")
13231            (float:MODEF
13232              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13233   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13234    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13235    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13236   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13237   [(set (attr "type")
13238         (cond [(match_operand:MODEF 3 "mult_operator")
13239                  (const_string "fmul")
13240                (match_operand:MODEF 3 "div_operator")
13241                  (const_string "fdiv")
13242               ]
13243               (const_string "fop")))
13244    (set_attr "fp_int_src" "true")
13245    (set_attr "mode" "<MODE>")])
13247 (define_insn "*fop_df_4_i387"
13248   [(set (match_operand:DF 0 "register_operand" "=f,f")
13249         (match_operator:DF 3 "binary_fp_operator"
13250            [(float_extend:DF
13251              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13252             (match_operand:DF 2 "register_operand" "0,f")]))]
13253   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13254    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13255    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13256   "* return output_387_binary_op (insn, operands);"
13257   [(set (attr "type")
13258         (cond [(match_operand:DF 3 "mult_operator")
13259                  (const_string "fmul")
13260                (match_operand:DF 3 "div_operator")
13261                  (const_string "fdiv")
13262               ]
13263               (const_string "fop")))
13264    (set_attr "mode" "SF")])
13266 (define_insn "*fop_df_5_i387"
13267   [(set (match_operand:DF 0 "register_operand" "=f,f")
13268         (match_operator:DF 3 "binary_fp_operator"
13269           [(match_operand:DF 1 "register_operand" "0,f")
13270            (float_extend:DF
13271             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13272   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13273    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13274   "* return output_387_binary_op (insn, operands);"
13275   [(set (attr "type")
13276         (cond [(match_operand:DF 3 "mult_operator")
13277                  (const_string "fmul")
13278                (match_operand:DF 3 "div_operator")
13279                  (const_string "fdiv")
13280               ]
13281               (const_string "fop")))
13282    (set_attr "mode" "SF")])
13284 (define_insn "*fop_df_6_i387"
13285   [(set (match_operand:DF 0 "register_operand" "=f,f")
13286         (match_operator:DF 3 "binary_fp_operator"
13287           [(float_extend:DF
13288             (match_operand:SF 1 "register_operand" "0,f"))
13289            (float_extend:DF
13290             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13291   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13292    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13293   "* return output_387_binary_op (insn, operands);"
13294   [(set (attr "type")
13295         (cond [(match_operand:DF 3 "mult_operator")
13296                  (const_string "fmul")
13297                (match_operand:DF 3 "div_operator")
13298                  (const_string "fdiv")
13299               ]
13300               (const_string "fop")))
13301    (set_attr "mode" "SF")])
13303 (define_insn "*fop_xf_comm_i387"
13304   [(set (match_operand:XF 0 "register_operand" "=f")
13305         (match_operator:XF 3 "binary_fp_operator"
13306                         [(match_operand:XF 1 "register_operand" "%0")
13307                          (match_operand:XF 2 "register_operand" "f")]))]
13308   "TARGET_80387
13309    && COMMUTATIVE_ARITH_P (operands[3])"
13310   "* return output_387_binary_op (insn, operands);"
13311   [(set (attr "type")
13312         (if_then_else (match_operand:XF 3 "mult_operator")
13313            (const_string "fmul")
13314            (const_string "fop")))
13315    (set_attr "mode" "XF")])
13317 (define_insn "*fop_xf_1_i387"
13318   [(set (match_operand:XF 0 "register_operand" "=f,f")
13319         (match_operator:XF 3 "binary_fp_operator"
13320                         [(match_operand:XF 1 "register_operand" "0,f")
13321                          (match_operand:XF 2 "register_operand" "f,0")]))]
13322   "TARGET_80387
13323    && !COMMUTATIVE_ARITH_P (operands[3])"
13324   "* return output_387_binary_op (insn, operands);"
13325   [(set (attr "type")
13326         (cond [(match_operand:XF 3 "mult_operator")
13327                  (const_string "fmul")
13328                (match_operand:XF 3 "div_operator")
13329                  (const_string "fdiv")
13330               ]
13331               (const_string "fop")))
13332    (set_attr "mode" "XF")])
13334 (define_insn "*fop_xf_2_i387"
13335   [(set (match_operand:XF 0 "register_operand" "=f,f")
13336         (match_operator:XF 3 "binary_fp_operator"
13337           [(float:XF
13338              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13339            (match_operand:XF 2 "register_operand" "0,0")]))]
13340   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13341   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13342   [(set (attr "type")
13343         (cond [(match_operand:XF 3 "mult_operator")
13344                  (const_string "fmul")
13345                (match_operand:XF 3 "div_operator")
13346                  (const_string "fdiv")
13347               ]
13348               (const_string "fop")))
13349    (set_attr "fp_int_src" "true")
13350    (set_attr "mode" "<MODE>")])
13352 (define_insn "*fop_xf_3_i387"
13353   [(set (match_operand:XF 0 "register_operand" "=f,f")
13354         (match_operator:XF 3 "binary_fp_operator"
13355           [(match_operand:XF 1 "register_operand" "0,0")
13356            (float:XF
13357              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13358   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13359   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13360   [(set (attr "type")
13361         (cond [(match_operand:XF 3 "mult_operator")
13362                  (const_string "fmul")
13363                (match_operand:XF 3 "div_operator")
13364                  (const_string "fdiv")
13365               ]
13366               (const_string "fop")))
13367    (set_attr "fp_int_src" "true")
13368    (set_attr "mode" "<MODE>")])
13370 (define_insn "*fop_xf_4_i387"
13371   [(set (match_operand:XF 0 "register_operand" "=f,f")
13372         (match_operator:XF 3 "binary_fp_operator"
13373            [(float_extend:XF
13374               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13375             (match_operand:XF 2 "register_operand" "0,f")]))]
13376   "TARGET_80387"
13377   "* return output_387_binary_op (insn, operands);"
13378   [(set (attr "type")
13379         (cond [(match_operand:XF 3 "mult_operator")
13380                  (const_string "fmul")
13381                (match_operand:XF 3 "div_operator")
13382                  (const_string "fdiv")
13383               ]
13384               (const_string "fop")))
13385    (set_attr "mode" "<MODE>")])
13387 (define_insn "*fop_xf_5_i387"
13388   [(set (match_operand:XF 0 "register_operand" "=f,f")
13389         (match_operator:XF 3 "binary_fp_operator"
13390           [(match_operand:XF 1 "register_operand" "0,f")
13391            (float_extend:XF
13392              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13393   "TARGET_80387"
13394   "* return output_387_binary_op (insn, operands);"
13395   [(set (attr "type")
13396         (cond [(match_operand:XF 3 "mult_operator")
13397                  (const_string "fmul")
13398                (match_operand:XF 3 "div_operator")
13399                  (const_string "fdiv")
13400               ]
13401               (const_string "fop")))
13402    (set_attr "mode" "<MODE>")])
13404 (define_insn "*fop_xf_6_i387"
13405   [(set (match_operand:XF 0 "register_operand" "=f,f")
13406         (match_operator:XF 3 "binary_fp_operator"
13407           [(float_extend:XF
13408              (match_operand:MODEF 1 "register_operand" "0,f"))
13409            (float_extend:XF
13410              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13411   "TARGET_80387"
13412   "* return output_387_binary_op (insn, operands);"
13413   [(set (attr "type")
13414         (cond [(match_operand:XF 3 "mult_operator")
13415                  (const_string "fmul")
13416                (match_operand:XF 3 "div_operator")
13417                  (const_string "fdiv")
13418               ]
13419               (const_string "fop")))
13420    (set_attr "mode" "<MODE>")])
13422 (define_split
13423   [(set (match_operand 0 "register_operand")
13424         (match_operator 3 "binary_fp_operator"
13425            [(float (match_operand:SWI24 1 "register_operand"))
13426             (match_operand 2 "register_operand")]))]
13427   "reload_completed
13428    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13429    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13430   [(const_int 0)]
13432   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13433   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13434   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13435                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13436                                           GET_MODE (operands[3]),
13437                                           operands[4],
13438                                           operands[2])));
13439   ix86_free_from_memory (GET_MODE (operands[1]));
13440   DONE;
13443 (define_split
13444   [(set (match_operand 0 "register_operand")
13445         (match_operator 3 "binary_fp_operator"
13446            [(match_operand 1 "register_operand")
13447             (float (match_operand:SWI24 2 "register_operand"))]))]
13448   "reload_completed
13449    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13450    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13451   [(const_int 0)]
13453   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13454   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13455   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13456                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13457                                           GET_MODE (operands[3]),
13458                                           operands[1],
13459                                           operands[4])));
13460   ix86_free_from_memory (GET_MODE (operands[2]));
13461   DONE;
13464 ;; FPU special functions.
13466 ;; This pattern implements a no-op XFmode truncation for
13467 ;; all fancy i386 XFmode math functions.
13469 (define_insn "truncxf<mode>2_i387_noop_unspec"
13470   [(set (match_operand:MODEF 0 "register_operand" "=f")
13471         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13472         UNSPEC_TRUNC_NOOP))]
13473   "TARGET_USE_FANCY_MATH_387"
13474   "* return output_387_reg_move (insn, operands);"
13475   [(set_attr "type" "fmov")
13476    (set_attr "mode" "<MODE>")])
13478 (define_insn "sqrtxf2"
13479   [(set (match_operand:XF 0 "register_operand" "=f")
13480         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13481   "TARGET_USE_FANCY_MATH_387"
13482   "fsqrt"
13483   [(set_attr "type" "fpspc")
13484    (set_attr "mode" "XF")
13485    (set_attr "athlon_decode" "direct")
13486    (set_attr "amdfam10_decode" "direct")
13487    (set_attr "bdver1_decode" "direct")])
13489 (define_insn "sqrt_extend<mode>xf2_i387"
13490   [(set (match_operand:XF 0 "register_operand" "=f")
13491         (sqrt:XF
13492           (float_extend:XF
13493             (match_operand:MODEF 1 "register_operand" "0"))))]
13494   "TARGET_USE_FANCY_MATH_387"
13495   "fsqrt"
13496   [(set_attr "type" "fpspc")
13497    (set_attr "mode" "XF")
13498    (set_attr "athlon_decode" "direct")
13499    (set_attr "amdfam10_decode" "direct")
13500    (set_attr "bdver1_decode" "direct")])
13502 (define_insn "*rsqrtsf2_sse"
13503   [(set (match_operand:SF 0 "register_operand" "=x")
13504         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13505                    UNSPEC_RSQRT))]
13506   "TARGET_SSE_MATH"
13507   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13508   [(set_attr "type" "sse")
13509    (set_attr "atom_sse_attr" "rcp")
13510    (set_attr "btver2_sse_attr" "rcp")
13511    (set_attr "prefix" "maybe_vex")
13512    (set_attr "mode" "SF")])
13514 (define_expand "rsqrtsf2"
13515   [(set (match_operand:SF 0 "register_operand")
13516         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13517                    UNSPEC_RSQRT))]
13518   "TARGET_SSE_MATH"
13520   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13521   DONE;
13524 (define_insn "*sqrt<mode>2_sse"
13525   [(set (match_operand:MODEF 0 "register_operand" "=x")
13526         (sqrt:MODEF
13527           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13528   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13529   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13530   [(set_attr "type" "sse")
13531    (set_attr "atom_sse_attr" "sqrt")
13532    (set_attr "btver2_sse_attr" "sqrt")
13533    (set_attr "prefix" "maybe_vex")
13534    (set_attr "mode" "<MODE>")
13535    (set_attr "athlon_decode" "*")
13536    (set_attr "amdfam10_decode" "*")
13537    (set_attr "bdver1_decode" "*")])
13539 (define_expand "sqrt<mode>2"
13540   [(set (match_operand:MODEF 0 "register_operand")
13541         (sqrt:MODEF
13542           (match_operand:MODEF 1 "nonimmediate_operand")))]
13543   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13544    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13546   if (<MODE>mode == SFmode
13547       && TARGET_SSE_MATH
13548       && TARGET_RECIP_SQRT
13549       && !optimize_function_for_size_p (cfun)
13550       && flag_finite_math_only && !flag_trapping_math
13551       && flag_unsafe_math_optimizations)
13552     {
13553       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13554       DONE;
13555     }
13557   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13558     {
13559       rtx op0 = gen_reg_rtx (XFmode);
13560       rtx op1 = force_reg (<MODE>mode, operands[1]);
13562       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13563       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13564       DONE;
13565    }
13568 (define_insn "fpremxf4_i387"
13569   [(set (match_operand:XF 0 "register_operand" "=f")
13570         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13571                     (match_operand:XF 3 "register_operand" "1")]
13572                    UNSPEC_FPREM_F))
13573    (set (match_operand:XF 1 "register_operand" "=u")
13574         (unspec:XF [(match_dup 2) (match_dup 3)]
13575                    UNSPEC_FPREM_U))
13576    (set (reg:CCFP FPSR_REG)
13577         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13578                      UNSPEC_C2_FLAG))]
13579   "TARGET_USE_FANCY_MATH_387"
13580   "fprem"
13581   [(set_attr "type" "fpspc")
13582    (set_attr "mode" "XF")])
13584 (define_expand "fmodxf3"
13585   [(use (match_operand:XF 0 "register_operand"))
13586    (use (match_operand:XF 1 "general_operand"))
13587    (use (match_operand:XF 2 "general_operand"))]
13588   "TARGET_USE_FANCY_MATH_387"
13590   rtx label = gen_label_rtx ();
13592   rtx op1 = gen_reg_rtx (XFmode);
13593   rtx op2 = gen_reg_rtx (XFmode);
13595   emit_move_insn (op2, operands[2]);
13596   emit_move_insn (op1, operands[1]);
13598   emit_label (label);
13599   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13600   ix86_emit_fp_unordered_jump (label);
13601   LABEL_NUSES (label) = 1;
13603   emit_move_insn (operands[0], op1);
13604   DONE;
13607 (define_expand "fmod<mode>3"
13608   [(use (match_operand:MODEF 0 "register_operand"))
13609    (use (match_operand:MODEF 1 "general_operand"))
13610    (use (match_operand:MODEF 2 "general_operand"))]
13611   "TARGET_USE_FANCY_MATH_387"
13613   rtx (*gen_truncxf) (rtx, rtx);
13615   rtx label = gen_label_rtx ();
13617   rtx op1 = gen_reg_rtx (XFmode);
13618   rtx op2 = gen_reg_rtx (XFmode);
13620   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13621   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13623   emit_label (label);
13624   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13625   ix86_emit_fp_unordered_jump (label);
13626   LABEL_NUSES (label) = 1;
13628   /* Truncate the result properly for strict SSE math.  */
13629   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13630       && !TARGET_MIX_SSE_I387)
13631     gen_truncxf = gen_truncxf<mode>2;
13632   else
13633     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13635   emit_insn (gen_truncxf (operands[0], op1));
13636   DONE;
13639 (define_insn "fprem1xf4_i387"
13640   [(set (match_operand:XF 0 "register_operand" "=f")
13641         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13642                     (match_operand:XF 3 "register_operand" "1")]
13643                    UNSPEC_FPREM1_F))
13644    (set (match_operand:XF 1 "register_operand" "=u")
13645         (unspec:XF [(match_dup 2) (match_dup 3)]
13646                    UNSPEC_FPREM1_U))
13647    (set (reg:CCFP FPSR_REG)
13648         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13649                      UNSPEC_C2_FLAG))]
13650   "TARGET_USE_FANCY_MATH_387"
13651   "fprem1"
13652   [(set_attr "type" "fpspc")
13653    (set_attr "mode" "XF")])
13655 (define_expand "remainderxf3"
13656   [(use (match_operand:XF 0 "register_operand"))
13657    (use (match_operand:XF 1 "general_operand"))
13658    (use (match_operand:XF 2 "general_operand"))]
13659   "TARGET_USE_FANCY_MATH_387"
13661   rtx label = gen_label_rtx ();
13663   rtx op1 = gen_reg_rtx (XFmode);
13664   rtx op2 = gen_reg_rtx (XFmode);
13666   emit_move_insn (op2, operands[2]);
13667   emit_move_insn (op1, operands[1]);
13669   emit_label (label);
13670   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13671   ix86_emit_fp_unordered_jump (label);
13672   LABEL_NUSES (label) = 1;
13674   emit_move_insn (operands[0], op1);
13675   DONE;
13678 (define_expand "remainder<mode>3"
13679   [(use (match_operand:MODEF 0 "register_operand"))
13680    (use (match_operand:MODEF 1 "general_operand"))
13681    (use (match_operand:MODEF 2 "general_operand"))]
13682   "TARGET_USE_FANCY_MATH_387"
13684   rtx (*gen_truncxf) (rtx, rtx);
13686   rtx label = gen_label_rtx ();
13688   rtx op1 = gen_reg_rtx (XFmode);
13689   rtx op2 = gen_reg_rtx (XFmode);
13691   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13692   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13694   emit_label (label);
13696   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13697   ix86_emit_fp_unordered_jump (label);
13698   LABEL_NUSES (label) = 1;
13700   /* Truncate the result properly for strict SSE math.  */
13701   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13702       && !TARGET_MIX_SSE_I387)
13703     gen_truncxf = gen_truncxf<mode>2;
13704   else
13705     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13707   emit_insn (gen_truncxf (operands[0], op1));
13708   DONE;
13711 (define_int_iterator SINCOS
13712         [UNSPEC_SIN
13713          UNSPEC_COS])
13715 (define_int_attr sincos
13716         [(UNSPEC_SIN "sin")
13717          (UNSPEC_COS "cos")])
13719 (define_insn "*<sincos>xf2_i387"
13720   [(set (match_operand:XF 0 "register_operand" "=f")
13721         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13722                    SINCOS))]
13723   "TARGET_USE_FANCY_MATH_387
13724    && flag_unsafe_math_optimizations"
13725   "f<sincos>"
13726   [(set_attr "type" "fpspc")
13727    (set_attr "mode" "XF")])
13729 (define_insn "*<sincos>_extend<mode>xf2_i387"
13730   [(set (match_operand:XF 0 "register_operand" "=f")
13731         (unspec:XF [(float_extend:XF
13732                       (match_operand:MODEF 1 "register_operand" "0"))]
13733                    SINCOS))]
13734   "TARGET_USE_FANCY_MATH_387
13735    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13736        || TARGET_MIX_SSE_I387)
13737    && flag_unsafe_math_optimizations"
13738   "f<sincos>"
13739   [(set_attr "type" "fpspc")
13740    (set_attr "mode" "XF")])
13742 ;; When sincos pattern is defined, sin and cos builtin functions will be
13743 ;; expanded to sincos pattern with one of its outputs left unused.
13744 ;; CSE pass will figure out if two sincos patterns can be combined,
13745 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13746 ;; depending on the unused output.
13748 (define_insn "sincosxf3"
13749   [(set (match_operand:XF 0 "register_operand" "=f")
13750         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13751                    UNSPEC_SINCOS_COS))
13752    (set (match_operand:XF 1 "register_operand" "=u")
13753         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13754   "TARGET_USE_FANCY_MATH_387
13755    && flag_unsafe_math_optimizations"
13756   "fsincos"
13757   [(set_attr "type" "fpspc")
13758    (set_attr "mode" "XF")])
13760 (define_split
13761   [(set (match_operand:XF 0 "register_operand")
13762         (unspec:XF [(match_operand:XF 2 "register_operand")]
13763                    UNSPEC_SINCOS_COS))
13764    (set (match_operand:XF 1 "register_operand")
13765         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13766   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13767    && can_create_pseudo_p ()"
13768   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13770 (define_split
13771   [(set (match_operand:XF 0 "register_operand")
13772         (unspec:XF [(match_operand:XF 2 "register_operand")]
13773                    UNSPEC_SINCOS_COS))
13774    (set (match_operand:XF 1 "register_operand")
13775         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13776   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13777    && can_create_pseudo_p ()"
13778   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13780 (define_insn "sincos_extend<mode>xf3_i387"
13781   [(set (match_operand:XF 0 "register_operand" "=f")
13782         (unspec:XF [(float_extend:XF
13783                       (match_operand:MODEF 2 "register_operand" "0"))]
13784                    UNSPEC_SINCOS_COS))
13785    (set (match_operand:XF 1 "register_operand" "=u")
13786         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13787   "TARGET_USE_FANCY_MATH_387
13788    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13789        || TARGET_MIX_SSE_I387)
13790    && flag_unsafe_math_optimizations"
13791   "fsincos"
13792   [(set_attr "type" "fpspc")
13793    (set_attr "mode" "XF")])
13795 (define_split
13796   [(set (match_operand:XF 0 "register_operand")
13797         (unspec:XF [(float_extend:XF
13798                       (match_operand:MODEF 2 "register_operand"))]
13799                    UNSPEC_SINCOS_COS))
13800    (set (match_operand:XF 1 "register_operand")
13801         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13802   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13803    && can_create_pseudo_p ()"
13804   [(set (match_dup 1)
13805         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13807 (define_split
13808   [(set (match_operand:XF 0 "register_operand")
13809         (unspec:XF [(float_extend:XF
13810                       (match_operand:MODEF 2 "register_operand"))]
13811                    UNSPEC_SINCOS_COS))
13812    (set (match_operand:XF 1 "register_operand")
13813         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13814   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13815    && can_create_pseudo_p ()"
13816   [(set (match_dup 0)
13817         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13819 (define_expand "sincos<mode>3"
13820   [(use (match_operand:MODEF 0 "register_operand"))
13821    (use (match_operand:MODEF 1 "register_operand"))
13822    (use (match_operand:MODEF 2 "register_operand"))]
13823   "TARGET_USE_FANCY_MATH_387
13824    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13825        || TARGET_MIX_SSE_I387)
13826    && flag_unsafe_math_optimizations"
13828   rtx op0 = gen_reg_rtx (XFmode);
13829   rtx op1 = gen_reg_rtx (XFmode);
13831   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13832   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13833   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13834   DONE;
13837 (define_insn "fptanxf4_i387"
13838   [(set (match_operand:XF 0 "register_operand" "=f")
13839         (match_operand:XF 3 "const_double_operand" "F"))
13840    (set (match_operand:XF 1 "register_operand" "=u")
13841         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13842                    UNSPEC_TAN))]
13843   "TARGET_USE_FANCY_MATH_387
13844    && flag_unsafe_math_optimizations
13845    && standard_80387_constant_p (operands[3]) == 2"
13846   "fptan"
13847   [(set_attr "type" "fpspc")
13848    (set_attr "mode" "XF")])
13850 (define_insn "fptan_extend<mode>xf4_i387"
13851   [(set (match_operand:MODEF 0 "register_operand" "=f")
13852         (match_operand:MODEF 3 "const_double_operand" "F"))
13853    (set (match_operand:XF 1 "register_operand" "=u")
13854         (unspec:XF [(float_extend:XF
13855                       (match_operand:MODEF 2 "register_operand" "0"))]
13856                    UNSPEC_TAN))]
13857   "TARGET_USE_FANCY_MATH_387
13858    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13859        || TARGET_MIX_SSE_I387)
13860    && flag_unsafe_math_optimizations
13861    && standard_80387_constant_p (operands[3]) == 2"
13862   "fptan"
13863   [(set_attr "type" "fpspc")
13864    (set_attr "mode" "XF")])
13866 (define_expand "tanxf2"
13867   [(use (match_operand:XF 0 "register_operand"))
13868    (use (match_operand:XF 1 "register_operand"))]
13869   "TARGET_USE_FANCY_MATH_387
13870    && flag_unsafe_math_optimizations"
13872   rtx one = gen_reg_rtx (XFmode);
13873   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13875   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13876   DONE;
13879 (define_expand "tan<mode>2"
13880   [(use (match_operand:MODEF 0 "register_operand"))
13881    (use (match_operand:MODEF 1 "register_operand"))]
13882   "TARGET_USE_FANCY_MATH_387
13883    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13884        || TARGET_MIX_SSE_I387)
13885    && flag_unsafe_math_optimizations"
13887   rtx op0 = gen_reg_rtx (XFmode);
13889   rtx one = gen_reg_rtx (<MODE>mode);
13890   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13892   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13893                                              operands[1], op2));
13894   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13895   DONE;
13898 (define_insn "*fpatanxf3_i387"
13899   [(set (match_operand:XF 0 "register_operand" "=f")
13900         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13901                     (match_operand:XF 2 "register_operand" "u")]
13902                    UNSPEC_FPATAN))
13903    (clobber (match_scratch:XF 3 "=2"))]
13904   "TARGET_USE_FANCY_MATH_387
13905    && flag_unsafe_math_optimizations"
13906   "fpatan"
13907   [(set_attr "type" "fpspc")
13908    (set_attr "mode" "XF")])
13910 (define_insn "fpatan_extend<mode>xf3_i387"
13911   [(set (match_operand:XF 0 "register_operand" "=f")
13912         (unspec:XF [(float_extend:XF
13913                       (match_operand:MODEF 1 "register_operand" "0"))
13914                     (float_extend:XF
13915                       (match_operand:MODEF 2 "register_operand" "u"))]
13916                    UNSPEC_FPATAN))
13917    (clobber (match_scratch:XF 3 "=2"))]
13918   "TARGET_USE_FANCY_MATH_387
13919    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13920        || TARGET_MIX_SSE_I387)
13921    && flag_unsafe_math_optimizations"
13922   "fpatan"
13923   [(set_attr "type" "fpspc")
13924    (set_attr "mode" "XF")])
13926 (define_expand "atan2xf3"
13927   [(parallel [(set (match_operand:XF 0 "register_operand")
13928                    (unspec:XF [(match_operand:XF 2 "register_operand")
13929                                (match_operand:XF 1 "register_operand")]
13930                               UNSPEC_FPATAN))
13931               (clobber (match_scratch:XF 3))])]
13932   "TARGET_USE_FANCY_MATH_387
13933    && flag_unsafe_math_optimizations")
13935 (define_expand "atan2<mode>3"
13936   [(use (match_operand:MODEF 0 "register_operand"))
13937    (use (match_operand:MODEF 1 "register_operand"))
13938    (use (match_operand:MODEF 2 "register_operand"))]
13939   "TARGET_USE_FANCY_MATH_387
13940    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13941        || TARGET_MIX_SSE_I387)
13942    && flag_unsafe_math_optimizations"
13944   rtx op0 = gen_reg_rtx (XFmode);
13946   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13947   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13948   DONE;
13951 (define_expand "atanxf2"
13952   [(parallel [(set (match_operand:XF 0 "register_operand")
13953                    (unspec:XF [(match_dup 2)
13954                                (match_operand:XF 1 "register_operand")]
13955                               UNSPEC_FPATAN))
13956               (clobber (match_scratch:XF 3))])]
13957   "TARGET_USE_FANCY_MATH_387
13958    && flag_unsafe_math_optimizations"
13960   operands[2] = gen_reg_rtx (XFmode);
13961   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13964 (define_expand "atan<mode>2"
13965   [(use (match_operand:MODEF 0 "register_operand"))
13966    (use (match_operand:MODEF 1 "register_operand"))]
13967   "TARGET_USE_FANCY_MATH_387
13968    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13969        || TARGET_MIX_SSE_I387)
13970    && flag_unsafe_math_optimizations"
13972   rtx op0 = gen_reg_rtx (XFmode);
13974   rtx op2 = gen_reg_rtx (<MODE>mode);
13975   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13977   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13978   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13979   DONE;
13982 (define_expand "asinxf2"
13983   [(set (match_dup 2)
13984         (mult:XF (match_operand:XF 1 "register_operand")
13985                  (match_dup 1)))
13986    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13987    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13988    (parallel [(set (match_operand:XF 0 "register_operand")
13989                    (unspec:XF [(match_dup 5) (match_dup 1)]
13990                               UNSPEC_FPATAN))
13991               (clobber (match_scratch:XF 6))])]
13992   "TARGET_USE_FANCY_MATH_387
13993    && flag_unsafe_math_optimizations"
13995   int i;
13997   if (optimize_insn_for_size_p ())
13998     FAIL;
14000   for (i = 2; i < 6; i++)
14001     operands[i] = gen_reg_rtx (XFmode);
14003   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14006 (define_expand "asin<mode>2"
14007   [(use (match_operand:MODEF 0 "register_operand"))
14008    (use (match_operand:MODEF 1 "general_operand"))]
14009  "TARGET_USE_FANCY_MATH_387
14010    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14011        || TARGET_MIX_SSE_I387)
14012    && flag_unsafe_math_optimizations"
14014   rtx op0 = gen_reg_rtx (XFmode);
14015   rtx op1 = gen_reg_rtx (XFmode);
14017   if (optimize_insn_for_size_p ())
14018     FAIL;
14020   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14021   emit_insn (gen_asinxf2 (op0, op1));
14022   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14023   DONE;
14026 (define_expand "acosxf2"
14027   [(set (match_dup 2)
14028         (mult:XF (match_operand:XF 1 "register_operand")
14029                  (match_dup 1)))
14030    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14031    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14032    (parallel [(set (match_operand:XF 0 "register_operand")
14033                    (unspec:XF [(match_dup 1) (match_dup 5)]
14034                               UNSPEC_FPATAN))
14035               (clobber (match_scratch:XF 6))])]
14036   "TARGET_USE_FANCY_MATH_387
14037    && flag_unsafe_math_optimizations"
14039   int i;
14041   if (optimize_insn_for_size_p ())
14042     FAIL;
14044   for (i = 2; i < 6; i++)
14045     operands[i] = gen_reg_rtx (XFmode);
14047   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14050 (define_expand "acos<mode>2"
14051   [(use (match_operand:MODEF 0 "register_operand"))
14052    (use (match_operand:MODEF 1 "general_operand"))]
14053  "TARGET_USE_FANCY_MATH_387
14054    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14055        || TARGET_MIX_SSE_I387)
14056    && flag_unsafe_math_optimizations"
14058   rtx op0 = gen_reg_rtx (XFmode);
14059   rtx op1 = gen_reg_rtx (XFmode);
14061   if (optimize_insn_for_size_p ())
14062     FAIL;
14064   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14065   emit_insn (gen_acosxf2 (op0, op1));
14066   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14067   DONE;
14070 (define_insn "fyl2xxf3_i387"
14071   [(set (match_operand:XF 0 "register_operand" "=f")
14072         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14073                     (match_operand:XF 2 "register_operand" "u")]
14074                    UNSPEC_FYL2X))
14075    (clobber (match_scratch:XF 3 "=2"))]
14076   "TARGET_USE_FANCY_MATH_387
14077    && flag_unsafe_math_optimizations"
14078   "fyl2x"
14079   [(set_attr "type" "fpspc")
14080    (set_attr "mode" "XF")])
14082 (define_insn "fyl2x_extend<mode>xf3_i387"
14083   [(set (match_operand:XF 0 "register_operand" "=f")
14084         (unspec:XF [(float_extend:XF
14085                       (match_operand:MODEF 1 "register_operand" "0"))
14086                     (match_operand:XF 2 "register_operand" "u")]
14087                    UNSPEC_FYL2X))
14088    (clobber (match_scratch:XF 3 "=2"))]
14089   "TARGET_USE_FANCY_MATH_387
14090    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14091        || TARGET_MIX_SSE_I387)
14092    && flag_unsafe_math_optimizations"
14093   "fyl2x"
14094   [(set_attr "type" "fpspc")
14095    (set_attr "mode" "XF")])
14097 (define_expand "logxf2"
14098   [(parallel [(set (match_operand:XF 0 "register_operand")
14099                    (unspec:XF [(match_operand:XF 1 "register_operand")
14100                                (match_dup 2)] UNSPEC_FYL2X))
14101               (clobber (match_scratch:XF 3))])]
14102   "TARGET_USE_FANCY_MATH_387
14103    && flag_unsafe_math_optimizations"
14105   operands[2] = gen_reg_rtx (XFmode);
14106   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14109 (define_expand "log<mode>2"
14110   [(use (match_operand:MODEF 0 "register_operand"))
14111    (use (match_operand:MODEF 1 "register_operand"))]
14112   "TARGET_USE_FANCY_MATH_387
14113    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14114        || TARGET_MIX_SSE_I387)
14115    && flag_unsafe_math_optimizations"
14117   rtx op0 = gen_reg_rtx (XFmode);
14119   rtx op2 = gen_reg_rtx (XFmode);
14120   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14122   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14123   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14124   DONE;
14127 (define_expand "log10xf2"
14128   [(parallel [(set (match_operand:XF 0 "register_operand")
14129                    (unspec:XF [(match_operand:XF 1 "register_operand")
14130                                (match_dup 2)] UNSPEC_FYL2X))
14131               (clobber (match_scratch:XF 3))])]
14132   "TARGET_USE_FANCY_MATH_387
14133    && flag_unsafe_math_optimizations"
14135   operands[2] = gen_reg_rtx (XFmode);
14136   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14139 (define_expand "log10<mode>2"
14140   [(use (match_operand:MODEF 0 "register_operand"))
14141    (use (match_operand:MODEF 1 "register_operand"))]
14142   "TARGET_USE_FANCY_MATH_387
14143    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14144        || TARGET_MIX_SSE_I387)
14145    && flag_unsafe_math_optimizations"
14147   rtx op0 = gen_reg_rtx (XFmode);
14149   rtx op2 = gen_reg_rtx (XFmode);
14150   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14152   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14153   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14154   DONE;
14157 (define_expand "log2xf2"
14158   [(parallel [(set (match_operand:XF 0 "register_operand")
14159                    (unspec:XF [(match_operand:XF 1 "register_operand")
14160                                (match_dup 2)] UNSPEC_FYL2X))
14161               (clobber (match_scratch:XF 3))])]
14162   "TARGET_USE_FANCY_MATH_387
14163    && flag_unsafe_math_optimizations"
14165   operands[2] = gen_reg_rtx (XFmode);
14166   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14169 (define_expand "log2<mode>2"
14170   [(use (match_operand:MODEF 0 "register_operand"))
14171    (use (match_operand:MODEF 1 "register_operand"))]
14172   "TARGET_USE_FANCY_MATH_387
14173    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14174        || TARGET_MIX_SSE_I387)
14175    && flag_unsafe_math_optimizations"
14177   rtx op0 = gen_reg_rtx (XFmode);
14179   rtx op2 = gen_reg_rtx (XFmode);
14180   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14182   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14183   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14184   DONE;
14187 (define_insn "fyl2xp1xf3_i387"
14188   [(set (match_operand:XF 0 "register_operand" "=f")
14189         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14190                     (match_operand:XF 2 "register_operand" "u")]
14191                    UNSPEC_FYL2XP1))
14192    (clobber (match_scratch:XF 3 "=2"))]
14193   "TARGET_USE_FANCY_MATH_387
14194    && flag_unsafe_math_optimizations"
14195   "fyl2xp1"
14196   [(set_attr "type" "fpspc")
14197    (set_attr "mode" "XF")])
14199 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14200   [(set (match_operand:XF 0 "register_operand" "=f")
14201         (unspec:XF [(float_extend:XF
14202                       (match_operand:MODEF 1 "register_operand" "0"))
14203                     (match_operand:XF 2 "register_operand" "u")]
14204                    UNSPEC_FYL2XP1))
14205    (clobber (match_scratch:XF 3 "=2"))]
14206   "TARGET_USE_FANCY_MATH_387
14207    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14208        || TARGET_MIX_SSE_I387)
14209    && flag_unsafe_math_optimizations"
14210   "fyl2xp1"
14211   [(set_attr "type" "fpspc")
14212    (set_attr "mode" "XF")])
14214 (define_expand "log1pxf2"
14215   [(use (match_operand:XF 0 "register_operand"))
14216    (use (match_operand:XF 1 "register_operand"))]
14217   "TARGET_USE_FANCY_MATH_387
14218    && flag_unsafe_math_optimizations"
14220   if (optimize_insn_for_size_p ())
14221     FAIL;
14223   ix86_emit_i387_log1p (operands[0], operands[1]);
14224   DONE;
14227 (define_expand "log1p<mode>2"
14228   [(use (match_operand:MODEF 0 "register_operand"))
14229    (use (match_operand:MODEF 1 "register_operand"))]
14230   "TARGET_USE_FANCY_MATH_387
14231    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14232        || TARGET_MIX_SSE_I387)
14233    && flag_unsafe_math_optimizations"
14235   rtx op0;
14237   if (optimize_insn_for_size_p ())
14238     FAIL;
14240   op0 = gen_reg_rtx (XFmode);
14242   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14244   ix86_emit_i387_log1p (op0, operands[1]);
14245   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14246   DONE;
14249 (define_insn "fxtractxf3_i387"
14250   [(set (match_operand:XF 0 "register_operand" "=f")
14251         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14252                    UNSPEC_XTRACT_FRACT))
14253    (set (match_operand:XF 1 "register_operand" "=u")
14254         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14255   "TARGET_USE_FANCY_MATH_387
14256    && flag_unsafe_math_optimizations"
14257   "fxtract"
14258   [(set_attr "type" "fpspc")
14259    (set_attr "mode" "XF")])
14261 (define_insn "fxtract_extend<mode>xf3_i387"
14262   [(set (match_operand:XF 0 "register_operand" "=f")
14263         (unspec:XF [(float_extend:XF
14264                       (match_operand:MODEF 2 "register_operand" "0"))]
14265                    UNSPEC_XTRACT_FRACT))
14266    (set (match_operand:XF 1 "register_operand" "=u")
14267         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14268   "TARGET_USE_FANCY_MATH_387
14269    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14270        || TARGET_MIX_SSE_I387)
14271    && flag_unsafe_math_optimizations"
14272   "fxtract"
14273   [(set_attr "type" "fpspc")
14274    (set_attr "mode" "XF")])
14276 (define_expand "logbxf2"
14277   [(parallel [(set (match_dup 2)
14278                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14279                               UNSPEC_XTRACT_FRACT))
14280               (set (match_operand:XF 0 "register_operand")
14281                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14282   "TARGET_USE_FANCY_MATH_387
14283    && flag_unsafe_math_optimizations"
14284   "operands[2] = gen_reg_rtx (XFmode);")
14286 (define_expand "logb<mode>2"
14287   [(use (match_operand:MODEF 0 "register_operand"))
14288    (use (match_operand:MODEF 1 "register_operand"))]
14289   "TARGET_USE_FANCY_MATH_387
14290    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14291        || TARGET_MIX_SSE_I387)
14292    && flag_unsafe_math_optimizations"
14294   rtx op0 = gen_reg_rtx (XFmode);
14295   rtx op1 = gen_reg_rtx (XFmode);
14297   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14298   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14299   DONE;
14302 (define_expand "ilogbxf2"
14303   [(use (match_operand:SI 0 "register_operand"))
14304    (use (match_operand:XF 1 "register_operand"))]
14305   "TARGET_USE_FANCY_MATH_387
14306    && flag_unsafe_math_optimizations"
14308   rtx op0, op1;
14310   if (optimize_insn_for_size_p ())
14311     FAIL;
14313   op0 = gen_reg_rtx (XFmode);
14314   op1 = gen_reg_rtx (XFmode);
14316   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14317   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14318   DONE;
14321 (define_expand "ilogb<mode>2"
14322   [(use (match_operand:SI 0 "register_operand"))
14323    (use (match_operand:MODEF 1 "register_operand"))]
14324   "TARGET_USE_FANCY_MATH_387
14325    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14326        || TARGET_MIX_SSE_I387)
14327    && flag_unsafe_math_optimizations"
14329   rtx op0, op1;
14331   if (optimize_insn_for_size_p ())
14332     FAIL;
14334   op0 = gen_reg_rtx (XFmode);
14335   op1 = gen_reg_rtx (XFmode);
14337   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14338   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14339   DONE;
14342 (define_insn "*f2xm1xf2_i387"
14343   [(set (match_operand:XF 0 "register_operand" "=f")
14344         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14345                    UNSPEC_F2XM1))]
14346   "TARGET_USE_FANCY_MATH_387
14347    && flag_unsafe_math_optimizations"
14348   "f2xm1"
14349   [(set_attr "type" "fpspc")
14350    (set_attr "mode" "XF")])
14352 (define_insn "*fscalexf4_i387"
14353   [(set (match_operand:XF 0 "register_operand" "=f")
14354         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14355                     (match_operand:XF 3 "register_operand" "1")]
14356                    UNSPEC_FSCALE_FRACT))
14357    (set (match_operand:XF 1 "register_operand" "=u")
14358         (unspec:XF [(match_dup 2) (match_dup 3)]
14359                    UNSPEC_FSCALE_EXP))]
14360   "TARGET_USE_FANCY_MATH_387
14361    && flag_unsafe_math_optimizations"
14362   "fscale"
14363   [(set_attr "type" "fpspc")
14364    (set_attr "mode" "XF")])
14366 (define_expand "expNcorexf3"
14367   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14368                                (match_operand:XF 2 "register_operand")))
14369    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14370    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14371    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14372    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14373    (parallel [(set (match_operand:XF 0 "register_operand")
14374                    (unspec:XF [(match_dup 8) (match_dup 4)]
14375                               UNSPEC_FSCALE_FRACT))
14376               (set (match_dup 9)
14377                    (unspec:XF [(match_dup 8) (match_dup 4)]
14378                               UNSPEC_FSCALE_EXP))])]
14379   "TARGET_USE_FANCY_MATH_387
14380    && flag_unsafe_math_optimizations"
14382   int i;
14384   if (optimize_insn_for_size_p ())
14385     FAIL;
14387   for (i = 3; i < 10; i++)
14388     operands[i] = gen_reg_rtx (XFmode);
14390   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14393 (define_expand "expxf2"
14394   [(use (match_operand:XF 0 "register_operand"))
14395    (use (match_operand:XF 1 "register_operand"))]
14396   "TARGET_USE_FANCY_MATH_387
14397    && flag_unsafe_math_optimizations"
14399   rtx op2;
14401   if (optimize_insn_for_size_p ())
14402     FAIL;
14404   op2 = gen_reg_rtx (XFmode);
14405   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14407   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14408   DONE;
14411 (define_expand "exp<mode>2"
14412   [(use (match_operand:MODEF 0 "register_operand"))
14413    (use (match_operand:MODEF 1 "general_operand"))]
14414  "TARGET_USE_FANCY_MATH_387
14415    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14416        || TARGET_MIX_SSE_I387)
14417    && flag_unsafe_math_optimizations"
14419   rtx op0, op1;
14421   if (optimize_insn_for_size_p ())
14422     FAIL;
14424   op0 = gen_reg_rtx (XFmode);
14425   op1 = gen_reg_rtx (XFmode);
14427   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14428   emit_insn (gen_expxf2 (op0, op1));
14429   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14430   DONE;
14433 (define_expand "exp10xf2"
14434   [(use (match_operand:XF 0 "register_operand"))
14435    (use (match_operand:XF 1 "register_operand"))]
14436   "TARGET_USE_FANCY_MATH_387
14437    && flag_unsafe_math_optimizations"
14439   rtx op2;
14441   if (optimize_insn_for_size_p ())
14442     FAIL;
14444   op2 = gen_reg_rtx (XFmode);
14445   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14447   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14448   DONE;
14451 (define_expand "exp10<mode>2"
14452   [(use (match_operand:MODEF 0 "register_operand"))
14453    (use (match_operand:MODEF 1 "general_operand"))]
14454  "TARGET_USE_FANCY_MATH_387
14455    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14456        || TARGET_MIX_SSE_I387)
14457    && flag_unsafe_math_optimizations"
14459   rtx op0, op1;
14461   if (optimize_insn_for_size_p ())
14462     FAIL;
14464   op0 = gen_reg_rtx (XFmode);
14465   op1 = gen_reg_rtx (XFmode);
14467   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14468   emit_insn (gen_exp10xf2 (op0, op1));
14469   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14470   DONE;
14473 (define_expand "exp2xf2"
14474   [(use (match_operand:XF 0 "register_operand"))
14475    (use (match_operand:XF 1 "register_operand"))]
14476   "TARGET_USE_FANCY_MATH_387
14477    && flag_unsafe_math_optimizations"
14479   rtx op2;
14481   if (optimize_insn_for_size_p ())
14482     FAIL;
14484   op2 = gen_reg_rtx (XFmode);
14485   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14487   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14488   DONE;
14491 (define_expand "exp2<mode>2"
14492   [(use (match_operand:MODEF 0 "register_operand"))
14493    (use (match_operand:MODEF 1 "general_operand"))]
14494  "TARGET_USE_FANCY_MATH_387
14495    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14496        || TARGET_MIX_SSE_I387)
14497    && flag_unsafe_math_optimizations"
14499   rtx op0, op1;
14501   if (optimize_insn_for_size_p ())
14502     FAIL;
14504   op0 = gen_reg_rtx (XFmode);
14505   op1 = gen_reg_rtx (XFmode);
14507   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14508   emit_insn (gen_exp2xf2 (op0, op1));
14509   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14510   DONE;
14513 (define_expand "expm1xf2"
14514   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14515                                (match_dup 2)))
14516    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14517    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14518    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14519    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14520    (parallel [(set (match_dup 7)
14521                    (unspec:XF [(match_dup 6) (match_dup 4)]
14522                               UNSPEC_FSCALE_FRACT))
14523               (set (match_dup 8)
14524                    (unspec:XF [(match_dup 6) (match_dup 4)]
14525                               UNSPEC_FSCALE_EXP))])
14526    (parallel [(set (match_dup 10)
14527                    (unspec:XF [(match_dup 9) (match_dup 8)]
14528                               UNSPEC_FSCALE_FRACT))
14529               (set (match_dup 11)
14530                    (unspec:XF [(match_dup 9) (match_dup 8)]
14531                               UNSPEC_FSCALE_EXP))])
14532    (set (match_dup 12) (minus:XF (match_dup 10)
14533                                  (float_extend:XF (match_dup 13))))
14534    (set (match_operand:XF 0 "register_operand")
14535         (plus:XF (match_dup 12) (match_dup 7)))]
14536   "TARGET_USE_FANCY_MATH_387
14537    && flag_unsafe_math_optimizations"
14539   int i;
14541   if (optimize_insn_for_size_p ())
14542     FAIL;
14544   for (i = 2; i < 13; i++)
14545     operands[i] = gen_reg_rtx (XFmode);
14547   operands[13]
14548     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14550   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14553 (define_expand "expm1<mode>2"
14554   [(use (match_operand:MODEF 0 "register_operand"))
14555    (use (match_operand:MODEF 1 "general_operand"))]
14556  "TARGET_USE_FANCY_MATH_387
14557    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14558        || TARGET_MIX_SSE_I387)
14559    && flag_unsafe_math_optimizations"
14561   rtx op0, op1;
14563   if (optimize_insn_for_size_p ())
14564     FAIL;
14566   op0 = gen_reg_rtx (XFmode);
14567   op1 = gen_reg_rtx (XFmode);
14569   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14570   emit_insn (gen_expm1xf2 (op0, op1));
14571   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14572   DONE;
14575 (define_expand "ldexpxf3"
14576   [(set (match_dup 3)
14577         (float:XF (match_operand:SI 2 "register_operand")))
14578    (parallel [(set (match_operand:XF 0 " register_operand")
14579                    (unspec:XF [(match_operand:XF 1 "register_operand")
14580                                (match_dup 3)]
14581                               UNSPEC_FSCALE_FRACT))
14582               (set (match_dup 4)
14583                    (unspec:XF [(match_dup 1) (match_dup 3)]
14584                               UNSPEC_FSCALE_EXP))])]
14585   "TARGET_USE_FANCY_MATH_387
14586    && flag_unsafe_math_optimizations"
14588   if (optimize_insn_for_size_p ())
14589     FAIL;
14591   operands[3] = gen_reg_rtx (XFmode);
14592   operands[4] = gen_reg_rtx (XFmode);
14595 (define_expand "ldexp<mode>3"
14596   [(use (match_operand:MODEF 0 "register_operand"))
14597    (use (match_operand:MODEF 1 "general_operand"))
14598    (use (match_operand:SI 2 "register_operand"))]
14599  "TARGET_USE_FANCY_MATH_387
14600    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14601        || TARGET_MIX_SSE_I387)
14602    && flag_unsafe_math_optimizations"
14604   rtx op0, op1;
14606   if (optimize_insn_for_size_p ())
14607     FAIL;
14609   op0 = gen_reg_rtx (XFmode);
14610   op1 = gen_reg_rtx (XFmode);
14612   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14613   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14614   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14615   DONE;
14618 (define_expand "scalbxf3"
14619   [(parallel [(set (match_operand:XF 0 " register_operand")
14620                    (unspec:XF [(match_operand:XF 1 "register_operand")
14621                                (match_operand:XF 2 "register_operand")]
14622                               UNSPEC_FSCALE_FRACT))
14623               (set (match_dup 3)
14624                    (unspec:XF [(match_dup 1) (match_dup 2)]
14625                               UNSPEC_FSCALE_EXP))])]
14626   "TARGET_USE_FANCY_MATH_387
14627    && flag_unsafe_math_optimizations"
14629   if (optimize_insn_for_size_p ())
14630     FAIL;
14632   operands[3] = gen_reg_rtx (XFmode);
14635 (define_expand "scalb<mode>3"
14636   [(use (match_operand:MODEF 0 "register_operand"))
14637    (use (match_operand:MODEF 1 "general_operand"))
14638    (use (match_operand:MODEF 2 "general_operand"))]
14639  "TARGET_USE_FANCY_MATH_387
14640    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14641        || TARGET_MIX_SSE_I387)
14642    && flag_unsafe_math_optimizations"
14644   rtx op0, op1, op2;
14646   if (optimize_insn_for_size_p ())
14647     FAIL;
14649   op0 = gen_reg_rtx (XFmode);
14650   op1 = gen_reg_rtx (XFmode);
14651   op2 = gen_reg_rtx (XFmode);
14653   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14654   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14655   emit_insn (gen_scalbxf3 (op0, op1, op2));
14656   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14657   DONE;
14660 (define_expand "significandxf2"
14661   [(parallel [(set (match_operand:XF 0 "register_operand")
14662                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14663                               UNSPEC_XTRACT_FRACT))
14664               (set (match_dup 2)
14665                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14666   "TARGET_USE_FANCY_MATH_387
14667    && flag_unsafe_math_optimizations"
14668   "operands[2] = gen_reg_rtx (XFmode);")
14670 (define_expand "significand<mode>2"
14671   [(use (match_operand:MODEF 0 "register_operand"))
14672    (use (match_operand:MODEF 1 "register_operand"))]
14673   "TARGET_USE_FANCY_MATH_387
14674    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14675        || TARGET_MIX_SSE_I387)
14676    && flag_unsafe_math_optimizations"
14678   rtx op0 = gen_reg_rtx (XFmode);
14679   rtx op1 = gen_reg_rtx (XFmode);
14681   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14682   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14683   DONE;
14687 (define_insn "sse4_1_round<mode>2"
14688   [(set (match_operand:MODEF 0 "register_operand" "=x")
14689         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14690                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14691                       UNSPEC_ROUND))]
14692   "TARGET_ROUND"
14693   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14694   [(set_attr "type" "ssecvt")
14695    (set_attr "prefix_extra" "1")
14696    (set_attr "prefix" "maybe_vex")
14697    (set_attr "mode" "<MODE>")])
14699 (define_insn "rintxf2"
14700   [(set (match_operand:XF 0 "register_operand" "=f")
14701         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14702                    UNSPEC_FRNDINT))]
14703   "TARGET_USE_FANCY_MATH_387
14704    && flag_unsafe_math_optimizations"
14705   "frndint"
14706   [(set_attr "type" "fpspc")
14707    (set_attr "mode" "XF")])
14709 (define_expand "rint<mode>2"
14710   [(use (match_operand:MODEF 0 "register_operand"))
14711    (use (match_operand:MODEF 1 "register_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)
14716    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14717        && !flag_trapping_math)"
14719   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14720       && !flag_trapping_math)
14721     {
14722       if (TARGET_ROUND)
14723         emit_insn (gen_sse4_1_round<mode>2
14724                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14725       else if (optimize_insn_for_size_p ())
14726         FAIL;
14727       else
14728         ix86_expand_rint (operands[0], operands[1]);
14729     }
14730   else
14731     {
14732       rtx op0 = gen_reg_rtx (XFmode);
14733       rtx op1 = gen_reg_rtx (XFmode);
14735       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14736       emit_insn (gen_rintxf2 (op0, op1));
14738       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14739     }
14740   DONE;
14743 (define_expand "round<mode>2"
14744   [(match_operand:X87MODEF 0 "register_operand")
14745    (match_operand:X87MODEF 1 "nonimmediate_operand")]
14746   "(TARGET_USE_FANCY_MATH_387
14747     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14748         || TARGET_MIX_SSE_I387)
14749     && flag_unsafe_math_optimizations)
14750    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14751        && !flag_trapping_math && !flag_rounding_math)"
14753   if (optimize_insn_for_size_p ())
14754     FAIL;
14756   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14757       && !flag_trapping_math && !flag_rounding_math)
14758     {
14759       if (TARGET_ROUND)
14760         {
14761           operands[1] = force_reg (<MODE>mode, operands[1]);
14762           ix86_expand_round_sse4 (operands[0], operands[1]);
14763         }
14764       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14765         ix86_expand_round (operands[0], operands[1]);
14766       else
14767         ix86_expand_rounddf_32 (operands[0], operands[1]);
14768     }
14769   else
14770     {
14771       operands[1] = force_reg (<MODE>mode, operands[1]);
14772       ix86_emit_i387_round (operands[0], operands[1]);
14773     }
14774   DONE;
14777 (define_insn_and_split "*fistdi2_1"
14778   [(set (match_operand:DI 0 "nonimmediate_operand")
14779         (unspec:DI [(match_operand:XF 1 "register_operand")]
14780                    UNSPEC_FIST))]
14781   "TARGET_USE_FANCY_MATH_387
14782    && can_create_pseudo_p ()"
14783   "#"
14784   "&& 1"
14785   [(const_int 0)]
14787   if (memory_operand (operands[0], VOIDmode))
14788     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14789   else
14790     {
14791       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14792       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14793                                          operands[2]));
14794     }
14795   DONE;
14797   [(set_attr "type" "fpspc")
14798    (set_attr "mode" "DI")])
14800 (define_insn "fistdi2"
14801   [(set (match_operand:DI 0 "memory_operand" "=m")
14802         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14803                    UNSPEC_FIST))
14804    (clobber (match_scratch:XF 2 "=&1f"))]
14805   "TARGET_USE_FANCY_MATH_387"
14806   "* return output_fix_trunc (insn, operands, false);"
14807   [(set_attr "type" "fpspc")
14808    (set_attr "mode" "DI")])
14810 (define_insn "fistdi2_with_temp"
14811   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14812         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14813                    UNSPEC_FIST))
14814    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14815    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14816   "TARGET_USE_FANCY_MATH_387"
14817   "#"
14818   [(set_attr "type" "fpspc")
14819    (set_attr "mode" "DI")])
14821 (define_split
14822   [(set (match_operand:DI 0 "register_operand")
14823         (unspec:DI [(match_operand:XF 1 "register_operand")]
14824                    UNSPEC_FIST))
14825    (clobber (match_operand:DI 2 "memory_operand"))
14826    (clobber (match_scratch 3))]
14827   "reload_completed"
14828   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14829               (clobber (match_dup 3))])
14830    (set (match_dup 0) (match_dup 2))])
14832 (define_split
14833   [(set (match_operand:DI 0 "memory_operand")
14834         (unspec:DI [(match_operand:XF 1 "register_operand")]
14835                    UNSPEC_FIST))
14836    (clobber (match_operand:DI 2 "memory_operand"))
14837    (clobber (match_scratch 3))]
14838   "reload_completed"
14839   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14840               (clobber (match_dup 3))])])
14842 (define_insn_and_split "*fist<mode>2_1"
14843   [(set (match_operand:SWI24 0 "register_operand")
14844         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14845                       UNSPEC_FIST))]
14846   "TARGET_USE_FANCY_MATH_387
14847    && can_create_pseudo_p ()"
14848   "#"
14849   "&& 1"
14850   [(const_int 0)]
14852   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14853   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14854                                         operands[2]));
14855   DONE;
14857   [(set_attr "type" "fpspc")
14858    (set_attr "mode" "<MODE>")])
14860 (define_insn "fist<mode>2"
14861   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14862         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14863                       UNSPEC_FIST))]
14864   "TARGET_USE_FANCY_MATH_387"
14865   "* return output_fix_trunc (insn, operands, false);"
14866   [(set_attr "type" "fpspc")
14867    (set_attr "mode" "<MODE>")])
14869 (define_insn "fist<mode>2_with_temp"
14870   [(set (match_operand:SWI24 0 "register_operand" "=r")
14871         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14872                       UNSPEC_FIST))
14873    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14874   "TARGET_USE_FANCY_MATH_387"
14875   "#"
14876   [(set_attr "type" "fpspc")
14877    (set_attr "mode" "<MODE>")])
14879 (define_split
14880   [(set (match_operand:SWI24 0 "register_operand")
14881         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14882                       UNSPEC_FIST))
14883    (clobber (match_operand:SWI24 2 "memory_operand"))]
14884   "reload_completed"
14885   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14886    (set (match_dup 0) (match_dup 2))])
14888 (define_split
14889   [(set (match_operand:SWI24 0 "memory_operand")
14890         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14891                       UNSPEC_FIST))
14892    (clobber (match_operand:SWI24 2 "memory_operand"))]
14893   "reload_completed"
14894   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14896 (define_expand "lrintxf<mode>2"
14897   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14898      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14899                      UNSPEC_FIST))]
14900   "TARGET_USE_FANCY_MATH_387")
14902 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
14903   [(set (match_operand:SWI48 0 "nonimmediate_operand")
14904      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
14905                    UNSPEC_FIX_NOTRUNC))]
14906   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
14908 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14909   [(match_operand:SWI248x 0 "nonimmediate_operand")
14910    (match_operand:X87MODEF 1 "register_operand")]
14911   "(TARGET_USE_FANCY_MATH_387
14912     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14913         || TARGET_MIX_SSE_I387)
14914     && flag_unsafe_math_optimizations)
14915    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14916        && <SWI248x:MODE>mode != HImode 
14917        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14918        && !flag_trapping_math && !flag_rounding_math)"
14920   if (optimize_insn_for_size_p ())
14921     FAIL;
14923   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14924       && <SWI248x:MODE>mode != HImode
14925       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14926       && !flag_trapping_math && !flag_rounding_math)
14927     ix86_expand_lround (operands[0], operands[1]);
14928   else
14929     ix86_emit_i387_round (operands[0], operands[1]);
14930   DONE;
14933 (define_int_iterator FRNDINT_ROUNDING
14934         [UNSPEC_FRNDINT_FLOOR
14935          UNSPEC_FRNDINT_CEIL
14936          UNSPEC_FRNDINT_TRUNC])
14938 (define_int_iterator FIST_ROUNDING
14939         [UNSPEC_FIST_FLOOR
14940          UNSPEC_FIST_CEIL])
14942 ;; Base name for define_insn
14943 (define_int_attr rounding_insn
14944         [(UNSPEC_FRNDINT_FLOOR "floor")
14945          (UNSPEC_FRNDINT_CEIL "ceil")
14946          (UNSPEC_FRNDINT_TRUNC "btrunc")
14947          (UNSPEC_FIST_FLOOR "floor")
14948          (UNSPEC_FIST_CEIL "ceil")])
14950 (define_int_attr rounding
14951         [(UNSPEC_FRNDINT_FLOOR "floor")
14952          (UNSPEC_FRNDINT_CEIL "ceil")
14953          (UNSPEC_FRNDINT_TRUNC "trunc")
14954          (UNSPEC_FIST_FLOOR "floor")
14955          (UNSPEC_FIST_CEIL "ceil")])
14957 (define_int_attr ROUNDING
14958         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
14959          (UNSPEC_FRNDINT_CEIL "CEIL")
14960          (UNSPEC_FRNDINT_TRUNC "TRUNC")
14961          (UNSPEC_FIST_FLOOR "FLOOR")
14962          (UNSPEC_FIST_CEIL "CEIL")])
14964 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14965 (define_insn_and_split "frndintxf2_<rounding>"
14966   [(set (match_operand:XF 0 "register_operand")
14967         (unspec:XF [(match_operand:XF 1 "register_operand")]
14968                    FRNDINT_ROUNDING))
14969    (clobber (reg:CC FLAGS_REG))]
14970   "TARGET_USE_FANCY_MATH_387
14971    && flag_unsafe_math_optimizations
14972    && can_create_pseudo_p ()"
14973   "#"
14974   "&& 1"
14975   [(const_int 0)]
14977   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
14979   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14980   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
14982   emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
14983                                              operands[2], operands[3]));
14984   DONE;
14986   [(set_attr "type" "frndint")
14987    (set_attr "i387_cw" "<rounding>")
14988    (set_attr "mode" "XF")])
14990 (define_insn "frndintxf2_<rounding>_i387"
14991   [(set (match_operand:XF 0 "register_operand" "=f")
14992         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14993                    FRNDINT_ROUNDING))
14994    (use (match_operand:HI 2 "memory_operand" "m"))
14995    (use (match_operand:HI 3 "memory_operand" "m"))]
14996   "TARGET_USE_FANCY_MATH_387
14997    && flag_unsafe_math_optimizations"
14998   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14999   [(set_attr "type" "frndint")
15000    (set_attr "i387_cw" "<rounding>")
15001    (set_attr "mode" "XF")])
15003 (define_expand "<rounding_insn>xf2"
15004   [(parallel [(set (match_operand:XF 0 "register_operand")
15005                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15006                               FRNDINT_ROUNDING))
15007               (clobber (reg:CC FLAGS_REG))])]
15008   "TARGET_USE_FANCY_MATH_387
15009    && flag_unsafe_math_optimizations
15010    && !optimize_insn_for_size_p ()")
15012 (define_expand "<rounding_insn><mode>2"
15013   [(parallel [(set (match_operand:MODEF 0 "register_operand")
15014                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15015                                  FRNDINT_ROUNDING))
15016               (clobber (reg:CC FLAGS_REG))])]
15017   "(TARGET_USE_FANCY_MATH_387
15018     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15019         || TARGET_MIX_SSE_I387)
15020     && flag_unsafe_math_optimizations)
15021    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15022        && !flag_trapping_math)"
15024   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15025       && !flag_trapping_math)
15026     {
15027       if (TARGET_ROUND)
15028         emit_insn (gen_sse4_1_round<mode>2
15029                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15030       else if (optimize_insn_for_size_p ())
15031         FAIL;
15032       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15033         {
15034           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15035             ix86_expand_floorceil (operands[0], operands[1], true);
15036           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15037             ix86_expand_floorceil (operands[0], operands[1], false);
15038           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15039             ix86_expand_trunc (operands[0], operands[1]);
15040           else
15041             gcc_unreachable ();
15042         }
15043       else
15044         {
15045           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15046             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15047           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15048             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15049           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15050             ix86_expand_truncdf_32 (operands[0], operands[1]);
15051           else
15052             gcc_unreachable ();
15053         }
15054     }
15055   else
15056     {
15057       rtx op0, op1;
15059       if (optimize_insn_for_size_p ())
15060         FAIL;
15062       op0 = gen_reg_rtx (XFmode);
15063       op1 = gen_reg_rtx (XFmode);
15064       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15065       emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15067       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15068     }
15069   DONE;
15072 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15073 (define_insn_and_split "frndintxf2_mask_pm"
15074   [(set (match_operand:XF 0 "register_operand")
15075         (unspec:XF [(match_operand:XF 1 "register_operand")]
15076                    UNSPEC_FRNDINT_MASK_PM))
15077    (clobber (reg:CC FLAGS_REG))]
15078   "TARGET_USE_FANCY_MATH_387
15079    && flag_unsafe_math_optimizations
15080    && can_create_pseudo_p ()"
15081   "#"
15082   "&& 1"
15083   [(const_int 0)]
15085   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15087   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15088   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15090   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15091                                           operands[2], operands[3]));
15092   DONE;
15094   [(set_attr "type" "frndint")
15095    (set_attr "i387_cw" "mask_pm")
15096    (set_attr "mode" "XF")])
15098 (define_insn "frndintxf2_mask_pm_i387"
15099   [(set (match_operand:XF 0 "register_operand" "=f")
15100         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15101                    UNSPEC_FRNDINT_MASK_PM))
15102    (use (match_operand:HI 2 "memory_operand" "m"))
15103    (use (match_operand:HI 3 "memory_operand" "m"))]
15104   "TARGET_USE_FANCY_MATH_387
15105    && flag_unsafe_math_optimizations"
15106   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15107   [(set_attr "type" "frndint")
15108    (set_attr "i387_cw" "mask_pm")
15109    (set_attr "mode" "XF")])
15111 (define_expand "nearbyintxf2"
15112   [(parallel [(set (match_operand:XF 0 "register_operand")
15113                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15114                               UNSPEC_FRNDINT_MASK_PM))
15115               (clobber (reg:CC FLAGS_REG))])]
15116   "TARGET_USE_FANCY_MATH_387
15117    && flag_unsafe_math_optimizations")
15119 (define_expand "nearbyint<mode>2"
15120   [(use (match_operand:MODEF 0 "register_operand"))
15121    (use (match_operand:MODEF 1 "register_operand"))]
15122   "TARGET_USE_FANCY_MATH_387
15123    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15124        || TARGET_MIX_SSE_I387)
15125    && flag_unsafe_math_optimizations"
15127   rtx op0 = gen_reg_rtx (XFmode);
15128   rtx op1 = gen_reg_rtx (XFmode);
15130   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15131   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15133   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15134   DONE;
15137 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15138 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15139   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15140         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15141                         FIST_ROUNDING))
15142    (clobber (reg:CC FLAGS_REG))]
15143   "TARGET_USE_FANCY_MATH_387
15144    && flag_unsafe_math_optimizations
15145    && can_create_pseudo_p ()"
15146   "#"
15147   "&& 1"
15148   [(const_int 0)]
15150   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15152   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15153   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15154   if (memory_operand (operands[0], VOIDmode))
15155     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15156                                            operands[2], operands[3]));
15157   else
15158     {
15159       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15160       emit_insn (gen_fist<mode>2_<rounding>_with_temp
15161                   (operands[0], operands[1], operands[2],
15162                    operands[3], operands[4]));
15163     }
15164   DONE;
15166   [(set_attr "type" "fistp")
15167    (set_attr "i387_cw" "<rounding>")
15168    (set_attr "mode" "<MODE>")])
15170 (define_insn "fistdi2_<rounding>"
15171   [(set (match_operand:DI 0 "memory_operand" "=m")
15172         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15173                    FIST_ROUNDING))
15174    (use (match_operand:HI 2 "memory_operand" "m"))
15175    (use (match_operand:HI 3 "memory_operand" "m"))
15176    (clobber (match_scratch:XF 4 "=&1f"))]
15177   "TARGET_USE_FANCY_MATH_387
15178    && flag_unsafe_math_optimizations"
15179   "* return output_fix_trunc (insn, operands, false);"
15180   [(set_attr "type" "fistp")
15181    (set_attr "i387_cw" "<rounding>")
15182    (set_attr "mode" "DI")])
15184 (define_insn "fistdi2_<rounding>_with_temp"
15185   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15186         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15187                    FIST_ROUNDING))
15188    (use (match_operand:HI 2 "memory_operand" "m,m"))
15189    (use (match_operand:HI 3 "memory_operand" "m,m"))
15190    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15191    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15192   "TARGET_USE_FANCY_MATH_387
15193    && flag_unsafe_math_optimizations"
15194   "#"
15195   [(set_attr "type" "fistp")
15196    (set_attr "i387_cw" "<rounding>")
15197    (set_attr "mode" "DI")])
15199 (define_split
15200   [(set (match_operand:DI 0 "register_operand")
15201         (unspec:DI [(match_operand:XF 1 "register_operand")]
15202                    FIST_ROUNDING))
15203    (use (match_operand:HI 2 "memory_operand"))
15204    (use (match_operand:HI 3 "memory_operand"))
15205    (clobber (match_operand:DI 4 "memory_operand"))
15206    (clobber (match_scratch 5))]
15207   "reload_completed"
15208   [(parallel [(set (match_dup 4)
15209                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15210               (use (match_dup 2))
15211               (use (match_dup 3))
15212               (clobber (match_dup 5))])
15213    (set (match_dup 0) (match_dup 4))])
15215 (define_split
15216   [(set (match_operand:DI 0 "memory_operand")
15217         (unspec:DI [(match_operand:XF 1 "register_operand")]
15218                    FIST_ROUNDING))
15219    (use (match_operand:HI 2 "memory_operand"))
15220    (use (match_operand:HI 3 "memory_operand"))
15221    (clobber (match_operand:DI 4 "memory_operand"))
15222    (clobber (match_scratch 5))]
15223   "reload_completed"
15224   [(parallel [(set (match_dup 0)
15225                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15226               (use (match_dup 2))
15227               (use (match_dup 3))
15228               (clobber (match_dup 5))])])
15230 (define_insn "fist<mode>2_<rounding>"
15231   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15232         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15233                       FIST_ROUNDING))
15234    (use (match_operand:HI 2 "memory_operand" "m"))
15235    (use (match_operand:HI 3 "memory_operand" "m"))]
15236   "TARGET_USE_FANCY_MATH_387
15237    && flag_unsafe_math_optimizations"
15238   "* return output_fix_trunc (insn, operands, false);"
15239   [(set_attr "type" "fistp")
15240    (set_attr "i387_cw" "<rounding>")
15241    (set_attr "mode" "<MODE>")])
15243 (define_insn "fist<mode>2_<rounding>_with_temp"
15244   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15245         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15246                       FIST_ROUNDING))
15247    (use (match_operand:HI 2 "memory_operand" "m,m"))
15248    (use (match_operand:HI 3 "memory_operand" "m,m"))
15249    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15250   "TARGET_USE_FANCY_MATH_387
15251    && flag_unsafe_math_optimizations"
15252   "#"
15253   [(set_attr "type" "fistp")
15254    (set_attr "i387_cw" "<rounding>")
15255    (set_attr "mode" "<MODE>")])
15257 (define_split
15258   [(set (match_operand:SWI24 0 "register_operand")
15259         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15260                       FIST_ROUNDING))
15261    (use (match_operand:HI 2 "memory_operand"))
15262    (use (match_operand:HI 3 "memory_operand"))
15263    (clobber (match_operand:SWI24 4 "memory_operand"))]
15264   "reload_completed"
15265   [(parallel [(set (match_dup 4)
15266                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15267               (use (match_dup 2))
15268               (use (match_dup 3))])
15269    (set (match_dup 0) (match_dup 4))])
15271 (define_split
15272   [(set (match_operand:SWI24 0 "memory_operand")
15273         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15274                       FIST_ROUNDING))
15275    (use (match_operand:HI 2 "memory_operand"))
15276    (use (match_operand:HI 3 "memory_operand"))
15277    (clobber (match_operand:SWI24 4 "memory_operand"))]
15278   "reload_completed"
15279   [(parallel [(set (match_dup 0)
15280                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15281               (use (match_dup 2))
15282               (use (match_dup 3))])])
15284 (define_expand "l<rounding_insn>xf<mode>2"
15285   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15286                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15287                                    FIST_ROUNDING))
15288               (clobber (reg:CC FLAGS_REG))])]
15289   "TARGET_USE_FANCY_MATH_387
15290    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15291    && flag_unsafe_math_optimizations")
15293 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15294   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15295                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15296                                  FIST_ROUNDING))
15297               (clobber (reg:CC FLAGS_REG))])]
15298   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15299    && !flag_trapping_math"
15301   if (TARGET_64BIT && optimize_insn_for_size_p ())
15302     FAIL;
15304   if (ROUND_<ROUNDING> == ROUND_FLOOR)
15305     ix86_expand_lfloorceil (operands[0], operands[1], true);
15306   else if (ROUND_<ROUNDING> == ROUND_CEIL)
15307     ix86_expand_lfloorceil (operands[0], operands[1], false);
15308   else
15309     gcc_unreachable ();
15311   DONE;
15314 (define_insn "fxam<mode>2_i387"
15315   [(set (match_operand:HI 0 "register_operand" "=a")
15316         (unspec:HI
15317           [(match_operand:X87MODEF 1 "register_operand" "f")]
15318           UNSPEC_FXAM))]
15319   "TARGET_USE_FANCY_MATH_387"
15320   "fxam\n\tfnstsw\t%0"
15321   [(set_attr "type" "multi")
15322    (set_attr "length" "4")
15323    (set_attr "unit" "i387")
15324    (set_attr "mode" "<MODE>")])
15326 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15327   [(set (match_operand:HI 0 "register_operand")
15328         (unspec:HI
15329           [(match_operand:MODEF 1 "memory_operand")]
15330           UNSPEC_FXAM_MEM))]
15331   "TARGET_USE_FANCY_MATH_387
15332    && can_create_pseudo_p ()"
15333   "#"
15334   "&& 1"
15335   [(set (match_dup 2)(match_dup 1))
15336    (set (match_dup 0)
15337         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15339   operands[2] = gen_reg_rtx (<MODE>mode);
15341   MEM_VOLATILE_P (operands[1]) = 1;
15343   [(set_attr "type" "multi")
15344    (set_attr "unit" "i387")
15345    (set_attr "mode" "<MODE>")])
15347 (define_expand "isinfxf2"
15348   [(use (match_operand:SI 0 "register_operand"))
15349    (use (match_operand:XF 1 "register_operand"))]
15350   "TARGET_USE_FANCY_MATH_387
15351    && ix86_libc_has_function (function_c99_misc)"
15353   rtx mask = GEN_INT (0x45);
15354   rtx val = GEN_INT (0x05);
15356   rtx cond;
15358   rtx scratch = gen_reg_rtx (HImode);
15359   rtx res = gen_reg_rtx (QImode);
15361   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15363   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15364   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15365   cond = gen_rtx_fmt_ee (EQ, QImode,
15366                          gen_rtx_REG (CCmode, FLAGS_REG),
15367                          const0_rtx);
15368   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15369   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15370   DONE;
15373 (define_expand "isinf<mode>2"
15374   [(use (match_operand:SI 0 "register_operand"))
15375    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15376   "TARGET_USE_FANCY_MATH_387
15377    && ix86_libc_has_function (function_c99_misc)
15378    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15380   rtx mask = GEN_INT (0x45);
15381   rtx val = GEN_INT (0x05);
15383   rtx cond;
15385   rtx scratch = gen_reg_rtx (HImode);
15386   rtx res = gen_reg_rtx (QImode);
15388   /* Remove excess precision by forcing value through memory. */
15389   if (memory_operand (operands[1], VOIDmode))
15390     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15391   else
15392     {
15393       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15395       emit_move_insn (temp, operands[1]);
15396       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15397     }
15399   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15400   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15401   cond = gen_rtx_fmt_ee (EQ, QImode,
15402                          gen_rtx_REG (CCmode, FLAGS_REG),
15403                          const0_rtx);
15404   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15405   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15406   DONE;
15409 (define_expand "signbitxf2"
15410   [(use (match_operand:SI 0 "register_operand"))
15411    (use (match_operand:XF 1 "register_operand"))]
15412   "TARGET_USE_FANCY_MATH_387"
15414   rtx scratch = gen_reg_rtx (HImode);
15416   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15417   emit_insn (gen_andsi3 (operands[0],
15418              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15419   DONE;
15422 (define_insn "movmsk_df"
15423   [(set (match_operand:SI 0 "register_operand" "=r")
15424         (unspec:SI
15425           [(match_operand:DF 1 "register_operand" "x")]
15426           UNSPEC_MOVMSK))]
15427   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15428   "%vmovmskpd\t{%1, %0|%0, %1}"
15429   [(set_attr "type" "ssemov")
15430    (set_attr "prefix" "maybe_vex")
15431    (set_attr "mode" "DF")])
15433 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15434 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15435 (define_expand "signbitdf2"
15436   [(use (match_operand:SI 0 "register_operand"))
15437    (use (match_operand:DF 1 "register_operand"))]
15438   "TARGET_USE_FANCY_MATH_387
15439    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15441   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15442     {
15443       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15444       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15445     }
15446   else
15447     {
15448       rtx scratch = gen_reg_rtx (HImode);
15450       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15451       emit_insn (gen_andsi3 (operands[0],
15452                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15453     }
15454   DONE;
15457 (define_expand "signbitsf2"
15458   [(use (match_operand:SI 0 "register_operand"))
15459    (use (match_operand:SF 1 "register_operand"))]
15460   "TARGET_USE_FANCY_MATH_387
15461    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15463   rtx scratch = gen_reg_rtx (HImode);
15465   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15466   emit_insn (gen_andsi3 (operands[0],
15467              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15468   DONE;
15471 ;; Block operation instructions
15473 (define_insn "cld"
15474   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15475   ""
15476   "cld"
15477   [(set_attr "length" "1")
15478    (set_attr "length_immediate" "0")
15479    (set_attr "modrm" "0")])
15481 (define_expand "movmem<mode>"
15482   [(use (match_operand:BLK 0 "memory_operand"))
15483    (use (match_operand:BLK 1 "memory_operand"))
15484    (use (match_operand:SWI48 2 "nonmemory_operand"))
15485    (use (match_operand:SWI48 3 "const_int_operand"))
15486    (use (match_operand:SI 4 "const_int_operand"))
15487    (use (match_operand:SI 5 "const_int_operand"))]
15488   ""
15490  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15491                          operands[4], operands[5]))
15492    DONE;
15493  else
15494    FAIL;
15497 ;; Most CPUs don't like single string operations
15498 ;; Handle this case here to simplify previous expander.
15500 (define_expand "strmov"
15501   [(set (match_dup 4) (match_operand 3 "memory_operand"))
15502    (set (match_operand 1 "memory_operand") (match_dup 4))
15503    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15504               (clobber (reg:CC FLAGS_REG))])
15505    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15506               (clobber (reg:CC FLAGS_REG))])]
15507   ""
15509   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15511   /* If .md ever supports :P for Pmode, these can be directly
15512      in the pattern above.  */
15513   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15514   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15516   /* Can't use this if the user has appropriated esi or edi.  */
15517   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15518       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15519     {
15520       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15521                                       operands[2], operands[3],
15522                                       operands[5], operands[6]));
15523       DONE;
15524     }
15526   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15529 (define_expand "strmov_singleop"
15530   [(parallel [(set (match_operand 1 "memory_operand")
15531                    (match_operand 3 "memory_operand"))
15532               (set (match_operand 0 "register_operand")
15533                    (match_operand 4))
15534               (set (match_operand 2 "register_operand")
15535                    (match_operand 5))])]
15536   ""
15537   "ix86_current_function_needs_cld = 1;")
15539 (define_insn "*strmovdi_rex_1"
15540   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15541         (mem:DI (match_operand:P 3 "register_operand" "1")))
15542    (set (match_operand:P 0 "register_operand" "=D")
15543         (plus:P (match_dup 2)
15544                 (const_int 8)))
15545    (set (match_operand:P 1 "register_operand" "=S")
15546         (plus:P (match_dup 3)
15547                 (const_int 8)))]
15548   "TARGET_64BIT
15549    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15550   "%^movsq"
15551   [(set_attr "type" "str")
15552    (set_attr "memory" "both")
15553    (set_attr "mode" "DI")])
15555 (define_insn "*strmovsi_1"
15556   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15557         (mem:SI (match_operand:P 3 "register_operand" "1")))
15558    (set (match_operand:P 0 "register_operand" "=D")
15559         (plus:P (match_dup 2)
15560                 (const_int 4)))
15561    (set (match_operand:P 1 "register_operand" "=S")
15562         (plus:P (match_dup 3)
15563                 (const_int 4)))]
15564   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15565   "%^movs{l|d}"
15566   [(set_attr "type" "str")
15567    (set_attr "memory" "both")
15568    (set_attr "mode" "SI")])
15570 (define_insn "*strmovhi_1"
15571   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15572         (mem:HI (match_operand:P 3 "register_operand" "1")))
15573    (set (match_operand:P 0 "register_operand" "=D")
15574         (plus:P (match_dup 2)
15575                 (const_int 2)))
15576    (set (match_operand:P 1 "register_operand" "=S")
15577         (plus:P (match_dup 3)
15578                 (const_int 2)))]
15579   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15580   "%^movsw"
15581   [(set_attr "type" "str")
15582    (set_attr "memory" "both")
15583    (set_attr "mode" "HI")])
15585 (define_insn "*strmovqi_1"
15586   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15587         (mem:QI (match_operand:P 3 "register_operand" "1")))
15588    (set (match_operand:P 0 "register_operand" "=D")
15589         (plus:P (match_dup 2)
15590                 (const_int 1)))
15591    (set (match_operand:P 1 "register_operand" "=S")
15592         (plus:P (match_dup 3)
15593                 (const_int 1)))]
15594   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15595   "%^movsb"
15596   [(set_attr "type" "str")
15597    (set_attr "memory" "both")
15598    (set (attr "prefix_rex")
15599         (if_then_else
15600           (match_test "<P:MODE>mode == DImode")
15601           (const_string "0")
15602           (const_string "*")))
15603    (set_attr "mode" "QI")])
15605 (define_expand "rep_mov"
15606   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15607               (set (match_operand 0 "register_operand")
15608                    (match_operand 5))
15609               (set (match_operand 2 "register_operand")
15610                    (match_operand 6))
15611               (set (match_operand 1 "memory_operand")
15612                    (match_operand 3 "memory_operand"))
15613               (use (match_dup 4))])]
15614   ""
15615   "ix86_current_function_needs_cld = 1;")
15617 (define_insn "*rep_movdi_rex64"
15618   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15619    (set (match_operand:P 0 "register_operand" "=D")
15620         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15621                           (const_int 3))
15622                 (match_operand:P 3 "register_operand" "0")))
15623    (set (match_operand:P 1 "register_operand" "=S")
15624         (plus:P (ashift:P (match_dup 5) (const_int 3))
15625                 (match_operand:P 4 "register_operand" "1")))
15626    (set (mem:BLK (match_dup 3))
15627         (mem:BLK (match_dup 4)))
15628    (use (match_dup 5))]
15629   "TARGET_64BIT
15630    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15631   "%^rep{%;} movsq"
15632   [(set_attr "type" "str")
15633    (set_attr "prefix_rep" "1")
15634    (set_attr "memory" "both")
15635    (set_attr "mode" "DI")])
15637 (define_insn "*rep_movsi"
15638   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15639    (set (match_operand:P 0 "register_operand" "=D")
15640         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15641                           (const_int 2))
15642                  (match_operand:P 3 "register_operand" "0")))
15643    (set (match_operand:P 1 "register_operand" "=S")
15644         (plus:P (ashift:P (match_dup 5) (const_int 2))
15645                 (match_operand:P 4 "register_operand" "1")))
15646    (set (mem:BLK (match_dup 3))
15647         (mem:BLK (match_dup 4)))
15648    (use (match_dup 5))]
15649   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15650   "%^rep{%;} movs{l|d}"
15651   [(set_attr "type" "str")
15652    (set_attr "prefix_rep" "1")
15653    (set_attr "memory" "both")
15654    (set_attr "mode" "SI")])
15656 (define_insn "*rep_movqi"
15657   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15658    (set (match_operand:P 0 "register_operand" "=D")
15659         (plus:P (match_operand:P 3 "register_operand" "0")
15660                 (match_operand:P 5 "register_operand" "2")))
15661    (set (match_operand:P 1 "register_operand" "=S")
15662         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15663    (set (mem:BLK (match_dup 3))
15664         (mem:BLK (match_dup 4)))
15665    (use (match_dup 5))]
15666   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15667   "%^rep{%;} movsb"
15668   [(set_attr "type" "str")
15669    (set_attr "prefix_rep" "1")
15670    (set_attr "memory" "both")
15671    (set_attr "mode" "QI")])
15673 (define_expand "setmem<mode>"
15674    [(use (match_operand:BLK 0 "memory_operand"))
15675     (use (match_operand:SWI48 1 "nonmemory_operand"))
15676     (use (match_operand:QI 2 "nonmemory_operand"))
15677     (use (match_operand 3 "const_int_operand"))
15678     (use (match_operand:SI 4 "const_int_operand"))
15679     (use (match_operand:SI 5 "const_int_operand"))]
15680   ""
15682  if (ix86_expand_setmem (operands[0], operands[1],
15683                          operands[2], operands[3],
15684                          operands[4], operands[5]))
15685    DONE;
15686  else
15687    FAIL;
15690 ;; Most CPUs don't like single string operations
15691 ;; Handle this case here to simplify previous expander.
15693 (define_expand "strset"
15694   [(set (match_operand 1 "memory_operand")
15695         (match_operand 2 "register_operand"))
15696    (parallel [(set (match_operand 0 "register_operand")
15697                    (match_dup 3))
15698               (clobber (reg:CC FLAGS_REG))])]
15699   ""
15701   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15702     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15704   /* If .md ever supports :P for Pmode, this can be directly
15705      in the pattern above.  */
15706   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15707                               GEN_INT (GET_MODE_SIZE (GET_MODE
15708                                                       (operands[2]))));
15709   /* Can't use this if the user has appropriated eax or edi.  */
15710   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15711       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15712     {
15713       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15714                                       operands[3]));
15715       DONE;
15716     }
15719 (define_expand "strset_singleop"
15720   [(parallel [(set (match_operand 1 "memory_operand")
15721                    (match_operand 2 "register_operand"))
15722               (set (match_operand 0 "register_operand")
15723                    (match_operand 3))
15724               (unspec [(const_int 0)] UNSPEC_STOS)])]
15725   ""
15726   "ix86_current_function_needs_cld = 1;")
15728 (define_insn "*strsetdi_rex_1"
15729   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15730         (match_operand:DI 2 "register_operand" "a"))
15731    (set (match_operand:P 0 "register_operand" "=D")
15732         (plus:P (match_dup 1)
15733                 (const_int 8)))
15734    (unspec [(const_int 0)] UNSPEC_STOS)]
15735   "TARGET_64BIT
15736    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15737   "%^stosq"
15738   [(set_attr "type" "str")
15739    (set_attr "memory" "store")
15740    (set_attr "mode" "DI")])
15742 (define_insn "*strsetsi_1"
15743   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15744         (match_operand:SI 2 "register_operand" "a"))
15745    (set (match_operand:P 0 "register_operand" "=D")
15746         (plus:P (match_dup 1)
15747                 (const_int 4)))
15748    (unspec [(const_int 0)] UNSPEC_STOS)]
15749   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15750   "%^stos{l|d}"
15751   [(set_attr "type" "str")
15752    (set_attr "memory" "store")
15753    (set_attr "mode" "SI")])
15755 (define_insn "*strsethi_1"
15756   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15757         (match_operand:HI 2 "register_operand" "a"))
15758    (set (match_operand:P 0 "register_operand" "=D")
15759         (plus:P (match_dup 1)
15760                 (const_int 2)))
15761    (unspec [(const_int 0)] UNSPEC_STOS)]
15762   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15763   "%^stosw"
15764   [(set_attr "type" "str")
15765    (set_attr "memory" "store")
15766    (set_attr "mode" "HI")])
15768 (define_insn "*strsetqi_1"
15769   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15770         (match_operand:QI 2 "register_operand" "a"))
15771    (set (match_operand:P 0 "register_operand" "=D")
15772         (plus:P (match_dup 1)
15773                 (const_int 1)))
15774    (unspec [(const_int 0)] UNSPEC_STOS)]
15775   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15776   "%^stosb"
15777   [(set_attr "type" "str")
15778    (set_attr "memory" "store")
15779    (set (attr "prefix_rex")
15780         (if_then_else
15781           (match_test "<P:MODE>mode == DImode")
15782           (const_string "0")
15783           (const_string "*")))
15784    (set_attr "mode" "QI")])
15786 (define_expand "rep_stos"
15787   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15788               (set (match_operand 0 "register_operand")
15789                    (match_operand 4))
15790               (set (match_operand 2 "memory_operand") (const_int 0))
15791               (use (match_operand 3 "register_operand"))
15792               (use (match_dup 1))])]
15793   ""
15794   "ix86_current_function_needs_cld = 1;")
15796 (define_insn "*rep_stosdi_rex64"
15797   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15798    (set (match_operand:P 0 "register_operand" "=D")
15799         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15800                           (const_int 3))
15801                  (match_operand:P 3 "register_operand" "0")))
15802    (set (mem:BLK (match_dup 3))
15803         (const_int 0))
15804    (use (match_operand:DI 2 "register_operand" "a"))
15805    (use (match_dup 4))]
15806   "TARGET_64BIT
15807    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15808   "%^rep{%;} stosq"
15809   [(set_attr "type" "str")
15810    (set_attr "prefix_rep" "1")
15811    (set_attr "memory" "store")
15812    (set_attr "mode" "DI")])
15814 (define_insn "*rep_stossi"
15815   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15816    (set (match_operand:P 0 "register_operand" "=D")
15817         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15818                           (const_int 2))
15819                  (match_operand:P 3 "register_operand" "0")))
15820    (set (mem:BLK (match_dup 3))
15821         (const_int 0))
15822    (use (match_operand:SI 2 "register_operand" "a"))
15823    (use (match_dup 4))]
15824   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15825   "%^rep{%;} stos{l|d}"
15826   [(set_attr "type" "str")
15827    (set_attr "prefix_rep" "1")
15828    (set_attr "memory" "store")
15829    (set_attr "mode" "SI")])
15831 (define_insn "*rep_stosqi"
15832   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15833    (set (match_operand:P 0 "register_operand" "=D")
15834         (plus:P (match_operand:P 3 "register_operand" "0")
15835                 (match_operand:P 4 "register_operand" "1")))
15836    (set (mem:BLK (match_dup 3))
15837         (const_int 0))
15838    (use (match_operand:QI 2 "register_operand" "a"))
15839    (use (match_dup 4))]
15840   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15841   "%^rep{%;} stosb"
15842   [(set_attr "type" "str")
15843    (set_attr "prefix_rep" "1")
15844    (set_attr "memory" "store")
15845    (set (attr "prefix_rex")
15846         (if_then_else
15847           (match_test "<P:MODE>mode == DImode")
15848           (const_string "0")
15849           (const_string "*")))
15850    (set_attr "mode" "QI")])
15852 (define_expand "cmpstrnsi"
15853   [(set (match_operand:SI 0 "register_operand")
15854         (compare:SI (match_operand:BLK 1 "general_operand")
15855                     (match_operand:BLK 2 "general_operand")))
15856    (use (match_operand 3 "general_operand"))
15857    (use (match_operand 4 "immediate_operand"))]
15858   ""
15860   rtx addr1, addr2, out, outlow, count, countreg, align;
15862   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15863     FAIL;
15865   /* Can't use this if the user has appropriated ecx, esi or edi.  */
15866   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
15867     FAIL;
15869   out = operands[0];
15870   if (!REG_P (out))
15871     out = gen_reg_rtx (SImode);
15873   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
15874   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
15875   if (addr1 != XEXP (operands[1], 0))
15876     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15877   if (addr2 != XEXP (operands[2], 0))
15878     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15880   count = operands[3];
15881   countreg = ix86_zero_extend_to_Pmode (count);
15883   /* %%% Iff we are testing strict equality, we can use known alignment
15884      to good advantage.  This may be possible with combine, particularly
15885      once cc0 is dead.  */
15886   align = operands[4];
15888   if (CONST_INT_P (count))
15889     {
15890       if (INTVAL (count) == 0)
15891         {
15892           emit_move_insn (operands[0], const0_rtx);
15893           DONE;
15894         }
15895       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15896                                      operands[1], operands[2]));
15897     }
15898   else
15899     {
15900       rtx (*gen_cmp) (rtx, rtx);
15902       gen_cmp = (TARGET_64BIT
15903                  ? gen_cmpdi_1 : gen_cmpsi_1);
15905       emit_insn (gen_cmp (countreg, countreg));
15906       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15907                                   operands[1], operands[2]));
15908     }
15910   outlow = gen_lowpart (QImode, out);
15911   emit_insn (gen_cmpintqi (outlow));
15912   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15914   if (operands[0] != out)
15915     emit_move_insn (operands[0], out);
15917   DONE;
15920 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15922 (define_expand "cmpintqi"
15923   [(set (match_dup 1)
15924         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15925    (set (match_dup 2)
15926         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15927    (parallel [(set (match_operand:QI 0 "register_operand")
15928                    (minus:QI (match_dup 1)
15929                              (match_dup 2)))
15930               (clobber (reg:CC FLAGS_REG))])]
15931   ""
15933   operands[1] = gen_reg_rtx (QImode);
15934   operands[2] = gen_reg_rtx (QImode);
15937 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15938 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15940 (define_expand "cmpstrnqi_nz_1"
15941   [(parallel [(set (reg:CC FLAGS_REG)
15942                    (compare:CC (match_operand 4 "memory_operand")
15943                                (match_operand 5 "memory_operand")))
15944               (use (match_operand 2 "register_operand"))
15945               (use (match_operand:SI 3 "immediate_operand"))
15946               (clobber (match_operand 0 "register_operand"))
15947               (clobber (match_operand 1 "register_operand"))
15948               (clobber (match_dup 2))])]
15949   ""
15950   "ix86_current_function_needs_cld = 1;")
15952 (define_insn "*cmpstrnqi_nz_1"
15953   [(set (reg:CC FLAGS_REG)
15954         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15955                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15956    (use (match_operand:P 6 "register_operand" "2"))
15957    (use (match_operand:SI 3 "immediate_operand" "i"))
15958    (clobber (match_operand:P 0 "register_operand" "=S"))
15959    (clobber (match_operand:P 1 "register_operand" "=D"))
15960    (clobber (match_operand:P 2 "register_operand" "=c"))]
15961   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15962   "%^repz{%;} cmpsb"
15963   [(set_attr "type" "str")
15964    (set_attr "mode" "QI")
15965    (set (attr "prefix_rex")
15966         (if_then_else
15967           (match_test "<P:MODE>mode == DImode")
15968           (const_string "0")
15969           (const_string "*")))
15970    (set_attr "prefix_rep" "1")])
15972 ;; The same, but the count is not known to not be zero.
15974 (define_expand "cmpstrnqi_1"
15975   [(parallel [(set (reg:CC FLAGS_REG)
15976                 (if_then_else:CC (ne (match_operand 2 "register_operand")
15977                                      (const_int 0))
15978                   (compare:CC (match_operand 4 "memory_operand")
15979                               (match_operand 5 "memory_operand"))
15980                   (const_int 0)))
15981               (use (match_operand:SI 3 "immediate_operand"))
15982               (use (reg:CC FLAGS_REG))
15983               (clobber (match_operand 0 "register_operand"))
15984               (clobber (match_operand 1 "register_operand"))
15985               (clobber (match_dup 2))])]
15986   ""
15987   "ix86_current_function_needs_cld = 1;")
15989 (define_insn "*cmpstrnqi_1"
15990   [(set (reg:CC FLAGS_REG)
15991         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15992                              (const_int 0))
15993           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15994                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
15995           (const_int 0)))
15996    (use (match_operand:SI 3 "immediate_operand" "i"))
15997    (use (reg:CC FLAGS_REG))
15998    (clobber (match_operand:P 0 "register_operand" "=S"))
15999    (clobber (match_operand:P 1 "register_operand" "=D"))
16000    (clobber (match_operand:P 2 "register_operand" "=c"))]
16001   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16002   "%^repz{%;} cmpsb"
16003   [(set_attr "type" "str")
16004    (set_attr "mode" "QI")
16005    (set (attr "prefix_rex")
16006         (if_then_else
16007           (match_test "<P:MODE>mode == DImode")
16008           (const_string "0")
16009           (const_string "*")))
16010    (set_attr "prefix_rep" "1")])
16012 (define_expand "strlen<mode>"
16013   [(set (match_operand:P 0 "register_operand")
16014         (unspec:P [(match_operand:BLK 1 "general_operand")
16015                    (match_operand:QI 2 "immediate_operand")
16016                    (match_operand 3 "immediate_operand")]
16017                   UNSPEC_SCAS))]
16018   ""
16020  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16021    DONE;
16022  else
16023    FAIL;
16026 (define_expand "strlenqi_1"
16027   [(parallel [(set (match_operand 0 "register_operand")
16028                    (match_operand 2))
16029               (clobber (match_operand 1 "register_operand"))
16030               (clobber (reg:CC FLAGS_REG))])]
16031   ""
16032   "ix86_current_function_needs_cld = 1;")
16034 (define_insn "*strlenqi_1"
16035   [(set (match_operand:P 0 "register_operand" "=&c")
16036         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16037                    (match_operand:QI 2 "register_operand" "a")
16038                    (match_operand:P 3 "immediate_operand" "i")
16039                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16040    (clobber (match_operand:P 1 "register_operand" "=D"))
16041    (clobber (reg:CC FLAGS_REG))]
16042   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16043   "%^repnz{%;} scasb"
16044   [(set_attr "type" "str")
16045    (set_attr "mode" "QI")
16046    (set (attr "prefix_rex")
16047         (if_then_else
16048           (match_test "<P:MODE>mode == DImode")
16049           (const_string "0")
16050           (const_string "*")))
16051    (set_attr "prefix_rep" "1")])
16053 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16054 ;; handled in combine, but it is not currently up to the task.
16055 ;; When used for their truth value, the cmpstrn* expanders generate
16056 ;; code like this:
16058 ;;   repz cmpsb
16059 ;;   seta       %al
16060 ;;   setb       %dl
16061 ;;   cmpb       %al, %dl
16062 ;;   jcc        label
16064 ;; The intermediate three instructions are unnecessary.
16066 ;; This one handles cmpstrn*_nz_1...
16067 (define_peephole2
16068   [(parallel[
16069      (set (reg:CC FLAGS_REG)
16070           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16071                       (mem:BLK (match_operand 5 "register_operand"))))
16072      (use (match_operand 6 "register_operand"))
16073      (use (match_operand:SI 3 "immediate_operand"))
16074      (clobber (match_operand 0 "register_operand"))
16075      (clobber (match_operand 1 "register_operand"))
16076      (clobber (match_operand 2 "register_operand"))])
16077    (set (match_operand:QI 7 "register_operand")
16078         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16079    (set (match_operand:QI 8 "register_operand")
16080         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16081    (set (reg FLAGS_REG)
16082         (compare (match_dup 7) (match_dup 8)))
16083   ]
16084   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16085   [(parallel[
16086      (set (reg:CC FLAGS_REG)
16087           (compare:CC (mem:BLK (match_dup 4))
16088                       (mem:BLK (match_dup 5))))
16089      (use (match_dup 6))
16090      (use (match_dup 3))
16091      (clobber (match_dup 0))
16092      (clobber (match_dup 1))
16093      (clobber (match_dup 2))])])
16095 ;; ...and this one handles cmpstrn*_1.
16096 (define_peephole2
16097   [(parallel[
16098      (set (reg:CC FLAGS_REG)
16099           (if_then_else:CC (ne (match_operand 6 "register_operand")
16100                                (const_int 0))
16101             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16102                         (mem:BLK (match_operand 5 "register_operand")))
16103             (const_int 0)))
16104      (use (match_operand:SI 3 "immediate_operand"))
16105      (use (reg:CC FLAGS_REG))
16106      (clobber (match_operand 0 "register_operand"))
16107      (clobber (match_operand 1 "register_operand"))
16108      (clobber (match_operand 2 "register_operand"))])
16109    (set (match_operand:QI 7 "register_operand")
16110         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16111    (set (match_operand:QI 8 "register_operand")
16112         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16113    (set (reg FLAGS_REG)
16114         (compare (match_dup 7) (match_dup 8)))
16115   ]
16116   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16117   [(parallel[
16118      (set (reg:CC FLAGS_REG)
16119           (if_then_else:CC (ne (match_dup 6)
16120                                (const_int 0))
16121             (compare:CC (mem:BLK (match_dup 4))
16122                         (mem:BLK (match_dup 5)))
16123             (const_int 0)))
16124      (use (match_dup 3))
16125      (use (reg:CC FLAGS_REG))
16126      (clobber (match_dup 0))
16127      (clobber (match_dup 1))
16128      (clobber (match_dup 2))])])
16130 ;; Conditional move instructions.
16132 (define_expand "mov<mode>cc"
16133   [(set (match_operand:SWIM 0 "register_operand")
16134         (if_then_else:SWIM (match_operand 1 "comparison_operator")
16135                            (match_operand:SWIM 2 "<general_operand>")
16136                            (match_operand:SWIM 3 "<general_operand>")))]
16137   ""
16138   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16140 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16141 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16142 ;; So just document what we're doing explicitly.
16144 (define_expand "x86_mov<mode>cc_0_m1"
16145   [(parallel
16146     [(set (match_operand:SWI48 0 "register_operand")
16147           (if_then_else:SWI48
16148             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16149              [(match_operand 1 "flags_reg_operand")
16150               (const_int 0)])
16151             (const_int -1)
16152             (const_int 0)))
16153      (clobber (reg:CC FLAGS_REG))])])
16155 (define_insn "*x86_mov<mode>cc_0_m1"
16156   [(set (match_operand:SWI48 0 "register_operand" "=r")
16157         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16158                              [(reg FLAGS_REG) (const_int 0)])
16159           (const_int -1)
16160           (const_int 0)))
16161    (clobber (reg:CC FLAGS_REG))]
16162   ""
16163   "sbb{<imodesuffix>}\t%0, %0"
16164   ; Since we don't have the proper number of operands for an alu insn,
16165   ; fill in all the blanks.
16166   [(set_attr "type" "alu")
16167    (set_attr "use_carry" "1")
16168    (set_attr "pent_pair" "pu")
16169    (set_attr "memory" "none")
16170    (set_attr "imm_disp" "false")
16171    (set_attr "mode" "<MODE>")
16172    (set_attr "length_immediate" "0")])
16174 (define_insn "*x86_mov<mode>cc_0_m1_se"
16175   [(set (match_operand:SWI48 0 "register_operand" "=r")
16176         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16177                              [(reg FLAGS_REG) (const_int 0)])
16178                             (const_int 1)
16179                             (const_int 0)))
16180    (clobber (reg:CC FLAGS_REG))]
16181   ""
16182   "sbb{<imodesuffix>}\t%0, %0"
16183   [(set_attr "type" "alu")
16184    (set_attr "use_carry" "1")
16185    (set_attr "pent_pair" "pu")
16186    (set_attr "memory" "none")
16187    (set_attr "imm_disp" "false")
16188    (set_attr "mode" "<MODE>")
16189    (set_attr "length_immediate" "0")])
16191 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16192   [(set (match_operand:SWI48 0 "register_operand" "=r")
16193         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16194                     [(reg FLAGS_REG) (const_int 0)])))
16195    (clobber (reg:CC FLAGS_REG))]
16196   ""
16197   "sbb{<imodesuffix>}\t%0, %0"
16198   [(set_attr "type" "alu")
16199    (set_attr "use_carry" "1")
16200    (set_attr "pent_pair" "pu")
16201    (set_attr "memory" "none")
16202    (set_attr "imm_disp" "false")
16203    (set_attr "mode" "<MODE>")
16204    (set_attr "length_immediate" "0")])
16206 (define_insn "*mov<mode>cc_noc"
16207   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16208         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16209                                [(reg FLAGS_REG) (const_int 0)])
16210           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16211           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16212   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16213   "@
16214    cmov%O2%C1\t{%2, %0|%0, %2}
16215    cmov%O2%c1\t{%3, %0|%0, %3}"
16216   [(set_attr "type" "icmov")
16217    (set_attr "mode" "<MODE>")])
16219 ;; Don't do conditional moves with memory inputs.  This splitter helps
16220 ;; register starved x86_32 by forcing inputs into registers before reload.
16221 (define_split
16222   [(set (match_operand:SWI248 0 "register_operand")
16223         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16224                                [(reg FLAGS_REG) (const_int 0)])
16225           (match_operand:SWI248 2 "nonimmediate_operand")
16226           (match_operand:SWI248 3 "nonimmediate_operand")))]
16227   "!TARGET_64BIT && TARGET_CMOVE
16228    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16229    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16230    && can_create_pseudo_p ()
16231    && optimize_insn_for_speed_p ()"
16232   [(set (match_dup 0)
16233         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16235   if (MEM_P (operands[2]))
16236     operands[2] = force_reg (<MODE>mode, operands[2]);
16237   if (MEM_P (operands[3]))
16238     operands[3] = force_reg (<MODE>mode, operands[3]);
16241 (define_insn "*movqicc_noc"
16242   [(set (match_operand:QI 0 "register_operand" "=r,r")
16243         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16244                            [(reg FLAGS_REG) (const_int 0)])
16245                       (match_operand:QI 2 "register_operand" "r,0")
16246                       (match_operand:QI 3 "register_operand" "0,r")))]
16247   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16248   "#"
16249   [(set_attr "type" "icmov")
16250    (set_attr "mode" "QI")])
16252 (define_split
16253   [(set (match_operand:SWI12 0 "register_operand")
16254         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16255                               [(reg FLAGS_REG) (const_int 0)])
16256                       (match_operand:SWI12 2 "register_operand")
16257                       (match_operand:SWI12 3 "register_operand")))]
16258   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16259    && reload_completed"
16260   [(set (match_dup 0)
16261         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16263   operands[0] = gen_lowpart (SImode, operands[0]);
16264   operands[2] = gen_lowpart (SImode, operands[2]);
16265   operands[3] = gen_lowpart (SImode, operands[3]);
16268 ;; Don't do conditional moves with memory inputs
16269 (define_peephole2
16270   [(match_scratch:SWI248 2 "r")
16271    (set (match_operand:SWI248 0 "register_operand")
16272         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16273                                [(reg FLAGS_REG) (const_int 0)])
16274           (match_dup 0)
16275           (match_operand:SWI248 3 "memory_operand")))]
16276   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16277    && optimize_insn_for_speed_p ()"
16278   [(set (match_dup 2) (match_dup 3))
16279    (set (match_dup 0)
16280         (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16282 (define_peephole2
16283   [(match_scratch:SWI248 2 "r")
16284    (set (match_operand:SWI248 0 "register_operand")
16285         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16286                                [(reg FLAGS_REG) (const_int 0)])
16287           (match_operand:SWI248 3 "memory_operand")
16288           (match_dup 0)))]
16289   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16290    && optimize_insn_for_speed_p ()"
16291   [(set (match_dup 2) (match_dup 3))
16292    (set (match_dup 0)
16293         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16295 (define_expand "mov<mode>cc"
16296   [(set (match_operand:X87MODEF 0 "register_operand")
16297         (if_then_else:X87MODEF
16298           (match_operand 1 "comparison_operator")
16299           (match_operand:X87MODEF 2 "register_operand")
16300           (match_operand:X87MODEF 3 "register_operand")))]
16301   "(TARGET_80387 && TARGET_CMOVE)
16302    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16303   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16305 (define_insn "*movxfcc_1"
16306   [(set (match_operand:XF 0 "register_operand" "=f,f")
16307         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16308                                 [(reg FLAGS_REG) (const_int 0)])
16309                       (match_operand:XF 2 "register_operand" "f,0")
16310                       (match_operand:XF 3 "register_operand" "0,f")))]
16311   "TARGET_80387 && TARGET_CMOVE"
16312   "@
16313    fcmov%F1\t{%2, %0|%0, %2}
16314    fcmov%f1\t{%3, %0|%0, %3}"
16315   [(set_attr "type" "fcmov")
16316    (set_attr "mode" "XF")])
16318 (define_insn "*movdfcc_1"
16319   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16320         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16321                                 [(reg FLAGS_REG) (const_int 0)])
16322                       (match_operand:DF 2 "nonimmediate_operand"
16323                                                "f ,0,rm,0 ,rm,0")
16324                       (match_operand:DF 3 "nonimmediate_operand"
16325                                                "0 ,f,0 ,rm,0, rm")))]
16326   "TARGET_80387 && TARGET_CMOVE
16327    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16328   "@
16329    fcmov%F1\t{%2, %0|%0, %2}
16330    fcmov%f1\t{%3, %0|%0, %3}
16331    #
16332    #
16333    cmov%O2%C1\t{%2, %0|%0, %2}
16334    cmov%O2%c1\t{%3, %0|%0, %3}"
16335   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16336    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16337    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16339 (define_split
16340   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16341         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16342                                 [(reg FLAGS_REG) (const_int 0)])
16343                       (match_operand:DF 2 "nonimmediate_operand")
16344                       (match_operand:DF 3 "nonimmediate_operand")))]
16345   "!TARGET_64BIT && reload_completed"
16346   [(set (match_dup 2)
16347         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16348    (set (match_dup 3)
16349         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16351   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16352   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16355 (define_insn "*movsfcc_1_387"
16356   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16357         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16358                                 [(reg FLAGS_REG) (const_int 0)])
16359                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16360                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16361   "TARGET_80387 && TARGET_CMOVE
16362    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16363   "@
16364    fcmov%F1\t{%2, %0|%0, %2}
16365    fcmov%f1\t{%3, %0|%0, %3}
16366    cmov%O2%C1\t{%2, %0|%0, %2}
16367    cmov%O2%c1\t{%3, %0|%0, %3}"
16368   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16369    (set_attr "mode" "SF,SF,SI,SI")])
16371 ;; Don't do conditional moves with memory inputs.  This splitter helps
16372 ;; register starved x86_32 by forcing inputs into registers before reload.
16373 (define_split
16374   [(set (match_operand:MODEF 0 "register_operand")
16375         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16376                               [(reg FLAGS_REG) (const_int 0)])
16377           (match_operand:MODEF 2 "nonimmediate_operand")
16378           (match_operand:MODEF 3 "nonimmediate_operand")))]
16379   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16380    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16381    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16382    && can_create_pseudo_p ()
16383    && optimize_insn_for_speed_p ()"
16384   [(set (match_dup 0)
16385         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16387   if (MEM_P (operands[2]))
16388     operands[2] = force_reg (<MODE>mode, operands[2]);
16389   if (MEM_P (operands[3]))
16390     operands[3] = force_reg (<MODE>mode, operands[3]);
16393 ;; Don't do conditional moves with memory inputs
16394 (define_peephole2
16395   [(match_scratch:MODEF 2 "r")
16396    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16397         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16398                               [(reg FLAGS_REG) (const_int 0)])
16399           (match_dup 0)
16400           (match_operand:MODEF 3 "memory_operand")))]
16401   "(<MODE>mode != DFmode || TARGET_64BIT)
16402    && TARGET_80387 && TARGET_CMOVE
16403    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16404    && optimize_insn_for_speed_p ()"
16405   [(set (match_dup 2) (match_dup 3))
16406    (set (match_dup 0)
16407         (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16409 (define_peephole2
16410   [(match_scratch:MODEF 2 "r")
16411    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16412         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16413                               [(reg FLAGS_REG) (const_int 0)])
16414           (match_operand:MODEF 3 "memory_operand")
16415           (match_dup 0)))]
16416   "(<MODE>mode != DFmode || TARGET_64BIT)
16417    && TARGET_80387 && TARGET_CMOVE
16418    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16419    && optimize_insn_for_speed_p ()"
16420   [(set (match_dup 2) (match_dup 3))
16421    (set (match_dup 0)
16422         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16424 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16425 ;; the scalar versions to have only XMM registers as operands.
16427 ;; XOP conditional move
16428 (define_insn "*xop_pcmov_<mode>"
16429   [(set (match_operand:MODEF 0 "register_operand" "=x")
16430         (if_then_else:MODEF
16431           (match_operand:MODEF 1 "register_operand" "x")
16432           (match_operand:MODEF 2 "register_operand" "x")
16433           (match_operand:MODEF 3 "register_operand" "x")))]
16434   "TARGET_XOP"
16435   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16436   [(set_attr "type" "sse4arg")])
16438 ;; These versions of the min/max patterns are intentionally ignorant of
16439 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16440 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16441 ;; are undefined in this condition, we're certain this is correct.
16443 (define_insn "<code><mode>3"
16444   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16445         (smaxmin:MODEF
16446           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16447           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16448   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16449   "@
16450    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16451    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16452   [(set_attr "isa" "noavx,avx")
16453    (set_attr "prefix" "orig,vex")
16454    (set_attr "type" "sseadd")
16455    (set_attr "mode" "<MODE>")])
16457 ;; These versions of the min/max patterns implement exactly the operations
16458 ;;   min = (op1 < op2 ? op1 : op2)
16459 ;;   max = (!(op1 < op2) ? op1 : op2)
16460 ;; Their operands are not commutative, and thus they may be used in the
16461 ;; presence of -0.0 and NaN.
16463 (define_int_iterator IEEE_MAXMIN
16464         [UNSPEC_IEEE_MAX
16465          UNSPEC_IEEE_MIN])
16467 (define_int_attr ieee_maxmin
16468         [(UNSPEC_IEEE_MAX "max")
16469          (UNSPEC_IEEE_MIN "min")])
16471 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16472   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16473         (unspec:MODEF
16474           [(match_operand:MODEF 1 "register_operand" "0,x")
16475            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16476           IEEE_MAXMIN))]
16477   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16478   "@
16479    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16480    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16481   [(set_attr "isa" "noavx,avx")
16482    (set_attr "prefix" "orig,vex")
16483    (set_attr "type" "sseadd")
16484    (set_attr "mode" "<MODE>")])
16486 ;; Make two stack loads independent:
16487 ;;   fld aa              fld aa
16488 ;;   fld %st(0)     ->   fld bb
16489 ;;   fmul bb             fmul %st(1), %st
16491 ;; Actually we only match the last two instructions for simplicity.
16492 (define_peephole2
16493   [(set (match_operand 0 "fp_register_operand")
16494         (match_operand 1 "fp_register_operand"))
16495    (set (match_dup 0)
16496         (match_operator 2 "binary_fp_operator"
16497            [(match_dup 0)
16498             (match_operand 3 "memory_operand")]))]
16499   "REGNO (operands[0]) != REGNO (operands[1])"
16500   [(set (match_dup 0) (match_dup 3))
16501    (set (match_dup 0) (match_dup 4))]
16503   ;; The % modifier is not operational anymore in peephole2's, so we have to
16504   ;; swap the operands manually in the case of addition and multiplication.
16506   rtx op0, op1;
16508   if (COMMUTATIVE_ARITH_P (operands[2]))
16509     op0 = operands[0], op1 = operands[1];
16510   else
16511     op0 = operands[1], op1 = operands[0];
16513   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16514                                 GET_MODE (operands[2]),
16515                                 op0, op1);
16518 ;; Conditional addition patterns
16519 (define_expand "add<mode>cc"
16520   [(match_operand:SWI 0 "register_operand")
16521    (match_operand 1 "ordered_comparison_operator")
16522    (match_operand:SWI 2 "register_operand")
16523    (match_operand:SWI 3 "const_int_operand")]
16524   ""
16525   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16527 ;; Misc patterns (?)
16529 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16530 ;; Otherwise there will be nothing to keep
16532 ;; [(set (reg ebp) (reg esp))]
16533 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16534 ;;  (clobber (eflags)]
16535 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16537 ;; in proper program order.
16539 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16540   [(set (match_operand:P 0 "register_operand" "=r,r")
16541         (plus:P (match_operand:P 1 "register_operand" "0,r")
16542                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16543    (clobber (reg:CC FLAGS_REG))
16544    (clobber (mem:BLK (scratch)))]
16545   ""
16547   switch (get_attr_type (insn))
16548     {
16549     case TYPE_IMOV:
16550       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16552     case TYPE_ALU:
16553       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16554       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16555         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16557       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16559     default:
16560       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16561       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16562     }
16564   [(set (attr "type")
16565         (cond [(and (eq_attr "alternative" "0")
16566                     (not (match_test "TARGET_OPT_AGU")))
16567                  (const_string "alu")
16568                (match_operand:<MODE> 2 "const0_operand")
16569                  (const_string "imov")
16570               ]
16571               (const_string "lea")))
16572    (set (attr "length_immediate")
16573         (cond [(eq_attr "type" "imov")
16574                  (const_string "0")
16575                (and (eq_attr "type" "alu")
16576                     (match_operand 2 "const128_operand"))
16577                  (const_string "1")
16578               ]
16579               (const_string "*")))
16580    (set_attr "mode" "<MODE>")])
16582 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16583   [(set (match_operand:P 0 "register_operand" "=r")
16584         (minus:P (match_operand:P 1 "register_operand" "0")
16585                  (match_operand:P 2 "register_operand" "r")))
16586    (clobber (reg:CC FLAGS_REG))
16587    (clobber (mem:BLK (scratch)))]
16588   ""
16589   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16590   [(set_attr "type" "alu")
16591    (set_attr "mode" "<MODE>")])
16593 (define_insn "allocate_stack_worker_probe_<mode>"
16594   [(set (match_operand:P 0 "register_operand" "=a")
16595         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16596                             UNSPECV_STACK_PROBE))
16597    (clobber (reg:CC FLAGS_REG))]
16598   "ix86_target_stack_probe ()"
16599   "call\t___chkstk_ms"
16600   [(set_attr "type" "multi")
16601    (set_attr "length" "5")])
16603 (define_expand "allocate_stack"
16604   [(match_operand 0 "register_operand")
16605    (match_operand 1 "general_operand")]
16606   "ix86_target_stack_probe ()"
16608   rtx x;
16610 #ifndef CHECK_STACK_LIMIT
16611 #define CHECK_STACK_LIMIT 0
16612 #endif
16614   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16615       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16616     x = operands[1];
16617   else
16618     {
16619       rtx (*insn) (rtx, rtx);
16621       x = copy_to_mode_reg (Pmode, operands[1]);
16623       insn = (TARGET_64BIT
16624               ? gen_allocate_stack_worker_probe_di
16625               : gen_allocate_stack_worker_probe_si);
16627       emit_insn (insn (x, x));
16628     }
16630   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16631                            stack_pointer_rtx, 0, OPTAB_DIRECT);
16633   if (x != stack_pointer_rtx)
16634     emit_move_insn (stack_pointer_rtx, x);
16636   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16637   DONE;
16640 ;; Use IOR for stack probes, this is shorter.
16641 (define_expand "probe_stack"
16642   [(match_operand 0 "memory_operand")]
16643   ""
16645   rtx (*gen_ior3) (rtx, rtx, rtx);
16647   gen_ior3 = (GET_MODE (operands[0]) == DImode
16648               ? gen_iordi3 : gen_iorsi3);
16650   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16651   DONE;
16654 (define_insn "adjust_stack_and_probe<mode>"
16655   [(set (match_operand:P 0 "register_operand" "=r")
16656         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16657                             UNSPECV_PROBE_STACK_RANGE))
16658    (set (reg:P SP_REG)
16659         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16660    (clobber (reg:CC FLAGS_REG))
16661    (clobber (mem:BLK (scratch)))]
16662   ""
16663   "* return output_adjust_stack_and_probe (operands[0]);"
16664   [(set_attr "type" "multi")])
16666 (define_insn "probe_stack_range<mode>"
16667   [(set (match_operand:P 0 "register_operand" "=r")
16668         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16669                             (match_operand:P 2 "const_int_operand" "n")]
16670                             UNSPECV_PROBE_STACK_RANGE))
16671    (clobber (reg:CC FLAGS_REG))]
16672   ""
16673   "* return output_probe_stack_range (operands[0], operands[2]);"
16674   [(set_attr "type" "multi")])
16676 (define_expand "builtin_setjmp_receiver"
16677   [(label_ref (match_operand 0))]
16678   "!TARGET_64BIT && flag_pic"
16680 #if TARGET_MACHO
16681   if (TARGET_MACHO)
16682     {
16683       rtx xops[3];
16684       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16685       rtx label_rtx = gen_label_rtx ();
16686       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16687       xops[0] = xops[1] = picreg;
16688       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16689       ix86_expand_binary_operator (MINUS, SImode, xops);
16690     }
16691   else
16692 #endif
16693     emit_insn (gen_set_got (pic_offset_table_rtx));
16694   DONE;
16697 (define_insn_and_split "nonlocal_goto_receiver"
16698   [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16699   "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16700   "#"
16701   "&& reload_completed"
16702   [(const_int 0)]
16704   if (crtl->uses_pic_offset_table)
16705     {
16706       rtx xops[3];
16707       rtx label_rtx = gen_label_rtx ();
16708       rtx tmp;
16710       /* Get a new pic base.  */
16711       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16712       /* Correct this with the offset from the new to the old.  */
16713       xops[0] = xops[1] = pic_offset_table_rtx;
16714       label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16715       tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16716                             UNSPEC_MACHOPIC_OFFSET);
16717       xops[2] = gen_rtx_CONST (Pmode, tmp);
16718       ix86_expand_binary_operator (MINUS, SImode, xops);
16719     }
16720   else
16721     /* No pic reg restore needed.  */
16722     emit_note (NOTE_INSN_DELETED);
16724   DONE;
16727 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16728 ;; Do not split instructions with mask registers.
16729 (define_split
16730   [(set (match_operand 0 "general_reg_operand")
16731         (match_operator 3 "promotable_binary_operator"
16732            [(match_operand 1 "general_reg_operand")
16733             (match_operand 2 "aligned_operand")]))
16734    (clobber (reg:CC FLAGS_REG))]
16735   "! TARGET_PARTIAL_REG_STALL && reload_completed
16736    && ((GET_MODE (operands[0]) == HImode
16737         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16738             /* ??? next two lines just !satisfies_constraint_K (...) */
16739             || !CONST_INT_P (operands[2])
16740             || satisfies_constraint_K (operands[2])))
16741        || (GET_MODE (operands[0]) == QImode
16742            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16743   [(parallel [(set (match_dup 0)
16744                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16745               (clobber (reg:CC FLAGS_REG))])]
16747   operands[0] = gen_lowpart (SImode, operands[0]);
16748   operands[1] = gen_lowpart (SImode, operands[1]);
16749   if (GET_CODE (operands[3]) != ASHIFT)
16750     operands[2] = gen_lowpart (SImode, operands[2]);
16751   PUT_MODE (operands[3], SImode);
16754 ; Promote the QImode tests, as i386 has encoding of the AND
16755 ; instruction with 32-bit sign-extended immediate and thus the
16756 ; instruction size is unchanged, except in the %eax case for
16757 ; which it is increased by one byte, hence the ! optimize_size.
16758 (define_split
16759   [(set (match_operand 0 "flags_reg_operand")
16760         (match_operator 2 "compare_operator"
16761           [(and (match_operand 3 "aligned_operand")
16762                 (match_operand 4 "const_int_operand"))
16763            (const_int 0)]))
16764    (set (match_operand 1 "register_operand")
16765         (and (match_dup 3) (match_dup 4)))]
16766   "! TARGET_PARTIAL_REG_STALL && reload_completed
16767    && optimize_insn_for_speed_p ()
16768    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16769        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16770    /* Ensure that the operand will remain sign-extended immediate.  */
16771    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16772   [(parallel [(set (match_dup 0)
16773                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16774                                     (const_int 0)]))
16775               (set (match_dup 1)
16776                    (and:SI (match_dup 3) (match_dup 4)))])]
16778   operands[4]
16779     = gen_int_mode (INTVAL (operands[4])
16780                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16781   operands[1] = gen_lowpart (SImode, operands[1]);
16782   operands[3] = gen_lowpart (SImode, operands[3]);
16785 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16786 ; the TEST instruction with 32-bit sign-extended immediate and thus
16787 ; the instruction size would at least double, which is not what we
16788 ; want even with ! optimize_size.
16789 (define_split
16790   [(set (match_operand 0 "flags_reg_operand")
16791         (match_operator 1 "compare_operator"
16792           [(and (match_operand:HI 2 "aligned_operand")
16793                 (match_operand:HI 3 "const_int_operand"))
16794            (const_int 0)]))]
16795   "! TARGET_PARTIAL_REG_STALL && reload_completed
16796    && ! TARGET_FAST_PREFIX
16797    && optimize_insn_for_speed_p ()
16798    /* Ensure that the operand will remain sign-extended immediate.  */
16799    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16800   [(set (match_dup 0)
16801         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16802                          (const_int 0)]))]
16804   operands[3]
16805     = gen_int_mode (INTVAL (operands[3])
16806                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16807   operands[2] = gen_lowpart (SImode, operands[2]);
16810 (define_split
16811   [(set (match_operand 0 "register_operand")
16812         (neg (match_operand 1 "register_operand")))
16813    (clobber (reg:CC FLAGS_REG))]
16814   "! TARGET_PARTIAL_REG_STALL && reload_completed
16815    && (GET_MODE (operands[0]) == HImode
16816        || (GET_MODE (operands[0]) == QImode
16817            && (TARGET_PROMOTE_QImode
16818                || optimize_insn_for_size_p ())))"
16819   [(parallel [(set (match_dup 0)
16820                    (neg:SI (match_dup 1)))
16821               (clobber (reg:CC FLAGS_REG))])]
16823   operands[0] = gen_lowpart (SImode, operands[0]);
16824   operands[1] = gen_lowpart (SImode, operands[1]);
16827 ;; Do not split instructions with mask regs.
16828 (define_split
16829   [(set (match_operand 0 "general_reg_operand")
16830         (not (match_operand 1 "general_reg_operand")))]
16831   "! TARGET_PARTIAL_REG_STALL && reload_completed
16832    && (GET_MODE (operands[0]) == HImode
16833        || (GET_MODE (operands[0]) == QImode
16834            && (TARGET_PROMOTE_QImode
16835                || optimize_insn_for_size_p ())))"
16836   [(set (match_dup 0)
16837         (not:SI (match_dup 1)))]
16839   operands[0] = gen_lowpart (SImode, operands[0]);
16840   operands[1] = gen_lowpart (SImode, operands[1]);
16843 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16844 ;; transform a complex memory operation into two memory to register operations.
16846 ;; Don't push memory operands
16847 (define_peephole2
16848   [(set (match_operand:SWI 0 "push_operand")
16849         (match_operand:SWI 1 "memory_operand"))
16850    (match_scratch:SWI 2 "<r>")]
16851   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16852    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16853   [(set (match_dup 2) (match_dup 1))
16854    (set (match_dup 0) (match_dup 2))])
16856 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16857 ;; SImode pushes.
16858 (define_peephole2
16859   [(set (match_operand:SF 0 "push_operand")
16860         (match_operand:SF 1 "memory_operand"))
16861    (match_scratch:SF 2 "r")]
16862   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16863    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16864   [(set (match_dup 2) (match_dup 1))
16865    (set (match_dup 0) (match_dup 2))])
16867 ;; Don't move an immediate directly to memory when the instruction
16868 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16869 (define_peephole2
16870   [(match_scratch:SWI124 1 "<r>")
16871    (set (match_operand:SWI124 0 "memory_operand")
16872         (const_int 0))]
16873   "optimize_insn_for_speed_p ()
16874    && ((<MODE>mode == HImode
16875        && TARGET_LCP_STALL)
16876        || (!TARGET_USE_MOV0
16877           && TARGET_SPLIT_LONG_MOVES
16878           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16879    && peep2_regno_dead_p (0, FLAGS_REG)"
16880   [(parallel [(set (match_dup 2) (const_int 0))
16881               (clobber (reg:CC FLAGS_REG))])
16882    (set (match_dup 0) (match_dup 1))]
16883   "operands[2] = gen_lowpart (SImode, operands[1]);")
16885 (define_peephole2
16886   [(match_scratch:SWI124 2 "<r>")
16887    (set (match_operand:SWI124 0 "memory_operand")
16888         (match_operand:SWI124 1 "immediate_operand"))]
16889   "optimize_insn_for_speed_p ()
16890    && ((<MODE>mode == HImode
16891        && TARGET_LCP_STALL)
16892        || (TARGET_SPLIT_LONG_MOVES
16893           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16894   [(set (match_dup 2) (match_dup 1))
16895    (set (match_dup 0) (match_dup 2))])
16897 ;; Don't compare memory with zero, load and use a test instead.
16898 (define_peephole2
16899   [(set (match_operand 0 "flags_reg_operand")
16900         (match_operator 1 "compare_operator"
16901           [(match_operand:SI 2 "memory_operand")
16902            (const_int 0)]))
16903    (match_scratch:SI 3 "r")]
16904   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16905   [(set (match_dup 3) (match_dup 2))
16906    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16908 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16909 ;; Don't split NOTs with a displacement operand, because resulting XOR
16910 ;; will not be pairable anyway.
16912 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16913 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16914 ;; so this split helps here as well.
16916 ;; Note: Can't do this as a regular split because we can't get proper
16917 ;; lifetime information then.
16919 (define_peephole2
16920   [(set (match_operand:SWI124 0 "nonimmediate_operand")
16921         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
16922   "optimize_insn_for_speed_p ()
16923    && ((TARGET_NOT_UNPAIRABLE
16924         && (!MEM_P (operands[0])
16925             || !memory_displacement_operand (operands[0], <MODE>mode)))
16926        || (TARGET_NOT_VECTORMODE
16927            && long_memory_operand (operands[0], <MODE>mode)))
16928    && peep2_regno_dead_p (0, FLAGS_REG)"
16929   [(parallel [(set (match_dup 0)
16930                    (xor:SWI124 (match_dup 1) (const_int -1)))
16931               (clobber (reg:CC FLAGS_REG))])])
16933 ;; Non pairable "test imm, reg" instructions can be translated to
16934 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16935 ;; byte opcode instead of two, have a short form for byte operands),
16936 ;; so do it for other CPUs as well.  Given that the value was dead,
16937 ;; this should not create any new dependencies.  Pass on the sub-word
16938 ;; versions if we're concerned about partial register stalls.
16940 (define_peephole2
16941   [(set (match_operand 0 "flags_reg_operand")
16942         (match_operator 1 "compare_operator"
16943           [(and:SI (match_operand:SI 2 "register_operand")
16944                    (match_operand:SI 3 "immediate_operand"))
16945            (const_int 0)]))]
16946   "ix86_match_ccmode (insn, CCNOmode)
16947    && (true_regnum (operands[2]) != AX_REG
16948        || satisfies_constraint_K (operands[3]))
16949    && peep2_reg_dead_p (1, operands[2])"
16950   [(parallel
16951      [(set (match_dup 0)
16952            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16953                             (const_int 0)]))
16954       (set (match_dup 2)
16955            (and:SI (match_dup 2) (match_dup 3)))])])
16957 ;; We don't need to handle HImode case, because it will be promoted to SImode
16958 ;; on ! TARGET_PARTIAL_REG_STALL
16960 (define_peephole2
16961   [(set (match_operand 0 "flags_reg_operand")
16962         (match_operator 1 "compare_operator"
16963           [(and:QI (match_operand:QI 2 "register_operand")
16964                    (match_operand:QI 3 "immediate_operand"))
16965            (const_int 0)]))]
16966   "! TARGET_PARTIAL_REG_STALL
16967    && ix86_match_ccmode (insn, CCNOmode)
16968    && true_regnum (operands[2]) != AX_REG
16969    && peep2_reg_dead_p (1, operands[2])"
16970   [(parallel
16971      [(set (match_dup 0)
16972            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16973                             (const_int 0)]))
16974       (set (match_dup 2)
16975            (and:QI (match_dup 2) (match_dup 3)))])])
16977 (define_peephole2
16978   [(set (match_operand 0 "flags_reg_operand")
16979         (match_operator 1 "compare_operator"
16980           [(and:SI
16981              (zero_extract:SI
16982                (match_operand 2 "ext_register_operand")
16983                (const_int 8)
16984                (const_int 8))
16985              (match_operand 3 "const_int_operand"))
16986            (const_int 0)]))]
16987   "! TARGET_PARTIAL_REG_STALL
16988    && ix86_match_ccmode (insn, CCNOmode)
16989    && true_regnum (operands[2]) != AX_REG
16990    && peep2_reg_dead_p (1, operands[2])"
16991   [(parallel [(set (match_dup 0)
16992                    (match_op_dup 1
16993                      [(and:SI
16994                         (zero_extract:SI
16995                           (match_dup 2)
16996                           (const_int 8)
16997                           (const_int 8))
16998                         (match_dup 3))
16999                       (const_int 0)]))
17000               (set (zero_extract:SI (match_dup 2)
17001                                     (const_int 8)
17002                                     (const_int 8))
17003                    (and:SI
17004                      (zero_extract:SI
17005                        (match_dup 2)
17006                        (const_int 8)
17007                        (const_int 8))
17008                      (match_dup 3)))])])
17010 ;; Don't do logical operations with memory inputs.
17011 (define_peephole2
17012   [(match_scratch:SI 2 "r")
17013    (parallel [(set (match_operand:SI 0 "register_operand")
17014                    (match_operator:SI 3 "arith_or_logical_operator"
17015                      [(match_dup 0)
17016                       (match_operand:SI 1 "memory_operand")]))
17017               (clobber (reg:CC FLAGS_REG))])]
17018   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17019   [(set (match_dup 2) (match_dup 1))
17020    (parallel [(set (match_dup 0)
17021                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17022               (clobber (reg:CC FLAGS_REG))])])
17024 (define_peephole2
17025   [(match_scratch:SI 2 "r")
17026    (parallel [(set (match_operand:SI 0 "register_operand")
17027                    (match_operator:SI 3 "arith_or_logical_operator"
17028                      [(match_operand:SI 1 "memory_operand")
17029                       (match_dup 0)]))
17030               (clobber (reg:CC FLAGS_REG))])]
17031   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17032   [(set (match_dup 2) (match_dup 1))
17033    (parallel [(set (match_dup 0)
17034                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17035               (clobber (reg:CC FLAGS_REG))])])
17037 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17038 ;; refers to the destination of the load!
17040 (define_peephole2
17041   [(set (match_operand:SI 0 "register_operand")
17042         (match_operand:SI 1 "register_operand"))
17043    (parallel [(set (match_dup 0)
17044                    (match_operator:SI 3 "commutative_operator"
17045                      [(match_dup 0)
17046                       (match_operand:SI 2 "memory_operand")]))
17047               (clobber (reg:CC FLAGS_REG))])]
17048   "REGNO (operands[0]) != REGNO (operands[1])
17049    && GENERAL_REGNO_P (REGNO (operands[0]))
17050    && GENERAL_REGNO_P (REGNO (operands[1]))"
17051   [(set (match_dup 0) (match_dup 4))
17052    (parallel [(set (match_dup 0)
17053                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17054               (clobber (reg:CC FLAGS_REG))])]
17055   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17057 (define_peephole2
17058   [(set (match_operand 0 "register_operand")
17059         (match_operand 1 "register_operand"))
17060    (set (match_dup 0)
17061                    (match_operator 3 "commutative_operator"
17062                      [(match_dup 0)
17063                       (match_operand 2 "memory_operand")]))]
17064   "REGNO (operands[0]) != REGNO (operands[1])
17065    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17066        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17067   [(set (match_dup 0) (match_dup 2))
17068    (set (match_dup 0)
17069         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17071 ; Don't do logical operations with memory outputs
17073 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17074 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17075 ; the same decoder scheduling characteristics as the original.
17077 (define_peephole2
17078   [(match_scratch:SI 2 "r")
17079    (parallel [(set (match_operand:SI 0 "memory_operand")
17080                    (match_operator:SI 3 "arith_or_logical_operator"
17081                      [(match_dup 0)
17082                       (match_operand:SI 1 "nonmemory_operand")]))
17083               (clobber (reg:CC FLAGS_REG))])]
17084   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17085    /* Do not split stack checking probes.  */
17086    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17087   [(set (match_dup 2) (match_dup 0))
17088    (parallel [(set (match_dup 2)
17089                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17090               (clobber (reg:CC FLAGS_REG))])
17091    (set (match_dup 0) (match_dup 2))])
17093 (define_peephole2
17094   [(match_scratch:SI 2 "r")
17095    (parallel [(set (match_operand:SI 0 "memory_operand")
17096                    (match_operator:SI 3 "arith_or_logical_operator"
17097                      [(match_operand:SI 1 "nonmemory_operand")
17098                       (match_dup 0)]))
17099               (clobber (reg:CC FLAGS_REG))])]
17100   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17101    /* Do not split stack checking probes.  */
17102    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17103   [(set (match_dup 2) (match_dup 0))
17104    (parallel [(set (match_dup 2)
17105                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17106               (clobber (reg:CC FLAGS_REG))])
17107    (set (match_dup 0) (match_dup 2))])
17109 ;; Attempt to use arith or logical operations with memory outputs with
17110 ;; setting of flags.
17111 (define_peephole2
17112   [(set (match_operand:SWI 0 "register_operand")
17113         (match_operand:SWI 1 "memory_operand"))
17114    (parallel [(set (match_dup 0)
17115                    (match_operator:SWI 3 "plusminuslogic_operator"
17116                      [(match_dup 0)
17117                       (match_operand:SWI 2 "<nonmemory_operand>")]))
17118               (clobber (reg:CC FLAGS_REG))])
17119    (set (match_dup 1) (match_dup 0))
17120    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17121   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17122    && peep2_reg_dead_p (4, operands[0])
17123    && !reg_overlap_mentioned_p (operands[0], operands[1])
17124    && !reg_overlap_mentioned_p (operands[0], operands[2])
17125    && (<MODE>mode != QImode
17126        || immediate_operand (operands[2], QImode)
17127        || q_regs_operand (operands[2], QImode))
17128    && ix86_match_ccmode (peep2_next_insn (3),
17129                          (GET_CODE (operands[3]) == PLUS
17130                           || GET_CODE (operands[3]) == MINUS)
17131                          ? CCGOCmode : CCNOmode)"
17132   [(parallel [(set (match_dup 4) (match_dup 5))
17133               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17134                                                   (match_dup 2)]))])]
17136   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17137   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17138                                 copy_rtx (operands[1]),
17139                                 copy_rtx (operands[2]));
17140   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17141                                  operands[5], const0_rtx);
17144 (define_peephole2
17145   [(parallel [(set (match_operand:SWI 0 "register_operand")
17146                    (match_operator:SWI 2 "plusminuslogic_operator"
17147                      [(match_dup 0)
17148                       (match_operand:SWI 1 "memory_operand")]))
17149               (clobber (reg:CC FLAGS_REG))])
17150    (set (match_dup 1) (match_dup 0))
17151    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17152   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17153    && GET_CODE (operands[2]) != MINUS
17154    && peep2_reg_dead_p (3, operands[0])
17155    && !reg_overlap_mentioned_p (operands[0], operands[1])
17156    && ix86_match_ccmode (peep2_next_insn (2),
17157                          GET_CODE (operands[2]) == PLUS
17158                          ? CCGOCmode : CCNOmode)"
17159   [(parallel [(set (match_dup 3) (match_dup 4))
17160               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17161                                                   (match_dup 0)]))])]
17163   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17164   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17165                                 copy_rtx (operands[1]),
17166                                 copy_rtx (operands[0]));
17167   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17168                                  operands[4], const0_rtx);
17171 (define_peephole2
17172   [(set (match_operand:SWI12 0 "register_operand")
17173         (match_operand:SWI12 1 "memory_operand"))
17174    (parallel [(set (match_operand:SI 4 "register_operand")
17175                    (match_operator:SI 3 "plusminuslogic_operator"
17176                      [(match_dup 4)
17177                       (match_operand:SI 2 "nonmemory_operand")]))
17178               (clobber (reg:CC FLAGS_REG))])
17179    (set (match_dup 1) (match_dup 0))
17180    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17181   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17182    && REG_P (operands[0]) && REG_P (operands[4])
17183    && REGNO (operands[0]) == REGNO (operands[4])
17184    && peep2_reg_dead_p (4, operands[0])
17185    && (<MODE>mode != QImode
17186        || immediate_operand (operands[2], SImode)
17187        || q_regs_operand (operands[2], SImode))
17188    && !reg_overlap_mentioned_p (operands[0], operands[1])
17189    && !reg_overlap_mentioned_p (operands[0], operands[2])
17190    && ix86_match_ccmode (peep2_next_insn (3),
17191                          (GET_CODE (operands[3]) == PLUS
17192                           || GET_CODE (operands[3]) == MINUS)
17193                          ? CCGOCmode : CCNOmode)"
17194   [(parallel [(set (match_dup 4) (match_dup 5))
17195               (set (match_dup 1) (match_dup 6))])]
17197   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17198   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17199   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17200                                 copy_rtx (operands[1]), operands[2]);
17201   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17202                                  operands[5], const0_rtx);
17203   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17204                                 copy_rtx (operands[1]),
17205                                 copy_rtx (operands[2]));
17208 ;; Attempt to always use XOR for zeroing registers.
17209 (define_peephole2
17210   [(set (match_operand 0 "register_operand")
17211         (match_operand 1 "const0_operand"))]
17212   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17213    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17214    && GENERAL_REG_P (operands[0])
17215    && peep2_regno_dead_p (0, FLAGS_REG)"
17216   [(parallel [(set (match_dup 0) (const_int 0))
17217               (clobber (reg:CC FLAGS_REG))])]
17218   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17220 (define_peephole2
17221   [(set (strict_low_part (match_operand 0 "register_operand"))
17222         (const_int 0))]
17223   "(GET_MODE (operands[0]) == QImode
17224     || GET_MODE (operands[0]) == HImode)
17225    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17226    && peep2_regno_dead_p (0, FLAGS_REG)"
17227   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17228               (clobber (reg:CC FLAGS_REG))])])
17230 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17231 (define_peephole2
17232   [(set (match_operand:SWI248 0 "register_operand")
17233         (const_int -1))]
17234   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17235    && peep2_regno_dead_p (0, FLAGS_REG)"
17236   [(parallel [(set (match_dup 0) (const_int -1))
17237               (clobber (reg:CC FLAGS_REG))])]
17239   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17240     operands[0] = gen_lowpart (SImode, operands[0]);
17243 ;; Attempt to convert simple lea to add/shift.
17244 ;; These can be created by move expanders.
17245 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17246 ;; relevant lea instructions were already split.
17248 (define_peephole2
17249   [(set (match_operand:SWI48 0 "register_operand")
17250         (plus:SWI48 (match_dup 0)
17251                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
17252   "!TARGET_OPT_AGU
17253    && peep2_regno_dead_p (0, FLAGS_REG)"
17254   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17255               (clobber (reg:CC FLAGS_REG))])])
17257 (define_peephole2
17258   [(set (match_operand:SWI48 0 "register_operand")
17259         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17260                     (match_dup 0)))]
17261   "!TARGET_OPT_AGU
17262    && peep2_regno_dead_p (0, FLAGS_REG)"
17263   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17264               (clobber (reg:CC FLAGS_REG))])])
17266 (define_peephole2
17267   [(set (match_operand:DI 0 "register_operand")
17268         (zero_extend:DI
17269           (plus:SI (match_operand:SI 1 "register_operand")
17270                    (match_operand:SI 2 "nonmemory_operand"))))]
17271   "TARGET_64BIT && !TARGET_OPT_AGU
17272    && REGNO (operands[0]) == REGNO (operands[1])
17273    && peep2_regno_dead_p (0, FLAGS_REG)"
17274   [(parallel [(set (match_dup 0)
17275                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17276               (clobber (reg:CC FLAGS_REG))])])
17278 (define_peephole2
17279   [(set (match_operand:DI 0 "register_operand")
17280         (zero_extend:DI
17281           (plus:SI (match_operand:SI 1 "nonmemory_operand")
17282                    (match_operand:SI 2 "register_operand"))))]
17283   "TARGET_64BIT && !TARGET_OPT_AGU
17284    && REGNO (operands[0]) == REGNO (operands[2])
17285    && peep2_regno_dead_p (0, FLAGS_REG)"
17286   [(parallel [(set (match_dup 0)
17287                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17288               (clobber (reg:CC FLAGS_REG))])])
17290 (define_peephole2
17291   [(set (match_operand:SWI48 0 "register_operand")
17292         (mult:SWI48 (match_dup 0)
17293                     (match_operand:SWI48 1 "const_int_operand")))]
17294   "exact_log2 (INTVAL (operands[1])) >= 0
17295    && peep2_regno_dead_p (0, FLAGS_REG)"
17296   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17297               (clobber (reg:CC FLAGS_REG))])]
17298   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17300 (define_peephole2
17301   [(set (match_operand:DI 0 "register_operand")
17302         (zero_extend:DI
17303           (mult:SI (match_operand:SI 1 "register_operand")
17304                    (match_operand:SI 2 "const_int_operand"))))]
17305   "TARGET_64BIT
17306    && exact_log2 (INTVAL (operands[2])) >= 0
17307    && REGNO (operands[0]) == REGNO (operands[1])
17308    && peep2_regno_dead_p (0, FLAGS_REG)"
17309   [(parallel [(set (match_dup 0)
17310                    (zero_extend (ashift:SI (match_dup 1) (match_dup 2))))
17311               (clobber (reg:CC FLAGS_REG))])]
17312   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17314 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17315 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17316 ;; On many CPUs it is also faster, since special hardware to avoid esp
17317 ;; dependencies is present.
17319 ;; While some of these conversions may be done using splitters, we use
17320 ;; peepholes in order to allow combine_stack_adjustments pass to see
17321 ;; nonobfuscated RTL.
17323 ;; Convert prologue esp subtractions to push.
17324 ;; We need register to push.  In order to keep verify_flow_info happy we have
17325 ;; two choices
17326 ;; - use scratch and clobber it in order to avoid dependencies
17327 ;; - use already live register
17328 ;; We can't use the second way right now, since there is no reliable way how to
17329 ;; verify that given register is live.  First choice will also most likely in
17330 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17331 ;; call clobbered registers are dead.  We may want to use base pointer as an
17332 ;; alternative when no register is available later.
17334 (define_peephole2
17335   [(match_scratch:W 1 "r")
17336    (parallel [(set (reg:P SP_REG)
17337                    (plus:P (reg:P SP_REG)
17338                            (match_operand:P 0 "const_int_operand")))
17339               (clobber (reg:CC FLAGS_REG))
17340               (clobber (mem:BLK (scratch)))])]
17341   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17342    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17343   [(clobber (match_dup 1))
17344    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17345               (clobber (mem:BLK (scratch)))])])
17347 (define_peephole2
17348   [(match_scratch:W 1 "r")
17349    (parallel [(set (reg:P SP_REG)
17350                    (plus:P (reg:P SP_REG)
17351                            (match_operand:P 0 "const_int_operand")))
17352               (clobber (reg:CC FLAGS_REG))
17353               (clobber (mem:BLK (scratch)))])]
17354   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17355    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17356   [(clobber (match_dup 1))
17357    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17358    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17359               (clobber (mem:BLK (scratch)))])])
17361 ;; Convert esp subtractions to push.
17362 (define_peephole2
17363   [(match_scratch:W 1 "r")
17364    (parallel [(set (reg:P SP_REG)
17365                    (plus:P (reg:P SP_REG)
17366                            (match_operand:P 0 "const_int_operand")))
17367               (clobber (reg:CC FLAGS_REG))])]
17368   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17369    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17370   [(clobber (match_dup 1))
17371    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17373 (define_peephole2
17374   [(match_scratch:W 1 "r")
17375    (parallel [(set (reg:P SP_REG)
17376                    (plus:P (reg:P SP_REG)
17377                            (match_operand:P 0 "const_int_operand")))
17378               (clobber (reg:CC FLAGS_REG))])]
17379   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17380    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17381   [(clobber (match_dup 1))
17382    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17383    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17385 ;; Convert epilogue deallocator to pop.
17386 (define_peephole2
17387   [(match_scratch:W 1 "r")
17388    (parallel [(set (reg:P SP_REG)
17389                    (plus:P (reg:P SP_REG)
17390                            (match_operand:P 0 "const_int_operand")))
17391               (clobber (reg:CC FLAGS_REG))
17392               (clobber (mem:BLK (scratch)))])]
17393   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17394    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17395   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17396               (clobber (mem:BLK (scratch)))])])
17398 ;; Two pops case is tricky, since pop causes dependency
17399 ;; on destination register.  We use two registers if available.
17400 (define_peephole2
17401   [(match_scratch:W 1 "r")
17402    (match_scratch:W 2 "r")
17403    (parallel [(set (reg:P SP_REG)
17404                    (plus:P (reg:P SP_REG)
17405                            (match_operand:P 0 "const_int_operand")))
17406               (clobber (reg:CC FLAGS_REG))
17407               (clobber (mem:BLK (scratch)))])]
17408   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17409    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17410   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17411               (clobber (mem:BLK (scratch)))])
17412    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17414 (define_peephole2
17415   [(match_scratch:W 1 "r")
17416    (parallel [(set (reg:P SP_REG)
17417                    (plus:P (reg:P SP_REG)
17418                            (match_operand:P 0 "const_int_operand")))
17419               (clobber (reg:CC FLAGS_REG))
17420               (clobber (mem:BLK (scratch)))])]
17421   "optimize_insn_for_size_p ()
17422    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17423   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17424               (clobber (mem:BLK (scratch)))])
17425    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17427 ;; Convert esp additions to pop.
17428 (define_peephole2
17429   [(match_scratch:W 1 "r")
17430    (parallel [(set (reg:P SP_REG)
17431                    (plus:P (reg:P SP_REG)
17432                            (match_operand:P 0 "const_int_operand")))
17433               (clobber (reg:CC FLAGS_REG))])]
17434   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17435   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17437 ;; Two pops case is tricky, since pop causes dependency
17438 ;; on destination register.  We use two registers if available.
17439 (define_peephole2
17440   [(match_scratch:W 1 "r")
17441    (match_scratch:W 2 "r")
17442    (parallel [(set (reg:P SP_REG)
17443                    (plus:P (reg:P SP_REG)
17444                            (match_operand:P 0 "const_int_operand")))
17445               (clobber (reg:CC FLAGS_REG))])]
17446   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17447   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17448    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17450 (define_peephole2
17451   [(match_scratch:W 1 "r")
17452    (parallel [(set (reg:P SP_REG)
17453                    (plus:P (reg:P SP_REG)
17454                            (match_operand:P 0 "const_int_operand")))
17455               (clobber (reg:CC FLAGS_REG))])]
17456   "optimize_insn_for_size_p ()
17457    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17458   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17459    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17461 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17462 ;; required and register dies.  Similarly for 128 to -128.
17463 (define_peephole2
17464   [(set (match_operand 0 "flags_reg_operand")
17465         (match_operator 1 "compare_operator"
17466           [(match_operand 2 "register_operand")
17467            (match_operand 3 "const_int_operand")]))]
17468   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17469      && incdec_operand (operands[3], GET_MODE (operands[3])))
17470     || (!TARGET_FUSE_CMP_AND_BRANCH
17471         && INTVAL (operands[3]) == 128))
17472    && ix86_match_ccmode (insn, CCGCmode)
17473    && peep2_reg_dead_p (1, operands[2])"
17474   [(parallel [(set (match_dup 0)
17475                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17476               (clobber (match_dup 2))])])
17478 ;; Convert imul by three, five and nine into lea
17479 (define_peephole2
17480   [(parallel
17481     [(set (match_operand:SWI48 0 "register_operand")
17482           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17483                       (match_operand:SWI48 2 "const359_operand")))
17484      (clobber (reg:CC FLAGS_REG))])]
17485   "!TARGET_PARTIAL_REG_STALL
17486    || <MODE>mode == SImode
17487    || optimize_function_for_size_p (cfun)"
17488   [(set (match_dup 0)
17489         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17490                     (match_dup 1)))]
17491   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17493 (define_peephole2
17494   [(parallel
17495     [(set (match_operand:SWI48 0 "register_operand")
17496           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17497                       (match_operand:SWI48 2 "const359_operand")))
17498      (clobber (reg:CC FLAGS_REG))])]
17499   "optimize_insn_for_speed_p ()
17500    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17501   [(set (match_dup 0) (match_dup 1))
17502    (set (match_dup 0)
17503         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17504                     (match_dup 0)))]
17505   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17507 ;; imul $32bit_imm, mem, reg is vector decoded, while
17508 ;; imul $32bit_imm, reg, reg is direct decoded.
17509 (define_peephole2
17510   [(match_scratch:SWI48 3 "r")
17511    (parallel [(set (match_operand:SWI48 0 "register_operand")
17512                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17513                                (match_operand:SWI48 2 "immediate_operand")))
17514               (clobber (reg:CC FLAGS_REG))])]
17515   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17516    && !satisfies_constraint_K (operands[2])"
17517   [(set (match_dup 3) (match_dup 1))
17518    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17519               (clobber (reg:CC FLAGS_REG))])])
17521 (define_peephole2
17522   [(match_scratch:SI 3 "r")
17523    (parallel [(set (match_operand:DI 0 "register_operand")
17524                    (zero_extend:DI
17525                      (mult:SI (match_operand:SI 1 "memory_operand")
17526                               (match_operand:SI 2 "immediate_operand"))))
17527               (clobber (reg:CC FLAGS_REG))])]
17528   "TARGET_64BIT
17529    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17530    && !satisfies_constraint_K (operands[2])"
17531   [(set (match_dup 3) (match_dup 1))
17532    (parallel [(set (match_dup 0)
17533                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17534               (clobber (reg:CC FLAGS_REG))])])
17536 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17537 ;; Convert it into imul reg, reg
17538 ;; It would be better to force assembler to encode instruction using long
17539 ;; immediate, but there is apparently no way to do so.
17540 (define_peephole2
17541   [(parallel [(set (match_operand:SWI248 0 "register_operand")
17542                    (mult:SWI248
17543                     (match_operand:SWI248 1 "nonimmediate_operand")
17544                     (match_operand:SWI248 2 "const_int_operand")))
17545               (clobber (reg:CC FLAGS_REG))])
17546    (match_scratch:SWI248 3 "r")]
17547   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17548    && satisfies_constraint_K (operands[2])"
17549   [(set (match_dup 3) (match_dup 2))
17550    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17551               (clobber (reg:CC FLAGS_REG))])]
17553   if (!rtx_equal_p (operands[0], operands[1]))
17554     emit_move_insn (operands[0], operands[1]);
17557 ;; After splitting up read-modify operations, array accesses with memory
17558 ;; operands might end up in form:
17559 ;;  sall    $2, %eax
17560 ;;  movl    4(%esp), %edx
17561 ;;  addl    %edx, %eax
17562 ;; instead of pre-splitting:
17563 ;;  sall    $2, %eax
17564 ;;  addl    4(%esp), %eax
17565 ;; Turn it into:
17566 ;;  movl    4(%esp), %edx
17567 ;;  leal    (%edx,%eax,4), %eax
17569 (define_peephole2
17570   [(match_scratch:W 5 "r")
17571    (parallel [(set (match_operand 0 "register_operand")
17572                    (ashift (match_operand 1 "register_operand")
17573                            (match_operand 2 "const_int_operand")))
17574                (clobber (reg:CC FLAGS_REG))])
17575    (parallel [(set (match_operand 3 "register_operand")
17576                    (plus (match_dup 0)
17577                          (match_operand 4 "x86_64_general_operand")))
17578                    (clobber (reg:CC FLAGS_REG))])]
17579   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17580    /* Validate MODE for lea.  */
17581    && ((!TARGET_PARTIAL_REG_STALL
17582         && (GET_MODE (operands[0]) == QImode
17583             || GET_MODE (operands[0]) == HImode))
17584        || GET_MODE (operands[0]) == SImode
17585        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17586    && (rtx_equal_p (operands[0], operands[3])
17587        || peep2_reg_dead_p (2, operands[0]))
17588    /* We reorder load and the shift.  */
17589    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17590   [(set (match_dup 5) (match_dup 4))
17591    (set (match_dup 0) (match_dup 1))]
17593   enum machine_mode op1mode = GET_MODE (operands[1]);
17594   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17595   int scale = 1 << INTVAL (operands[2]);
17596   rtx index = gen_lowpart (word_mode, operands[1]);
17597   rtx base = gen_lowpart (word_mode, operands[5]);
17598   rtx dest = gen_lowpart (mode, operands[3]);
17600   operands[1] = gen_rtx_PLUS (word_mode, base,
17601                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17602   operands[5] = base;
17603   if (mode != word_mode)
17604     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17605   if (op1mode != word_mode)
17606     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17607   operands[0] = dest;
17610 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17611 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17612 ;; caught for use by garbage collectors and the like.  Using an insn that
17613 ;; maps to SIGILL makes it more likely the program will rightfully die.
17614 ;; Keeping with tradition, "6" is in honor of #UD.
17615 (define_insn "trap"
17616   [(trap_if (const_int 1) (const_int 6))]
17617   ""
17618   { return ASM_SHORT "0x0b0f"; }
17619   [(set_attr "length" "2")])
17621 (define_expand "prefetch"
17622   [(prefetch (match_operand 0 "address_operand")
17623              (match_operand:SI 1 "const_int_operand")
17624              (match_operand:SI 2 "const_int_operand"))]
17625   "TARGET_PREFETCH_SSE || TARGET_PRFCHW"
17627   bool write = INTVAL (operands[1]) != 0;
17628   int locality = INTVAL (operands[2]);
17630   gcc_assert (IN_RANGE (locality, 0, 3));
17632   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17633      supported by SSE counterpart or the SSE prefetch is not available
17634      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17635      of locality.  */
17636   if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17637     operands[2] = GEN_INT (3);
17638   else
17639     operands[1] = const0_rtx;
17642 (define_insn "*prefetch_sse"
17643   [(prefetch (match_operand 0 "address_operand" "p")
17644              (const_int 0)
17645              (match_operand:SI 1 "const_int_operand"))]
17646   "TARGET_PREFETCH_SSE"
17648   static const char * const patterns[4] = {
17649    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17650   };
17652   int locality = INTVAL (operands[1]);
17653   gcc_assert (IN_RANGE (locality, 0, 3));
17655   return patterns[locality];
17657   [(set_attr "type" "sse")
17658    (set_attr "atom_sse_attr" "prefetch")
17659    (set (attr "length_address")
17660         (symbol_ref "memory_address_length (operands[0], false)"))
17661    (set_attr "memory" "none")])
17663 (define_insn "*prefetch_3dnow"
17664   [(prefetch (match_operand 0 "address_operand" "p")
17665              (match_operand:SI 1 "const_int_operand" "n")
17666              (const_int 3))]
17667   "TARGET_PRFCHW"
17669   if (INTVAL (operands[1]) == 0)
17670     return "prefetch\t%a0";
17671   else
17672     return "prefetchw\t%a0";
17674   [(set_attr "type" "mmx")
17675    (set (attr "length_address")
17676         (symbol_ref "memory_address_length (operands[0], false)"))
17677    (set_attr "memory" "none")])
17679 (define_expand "stack_protect_set"
17680   [(match_operand 0 "memory_operand")
17681    (match_operand 1 "memory_operand")]
17682   "TARGET_SSP_TLS_GUARD"
17684   rtx (*insn)(rtx, rtx);
17686 #ifdef TARGET_THREAD_SSP_OFFSET
17687   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17688   insn = (TARGET_LP64
17689           ? gen_stack_tls_protect_set_di
17690           : gen_stack_tls_protect_set_si);
17691 #else
17692   insn = (TARGET_LP64
17693           ? gen_stack_protect_set_di
17694           : gen_stack_protect_set_si);
17695 #endif
17697   emit_insn (insn (operands[0], operands[1]));
17698   DONE;
17701 (define_insn "stack_protect_set_<mode>"
17702   [(set (match_operand:PTR 0 "memory_operand" "=m")
17703         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17704                     UNSPEC_SP_SET))
17705    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17706    (clobber (reg:CC FLAGS_REG))]
17707   "TARGET_SSP_TLS_GUARD"
17708   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17709   [(set_attr "type" "multi")])
17711 (define_insn "stack_tls_protect_set_<mode>"
17712   [(set (match_operand:PTR 0 "memory_operand" "=m")
17713         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17714                     UNSPEC_SP_TLS_SET))
17715    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17716    (clobber (reg:CC FLAGS_REG))]
17717   ""
17718   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17719   [(set_attr "type" "multi")])
17721 (define_expand "stack_protect_test"
17722   [(match_operand 0 "memory_operand")
17723    (match_operand 1 "memory_operand")
17724    (match_operand 2)]
17725   "TARGET_SSP_TLS_GUARD"
17727   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17729   rtx (*insn)(rtx, rtx, rtx);
17731 #ifdef TARGET_THREAD_SSP_OFFSET
17732   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17733   insn = (TARGET_LP64
17734           ? gen_stack_tls_protect_test_di
17735           : gen_stack_tls_protect_test_si);
17736 #else
17737   insn = (TARGET_LP64
17738           ? gen_stack_protect_test_di
17739           : gen_stack_protect_test_si);
17740 #endif
17742   emit_insn (insn (flags, operands[0], operands[1]));
17744   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17745                                   flags, const0_rtx, operands[2]));
17746   DONE;
17749 (define_insn "stack_protect_test_<mode>"
17750   [(set (match_operand:CCZ 0 "flags_reg_operand")
17751         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17752                      (match_operand:PTR 2 "memory_operand" "m")]
17753                     UNSPEC_SP_TEST))
17754    (clobber (match_scratch:PTR 3 "=&r"))]
17755   "TARGET_SSP_TLS_GUARD"
17756   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17757   [(set_attr "type" "multi")])
17759 (define_insn "stack_tls_protect_test_<mode>"
17760   [(set (match_operand:CCZ 0 "flags_reg_operand")
17761         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17762                      (match_operand:PTR 2 "const_int_operand" "i")]
17763                     UNSPEC_SP_TLS_TEST))
17764    (clobber (match_scratch:PTR 3 "=r"))]
17765   ""
17766   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17767   [(set_attr "type" "multi")])
17769 (define_insn "sse4_2_crc32<mode>"
17770   [(set (match_operand:SI 0 "register_operand" "=r")
17771         (unspec:SI
17772           [(match_operand:SI 1 "register_operand" "0")
17773            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17774           UNSPEC_CRC32))]
17775   "TARGET_SSE4_2 || TARGET_CRC32"
17776   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17777   [(set_attr "type" "sselog1")
17778    (set_attr "prefix_rep" "1")
17779    (set_attr "prefix_extra" "1")
17780    (set (attr "prefix_data16")
17781      (if_then_else (match_operand:HI 2)
17782        (const_string "1")
17783        (const_string "*")))
17784    (set (attr "prefix_rex")
17785      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17786        (const_string "1")
17787        (const_string "*")))
17788    (set_attr "mode" "SI")])
17790 (define_insn "sse4_2_crc32di"
17791   [(set (match_operand:DI 0 "register_operand" "=r")
17792         (unspec:DI
17793           [(match_operand:DI 1 "register_operand" "0")
17794            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17795           UNSPEC_CRC32))]
17796   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17797   "crc32{q}\t{%2, %0|%0, %2}"
17798   [(set_attr "type" "sselog1")
17799    (set_attr "prefix_rep" "1")
17800    (set_attr "prefix_extra" "1")
17801    (set_attr "mode" "DI")])
17803 (define_insn "rdpmc"
17804   [(set (match_operand:DI 0 "register_operand" "=A")
17805         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17806                             UNSPECV_RDPMC))]
17807   "!TARGET_64BIT"
17808   "rdpmc"
17809   [(set_attr "type" "other")
17810    (set_attr "length" "2")])
17812 (define_insn "rdpmc_rex64"
17813   [(set (match_operand:DI 0 "register_operand" "=a")
17814         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17815                             UNSPECV_RDPMC))
17816    (set (match_operand:DI 1 "register_operand" "=d")
17817         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
17818   "TARGET_64BIT"
17819   "rdpmc"
17820   [(set_attr "type" "other")
17821    (set_attr "length" "2")])
17823 (define_insn "rdtsc"
17824   [(set (match_operand:DI 0 "register_operand" "=A")
17825         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17826   "!TARGET_64BIT"
17827   "rdtsc"
17828   [(set_attr "type" "other")
17829    (set_attr "length" "2")])
17831 (define_insn "rdtsc_rex64"
17832   [(set (match_operand:DI 0 "register_operand" "=a")
17833         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17834    (set (match_operand:DI 1 "register_operand" "=d")
17835         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17836   "TARGET_64BIT"
17837   "rdtsc"
17838   [(set_attr "type" "other")
17839    (set_attr "length" "2")])
17841 (define_insn "rdtscp"
17842   [(set (match_operand:DI 0 "register_operand" "=A")
17843         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17844    (set (match_operand:SI 1 "register_operand" "=c")
17845         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17846   "!TARGET_64BIT"
17847   "rdtscp"
17848   [(set_attr "type" "other")
17849    (set_attr "length" "3")])
17851 (define_insn "rdtscp_rex64"
17852   [(set (match_operand:DI 0 "register_operand" "=a")
17853         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17854    (set (match_operand:DI 1 "register_operand" "=d")
17855         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17856    (set (match_operand:SI 2 "register_operand" "=c")
17857         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17858   "TARGET_64BIT"
17859   "rdtscp"
17860   [(set_attr "type" "other")
17861    (set_attr "length" "3")])
17863 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17865 ;; FXSR, XSAVE and XSAVEOPT instructions
17867 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17869 (define_insn "fxsave"
17870   [(set (match_operand:BLK 0 "memory_operand" "=m")
17871         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
17872   "TARGET_FXSR"
17873   "fxsave\t%0"
17874   [(set_attr "type" "other")
17875    (set_attr "memory" "store")
17876    (set (attr "length")
17877         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17879 (define_insn "fxsave64"
17880   [(set (match_operand:BLK 0 "memory_operand" "=m")
17881         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
17882   "TARGET_64BIT && TARGET_FXSR"
17883   "fxsave64\t%0"
17884   [(set_attr "type" "other")
17885    (set_attr "memory" "store")
17886    (set (attr "length")
17887         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17889 (define_insn "fxrstor"
17890   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17891                     UNSPECV_FXRSTOR)]
17892   "TARGET_FXSR"
17893   "fxrstor\t%0"
17894   [(set_attr "type" "other")
17895    (set_attr "memory" "load")
17896    (set (attr "length")
17897         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17899 (define_insn "fxrstor64"
17900   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17901                     UNSPECV_FXRSTOR64)]
17902   "TARGET_64BIT && TARGET_FXSR"
17903   "fxrstor64\t%0"
17904   [(set_attr "type" "other")
17905    (set_attr "memory" "load")
17906    (set (attr "length")
17907         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17909 (define_int_iterator ANY_XSAVE
17910         [UNSPECV_XSAVE
17911          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")])
17913 (define_int_iterator ANY_XSAVE64
17914         [UNSPECV_XSAVE64
17915          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")])
17917 (define_int_attr xsave
17918         [(UNSPECV_XSAVE "xsave")
17919          (UNSPECV_XSAVE64 "xsave64")
17920          (UNSPECV_XSAVEOPT "xsaveopt")
17921          (UNSPECV_XSAVEOPT64 "xsaveopt64")])
17923 (define_insn "<xsave>"
17924   [(set (match_operand:BLK 0 "memory_operand" "=m")
17925         (unspec_volatile:BLK
17926          [(match_operand:DI 1 "register_operand" "A")]
17927          ANY_XSAVE))]
17928   "!TARGET_64BIT && TARGET_XSAVE"
17929   "<xsave>\t%0"
17930   [(set_attr "type" "other")
17931    (set_attr "memory" "store")
17932    (set (attr "length")
17933         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17935 (define_insn "<xsave>_rex64"
17936   [(set (match_operand:BLK 0 "memory_operand" "=m")
17937         (unspec_volatile:BLK
17938          [(match_operand:SI 1 "register_operand" "a")
17939           (match_operand:SI 2 "register_operand" "d")]
17940          ANY_XSAVE))]
17941   "TARGET_64BIT && TARGET_XSAVE"
17942   "<xsave>\t%0"
17943   [(set_attr "type" "other")
17944    (set_attr "memory" "store")
17945    (set (attr "length")
17946         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17948 (define_insn "<xsave>"
17949   [(set (match_operand:BLK 0 "memory_operand" "=m")
17950         (unspec_volatile:BLK
17951          [(match_operand:SI 1 "register_operand" "a")
17952           (match_operand:SI 2 "register_operand" "d")]
17953          ANY_XSAVE64))]
17954   "TARGET_64BIT && TARGET_XSAVE"
17955   "<xsave>\t%0"
17956   [(set_attr "type" "other")
17957    (set_attr "memory" "store")
17958    (set (attr "length")
17959         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17961 (define_insn "xrstor"
17962    [(unspec_volatile:BLK
17963      [(match_operand:BLK 0 "memory_operand" "m")
17964       (match_operand:DI 1 "register_operand" "A")]
17965      UNSPECV_XRSTOR)]
17966   "!TARGET_64BIT && TARGET_XSAVE"
17967   "xrstor\t%0"
17968   [(set_attr "type" "other")
17969    (set_attr "memory" "load")
17970    (set (attr "length")
17971         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17973 (define_insn "xrstor_rex64"
17974    [(unspec_volatile:BLK
17975      [(match_operand:BLK 0 "memory_operand" "m")
17976       (match_operand:SI 1 "register_operand" "a")
17977       (match_operand:SI 2 "register_operand" "d")]
17978      UNSPECV_XRSTOR)]
17979   "TARGET_64BIT && TARGET_XSAVE"
17980   "xrstor\t%0"
17981   [(set_attr "type" "other")
17982    (set_attr "memory" "load")
17983    (set (attr "length")
17984         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17986 (define_insn "xrstor64"
17987    [(unspec_volatile:BLK
17988      [(match_operand:BLK 0 "memory_operand" "m")
17989       (match_operand:SI 1 "register_operand" "a")
17990       (match_operand:SI 2 "register_operand" "d")]
17991      UNSPECV_XRSTOR64)]
17992   "TARGET_64BIT && TARGET_XSAVE"
17993   "xrstor64\t%0"
17994   [(set_attr "type" "other")
17995    (set_attr "memory" "load")
17996    (set (attr "length")
17997         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17999 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18001 ;; LWP instructions
18003 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18005 (define_expand "lwp_llwpcb"
18006   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18007                     UNSPECV_LLWP_INTRINSIC)]
18008   "TARGET_LWP")
18010 (define_insn "*lwp_llwpcb<mode>1"
18011   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18012                     UNSPECV_LLWP_INTRINSIC)]
18013   "TARGET_LWP"
18014   "llwpcb\t%0"
18015   [(set_attr "type" "lwp")
18016    (set_attr "mode" "<MODE>")
18017    (set_attr "length" "5")])
18019 (define_expand "lwp_slwpcb"
18020   [(set (match_operand 0 "register_operand" "=r")
18021         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18022   "TARGET_LWP"
18024   rtx (*insn)(rtx);
18026   insn = (Pmode == DImode
18027           ? gen_lwp_slwpcbdi
18028           : gen_lwp_slwpcbsi);
18030   emit_insn (insn (operands[0]));
18031   DONE;
18034 (define_insn "lwp_slwpcb<mode>"
18035   [(set (match_operand:P 0 "register_operand" "=r")
18036         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18037   "TARGET_LWP"
18038   "slwpcb\t%0"
18039   [(set_attr "type" "lwp")
18040    (set_attr "mode" "<MODE>")
18041    (set_attr "length" "5")])
18043 (define_expand "lwp_lwpval<mode>3"
18044   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18045                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18046                      (match_operand:SI 3 "const_int_operand" "i")]
18047                     UNSPECV_LWPVAL_INTRINSIC)]
18048   "TARGET_LWP"
18049   ;; Avoid unused variable warning.
18050   "(void) operands[0];")
18052 (define_insn "*lwp_lwpval<mode>3_1"
18053   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18054                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18055                      (match_operand:SI 2 "const_int_operand" "i")]
18056                     UNSPECV_LWPVAL_INTRINSIC)]
18057   "TARGET_LWP"
18058   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18059   [(set_attr "type" "lwp")
18060    (set_attr "mode" "<MODE>")
18061    (set (attr "length")
18062         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18064 (define_expand "lwp_lwpins<mode>3"
18065   [(set (reg:CCC FLAGS_REG)
18066         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18067                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18068                               (match_operand:SI 3 "const_int_operand" "i")]
18069                              UNSPECV_LWPINS_INTRINSIC))
18070    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18071         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18072   "TARGET_LWP")
18074 (define_insn "*lwp_lwpins<mode>3_1"
18075   [(set (reg:CCC FLAGS_REG)
18076         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18077                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18078                               (match_operand:SI 2 "const_int_operand" "i")]
18079                              UNSPECV_LWPINS_INTRINSIC))]
18080   "TARGET_LWP"
18081   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18082   [(set_attr "type" "lwp")
18083    (set_attr "mode" "<MODE>")
18084    (set (attr "length")
18085         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18087 (define_int_iterator RDFSGSBASE
18088         [UNSPECV_RDFSBASE
18089          UNSPECV_RDGSBASE])
18091 (define_int_iterator WRFSGSBASE
18092         [UNSPECV_WRFSBASE
18093          UNSPECV_WRGSBASE])
18095 (define_int_attr fsgs
18096         [(UNSPECV_RDFSBASE "fs")
18097          (UNSPECV_RDGSBASE "gs")
18098          (UNSPECV_WRFSBASE "fs")
18099          (UNSPECV_WRGSBASE "gs")])
18101 (define_insn "rd<fsgs>base<mode>"
18102   [(set (match_operand:SWI48 0 "register_operand" "=r")
18103         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18104   "TARGET_64BIT && TARGET_FSGSBASE"
18105   "rd<fsgs>base\t%0"
18106   [(set_attr "type" "other")
18107    (set_attr "prefix_extra" "2")])
18109 (define_insn "wr<fsgs>base<mode>"
18110   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18111                     WRFSGSBASE)]
18112   "TARGET_64BIT && TARGET_FSGSBASE"
18113   "wr<fsgs>base\t%0"
18114   [(set_attr "type" "other")
18115    (set_attr "prefix_extra" "2")])
18117 (define_insn "rdrand<mode>_1"
18118   [(set (match_operand:SWI248 0 "register_operand" "=r")
18119         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18120    (set (reg:CCC FLAGS_REG)
18121         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18122   "TARGET_RDRND"
18123   "rdrand\t%0"
18124   [(set_attr "type" "other")
18125    (set_attr "prefix_extra" "1")])
18127 (define_insn "rdseed<mode>_1"
18128   [(set (match_operand:SWI248 0 "register_operand" "=r")
18129         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18130    (set (reg:CCC FLAGS_REG)
18131         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18132   "TARGET_RDSEED"
18133   "rdseed\t%0"
18134   [(set_attr "type" "other")
18135    (set_attr "prefix_extra" "1")])
18137 (define_expand "pause"
18138   [(set (match_dup 0)
18139         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18140   ""
18142   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18143   MEM_VOLATILE_P (operands[0]) = 1;
18146 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18147 ;; They have the same encoding.
18148 (define_insn "*pause"
18149   [(set (match_operand:BLK 0)
18150         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18151   ""
18152   "rep%; nop"
18153   [(set_attr "length" "2")
18154    (set_attr "memory" "unknown")])
18156 (define_expand "xbegin"
18157   [(set (match_operand:SI 0 "register_operand")
18158         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18159   "TARGET_RTM"
18161   rtx label = gen_label_rtx ();
18163   /* xbegin is emitted as jump_insn, so reload won't be able
18164      to reload its operand.  Force the value into AX hard register.  */
18165   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18166   emit_move_insn (ax_reg, constm1_rtx);
18168   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18170   emit_label (label);
18171   LABEL_NUSES (label) = 1;
18173   emit_move_insn (operands[0], ax_reg);
18175   DONE;
18178 (define_insn "xbegin_1"
18179   [(set (pc)
18180         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18181                           (const_int 0))
18182                       (label_ref (match_operand 1))
18183                       (pc)))
18184    (set (match_operand:SI 0 "register_operand" "+a")
18185         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18186   "TARGET_RTM"
18187   "xbegin\t%l1"
18188   [(set_attr "type" "other")
18189    (set_attr "length" "6")])
18191 (define_insn "xend"
18192   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18193   "TARGET_RTM"
18194   "xend"
18195   [(set_attr "type" "other")
18196    (set_attr "length" "3")])
18198 (define_insn "xabort"
18199   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18200                     UNSPECV_XABORT)]
18201   "TARGET_RTM"
18202   "xabort\t%0"
18203   [(set_attr "type" "other")
18204    (set_attr "length" "3")])
18206 (define_expand "xtest"
18207   [(set (match_operand:QI 0 "register_operand")
18208         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18209   "TARGET_RTM"
18211   emit_insn (gen_xtest_1 ());
18213   ix86_expand_setcc (operands[0], NE,
18214                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18215   DONE;
18218 (define_insn "xtest_1"
18219   [(set (reg:CCZ FLAGS_REG)
18220         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18221   "TARGET_RTM"
18222   "xtest"
18223   [(set_attr "type" "other")
18224    (set_attr "length" "3")])
18226 ;; MPX instructions
18228 (define_expand "<mode>_mk"
18229   [(set (match_operand:BND 0 "register_operand")
18230     (unspec:BND
18231       [(mem:<bnd_ptr>
18232        (match_par_dup 3
18233         [(match_operand:<bnd_ptr> 1 "register_operand")
18234          (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
18235       UNSPEC_BNDMK))]
18236   "TARGET_MPX"
18238   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18239                                                   operands[2]),
18240                                 UNSPEC_BNDMK_ADDR);
18243 (define_insn "*<mode>_mk"
18244   [(set (match_operand:BND 0 "register_operand" "=B")
18245     (unspec:BND
18246       [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18247         [(unspec:<bnd_ptr>
18248            [(match_operand:<bnd_ptr> 1 "register_operand" "r")
18249             (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
18250            UNSPEC_BNDMK_ADDR)])]
18251       UNSPEC_BNDMK))]
18252   "TARGET_MPX"
18253   "bndmk\t{%3, %0|%0, %3}"
18254   [(set_attr "type" "mpxmk")])
18256 (define_expand "mov<mode>"
18257   [(set (match_operand:BND 0 "general_operand")
18258         (match_operand:BND 1 "general_operand"))]
18259   "TARGET_MPX"
18261   ix86_expand_move (<MODE>mode, operands);DONE;
18264 (define_insn "*mov<mode>_internal_mpx"
18265   [(set (match_operand:BND 0 "nonimmediate_operand" "=B,m")
18266         (match_operand:BND 1 "general_operand" "Bm,B"))]
18267   "TARGET_MPX"
18268   "bndmov\t{%1, %0|%0, %1}"
18269   [(set_attr "type" "mpxmov")])
18271 (define_expand "<mode>_<bndcheck>"
18272   [(parallel [(unspec [(match_operand:BND 0 "register_operand")
18273                        (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
18274               (set (match_dup 2)
18275                    (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18276   "TARGET_MPX"
18278   operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
18279   MEM_VOLATILE_P (operands[2]) = 1;
18282 (define_insn "*<mode>_<bndcheck>"
18283   [(parallel [(unspec [(match_operand:BND 0 "register_operand" "B")
18284                        (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "p")] BNDCHECK)
18285               (set (match_operand:BLK 2 "bnd_mem_operator")
18286                    (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18287   "TARGET_MPX"
18288   "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
18289   [(set_attr "type" "mpxchk")])
18291 (define_expand "<mode>_ldx"
18292   [(parallel [(set:BND (match_operand:BND 0 "register_operand")
18293                        (unspec:BND
18294                          [(mem:<bnd_ptr>
18295                            (match_par_dup 3
18296                              [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
18297                               (match_operand:<bnd_ptr> 2 "register_operand")]))]
18298                          UNSPEC_BNDLDX))
18299               (use (mem:BLK (match_dup 1)))])]
18300   "TARGET_MPX"
18302   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18303                                                   operands[2]),
18304                                 UNSPEC_BNDLDX_ADDR);
18307 (define_insn "*<mode>_ldx"
18308   [(parallel [(set:BND (match_operand:BND 0 "register_operand" "=B")
18309                        (unspec:BND
18310                          [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18311                            [(unspec:<bnd_ptr>
18312                              [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
18313                               (match_operand:<bnd_ptr> 2 "register_operand" "l")]
18314                             UNSPEC_BNDLDX_ADDR)])]
18315                          UNSPEC_BNDLDX))
18316               (use (mem:BLK (match_dup 1)))])]
18317   "TARGET_MPX"
18318   "bndldx\t{%3, %0|%0, %3}"
18319   [(set_attr "type" "mpxld")])
18321 (define_expand "<mode>_stx"
18322   [(parallel [(unspec [(mem:<bnd_ptr>
18323                          (match_par_dup 3
18324                            [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
18325                             (match_operand:<bnd_ptr> 1 "register_operand")]))
18326                        (match_operand:BND 2 "register_operand")] UNSPEC_BNDSTX)
18327               (set (match_dup 4)
18328                    (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18329   "TARGET_MPX"
18331   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
18332                                                   operands[1]),
18333                                 UNSPEC_BNDLDX_ADDR);
18334   operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
18335   MEM_VOLATILE_P (operands[4]) = 1;
18338 (define_insn "*<mode>_stx"
18339   [(parallel [(unspec [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18340                          [(unspec:<bnd_ptr>
18341                           [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
18342                            (match_operand:<bnd_ptr> 1 "register_operand" "l")]
18343                          UNSPEC_BNDLDX_ADDR)])
18344                        (match_operand:BND 2 "register_operand" "B")] UNSPEC_BNDSTX)
18345               (set (match_operand:BLK 4 "bnd_mem_operator")
18346                    (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18347   "TARGET_MPX"
18348   "bndstx\t{%2, %3|%3, %2}"
18349   [(set_attr "type" "mpxst")])
18351 (include "mmx.md")
18352 (include "sse.md")
18353 (include "sync.md")