* config/i386/sse.md (*vec_extractv4si_0_zext): New pattern.
[official-gcc.git] / gcc / config / i386 / i386.md
blobdea5d513e84d15a263df00e01e44610be9bfe6d6
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
67 (define_c_enum "unspec" [
68   ;; Relocation specifiers
69   UNSPEC_GOT
70   UNSPEC_GOTOFF
71   UNSPEC_GOTPCREL
72   UNSPEC_GOTTPOFF
73   UNSPEC_TPOFF
74   UNSPEC_NTPOFF
75   UNSPEC_DTPOFF
76   UNSPEC_GOTNTPOFF
77   UNSPEC_INDNTPOFF
78   UNSPEC_PLTOFF
79   UNSPEC_MACHOPIC_OFFSET
80   UNSPEC_PCREL
82   ;; Prologue support
83   UNSPEC_STACK_ALLOC
84   UNSPEC_SET_GOT
85   UNSPEC_SET_RIP
86   UNSPEC_SET_GOT_OFFSET
87   UNSPEC_MEMORY_BLOCKAGE
88   UNSPEC_STACK_CHECK
90   ;; TLS support
91   UNSPEC_TP
92   UNSPEC_TLS_GD
93   UNSPEC_TLS_LD_BASE
94   UNSPEC_TLSDESC
95   UNSPEC_TLS_IE_SUN
97   ;; Other random patterns
98   UNSPEC_SCAS
99   UNSPEC_FNSTSW
100   UNSPEC_SAHF
101   UNSPEC_PARITY
102   UNSPEC_FSTCW
103   UNSPEC_ADD_CARRY
104   UNSPEC_FLDCW
105   UNSPEC_REP
106   UNSPEC_LD_MPIC        ; load_macho_picbase
107   UNSPEC_TRUNC_NOOP
108   UNSPEC_DIV_ALREADY_SPLIT
109   UNSPEC_MS_TO_SYSV_CALL
110   UNSPEC_PAUSE
111   UNSPEC_LEA_ADDR
112   UNSPEC_XBEGIN_ABORT
113   UNSPEC_STOS
115   ;; For SSE/MMX support:
116   UNSPEC_FIX_NOTRUNC
117   UNSPEC_MASKMOV
118   UNSPEC_MOVMSK
119   UNSPEC_RCP
120   UNSPEC_RSQRT
121   UNSPEC_PSADBW
123   ;; Generic math support
124   UNSPEC_COPYSIGN
125   UNSPEC_IEEE_MIN       ; not commutative
126   UNSPEC_IEEE_MAX       ; not commutative
128   ;; x87 Floating point
129   UNSPEC_SIN
130   UNSPEC_COS
131   UNSPEC_FPATAN
132   UNSPEC_FYL2X
133   UNSPEC_FYL2XP1
134   UNSPEC_FRNDINT
135   UNSPEC_FIST
136   UNSPEC_F2XM1
137   UNSPEC_TAN
138   UNSPEC_FXAM
140   ;; x87 Rounding
141   UNSPEC_FRNDINT_FLOOR
142   UNSPEC_FRNDINT_CEIL
143   UNSPEC_FRNDINT_TRUNC
144   UNSPEC_FRNDINT_MASK_PM
145   UNSPEC_FIST_FLOOR
146   UNSPEC_FIST_CEIL
148   ;; x87 Double output FP
149   UNSPEC_SINCOS_COS
150   UNSPEC_SINCOS_SIN
151   UNSPEC_XTRACT_FRACT
152   UNSPEC_XTRACT_EXP
153   UNSPEC_FSCALE_FRACT
154   UNSPEC_FSCALE_EXP
155   UNSPEC_FPREM_F
156   UNSPEC_FPREM_U
157   UNSPEC_FPREM1_F
158   UNSPEC_FPREM1_U
160   UNSPEC_C2_FLAG
161   UNSPEC_FXAM_MEM
163   ;; SSP patterns
164   UNSPEC_SP_SET
165   UNSPEC_SP_TEST
166   UNSPEC_SP_TLS_SET
167   UNSPEC_SP_TLS_TEST
169   ;; For ROUND support
170   UNSPEC_ROUND
172   ;; For CRC32 support
173   UNSPEC_CRC32
175   ;; For BMI support
176   UNSPEC_BEXTR
178   ;; For BMI2 support
179   UNSPEC_PDEP
180   UNSPEC_PEXT
183 (define_c_enum "unspecv" [
184   UNSPECV_BLOCKAGE
185   UNSPECV_STACK_PROBE
186   UNSPECV_PROBE_STACK_RANGE
187   UNSPECV_ALIGN
188   UNSPECV_PROLOGUE_USE
189   UNSPECV_SPLIT_STACK_RETURN
190   UNSPECV_CLD
191   UNSPECV_NOPS
192   UNSPECV_RDTSC
193   UNSPECV_RDTSCP
194   UNSPECV_RDPMC
195   UNSPECV_LLWP_INTRINSIC
196   UNSPECV_SLWP_INTRINSIC
197   UNSPECV_LWPVAL_INTRINSIC
198   UNSPECV_LWPINS_INTRINSIC
199   UNSPECV_RDFSBASE
200   UNSPECV_RDGSBASE
201   UNSPECV_WRFSBASE
202   UNSPECV_WRGSBASE
203   UNSPECV_FXSAVE
204   UNSPECV_FXRSTOR
205   UNSPECV_FXSAVE64
206   UNSPECV_FXRSTOR64
207   UNSPECV_XSAVE
208   UNSPECV_XRSTOR
209   UNSPECV_XSAVE64
210   UNSPECV_XRSTOR64
211   UNSPECV_XSAVEOPT
212   UNSPECV_XSAVEOPT64
214   ;; For RDRAND support
215   UNSPECV_RDRAND
217   ;; For RDSEED support
218   UNSPECV_RDSEED
220   ;; For RTM support
221   UNSPECV_XBEGIN
222   UNSPECV_XEND
223   UNSPECV_XABORT
224   UNSPECV_XTEST
227 ;; Constants to represent rounding modes in the ROUND instruction
228 (define_constants
229   [(ROUND_FLOOR                 0x1)
230    (ROUND_CEIL                  0x2)
231    (ROUND_TRUNC                 0x3)
232    (ROUND_MXCSR                 0x4)
233    (ROUND_NO_EXC                0x8)
234   ])
236 ;; Constants to represent pcomtrue/pcomfalse variants
237 (define_constants
238   [(PCOM_FALSE                  0)
239    (PCOM_TRUE                   1)
240    (COM_FALSE_S                 2)
241    (COM_FALSE_P                 3)
242    (COM_TRUE_S                  4)
243    (COM_TRUE_P                  5)
244   ])
246 ;; Constants used in the XOP pperm instruction
247 (define_constants
248   [(PPERM_SRC                   0x00)   /* copy source */
249    (PPERM_INVERT                0x20)   /* invert source */
250    (PPERM_REVERSE               0x40)   /* bit reverse source */
251    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
252    (PPERM_ZERO                  0x80)   /* all 0's */
253    (PPERM_ONES                  0xa0)   /* all 1's */
254    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
255    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
256    (PPERM_SRC1                  0x00)   /* use first source byte */
257    (PPERM_SRC2                  0x10)   /* use second source byte */
258    ])
260 ;; Registers by name.
261 (define_constants
262   [(AX_REG                       0)
263    (DX_REG                       1)
264    (CX_REG                       2)
265    (BX_REG                       3)
266    (SI_REG                       4)
267    (DI_REG                       5)
268    (BP_REG                       6)
269    (SP_REG                       7)
270    (ST0_REG                      8)
271    (ST1_REG                      9)
272    (ST2_REG                     10)
273    (ST3_REG                     11)
274    (ST4_REG                     12)
275    (ST5_REG                     13)
276    (ST6_REG                     14)
277    (ST7_REG                     15)
278    (FLAGS_REG                   17)
279    (FPSR_REG                    18)
280    (FPCR_REG                    19)
281    (XMM0_REG                    21)
282    (XMM1_REG                    22)
283    (XMM2_REG                    23)
284    (XMM3_REG                    24)
285    (XMM4_REG                    25)
286    (XMM5_REG                    26)
287    (XMM6_REG                    27)
288    (XMM7_REG                    28)
289    (MM0_REG                     29)
290    (MM1_REG                     30)
291    (MM2_REG                     31)
292    (MM3_REG                     32)
293    (MM4_REG                     33)
294    (MM5_REG                     34)
295    (MM6_REG                     35)
296    (MM7_REG                     36)
297    (R8_REG                      37)
298    (R9_REG                      38)
299    (R10_REG                     39)
300    (R11_REG                     40)
301    (R12_REG                     41)
302    (R13_REG                     42)
303    (R14_REG                     43)
304    (R15_REG                     44)
305    (XMM8_REG                    45)
306    (XMM9_REG                    46)
307    (XMM10_REG                   47)
308    (XMM11_REG                   48)
309    (XMM12_REG                   49)
310    (XMM13_REG                   50)
311    (XMM14_REG                   51)
312    (XMM15_REG                   52)
313   ])
315 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
316 ;; from i386.c.
318 ;; In C guard expressions, put expressions which may be compile-time
319 ;; constants first.  This allows for better optimization.  For
320 ;; example, write "TARGET_64BIT && reload_completed", not
321 ;; "reload_completed && TARGET_64BIT".
324 ;; Processor type.
325 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
326                     atom,generic64,amdfam10,bdver1,bdver2,bdver3,btver1,btver2"
327   (const (symbol_ref "ix86_schedule")))
329 ;; A basic instruction type.  Refinements due to arguments to be
330 ;; provided in other attributes.
331 (define_attr "type"
332   "other,multi,
333    alu,alu1,negnot,imov,imovx,lea,
334    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
335    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
336    push,pop,call,callv,leave,
337    str,bitmanip,
338    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
339    fxch,fistp,fisttp,frndint,
340    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
341    ssemul,sseimul,ssediv,sselog,sselog1,
342    sseishft,sseishft1,ssecmp,ssecomi,
343    ssecvt,ssecvt1,sseicvt,sseins,
344    sseshuf,sseshuf1,ssemuladd,sse4arg,
345    lwp,
346    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
347   (const_string "other"))
349 ;; Main data type used by the insn
350 (define_attr "mode"
351   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
352   (const_string "unknown"))
354 ;; The CPU unit operations uses.
355 (define_attr "unit" "integer,i387,sse,mmx,unknown"
356   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
357                           fxch,fistp,fisttp,frndint")
358            (const_string "i387")
359          (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
360                           ssemul,sseimul,ssediv,sselog,sselog1,
361                           sseishft,sseishft1,ssecmp,ssecomi,
362                           ssecvt,ssecvt1,sseicvt,sseins,
363                           sseshuf,sseshuf1,ssemuladd,sse4arg")
364            (const_string "sse")
365          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
366            (const_string "mmx")
367          (eq_attr "type" "other")
368            (const_string "unknown")]
369          (const_string "integer")))
371 ;; The (bounding maximum) length of an instruction immediate.
372 (define_attr "length_immediate" ""
373   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
374                           bitmanip,imulx")
375            (const_int 0)
376          (eq_attr "unit" "i387,sse,mmx")
377            (const_int 0)
378          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
379                           rotate,rotatex,rotate1,imul,icmp,push,pop")
380            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
381          (eq_attr "type" "imov,test")
382            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
383          (eq_attr "type" "call")
384            (if_then_else (match_operand 0 "constant_call_address_operand")
385              (const_int 4)
386              (const_int 0))
387          (eq_attr "type" "callv")
388            (if_then_else (match_operand 1 "constant_call_address_operand")
389              (const_int 4)
390              (const_int 0))
391          ;; We don't know the size before shorten_branches.  Expect
392          ;; the instruction to fit for better scheduling.
393          (eq_attr "type" "ibr")
394            (const_int 1)
395          ]
396          (symbol_ref "/* Update immediate_length and other attributes! */
397                       gcc_unreachable (),1")))
399 ;; The (bounding maximum) length of an instruction address.
400 (define_attr "length_address" ""
401   (cond [(eq_attr "type" "str,other,multi,fxch")
402            (const_int 0)
403          (and (eq_attr "type" "call")
404               (match_operand 0 "constant_call_address_operand"))
405              (const_int 0)
406          (and (eq_attr "type" "callv")
407               (match_operand 1 "constant_call_address_operand"))
408              (const_int 0)
409          ]
410          (symbol_ref "ix86_attr_length_address_default (insn)")))
412 ;; Set when length prefix is used.
413 (define_attr "prefix_data16" ""
414   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
415            (const_int 0)
416          (eq_attr "mode" "HI")
417            (const_int 1)
418          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
419            (const_int 1)
420         ]
421         (const_int 0)))
423 ;; Set when string REP prefix is used.
424 (define_attr "prefix_rep" ""
425   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
426            (const_int 0)
427          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
428            (const_int 1)
429         ]
430         (const_int 0)))
432 ;; Set when 0f opcode prefix is used.
433 (define_attr "prefix_0f" ""
434   (if_then_else
435     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
436          (eq_attr "unit" "sse,mmx"))
437     (const_int 1)
438     (const_int 0)))
440 ;; Set when REX opcode prefix is used.
441 (define_attr "prefix_rex" ""
442   (cond [(not (match_test "TARGET_64BIT"))
443            (const_int 0)
444          (and (eq_attr "mode" "DI")
445               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
446                    (eq_attr "unit" "!mmx")))
447            (const_int 1)
448          (and (eq_attr "mode" "QI")
449               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
450            (const_int 1)
451          (match_test "x86_extended_reg_mentioned_p (insn)")
452            (const_int 1)
453          (and (eq_attr "type" "imovx")
454               (match_operand:QI 1 "ext_QIreg_operand"))
455            (const_int 1)
456         ]
457         (const_int 0)))
459 ;; There are also additional prefixes in 3DNOW, SSSE3.
460 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
461 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
462 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
463 (define_attr "prefix_extra" ""
464   (cond [(eq_attr "type" "ssemuladd,sse4arg")
465            (const_int 2)
466          (eq_attr "type" "sseiadd1,ssecvt1")
467            (const_int 1)
468         ]
469         (const_int 0)))
471 ;; Prefix used: original, VEX or maybe VEX.
472 (define_attr "prefix" "orig,vex,maybe_vex"
473   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
474     (const_string "vex")
475     (const_string "orig")))
477 ;; VEX W bit is used.
478 (define_attr "prefix_vex_w" "" (const_int 0))
480 ;; The length of VEX prefix
481 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
482 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
483 ;; still prefix_0f 1, with prefix_extra 1.
484 (define_attr "length_vex" ""
485   (if_then_else (and (eq_attr "prefix_0f" "1")
486                      (eq_attr "prefix_extra" "0"))
487     (if_then_else (eq_attr "prefix_vex_w" "1")
488       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
489       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
490     (if_then_else (eq_attr "prefix_vex_w" "1")
491       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
492       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
494 ;; Set when modrm byte is used.
495 (define_attr "modrm" ""
496   (cond [(eq_attr "type" "str,leave")
497            (const_int 0)
498          (eq_attr "unit" "i387")
499            (const_int 0)
500          (and (eq_attr "type" "incdec")
501               (and (not (match_test "TARGET_64BIT"))
502                    (ior (match_operand:SI 1 "register_operand")
503                         (match_operand:HI 1 "register_operand"))))
504            (const_int 0)
505          (and (eq_attr "type" "push")
506               (not (match_operand 1 "memory_operand")))
507            (const_int 0)
508          (and (eq_attr "type" "pop")
509               (not (match_operand 0 "memory_operand")))
510            (const_int 0)
511          (and (eq_attr "type" "imov")
512               (and (not (eq_attr "mode" "DI"))
513                    (ior (and (match_operand 0 "register_operand")
514                              (match_operand 1 "immediate_operand"))
515                         (ior (and (match_operand 0 "ax_reg_operand")
516                                   (match_operand 1 "memory_displacement_only_operand"))
517                              (and (match_operand 0 "memory_displacement_only_operand")
518                                   (match_operand 1 "ax_reg_operand"))))))
519            (const_int 0)
520          (and (eq_attr "type" "call")
521               (match_operand 0 "constant_call_address_operand"))
522              (const_int 0)
523          (and (eq_attr "type" "callv")
524               (match_operand 1 "constant_call_address_operand"))
525              (const_int 0)
526          (and (eq_attr "type" "alu,alu1,icmp,test")
527               (match_operand 0 "ax_reg_operand"))
528              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
529          ]
530          (const_int 1)))
532 ;; The (bounding maximum) length of an instruction in bytes.
533 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
534 ;; Later we may want to split them and compute proper length as for
535 ;; other insns.
536 (define_attr "length" ""
537   (cond [(eq_attr "type" "other,multi,fistp,frndint")
538            (const_int 16)
539          (eq_attr "type" "fcmp")
540            (const_int 4)
541          (eq_attr "unit" "i387")
542            (plus (const_int 2)
543                  (plus (attr "prefix_data16")
544                        (attr "length_address")))
545          (ior (eq_attr "prefix" "vex")
546               (and (eq_attr "prefix" "maybe_vex")
547                    (match_test "TARGET_AVX")))
548            (plus (attr "length_vex")
549                  (plus (attr "length_immediate")
550                        (plus (attr "modrm")
551                              (attr "length_address"))))]
552          (plus (plus (attr "modrm")
553                      (plus (attr "prefix_0f")
554                            (plus (attr "prefix_rex")
555                                  (plus (attr "prefix_extra")
556                                        (const_int 1)))))
557                (plus (attr "prefix_rep")
558                      (plus (attr "prefix_data16")
559                            (plus (attr "length_immediate")
560                                  (attr "length_address")))))))
562 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
563 ;; `store' if there is a simple memory reference therein, or `unknown'
564 ;; if the instruction is complex.
566 (define_attr "memory" "none,load,store,both,unknown"
567   (cond [(eq_attr "type" "other,multi,str,lwp")
568            (const_string "unknown")
569          (eq_attr "type" "lea,fcmov,fpspc")
570            (const_string "none")
571          (eq_attr "type" "fistp,leave")
572            (const_string "both")
573          (eq_attr "type" "frndint")
574            (const_string "load")
575          (eq_attr "type" "push")
576            (if_then_else (match_operand 1 "memory_operand")
577              (const_string "both")
578              (const_string "store"))
579          (eq_attr "type" "pop")
580            (if_then_else (match_operand 0 "memory_operand")
581              (const_string "both")
582              (const_string "load"))
583          (eq_attr "type" "setcc")
584            (if_then_else (match_operand 0 "memory_operand")
585              (const_string "store")
586              (const_string "none"))
587          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
588            (if_then_else (ior (match_operand 0 "memory_operand")
589                               (match_operand 1 "memory_operand"))
590              (const_string "load")
591              (const_string "none"))
592          (eq_attr "type" "ibr")
593            (if_then_else (match_operand 0 "memory_operand")
594              (const_string "load")
595              (const_string "none"))
596          (eq_attr "type" "call")
597            (if_then_else (match_operand 0 "constant_call_address_operand")
598              (const_string "none")
599              (const_string "load"))
600          (eq_attr "type" "callv")
601            (if_then_else (match_operand 1 "constant_call_address_operand")
602              (const_string "none")
603              (const_string "load"))
604          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
605               (match_operand 1 "memory_operand"))
606            (const_string "both")
607          (and (match_operand 0 "memory_operand")
608               (match_operand 1 "memory_operand"))
609            (const_string "both")
610          (match_operand 0 "memory_operand")
611            (const_string "store")
612          (match_operand 1 "memory_operand")
613            (const_string "load")
614          (and (eq_attr "type"
615                  "!alu1,negnot,ishift1,
616                    imov,imovx,icmp,test,bitmanip,
617                    fmov,fcmp,fsgn,
618                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
619                    sseshuf1,sseadd1,sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
620               (match_operand 2 "memory_operand"))
621            (const_string "load")
622          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
623               (match_operand 3 "memory_operand"))
624            (const_string "load")
625         ]
626         (const_string "none")))
628 ;; Indicates if an instruction has both an immediate and a displacement.
630 (define_attr "imm_disp" "false,true,unknown"
631   (cond [(eq_attr "type" "other,multi")
632            (const_string "unknown")
633          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
634               (and (match_operand 0 "memory_displacement_operand")
635                    (match_operand 1 "immediate_operand")))
636            (const_string "true")
637          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
638               (and (match_operand 0 "memory_displacement_operand")
639                    (match_operand 2 "immediate_operand")))
640            (const_string "true")
641         ]
642         (const_string "false")))
644 ;; Indicates if an FP operation has an integer source.
646 (define_attr "fp_int_src" "false,true"
647   (const_string "false"))
649 ;; Defines rounding mode of an FP operation.
651 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
652   (const_string "any"))
654 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
655 (define_attr "use_carry" "0,1" (const_string "0"))
657 ;; Define attribute to indicate unaligned ssemov insns
658 (define_attr "movu" "0,1" (const_string "0"))
660 ;; Used to control the "enabled" attribute on a per-instruction basis.
661 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
662                     sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
663                     avx2,noavx2,bmi2,fma4,fma"
664   (const_string "base"))
666 (define_attr "enabled" ""
667   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
668          (eq_attr "isa" "x64_sse4")
669            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
670          (eq_attr "isa" "x64_sse4_noavx")
671            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
672          (eq_attr "isa" "x64_avx")
673            (symbol_ref "TARGET_64BIT && TARGET_AVX")
674          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
675          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
676          (eq_attr "isa" "sse2_noavx")
677            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
678          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
679          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
680          (eq_attr "isa" "sse4_noavx")
681            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
682          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
683          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
684          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
685          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
686          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
687          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
688          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
689         ]
690         (const_int 1)))
692 ;; Describe a user's asm statement.
693 (define_asm_attributes
694   [(set_attr "length" "128")
695    (set_attr "type" "multi")])
697 (define_code_iterator plusminus [plus minus])
699 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
701 ;; Base name for define_insn
702 (define_code_attr plusminus_insn
703   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
704    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
706 ;; Base name for insn mnemonic.
707 (define_code_attr plusminus_mnemonic
708   [(plus "add") (ss_plus "adds") (us_plus "addus")
709    (minus "sub") (ss_minus "subs") (us_minus "subus")])
710 (define_code_attr plusminus_carry_mnemonic
711   [(plus "adc") (minus "sbb")])
713 ;; Mark commutative operators as such in constraints.
714 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
715                         (minus "") (ss_minus "") (us_minus "")])
717 ;; Mapping of max and min
718 (define_code_iterator maxmin [smax smin umax umin])
720 ;; Mapping of signed max and min
721 (define_code_iterator smaxmin [smax smin])
723 ;; Mapping of unsigned max and min
724 (define_code_iterator umaxmin [umax umin])
726 ;; Base name for integer and FP insn mnemonic
727 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
728                               (umax "maxu") (umin "minu")])
729 (define_code_attr maxmin_float [(smax "max") (smin "min")])
731 ;; Mapping of logic operators
732 (define_code_iterator any_logic [and ior xor])
733 (define_code_iterator any_or [ior xor])
735 ;; Base name for insn mnemonic.
736 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
738 ;; Mapping of logic-shift operators
739 (define_code_iterator any_lshift [ashift lshiftrt])
741 ;; Mapping of shift-right operators
742 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
744 ;; Mapping of all shift operators
745 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
747 ;; Base name for define_insn
748 (define_code_attr shift_insn
749   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
751 ;; Base name for insn mnemonic.
752 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
753 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
755 ;; Mapping of rotate operators
756 (define_code_iterator any_rotate [rotate rotatert])
758 ;; Base name for define_insn
759 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
761 ;; Base name for insn mnemonic.
762 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
764 ;; Mapping of abs neg operators
765 (define_code_iterator absneg [abs neg])
767 ;; Base name for x87 insn mnemonic.
768 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
770 ;; Used in signed and unsigned widening multiplications.
771 (define_code_iterator any_extend [sign_extend zero_extend])
773 ;; Prefix for insn menmonic.
774 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
776 ;; Prefix for define_insn
777 (define_code_attr u [(sign_extend "") (zero_extend "u")])
778 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
779 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
781 ;; All integer modes.
782 (define_mode_iterator SWI1248x [QI HI SI DI])
784 ;; All integer modes without QImode.
785 (define_mode_iterator SWI248x [HI SI DI])
787 ;; All integer modes without QImode and HImode.
788 (define_mode_iterator SWI48x [SI DI])
790 ;; All integer modes without SImode and DImode.
791 (define_mode_iterator SWI12 [QI HI])
793 ;; All integer modes without DImode.
794 (define_mode_iterator SWI124 [QI HI SI])
796 ;; All integer modes without QImode and DImode.
797 (define_mode_iterator SWI24 [HI SI])
799 ;; Single word integer modes.
800 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
802 ;; Single word integer modes without QImode.
803 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
805 ;; Single word integer modes without QImode and HImode.
806 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
808 ;; All math-dependant single and double word integer modes.
809 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
810                              (HI "TARGET_HIMODE_MATH")
811                              SI DI (TI "TARGET_64BIT")])
813 ;; Math-dependant single word integer modes.
814 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
815                             (HI "TARGET_HIMODE_MATH")
816                             SI (DI "TARGET_64BIT")])
818 ;; Math-dependant integer modes without DImode.
819 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
820                                (HI "TARGET_HIMODE_MATH")
821                                SI])
823 ;; Math-dependant single word integer modes without QImode.
824 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
825                                SI (DI "TARGET_64BIT")])
827 ;; Double word integer modes.
828 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
829                            (TI "TARGET_64BIT")])
831 ;; Double word integer modes as mode attribute.
832 (define_mode_attr DWI [(SI "DI") (DI "TI")])
833 (define_mode_attr dwi [(SI "di") (DI "ti")])
835 ;; Half mode for double word integer modes.
836 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
837                             (DI "TARGET_64BIT")])
839 ;; Instruction suffix for integer modes.
840 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
842 ;; Pointer size prefix for integer modes (Intel asm dialect)
843 (define_mode_attr iptrsize [(QI "BYTE")
844                             (HI "WORD")
845                             (SI "DWORD")
846                             (DI "QWORD")])
848 ;; Register class for integer modes.
849 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
851 ;; Immediate operand constraint for integer modes.
852 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
854 ;; General operand constraint for word modes.
855 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
857 ;; Immediate operand constraint for double integer modes.
858 (define_mode_attr di [(SI "nF") (DI "e")])
860 ;; Immediate operand constraint for shifts.
861 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
863 ;; General operand predicate for integer modes.
864 (define_mode_attr general_operand
865         [(QI "general_operand")
866          (HI "general_operand")
867          (SI "x86_64_general_operand")
868          (DI "x86_64_general_operand")
869          (TI "x86_64_general_operand")])
871 ;; General sign/zero extend operand predicate for integer modes.
872 (define_mode_attr general_szext_operand
873         [(QI "general_operand")
874          (HI "general_operand")
875          (SI "x86_64_szext_general_operand")
876          (DI "x86_64_szext_general_operand")])
878 ;; Immediate operand predicate for integer modes.
879 (define_mode_attr immediate_operand
880         [(QI "immediate_operand")
881          (HI "immediate_operand")
882          (SI "x86_64_immediate_operand")
883          (DI "x86_64_immediate_operand")])
885 ;; Nonmemory operand predicate for integer modes.
886 (define_mode_attr nonmemory_operand
887         [(QI "nonmemory_operand")
888          (HI "nonmemory_operand")
889          (SI "x86_64_nonmemory_operand")
890          (DI "x86_64_nonmemory_operand")])
892 ;; Operand predicate for shifts.
893 (define_mode_attr shift_operand
894         [(QI "nonimmediate_operand")
895          (HI "nonimmediate_operand")
896          (SI "nonimmediate_operand")
897          (DI "shiftdi_operand")
898          (TI "register_operand")])
900 ;; Operand predicate for shift argument.
901 (define_mode_attr shift_immediate_operand
902         [(QI "const_1_to_31_operand")
903          (HI "const_1_to_31_operand")
904          (SI "const_1_to_31_operand")
905          (DI "const_1_to_63_operand")])
907 ;; Input operand predicate for arithmetic left shifts.
908 (define_mode_attr ashl_input_operand
909         [(QI "nonimmediate_operand")
910          (HI "nonimmediate_operand")
911          (SI "nonimmediate_operand")
912          (DI "ashldi_input_operand")
913          (TI "reg_or_pm1_operand")])
915 ;; SSE and x87 SFmode and DFmode floating point modes
916 (define_mode_iterator MODEF [SF DF])
918 ;; All x87 floating point modes
919 (define_mode_iterator X87MODEF [SF DF XF])
921 ;; SSE instruction suffix for various modes
922 (define_mode_attr ssemodesuffix
923   [(SF "ss") (DF "sd")
924    (V8SF "ps") (V4DF "pd")
925    (V4SF "ps") (V2DF "pd")
926    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
927    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
929 ;; SSE vector suffix for floating point modes
930 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
932 ;; SSE vector mode corresponding to a scalar mode
933 (define_mode_attr ssevecmode
934   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
935 (define_mode_attr ssevecmodelower
936   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
938 ;; Instruction suffix for REX 64bit operators.
939 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
941 ;; This mode iterator allows :P to be used for patterns that operate on
942 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
943 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
945 ;; This mode iterator allows :W to be used for patterns that operate on
946 ;; word_mode sized quantities.
947 (define_mode_iterator W
948   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
950 ;; This mode iterator allows :PTR to be used for patterns that operate on
951 ;; ptr_mode sized quantities.
952 (define_mode_iterator PTR
953   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
955 ;; Scheduling descriptions
957 (include "pentium.md")
958 (include "ppro.md")
959 (include "k6.md")
960 (include "athlon.md")
961 (include "bdver1.md")
962 (include "bdver3.md")
963 (include "btver2.md")
964 (include "geode.md")
965 (include "atom.md")
966 (include "core2.md")
969 ;; Operand and operator predicates and constraints
971 (include "predicates.md")
972 (include "constraints.md")
975 ;; Compare and branch/compare and store instructions.
977 (define_expand "cbranch<mode>4"
978   [(set (reg:CC FLAGS_REG)
979         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
980                     (match_operand:SDWIM 2 "<general_operand>")))
981    (set (pc) (if_then_else
982                (match_operator 0 "ordered_comparison_operator"
983                 [(reg:CC FLAGS_REG) (const_int 0)])
984                (label_ref (match_operand 3))
985                (pc)))]
986   ""
988   if (MEM_P (operands[1]) && MEM_P (operands[2]))
989     operands[1] = force_reg (<MODE>mode, operands[1]);
990   ix86_expand_branch (GET_CODE (operands[0]),
991                       operands[1], operands[2], operands[3]);
992   DONE;
995 (define_expand "cstore<mode>4"
996   [(set (reg:CC FLAGS_REG)
997         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
998                     (match_operand:SWIM 3 "<general_operand>")))
999    (set (match_operand:QI 0 "register_operand")
1000         (match_operator 1 "ordered_comparison_operator"
1001           [(reg:CC FLAGS_REG) (const_int 0)]))]
1002   ""
1004   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1005     operands[2] = force_reg (<MODE>mode, operands[2]);
1006   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1007                      operands[2], operands[3]);
1008   DONE;
1011 (define_expand "cmp<mode>_1"
1012   [(set (reg:CC FLAGS_REG)
1013         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1014                     (match_operand:SWI48 1 "<general_operand>")))])
1016 (define_insn "*cmp<mode>_ccno_1"
1017   [(set (reg FLAGS_REG)
1018         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1019                  (match_operand:SWI 1 "const0_operand")))]
1020   "ix86_match_ccmode (insn, CCNOmode)"
1021   "@
1022    test{<imodesuffix>}\t%0, %0
1023    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1024   [(set_attr "type" "test,icmp")
1025    (set_attr "length_immediate" "0,1")
1026    (set_attr "mode" "<MODE>")])
1028 (define_insn "*cmp<mode>_1"
1029   [(set (reg FLAGS_REG)
1030         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1031                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1032   "ix86_match_ccmode (insn, CCmode)"
1033   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1034   [(set_attr "type" "icmp")
1035    (set_attr "mode" "<MODE>")])
1037 (define_insn "*cmp<mode>_minus_1"
1038   [(set (reg FLAGS_REG)
1039         (compare
1040           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1041                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1042           (const_int 0)))]
1043   "ix86_match_ccmode (insn, CCGOCmode)"
1044   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1045   [(set_attr "type" "icmp")
1046    (set_attr "mode" "<MODE>")])
1048 (define_insn "*cmpqi_ext_1"
1049   [(set (reg FLAGS_REG)
1050         (compare
1051           (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1052           (subreg:QI
1053             (zero_extract:SI
1054               (match_operand 1 "ext_register_operand" "Q,Q")
1055               (const_int 8)
1056               (const_int 8)) 0)))]
1057   "ix86_match_ccmode (insn, CCmode)"
1058   "cmp{b}\t{%h1, %0|%0, %h1}"
1059   [(set_attr "isa" "*,nox64")
1060    (set_attr "type" "icmp")
1061    (set_attr "mode" "QI")])
1063 (define_insn "*cmpqi_ext_2"
1064   [(set (reg FLAGS_REG)
1065         (compare
1066           (subreg:QI
1067             (zero_extract:SI
1068               (match_operand 0 "ext_register_operand" "Q")
1069               (const_int 8)
1070               (const_int 8)) 0)
1071           (match_operand:QI 1 "const0_operand")))]
1072   "ix86_match_ccmode (insn, CCNOmode)"
1073   "test{b}\t%h0, %h0"
1074   [(set_attr "type" "test")
1075    (set_attr "length_immediate" "0")
1076    (set_attr "mode" "QI")])
1078 (define_expand "cmpqi_ext_3"
1079   [(set (reg:CC FLAGS_REG)
1080         (compare:CC
1081           (subreg:QI
1082             (zero_extract:SI
1083               (match_operand 0 "ext_register_operand")
1084               (const_int 8)
1085               (const_int 8)) 0)
1086           (match_operand:QI 1 "const_int_operand")))])
1088 (define_insn "*cmpqi_ext_3"
1089   [(set (reg FLAGS_REG)
1090         (compare
1091           (subreg:QI
1092             (zero_extract:SI
1093               (match_operand 0 "ext_register_operand" "Q,Q")
1094               (const_int 8)
1095               (const_int 8)) 0)
1096           (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1097   "ix86_match_ccmode (insn, CCmode)"
1098   "cmp{b}\t{%1, %h0|%h0, %1}"
1099   [(set_attr "isa" "*,nox64")
1100    (set_attr "type" "icmp")
1101    (set_attr "modrm" "1")
1102    (set_attr "mode" "QI")])
1104 (define_insn "*cmpqi_ext_4"
1105   [(set (reg FLAGS_REG)
1106         (compare
1107           (subreg:QI
1108             (zero_extract:SI
1109               (match_operand 0 "ext_register_operand" "Q")
1110               (const_int 8)
1111               (const_int 8)) 0)
1112           (subreg:QI
1113             (zero_extract:SI
1114               (match_operand 1 "ext_register_operand" "Q")
1115               (const_int 8)
1116               (const_int 8)) 0)))]
1117   "ix86_match_ccmode (insn, CCmode)"
1118   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1119   [(set_attr "type" "icmp")
1120    (set_attr "mode" "QI")])
1122 ;; These implement float point compares.
1123 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1124 ;; which would allow mix and match FP modes on the compares.  Which is what
1125 ;; the old patterns did, but with many more of them.
1127 (define_expand "cbranchxf4"
1128   [(set (reg:CC FLAGS_REG)
1129         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1130                     (match_operand:XF 2 "nonmemory_operand")))
1131    (set (pc) (if_then_else
1132               (match_operator 0 "ix86_fp_comparison_operator"
1133                [(reg:CC FLAGS_REG)
1134                 (const_int 0)])
1135               (label_ref (match_operand 3))
1136               (pc)))]
1137   "TARGET_80387"
1139   ix86_expand_branch (GET_CODE (operands[0]),
1140                       operands[1], operands[2], operands[3]);
1141   DONE;
1144 (define_expand "cstorexf4"
1145   [(set (reg:CC FLAGS_REG)
1146         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1147                     (match_operand:XF 3 "nonmemory_operand")))
1148    (set (match_operand:QI 0 "register_operand")
1149               (match_operator 1 "ix86_fp_comparison_operator"
1150                [(reg:CC FLAGS_REG)
1151                 (const_int 0)]))]
1152   "TARGET_80387"
1154   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1155                      operands[2], operands[3]);
1156   DONE;
1159 (define_expand "cbranch<mode>4"
1160   [(set (reg:CC FLAGS_REG)
1161         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1162                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1163    (set (pc) (if_then_else
1164               (match_operator 0 "ix86_fp_comparison_operator"
1165                [(reg:CC FLAGS_REG)
1166                 (const_int 0)])
1167               (label_ref (match_operand 3))
1168               (pc)))]
1169   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1171   ix86_expand_branch (GET_CODE (operands[0]),
1172                       operands[1], operands[2], operands[3]);
1173   DONE;
1176 (define_expand "cstore<mode>4"
1177   [(set (reg:CC FLAGS_REG)
1178         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1179                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1180    (set (match_operand:QI 0 "register_operand")
1181               (match_operator 1 "ix86_fp_comparison_operator"
1182                [(reg:CC FLAGS_REG)
1183                 (const_int 0)]))]
1184   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1186   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1187                      operands[2], operands[3]);
1188   DONE;
1191 (define_expand "cbranchcc4"
1192   [(set (pc) (if_then_else
1193               (match_operator 0 "comparison_operator"
1194                [(match_operand 1 "flags_reg_operand")
1195                 (match_operand 2 "const0_operand")])
1196               (label_ref (match_operand 3))
1197               (pc)))]
1198   ""
1200   ix86_expand_branch (GET_CODE (operands[0]),
1201                       operands[1], operands[2], operands[3]);
1202   DONE;
1205 (define_expand "cstorecc4"
1206   [(set (match_operand:QI 0 "register_operand")
1207               (match_operator 1 "comparison_operator"
1208                [(match_operand 2 "flags_reg_operand")
1209                 (match_operand 3 "const0_operand")]))]
1210   ""
1212   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1213                      operands[2], operands[3]);
1214   DONE;
1218 ;; FP compares, step 1:
1219 ;; Set the FP condition codes.
1221 ;; CCFPmode     compare with exceptions
1222 ;; CCFPUmode    compare with no exceptions
1224 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1225 ;; used to manage the reg stack popping would not be preserved.
1227 (define_insn "*cmp<mode>_0_i387"
1228   [(set (match_operand:HI 0 "register_operand" "=a")
1229         (unspec:HI
1230           [(compare:CCFP
1231              (match_operand:X87MODEF 1 "register_operand" "f")
1232              (match_operand:X87MODEF 2 "const0_operand"))]
1233         UNSPEC_FNSTSW))]
1234   "TARGET_80387"
1235   "* return output_fp_compare (insn, operands, false, false);"
1236   [(set_attr "type" "multi")
1237    (set_attr "unit" "i387")
1238    (set_attr "mode" "<MODE>")])
1240 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1241   [(set (reg:CCFP FLAGS_REG)
1242         (compare:CCFP
1243           (match_operand:X87MODEF 1 "register_operand" "f")
1244           (match_operand:X87MODEF 2 "const0_operand")))
1245    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1246   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1247   "#"
1248   "&& reload_completed"
1249   [(set (match_dup 0)
1250         (unspec:HI
1251           [(compare:CCFP (match_dup 1)(match_dup 2))]
1252         UNSPEC_FNSTSW))
1253    (set (reg:CC FLAGS_REG)
1254         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1255   ""
1256   [(set_attr "type" "multi")
1257    (set_attr "unit" "i387")
1258    (set_attr "mode" "<MODE>")])
1260 (define_insn "*cmpxf_i387"
1261   [(set (match_operand:HI 0 "register_operand" "=a")
1262         (unspec:HI
1263           [(compare:CCFP
1264              (match_operand:XF 1 "register_operand" "f")
1265              (match_operand:XF 2 "register_operand" "f"))]
1266           UNSPEC_FNSTSW))]
1267   "TARGET_80387"
1268   "* return output_fp_compare (insn, operands, false, false);"
1269   [(set_attr "type" "multi")
1270    (set_attr "unit" "i387")
1271    (set_attr "mode" "XF")])
1273 (define_insn_and_split "*cmpxf_cc_i387"
1274   [(set (reg:CCFP FLAGS_REG)
1275         (compare:CCFP
1276           (match_operand:XF 1 "register_operand" "f")
1277           (match_operand:XF 2 "register_operand" "f")))
1278    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1279   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1280   "#"
1281   "&& reload_completed"
1282   [(set (match_dup 0)
1283         (unspec:HI
1284           [(compare:CCFP (match_dup 1)(match_dup 2))]
1285         UNSPEC_FNSTSW))
1286    (set (reg:CC FLAGS_REG)
1287         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1288   ""
1289   [(set_attr "type" "multi")
1290    (set_attr "unit" "i387")
1291    (set_attr "mode" "XF")])
1293 (define_insn "*cmp<mode>_i387"
1294   [(set (match_operand:HI 0 "register_operand" "=a")
1295         (unspec:HI
1296           [(compare:CCFP
1297              (match_operand:MODEF 1 "register_operand" "f")
1298              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1299           UNSPEC_FNSTSW))]
1300   "TARGET_80387"
1301   "* return output_fp_compare (insn, operands, false, false);"
1302   [(set_attr "type" "multi")
1303    (set_attr "unit" "i387")
1304    (set_attr "mode" "<MODE>")])
1306 (define_insn_and_split "*cmp<mode>_cc_i387"
1307   [(set (reg:CCFP FLAGS_REG)
1308         (compare:CCFP
1309           (match_operand:MODEF 1 "register_operand" "f")
1310           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1311    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1312   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1313   "#"
1314   "&& reload_completed"
1315   [(set (match_dup 0)
1316         (unspec:HI
1317           [(compare:CCFP (match_dup 1)(match_dup 2))]
1318         UNSPEC_FNSTSW))
1319    (set (reg:CC FLAGS_REG)
1320         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1321   ""
1322   [(set_attr "type" "multi")
1323    (set_attr "unit" "i387")
1324    (set_attr "mode" "<MODE>")])
1326 (define_insn "*cmpu<mode>_i387"
1327   [(set (match_operand:HI 0 "register_operand" "=a")
1328         (unspec:HI
1329           [(compare:CCFPU
1330              (match_operand:X87MODEF 1 "register_operand" "f")
1331              (match_operand:X87MODEF 2 "register_operand" "f"))]
1332           UNSPEC_FNSTSW))]
1333   "TARGET_80387"
1334   "* return output_fp_compare (insn, operands, false, true);"
1335   [(set_attr "type" "multi")
1336    (set_attr "unit" "i387")
1337    (set_attr "mode" "<MODE>")])
1339 (define_insn_and_split "*cmpu<mode>_cc_i387"
1340   [(set (reg:CCFPU FLAGS_REG)
1341         (compare:CCFPU
1342           (match_operand:X87MODEF 1 "register_operand" "f")
1343           (match_operand:X87MODEF 2 "register_operand" "f")))
1344    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1345   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1346   "#"
1347   "&& reload_completed"
1348   [(set (match_dup 0)
1349         (unspec:HI
1350           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1351         UNSPEC_FNSTSW))
1352    (set (reg:CC FLAGS_REG)
1353         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1354   ""
1355   [(set_attr "type" "multi")
1356    (set_attr "unit" "i387")
1357    (set_attr "mode" "<MODE>")])
1359 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1360   [(set (match_operand:HI 0 "register_operand" "=a")
1361         (unspec:HI
1362           [(compare:CCFP
1363              (match_operand:X87MODEF 1 "register_operand" "f")
1364              (match_operator:X87MODEF 3 "float_operator"
1365                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1366           UNSPEC_FNSTSW))]
1367   "TARGET_80387
1368    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1369        || optimize_function_for_size_p (cfun))"
1370   "* return output_fp_compare (insn, operands, false, false);"
1371   [(set_attr "type" "multi")
1372    (set_attr "unit" "i387")
1373    (set_attr "fp_int_src" "true")
1374    (set_attr "mode" "<SWI24:MODE>")])
1376 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1377   [(set (reg:CCFP FLAGS_REG)
1378         (compare:CCFP
1379           (match_operand:X87MODEF 1 "register_operand" "f")
1380           (match_operator:X87MODEF 3 "float_operator"
1381             [(match_operand:SWI24 2 "memory_operand" "m")])))
1382    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1383   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1384    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1385        || optimize_function_for_size_p (cfun))"
1386   "#"
1387   "&& reload_completed"
1388   [(set (match_dup 0)
1389         (unspec:HI
1390           [(compare:CCFP
1391              (match_dup 1)
1392              (match_op_dup 3 [(match_dup 2)]))]
1393         UNSPEC_FNSTSW))
1394    (set (reg:CC FLAGS_REG)
1395         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1396   ""
1397   [(set_attr "type" "multi")
1398    (set_attr "unit" "i387")
1399    (set_attr "fp_int_src" "true")
1400    (set_attr "mode" "<SWI24:MODE>")])
1402 ;; FP compares, step 2
1403 ;; Move the fpsw to ax.
1405 (define_insn "x86_fnstsw_1"
1406   [(set (match_operand:HI 0 "register_operand" "=a")
1407         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1408   "TARGET_80387"
1409   "fnstsw\t%0"
1410   [(set (attr "length")
1411         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1412    (set_attr "mode" "SI")
1413    (set_attr "unit" "i387")])
1415 ;; FP compares, step 3
1416 ;; Get ax into flags, general case.
1418 (define_insn "x86_sahf_1"
1419   [(set (reg:CC FLAGS_REG)
1420         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1421                    UNSPEC_SAHF))]
1422   "TARGET_SAHF"
1424 #ifndef HAVE_AS_IX86_SAHF
1425   if (TARGET_64BIT)
1426     return ASM_BYTE "0x9e";
1427   else
1428 #endif
1429   return "sahf";
1431   [(set_attr "length" "1")
1432    (set_attr "athlon_decode" "vector")
1433    (set_attr "amdfam10_decode" "direct")
1434    (set_attr "bdver1_decode" "direct")
1435    (set_attr "mode" "SI")])
1437 ;; Pentium Pro can do steps 1 through 3 in one go.
1438 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1439 ;; (these i387 instructions set flags directly)
1441 (define_mode_iterator FPCMP [CCFP CCFPU])
1442 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1444 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1445   [(set (reg:FPCMP FLAGS_REG)
1446         (compare:FPCMP
1447           (match_operand:MODEF 0 "register_operand" "f,x")
1448           (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1449   "TARGET_MIX_SSE_I387
1450    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1451   "* return output_fp_compare (insn, operands, true,
1452                                <FPCMP:MODE>mode == CCFPUmode);"
1453   [(set_attr "type" "fcmp,ssecomi")
1454    (set_attr "prefix" "orig,maybe_vex")
1455    (set_attr "mode" "<MODEF:MODE>")
1456    (set (attr "prefix_rep")
1457         (if_then_else (eq_attr "type" "ssecomi")
1458                       (const_string "0")
1459                       (const_string "*")))
1460    (set (attr "prefix_data16")
1461         (cond [(eq_attr "type" "fcmp")
1462                  (const_string "*")
1463                (eq_attr "mode" "DF")
1464                  (const_string "1")
1465               ]
1466               (const_string "0")))
1467    (set_attr "athlon_decode" "vector")
1468    (set_attr "amdfam10_decode" "direct")
1469    (set_attr "bdver1_decode" "double")])
1471 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1472   [(set (reg:FPCMP FLAGS_REG)
1473         (compare:FPCMP
1474           (match_operand:MODEF 0 "register_operand" "x")
1475           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1476   "TARGET_SSE_MATH
1477    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1478   "* return output_fp_compare (insn, operands, true,
1479                                <FPCMP:MODE>mode == CCFPUmode);"
1480   [(set_attr "type" "ssecomi")
1481    (set_attr "prefix" "maybe_vex")
1482    (set_attr "mode" "<MODEF:MODE>")
1483    (set_attr "prefix_rep" "0")
1484    (set (attr "prefix_data16")
1485         (if_then_else (eq_attr "mode" "DF")
1486                       (const_string "1")
1487                       (const_string "0")))
1488    (set_attr "athlon_decode" "vector")
1489    (set_attr "amdfam10_decode" "direct")
1490    (set_attr "bdver1_decode" "double")])
1492 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1493   [(set (reg:FPCMP FLAGS_REG)
1494         (compare:FPCMP
1495           (match_operand:X87MODEF 0 "register_operand" "f")
1496           (match_operand:X87MODEF 1 "register_operand" "f")))]
1497   "TARGET_80387 && TARGET_CMOVE
1498    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1499   "* return output_fp_compare (insn, operands, true,
1500                                <FPCMP:MODE>mode == CCFPUmode);"
1501   [(set_attr "type" "fcmp")
1502    (set_attr "mode" "<X87MODEF:MODE>")
1503    (set_attr "athlon_decode" "vector")
1504    (set_attr "amdfam10_decode" "direct")
1505    (set_attr "bdver1_decode" "double")])
1507 ;; Push/pop instructions.
1509 (define_insn "*push<mode>2"
1510   [(set (match_operand:DWI 0 "push_operand" "=<")
1511         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1512   ""
1513   "#"
1514   [(set_attr "type" "multi")
1515    (set_attr "mode" "<MODE>")])
1517 (define_split
1518   [(set (match_operand:TI 0 "push_operand")
1519         (match_operand:TI 1 "general_operand"))]
1520   "TARGET_64BIT && reload_completed
1521    && !SSE_REG_P (operands[1])"
1522   [(const_int 0)]
1523   "ix86_split_long_move (operands); DONE;")
1525 (define_insn "*pushdi2_rex64"
1526   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1527         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1528   "TARGET_64BIT"
1529   "@
1530    push{q}\t%1
1531    #"
1532   [(set_attr "type" "push,multi")
1533    (set_attr "mode" "DI")])
1535 ;; Convert impossible pushes of immediate to existing instructions.
1536 ;; First try to get scratch register and go through it.  In case this
1537 ;; fails, push sign extended lower part first and then overwrite
1538 ;; upper part by 32bit move.
1539 (define_peephole2
1540   [(match_scratch:DI 2 "r")
1541    (set (match_operand:DI 0 "push_operand")
1542         (match_operand:DI 1 "immediate_operand"))]
1543   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1544    && !x86_64_immediate_operand (operands[1], DImode)"
1545   [(set (match_dup 2) (match_dup 1))
1546    (set (match_dup 0) (match_dup 2))])
1548 ;; We need to define this as both peepholer and splitter for case
1549 ;; peephole2 pass is not run.
1550 ;; "&& 1" is needed to keep it from matching the previous pattern.
1551 (define_peephole2
1552   [(set (match_operand:DI 0 "push_operand")
1553         (match_operand:DI 1 "immediate_operand"))]
1554   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1555    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1556   [(set (match_dup 0) (match_dup 1))
1557    (set (match_dup 2) (match_dup 3))]
1559   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1561   operands[1] = gen_lowpart (DImode, operands[2]);
1562   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1563                                                    GEN_INT (4)));
1566 (define_split
1567   [(set (match_operand:DI 0 "push_operand")
1568         (match_operand:DI 1 "immediate_operand"))]
1569   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1570                     ? epilogue_completed : reload_completed)
1571    && !symbolic_operand (operands[1], DImode)
1572    && !x86_64_immediate_operand (operands[1], DImode)"
1573   [(set (match_dup 0) (match_dup 1))
1574    (set (match_dup 2) (match_dup 3))]
1576   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1578   operands[1] = gen_lowpart (DImode, operands[2]);
1579   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1580                                                    GEN_INT (4)));
1583 (define_split
1584   [(set (match_operand:DI 0 "push_operand")
1585         (match_operand:DI 1 "general_operand"))]
1586   "!TARGET_64BIT && reload_completed
1587    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1588   [(const_int 0)]
1589   "ix86_split_long_move (operands); DONE;")
1591 (define_insn "*pushsi2"
1592   [(set (match_operand:SI 0 "push_operand" "=<")
1593         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1594   "!TARGET_64BIT"
1595   "push{l}\t%1"
1596   [(set_attr "type" "push")
1597    (set_attr "mode" "SI")])
1599 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1600 ;; "push a byte/word".  But actually we use pushl, which has the effect
1601 ;; of rounding the amount pushed up to a word.
1603 ;; For TARGET_64BIT we always round up to 8 bytes.
1604 (define_insn "*push<mode>2_rex64"
1605   [(set (match_operand:SWI124 0 "push_operand" "=X")
1606         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1607   "TARGET_64BIT"
1608   "push{q}\t%q1"
1609   [(set_attr "type" "push")
1610    (set_attr "mode" "DI")])
1612 (define_insn "*push<mode>2"
1613   [(set (match_operand:SWI12 0 "push_operand" "=X")
1614         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1615   "!TARGET_64BIT"
1616   "push{l}\t%k1"
1617   [(set_attr "type" "push")
1618    (set_attr "mode" "SI")])
1620 (define_insn "*push<mode>2_prologue"
1621   [(set (match_operand:W 0 "push_operand" "=<")
1622         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1623    (clobber (mem:BLK (scratch)))]
1624   ""
1625   "push{<imodesuffix>}\t%1"
1626   [(set_attr "type" "push")
1627    (set_attr "mode" "<MODE>")])
1629 (define_insn "*pop<mode>1"
1630   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1631         (match_operand:W 1 "pop_operand" ">"))]
1632   ""
1633   "pop{<imodesuffix>}\t%0"
1634   [(set_attr "type" "pop")
1635    (set_attr "mode" "<MODE>")])
1637 (define_insn "*pop<mode>1_epilogue"
1638   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1639         (match_operand:W 1 "pop_operand" ">"))
1640    (clobber (mem:BLK (scratch)))]
1641   ""
1642   "pop{<imodesuffix>}\t%0"
1643   [(set_attr "type" "pop")
1644    (set_attr "mode" "<MODE>")])
1646 ;; Move instructions.
1648 ;; Reload patterns to support multi-word load/store
1649 ;; with non-offsetable address.
1650 (define_expand "reload_noff_store"
1651   [(parallel [(match_operand 0 "memory_operand" "=m")
1652               (match_operand 1 "register_operand" "r")
1653               (match_operand:DI 2 "register_operand" "=&r")])]
1654   "TARGET_64BIT"
1656   rtx mem = operands[0];
1657   rtx addr = XEXP (mem, 0);
1659   emit_move_insn (operands[2], addr);
1660   mem = replace_equiv_address_nv (mem, operands[2]);
1662   emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1663   DONE;
1666 (define_expand "reload_noff_load"
1667   [(parallel [(match_operand 0 "register_operand" "=r")
1668               (match_operand 1 "memory_operand" "m")
1669               (match_operand:DI 2 "register_operand" "=r")])]
1670   "TARGET_64BIT"
1672   rtx mem = operands[1];
1673   rtx addr = XEXP (mem, 0);
1675   emit_move_insn (operands[2], addr);
1676   mem = replace_equiv_address_nv (mem, operands[2]);
1678   emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1679   DONE;
1682 (define_expand "movoi"
1683   [(set (match_operand:OI 0 "nonimmediate_operand")
1684         (match_operand:OI 1 "general_operand"))]
1685   "TARGET_AVX"
1686   "ix86_expand_move (OImode, operands); DONE;")
1688 (define_expand "movti"
1689   [(set (match_operand:TI 0 "nonimmediate_operand")
1690         (match_operand:TI 1 "nonimmediate_operand"))]
1691   "TARGET_64BIT || TARGET_SSE"
1693   if (TARGET_64BIT)
1694     ix86_expand_move (TImode, operands);
1695   else if (push_operand (operands[0], TImode))
1696     ix86_expand_push (TImode, operands[1]);
1697   else
1698     ix86_expand_vector_move (TImode, operands);
1699   DONE;
1702 ;; This expands to what emit_move_complex would generate if we didn't
1703 ;; have a movti pattern.  Having this avoids problems with reload on
1704 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1705 ;; to have around all the time.
1706 (define_expand "movcdi"
1707   [(set (match_operand:CDI 0 "nonimmediate_operand")
1708         (match_operand:CDI 1 "general_operand"))]
1709   ""
1711   if (push_operand (operands[0], CDImode))
1712     emit_move_complex_push (CDImode, operands[0], operands[1]);
1713   else
1714     emit_move_complex_parts (operands[0], operands[1]);
1715   DONE;
1718 (define_expand "mov<mode>"
1719   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1720         (match_operand:SWI1248x 1 "general_operand"))]
1721   ""
1722   "ix86_expand_move (<MODE>mode, operands); DONE;")
1724 (define_insn "*mov<mode>_xor"
1725   [(set (match_operand:SWI48 0 "register_operand" "=r")
1726         (match_operand:SWI48 1 "const0_operand"))
1727    (clobber (reg:CC FLAGS_REG))]
1728   "reload_completed"
1729   "xor{l}\t%k0, %k0"
1730   [(set_attr "type" "alu1")
1731    (set_attr "mode" "SI")
1732    (set_attr "length_immediate" "0")])
1734 (define_insn "*mov<mode>_or"
1735   [(set (match_operand:SWI48 0 "register_operand" "=r")
1736         (match_operand:SWI48 1 "const_int_operand"))
1737    (clobber (reg:CC FLAGS_REG))]
1738   "reload_completed
1739    && operands[1] == constm1_rtx"
1740   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1741   [(set_attr "type" "alu1")
1742    (set_attr "mode" "<MODE>")
1743    (set_attr "length_immediate" "1")])
1745 (define_insn "*movoi_internal_avx"
1746   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1747         (match_operand:OI 1 "vector_move_operand"  "C ,xm,x"))]
1748   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1750   switch (get_attr_type (insn))
1751     {
1752     case TYPE_SSELOG1:
1753       return standard_sse_constant_opcode (insn, operands[1]);
1755     case TYPE_SSEMOV:
1756       if (misaligned_operand (operands[0], OImode)
1757           || misaligned_operand (operands[1], OImode))
1758         {
1759           if (get_attr_mode (insn) == MODE_V8SF)
1760             return "vmovups\t{%1, %0|%0, %1}";
1761           else
1762             return "vmovdqu\t{%1, %0|%0, %1}";
1763         }
1764       else
1765         {
1766           if (get_attr_mode (insn) == MODE_V8SF)
1767             return "vmovaps\t{%1, %0|%0, %1}";
1768           else
1769             return "vmovdqa\t{%1, %0|%0, %1}";
1770         }
1772     default:
1773       gcc_unreachable ();
1774     }
1776   [(set_attr "type" "sselog1,ssemov,ssemov")
1777    (set_attr "prefix" "vex")
1778    (set (attr "mode")
1779         (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1780                  (const_string "V8SF")
1781                (and (eq_attr "alternative" "2")
1782                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1783                  (const_string "V8SF")
1784               ]
1785               (const_string "OI")))])
1787 (define_insn "*movti_internal"
1788   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1789         (match_operand:TI 1 "general_operand"      "riFo,re,C,xm,x"))]
1790   "(TARGET_64BIT || TARGET_SSE)
1791    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1793   switch (get_attr_type (insn))
1794     {
1795     case TYPE_MULTI:
1796       return "#";
1798     case TYPE_SSELOG1:
1799       return standard_sse_constant_opcode (insn, operands[1]);
1801     case TYPE_SSEMOV:
1802       /* TDmode values are passed as TImode on the stack.  Moving them
1803          to stack may result in unaligned memory access.  */
1804       if (misaligned_operand (operands[0], TImode)
1805           || misaligned_operand (operands[1], TImode))
1806         {
1807           if (get_attr_mode (insn) == MODE_V4SF)
1808             return "%vmovups\t{%1, %0|%0, %1}";
1809           else
1810             return "%vmovdqu\t{%1, %0|%0, %1}";
1811         }
1812       else
1813         {
1814           if (get_attr_mode (insn) == MODE_V4SF)
1815             return "%vmovaps\t{%1, %0|%0, %1}";
1816           else
1817             return "%vmovdqa\t{%1, %0|%0, %1}";
1818         }
1820     default:
1821       gcc_unreachable ();
1822     }
1824   [(set_attr "isa" "x64,x64,*,*,*")
1825    (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
1826    (set (attr "prefix")
1827      (if_then_else (eq_attr "type" "sselog1,ssemov")
1828        (const_string "maybe_vex")
1829        (const_string "orig")))
1830    (set (attr "mode")
1831         (cond [(eq_attr "alternative" "0,1")
1832                  (const_string "DI")
1833                (ior (not (match_test "TARGET_SSE2"))
1834                     (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1835                  (const_string "V4SF")
1836                (and (eq_attr "alternative" "4")
1837                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1838                  (const_string "V4SF")
1839                (match_test "TARGET_AVX")
1840                  (const_string "TI")
1841                (match_test "optimize_function_for_size_p (cfun)")
1842                  (const_string "V4SF")
1843                ]
1844                (const_string "TI")))])
1846 (define_split
1847   [(set (match_operand:TI 0 "nonimmediate_operand")
1848         (match_operand:TI 1 "general_operand"))]
1849   "reload_completed
1850    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1851   [(const_int 0)]
1852   "ix86_split_long_move (operands); DONE;")
1854 (define_insn "*movdi_internal"
1855   [(set (match_operand:DI 0 "nonimmediate_operand"
1856     "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*x,*x,*x,m ,?r ,?r,?*Yi,?*Ym,?*Yi")
1857         (match_operand:DI 1 "general_operand"
1858     "riFo,riF,Z,rem,i,re,C ,*y,m  ,*y,*Yn,r   ,C ,*x,m ,*x,*Yj,*x,r   ,*Yj ,*Yn"))]
1859   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1861   switch (get_attr_type (insn))
1862     {
1863     case TYPE_MULTI:
1864       return "#";
1866     case TYPE_MMX:
1867       return "pxor\t%0, %0";
1869     case TYPE_MMXMOV:
1870 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
1871       /* Handle broken assemblers that require movd instead of movq.  */
1872       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1873         return "movd\t{%1, %0|%0, %1}";
1874 #endif
1875       return "movq\t{%1, %0|%0, %1}";
1877     case TYPE_SSELOG1:
1878       if (GENERAL_REG_P (operands[0]))
1879         return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
1881       return standard_sse_constant_opcode (insn, operands[1]);
1883     case TYPE_SSEMOV:
1884       switch (get_attr_mode (insn))
1885         {
1886         case MODE_DI:
1887 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
1888           /* Handle broken assemblers that require movd instead of movq.  */
1889           if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1890             return "%vmovd\t{%1, %0|%0, %1}";
1891 #endif
1892           return "%vmovq\t{%1, %0|%0, %1}";
1893         case MODE_TI:
1894           return "%vmovdqa\t{%1, %0|%0, %1}";
1896         case MODE_V2SF:
1897           gcc_assert (!TARGET_AVX);
1898           return "movlps\t{%1, %0|%0, %1}";
1899         case MODE_V4SF:
1900           return "%vmovaps\t{%1, %0|%0, %1}";
1902         default:
1903           gcc_unreachable ();
1904         }
1906     case TYPE_SSECVT:
1907       if (SSE_REG_P (operands[0]))
1908         return "movq2dq\t{%1, %0|%0, %1}";
1909       else
1910         return "movdq2q\t{%1, %0|%0, %1}";
1912     case TYPE_LEA:
1913       return "lea{q}\t{%E1, %0|%0, %E1}";
1915     case TYPE_IMOV:
1916       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1917       if (get_attr_mode (insn) == MODE_SI)
1918         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1919       else if (which_alternative == 4)
1920         return "movabs{q}\t{%1, %0|%0, %1}";
1921       else if (ix86_use_lea_for_mov (insn, operands))
1922         return "lea{q}\t{%E1, %0|%0, %E1}";
1923       else
1924         return "mov{q}\t{%1, %0|%0, %1}";
1926     default:
1927       gcc_unreachable ();
1928     }
1930   [(set (attr "isa")
1931      (cond [(eq_attr "alternative" "0,1")
1932               (const_string "nox64")
1933             (eq_attr "alternative" "2,3,4,5,10,11,16,18")
1934               (const_string "x64")
1935             (eq_attr "alternative" "17")
1936               (const_string "x64_sse4")
1937            ]
1938            (const_string "*")))
1939    (set (attr "type")
1940      (cond [(eq_attr "alternative" "0,1")
1941               (const_string "multi")
1942             (eq_attr "alternative" "6")
1943               (const_string "mmx")
1944             (eq_attr "alternative" "7,8,9,10,11")
1945               (const_string "mmxmov")
1946             (eq_attr "alternative" "12,17")
1947               (const_string "sselog1")
1948             (eq_attr "alternative" "13,14,15,16,18")
1949               (const_string "ssemov")
1950             (eq_attr "alternative" "19,20")
1951               (const_string "ssecvt")
1952             (match_operand 1 "pic_32bit_operand")
1953               (const_string "lea")
1954            ]
1955            (const_string "imov")))
1956    (set (attr "modrm")
1957      (if_then_else
1958        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
1959          (const_string "0")
1960          (const_string "*")))
1961    (set (attr "length_immediate")
1962      (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
1963               (const_string "8")
1964             (eq_attr "alternative" "17")
1965               (const_string "1")
1966            ]
1967            (const_string "*")))
1968    (set (attr "prefix_rex")
1969      (if_then_else (eq_attr "alternative" "10,11,16,17,18")
1970        (const_string "1")
1971        (const_string "*")))
1972    (set (attr "prefix_extra")
1973      (if_then_else (eq_attr "alternative" "17")
1974        (const_string "1")
1975        (const_string "*")))
1976    (set (attr "prefix")
1977      (if_then_else (eq_attr "type" "sselog1,ssemov")
1978        (const_string "maybe_vex")
1979        (const_string "orig")))
1980    (set (attr "prefix_data16")
1981      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
1982        (const_string "1")
1983        (const_string "*")))
1984    (set (attr "mode")
1985      (cond [(eq_attr "alternative" "2")
1986               (const_string "SI")
1987             (eq_attr "alternative" "12,13")
1988               (cond [(ior (not (match_test "TARGET_SSE2"))
1989                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1990                        (const_string "V4SF")
1991                      (match_test "TARGET_AVX")
1992                        (const_string "TI")
1993                      (match_test "optimize_function_for_size_p (cfun)")
1994                        (const_string "V4SF")
1995                     ]
1996                     (const_string "TI"))
1998             (and (eq_attr "alternative" "14,15")
1999                  (not (match_test "TARGET_SSE2")))
2000               (const_string "V2SF")
2001             (eq_attr "alternative" "17")
2002               (const_string "TI")
2003            ]
2004            (const_string "DI")))])
2006 (define_split
2007   [(set (match_operand:DI 0 "nonimmediate_operand")
2008         (match_operand:DI 1 "general_operand"))]
2009   "!TARGET_64BIT && reload_completed
2010    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2011    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2012   [(const_int 0)]
2013   "ix86_split_long_move (operands); DONE;")
2015 (define_insn "*movsi_internal"
2016   [(set (match_operand:SI 0 "nonimmediate_operand"
2017                         "=r,m ,*y,*y,?rm,?*y,*x,*x,*x,m ,?r ,?r,?*Yi")
2018         (match_operand:SI 1 "general_operand"
2019                         "g ,re,C ,*y,*y ,rm ,C ,*x,m ,*x,*Yj,*x,r"))]
2020   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2022   switch (get_attr_type (insn))
2023     {
2024     case TYPE_SSELOG1:
2025       if (GENERAL_REG_P (operands[0]))
2026         return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2028       return standard_sse_constant_opcode (insn, operands[1]);
2030     case TYPE_SSEMOV:
2031       switch (get_attr_mode (insn))
2032         {
2033         case MODE_SI:
2034           return "%vmovd\t{%1, %0|%0, %1}";
2035         case MODE_TI:
2036           return "%vmovdqa\t{%1, %0|%0, %1}";
2038         case MODE_V4SF:
2039           return "%vmovaps\t{%1, %0|%0, %1}";
2041         case MODE_SF:
2042           gcc_assert (!TARGET_AVX);
2043           return "movss\t{%1, %0|%0, %1}";
2045         default:
2046           gcc_unreachable ();
2047         }
2049     case TYPE_MMX:
2050       return "pxor\t%0, %0";
2052     case TYPE_MMXMOV:
2053       switch (get_attr_mode (insn))
2054         {
2055         case MODE_DI:
2056           return "movq\t{%1, %0|%0, %1}";
2057         case MODE_SI:
2058           return "movd\t{%1, %0|%0, %1}";
2060         default:
2061           gcc_unreachable ();
2062         }
2064     case TYPE_LEA:
2065       return "lea{l}\t{%E1, %0|%0, %E1}";
2067     case TYPE_IMOV:
2068       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2069       if (ix86_use_lea_for_mov (insn, operands))
2070         return "lea{l}\t{%E1, %0|%0, %E1}";
2071       else
2072         return "mov{l}\t{%1, %0|%0, %1}";
2074     default:
2075       gcc_unreachable ();
2076     }
2078   [(set (attr "isa")
2079      (if_then_else (eq_attr "alternative" "11")
2080        (const_string "sse4")
2081        (const_string "*")))
2082    (set (attr "type")
2083      (cond [(eq_attr "alternative" "2")
2084               (const_string "mmx")
2085             (eq_attr "alternative" "3,4,5")
2086               (const_string "mmxmov")
2087             (eq_attr "alternative" "6,11")
2088               (const_string "sselog1")
2089             (eq_attr "alternative" "7,8,9,10,12")
2090               (const_string "ssemov")
2091             (match_operand 1 "pic_32bit_operand")
2092               (const_string "lea")
2093            ]
2094            (const_string "imov")))
2095    (set (attr "length_immediate")
2096      (if_then_else (eq_attr "alternative" "11")
2097        (const_string "1")
2098        (const_string "*")))
2099    (set (attr "prefix_extra")
2100      (if_then_else (eq_attr "alternative" "11")
2101        (const_string "1")
2102        (const_string "*")))
2103    (set (attr "prefix")
2104      (if_then_else (eq_attr "type" "sselog1,ssemov")
2105        (const_string "maybe_vex")
2106        (const_string "orig")))
2107    (set (attr "prefix_data16")
2108      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2109        (const_string "1")
2110        (const_string "*")))
2111    (set (attr "mode")
2112      (cond [(eq_attr "alternative" "2,3")
2113               (const_string "DI")
2114             (eq_attr "alternative" "6,7")
2115               (cond [(ior (not (match_test "TARGET_SSE2"))
2116                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2117                        (const_string "V4SF")
2118                      (match_test "TARGET_AVX")
2119                        (const_string "TI")
2120                      (match_test "optimize_function_for_size_p (cfun)")
2121                        (const_string "V4SF")
2122                     ]
2123                     (const_string "TI"))
2125             (and (eq_attr "alternative" "8,9")
2126                  (not (match_test "TARGET_SSE2")))
2127               (const_string "SF")
2128             (eq_attr "alternative" "11")
2129               (const_string "TI")
2130            ]
2131            (const_string "SI")))])
2133 (define_insn "*movhi_internal"
2134   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m")
2135         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn"))]
2136   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2138   switch (get_attr_type (insn))
2139     {
2140     case TYPE_IMOVX:
2141       /* movzwl is faster than movw on p2 due to partial word stalls,
2142          though not as fast as an aligned movl.  */
2143       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2144     default:
2145       if (get_attr_mode (insn) == MODE_SI)
2146         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2147       else
2148         return "mov{w}\t{%1, %0|%0, %1}";
2149     }
2151   [(set (attr "type")
2152      (cond [(match_test "optimize_function_for_size_p (cfun)")
2153               (const_string "imov")
2154             (and (eq_attr "alternative" "0")
2155                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2156                       (not (match_test "TARGET_HIMODE_MATH"))))
2157               (const_string "imov")
2158             (and (eq_attr "alternative" "1,2")
2159                  (match_operand:HI 1 "aligned_operand"))
2160               (const_string "imov")
2161             (and (match_test "TARGET_MOVX")
2162                  (eq_attr "alternative" "0,2"))
2163               (const_string "imovx")
2164            ]
2165            (const_string "imov")))
2166     (set (attr "mode")
2167       (cond [(eq_attr "type" "imovx")
2168                (const_string "SI")
2169              (and (eq_attr "alternative" "1,2")
2170                   (match_operand:HI 1 "aligned_operand"))
2171                (const_string "SI")
2172              (and (eq_attr "alternative" "0")
2173                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2174                        (not (match_test "TARGET_HIMODE_MATH"))))
2175                (const_string "SI")
2176             ]
2177             (const_string "HI")))])
2179 ;; Situation is quite tricky about when to choose full sized (SImode) move
2180 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2181 ;; partial register dependency machines (such as AMD Athlon), where QImode
2182 ;; moves issue extra dependency and for partial register stalls machines
2183 ;; that don't use QImode patterns (and QImode move cause stall on the next
2184 ;; instruction).
2186 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2187 ;; register stall machines with, where we use QImode instructions, since
2188 ;; partial register stall can be caused there.  Then we use movzx.
2189 (define_insn "*movqi_internal"
2190   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2191         (match_operand:QI 1 "general_operand"      "q ,qn,qm,q,rn,qm,qn"))]
2192   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2194   switch (get_attr_type (insn))
2195     {
2196     case TYPE_IMOVX:
2197       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2198       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2199     default:
2200       if (get_attr_mode (insn) == MODE_SI)
2201         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2202       else
2203         return "mov{b}\t{%1, %0|%0, %1}";
2204     }
2206   [(set (attr "type")
2207      (cond [(and (eq_attr "alternative" "5")
2208                  (not (match_operand:QI 1 "aligned_operand")))
2209               (const_string "imovx")
2210             (match_test "optimize_function_for_size_p (cfun)")
2211               (const_string "imov")
2212             (and (eq_attr "alternative" "3")
2213                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2214                       (not (match_test "TARGET_QIMODE_MATH"))))
2215               (const_string "imov")
2216             (eq_attr "alternative" "3,5")
2217               (const_string "imovx")
2218             (and (match_test "TARGET_MOVX")
2219                  (eq_attr "alternative" "2"))
2220               (const_string "imovx")
2221            ]
2222            (const_string "imov")))
2223    (set (attr "mode")
2224       (cond [(eq_attr "alternative" "3,4,5")
2225                (const_string "SI")
2226              (eq_attr "alternative" "6")
2227                (const_string "QI")
2228              (eq_attr "type" "imovx")
2229                (const_string "SI")
2230              (and (eq_attr "type" "imov")
2231                   (and (eq_attr "alternative" "0,1")
2232                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2233                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2234                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2235                (const_string "SI")
2236              ;; Avoid partial register stalls when not using QImode arithmetic
2237              (and (eq_attr "type" "imov")
2238                   (and (eq_attr "alternative" "0,1")
2239                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2240                             (not (match_test "TARGET_QIMODE_MATH")))))
2241                (const_string "SI")
2242            ]
2243            (const_string "QI")))])
2245 ;; Stores and loads of ax to arbitrary constant address.
2246 ;; We fake an second form of instruction to force reload to load address
2247 ;; into register when rax is not available
2248 (define_insn "*movabs<mode>_1"
2249   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2250         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2251   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2252   "@
2253    movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2254    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2255   [(set_attr "type" "imov")
2256    (set_attr "modrm" "0,*")
2257    (set_attr "length_address" "8,0")
2258    (set_attr "length_immediate" "0,*")
2259    (set_attr "memory" "store")
2260    (set_attr "mode" "<MODE>")])
2262 (define_insn "*movabs<mode>_2"
2263   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2264         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2265   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2266   "@
2267    movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2268    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2269   [(set_attr "type" "imov")
2270    (set_attr "modrm" "0,*")
2271    (set_attr "length_address" "8,0")
2272    (set_attr "length_immediate" "0")
2273    (set_attr "memory" "load")
2274    (set_attr "mode" "<MODE>")])
2276 (define_insn "swap<mode>"
2277   [(set (match_operand:SWI48 0 "register_operand" "+r")
2278         (match_operand:SWI48 1 "register_operand" "+r"))
2279    (set (match_dup 1)
2280         (match_dup 0))]
2281   ""
2282   "xchg{<imodesuffix>}\t%1, %0"
2283   [(set_attr "type" "imov")
2284    (set_attr "mode" "<MODE>")
2285    (set_attr "pent_pair" "np")
2286    (set_attr "athlon_decode" "vector")
2287    (set_attr "amdfam10_decode" "double")
2288    (set_attr "bdver1_decode" "double")])
2290 (define_insn "*swap<mode>_1"
2291   [(set (match_operand:SWI12 0 "register_operand" "+r")
2292         (match_operand:SWI12 1 "register_operand" "+r"))
2293    (set (match_dup 1)
2294         (match_dup 0))]
2295   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2296   "xchg{l}\t%k1, %k0"
2297   [(set_attr "type" "imov")
2298    (set_attr "mode" "SI")
2299    (set_attr "pent_pair" "np")
2300    (set_attr "athlon_decode" "vector")
2301    (set_attr "amdfam10_decode" "double")
2302    (set_attr "bdver1_decode" "double")])
2304 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2305 ;; is disabled for AMDFAM10
2306 (define_insn "*swap<mode>_2"
2307   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2308         (match_operand:SWI12 1 "register_operand" "+<r>"))
2309    (set (match_dup 1)
2310         (match_dup 0))]
2311   "TARGET_PARTIAL_REG_STALL"
2312   "xchg{<imodesuffix>}\t%1, %0"
2313   [(set_attr "type" "imov")
2314    (set_attr "mode" "<MODE>")
2315    (set_attr "pent_pair" "np")
2316    (set_attr "athlon_decode" "vector")])
2318 (define_expand "movstrict<mode>"
2319   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2320         (match_operand:SWI12 1 "general_operand"))]
2321   ""
2323   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2324     FAIL;
2325   if (GET_CODE (operands[0]) == SUBREG
2326       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2327     FAIL;
2328   /* Don't generate memory->memory moves, go through a register */
2329   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2330     operands[1] = force_reg (<MODE>mode, operands[1]);
2333 (define_insn "*movstrict<mode>_1"
2334   [(set (strict_low_part
2335           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2336         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2337   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2338    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2339   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2340   [(set_attr "type" "imov")
2341    (set_attr "mode" "<MODE>")])
2343 (define_insn "*movstrict<mode>_xor"
2344   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2345         (match_operand:SWI12 1 "const0_operand"))
2346    (clobber (reg:CC FLAGS_REG))]
2347   "reload_completed"
2348   "xor{<imodesuffix>}\t%0, %0"
2349   [(set_attr "type" "alu1")
2350    (set_attr "mode" "<MODE>")
2351    (set_attr "length_immediate" "0")])
2353 (define_insn "*mov<mode>_extv_1"
2354   [(set (match_operand:SWI24 0 "register_operand" "=R")
2355         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2356                             (const_int 8)
2357                             (const_int 8)))]
2358   ""
2359   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2360   [(set_attr "type" "imovx")
2361    (set_attr "mode" "SI")])
2363 (define_insn "*movqi_extv_1"
2364   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2365         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2366                          (const_int 8)
2367                          (const_int 8)))]
2368   ""
2370   switch (get_attr_type (insn))
2371     {
2372     case TYPE_IMOVX:
2373       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2374     default:
2375       return "mov{b}\t{%h1, %0|%0, %h1}";
2376     }
2378   [(set_attr "isa" "*,*,nox64")
2379    (set (attr "type")
2380      (if_then_else (and (match_operand:QI 0 "register_operand")
2381                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2382                              (match_test "TARGET_MOVX")))
2383         (const_string "imovx")
2384         (const_string "imov")))
2385    (set (attr "mode")
2386      (if_then_else (eq_attr "type" "imovx")
2387         (const_string "SI")
2388         (const_string "QI")))])
2390 (define_insn "*mov<mode>_extzv_1"
2391   [(set (match_operand:SWI48 0 "register_operand" "=R")
2392         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2393                             (const_int 8)
2394                             (const_int 8)))]
2395   ""
2396   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2397   [(set_attr "type" "imovx")
2398    (set_attr "mode" "SI")])
2400 (define_insn "*movqi_extzv_2"
2401   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2402         (subreg:QI
2403           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2404                            (const_int 8)
2405                            (const_int 8)) 0))]
2406   ""
2408   switch (get_attr_type (insn))
2409     {
2410     case TYPE_IMOVX:
2411       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2412     default:
2413       return "mov{b}\t{%h1, %0|%0, %h1}";
2414     }
2416   [(set_attr "isa" "*,*,nox64")
2417    (set (attr "type")
2418      (if_then_else (and (match_operand:QI 0 "register_operand")
2419                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2420                              (match_test "TARGET_MOVX")))
2421         (const_string "imovx")
2422         (const_string "imov")))
2423    (set (attr "mode")
2424      (if_then_else (eq_attr "type" "imovx")
2425         (const_string "SI")
2426         (const_string "QI")))])
2428 (define_insn "mov<mode>_insv_1"
2429   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2430                              (const_int 8)
2431                              (const_int 8))
2432         (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2433   ""
2435   if (CONST_INT_P (operands[1]))
2436     operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2437   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2439   [(set_attr "isa" "*,nox64")
2440    (set_attr "type" "imov")
2441    (set_attr "mode" "QI")])
2443 (define_insn "*movqi_insv_2"
2444   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2445                          (const_int 8)
2446                          (const_int 8))
2447         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2448                      (const_int 8)))]
2449   ""
2450   "mov{b}\t{%h1, %h0|%h0, %h1}"
2451   [(set_attr "type" "imov")
2452    (set_attr "mode" "QI")])
2454 ;; Floating point push instructions.
2456 (define_insn "*pushtf"
2457   [(set (match_operand:TF 0 "push_operand" "=<,<")
2458         (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2459   "TARGET_64BIT || TARGET_SSE"
2461   /* This insn should be already split before reg-stack.  */
2462   gcc_unreachable ();
2464   [(set_attr "isa" "*,x64")
2465    (set_attr "type" "multi")
2466    (set_attr "unit" "sse,*")
2467    (set_attr "mode" "TF,DI")])
2469 ;; %%% Kill this when call knows how to work this out.
2470 (define_split
2471   [(set (match_operand:TF 0 "push_operand")
2472         (match_operand:TF 1 "sse_reg_operand"))]
2473   "TARGET_SSE && reload_completed"
2474   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2475    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2477 (define_insn "*pushxf"
2478   [(set (match_operand:XF 0 "push_operand" "=<,<")
2479         (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2480   ""
2482   /* This insn should be already split before reg-stack.  */
2483   gcc_unreachable ();
2485   [(set_attr "type" "multi")
2486    (set_attr "unit" "i387,*")
2487    (set (attr "mode")
2488         (cond [(eq_attr "alternative" "1")
2489                  (if_then_else (match_test "TARGET_64BIT")
2490                    (const_string "DI")
2491                    (const_string "SI"))
2492               ]
2493               (const_string "XF")))])
2495 ;; %%% Kill this when call knows how to work this out.
2496 (define_split
2497   [(set (match_operand:XF 0 "push_operand")
2498         (match_operand:XF 1 "fp_register_operand"))]
2499   "reload_completed"
2500   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2501    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2502   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2504 (define_insn "*pushdf"
2505   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2506         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2507   ""
2509   /* This insn should be already split before reg-stack.  */
2510   gcc_unreachable ();
2512   [(set_attr "isa" "*,nox64,x64,sse2")
2513    (set_attr "type" "multi")
2514    (set_attr "unit" "i387,*,*,sse")
2515    (set_attr "mode" "DF,SI,DI,DF")])
2517 ;; %%% Kill this when call knows how to work this out.
2518 (define_split
2519   [(set (match_operand:DF 0 "push_operand")
2520         (match_operand:DF 1 "any_fp_register_operand"))]
2521   "reload_completed"
2522   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2523    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2525 (define_insn "*pushsf_rex64"
2526   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2527         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2528   "TARGET_64BIT"
2530   /* Anything else should be already split before reg-stack.  */
2531   gcc_assert (which_alternative == 1);
2532   return "push{q}\t%q1";
2534   [(set_attr "type" "multi,push,multi")
2535    (set_attr "unit" "i387,*,*")
2536    (set_attr "mode" "SF,DI,SF")])
2538 (define_insn "*pushsf"
2539   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2540         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2541   "!TARGET_64BIT"
2543   /* Anything else should be already split before reg-stack.  */
2544   gcc_assert (which_alternative == 1);
2545   return "push{l}\t%1";
2547   [(set_attr "type" "multi,push,multi")
2548    (set_attr "unit" "i387,*,*")
2549    (set_attr "mode" "SF,SI,SF")])
2551 ;; %%% Kill this when call knows how to work this out.
2552 (define_split
2553   [(set (match_operand:SF 0 "push_operand")
2554         (match_operand:SF 1 "any_fp_register_operand"))]
2555   "reload_completed"
2556   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2557    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2558   "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2560 (define_split
2561   [(set (match_operand:SF 0 "push_operand")
2562         (match_operand:SF 1 "memory_operand"))]
2563   "reload_completed
2564    && (operands[2] = find_constant_src (insn))"
2565   [(set (match_dup 0) (match_dup 2))])
2567 (define_split
2568   [(set (match_operand 0 "push_operand")
2569         (match_operand 1 "general_operand"))]
2570   "reload_completed
2571    && (GET_MODE (operands[0]) == TFmode
2572        || GET_MODE (operands[0]) == XFmode
2573        || GET_MODE (operands[0]) == DFmode)
2574    && !ANY_FP_REG_P (operands[1])"
2575   [(const_int 0)]
2576   "ix86_split_long_move (operands); DONE;")
2578 ;; Floating point move instructions.
2580 (define_expand "movtf"
2581   [(set (match_operand:TF 0 "nonimmediate_operand")
2582         (match_operand:TF 1 "nonimmediate_operand"))]
2583   "TARGET_64BIT || TARGET_SSE"
2584   "ix86_expand_move (TFmode, operands); DONE;")
2586 (define_expand "mov<mode>"
2587   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2588         (match_operand:X87MODEF 1 "general_operand"))]
2589   ""
2590   "ix86_expand_move (<MODE>mode, operands); DONE;")
2592 (define_insn "*movtf_internal"
2593   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2594         (match_operand:TF 1 "general_operand"      "C ,xm,x,*roF,*rC"))]
2595   "(TARGET_64BIT || TARGET_SSE)
2596    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2597    && (!can_create_pseudo_p ()
2598        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2599        || GET_CODE (operands[1]) != CONST_DOUBLE
2600        || (optimize_function_for_size_p (cfun)
2601            && standard_sse_constant_p (operands[1])
2602            && !memory_operand (operands[0], TFmode))
2603        || (!TARGET_MEMORY_MISMATCH_STALL
2604            && memory_operand (operands[0], TFmode)))"
2606   switch (get_attr_type (insn))
2607     {
2608     case TYPE_SSELOG1:
2609       return standard_sse_constant_opcode (insn, operands[1]);
2611     case TYPE_SSEMOV:
2612       /* Handle misaligned load/store since we
2613          don't have movmisaligntf pattern. */
2614       if (misaligned_operand (operands[0], TFmode)
2615           || misaligned_operand (operands[1], TFmode))
2616         {
2617           if (get_attr_mode (insn) == MODE_V4SF)
2618             return "%vmovups\t{%1, %0|%0, %1}";
2619           else
2620             return "%vmovdqu\t{%1, %0|%0, %1}";
2621         }
2622       else
2623         {
2624           if (get_attr_mode (insn) == MODE_V4SF)
2625             return "%vmovaps\t{%1, %0|%0, %1}";
2626           else
2627             return "%vmovdqa\t{%1, %0|%0, %1}";
2628         }
2630     case TYPE_MULTI:
2631         return "#";
2633     default:
2634       gcc_unreachable ();
2635     }
2637   [(set_attr "isa" "*,*,*,x64,x64")
2638    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2639    (set (attr "prefix")
2640      (if_then_else (eq_attr "type" "sselog1,ssemov")
2641        (const_string "maybe_vex")
2642        (const_string "orig")))
2643    (set (attr "mode")
2644         (cond [(eq_attr "alternative" "3,4")
2645                  (const_string "DI")
2646                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2647                  (const_string "V4SF")
2648                (and (eq_attr "alternative" "2")
2649                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2650                  (const_string "V4SF")
2651                (match_test "TARGET_AVX")
2652                  (const_string "TI")
2653                (ior (not (match_test "TARGET_SSE2"))
2654                     (match_test "optimize_function_for_size_p (cfun)"))
2655                  (const_string "V4SF")
2656                ]
2657                (const_string "TI")))])
2659 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2660 (define_insn "*movxf_internal"
2661   [(set (match_operand:XF 0 "nonimmediate_operand"
2662          "=f,m,f,?Yx*r ,!o   ,!o")
2663         (match_operand:XF 1 "general_operand"
2664          "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2665   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2666    && (!can_create_pseudo_p ()
2667        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2668        || GET_CODE (operands[1]) != CONST_DOUBLE
2669        || (optimize_function_for_size_p (cfun)
2670            && standard_80387_constant_p (operands[1]) > 0
2671            && !memory_operand (operands[0], XFmode))
2672        || (!TARGET_MEMORY_MISMATCH_STALL
2673            && memory_operand (operands[0], XFmode)))"
2675   switch (get_attr_type (insn))
2676     {
2677     case TYPE_FMOV:
2678       if (which_alternative == 2)
2679         return standard_80387_constant_opcode (operands[1]);
2680       return output_387_reg_move (insn, operands);
2682     case TYPE_MULTI:
2683       return "#";
2685     default:
2686       gcc_unreachable ();
2687     }
2689   [(set_attr "isa" "*,*,*,*,nox64,x64")
2690    (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
2691    (set (attr "mode")
2692         (cond [(eq_attr "alternative" "3,4,5")
2693                  (if_then_else (match_test "TARGET_64BIT")
2694                    (const_string "DI")
2695                    (const_string "SI"))
2696               ]
2697               (const_string "XF")))])
2699 ;; Possible store forwarding (partial memory) stall in alternative 4.
2700 (define_insn "*movdf_internal"
2701   [(set (match_operand:DF 0 "nonimmediate_operand"
2702     "=Yf*f,m   ,Yf*f,?Yd*r ,!o   ,?r,?m,?r,?r,x,x,x,m,*x,*x,*x,m ,r ,Yi")
2703         (match_operand:DF 1 "general_operand"
2704     "Yf*fm,Yf*f,G   ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,x,m,x,C ,*x,m ,*x,Yj,r"))]
2705   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2706    && (!can_create_pseudo_p ()
2707        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2708        || GET_CODE (operands[1]) != CONST_DOUBLE
2709        || (optimize_function_for_size_p (cfun)
2710            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2711                 && standard_80387_constant_p (operands[1]) > 0)
2712                || (TARGET_SSE2 && TARGET_SSE_MATH
2713                    && standard_sse_constant_p (operands[1])))
2714            && !memory_operand (operands[0], DFmode))
2715        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
2716            && memory_operand (operands[0], DFmode)))"
2718   switch (get_attr_type (insn))
2719     {
2720     case TYPE_FMOV:
2721       if (which_alternative == 2)
2722         return standard_80387_constant_opcode (operands[1]);
2723       return output_387_reg_move (insn, operands);
2725     case TYPE_MULTI:
2726       return "#";
2728     case TYPE_IMOV:
2729       if (get_attr_mode (insn) == MODE_SI)
2730         return "mov{l}\t{%1, %k0|%k0, %1}";
2731       else if (which_alternative == 8)
2732         return "movabs{q}\t{%1, %0|%0, %1}";
2733       else
2734         return "mov{q}\t{%1, %0|%0, %1}";
2736     case TYPE_SSELOG1:
2737       return standard_sse_constant_opcode (insn, operands[1]);
2739     case TYPE_SSEMOV:
2740       switch (get_attr_mode (insn))
2741         {
2742         case MODE_DF:
2743           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2744             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2745           return "%vmovsd\t{%1, %0|%0, %1}";
2747         case MODE_V4SF:
2748           return "%vmovaps\t{%1, %0|%0, %1}";
2749         case MODE_V2DF:
2750           return "%vmovapd\t{%1, %0|%0, %1}";
2752         case MODE_V2SF:
2753           gcc_assert (!TARGET_AVX);
2754           return "movlps\t{%1, %0|%0, %1}";
2755         case MODE_V1DF:
2756           gcc_assert (!TARGET_AVX);
2757           return "movlpd\t{%1, %0|%0, %1}";
2759         case MODE_DI:
2760 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
2761           /* Handle broken assemblers that require movd instead of movq.  */
2762           if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2763             return "%vmovd\t{%1, %0|%0, %1}";
2764 #endif
2765           return "%vmovq\t{%1, %0|%0, %1}";
2767         default:
2768           gcc_unreachable ();
2769         }
2771     default:
2772       gcc_unreachable ();
2773     }
2775   [(set (attr "isa")
2776         (cond [(eq_attr "alternative" "3,4")
2777                  (const_string "nox64")
2778                (eq_attr "alternative" "5,6,7,8,17,18")
2779                  (const_string "x64")
2780                (eq_attr "alternative" "9,10,11,12")
2781                  (const_string "sse2")
2782               ]
2783               (const_string "*")))
2784    (set (attr "type")
2785         (cond [(eq_attr "alternative" "0,1,2")
2786                  (const_string "fmov")
2787                (eq_attr "alternative" "3,4")
2788                  (const_string "multi")
2789                (eq_attr "alternative" "5,6,7,8")
2790                  (const_string "imov")
2791                (eq_attr "alternative" "9,13")
2792                  (const_string "sselog1")
2793               ]
2794               (const_string "ssemov")))
2795    (set (attr "modrm")
2796      (if_then_else (eq_attr "alternative" "8")
2797        (const_string "0")
2798        (const_string "*")))
2799    (set (attr "length_immediate")
2800      (if_then_else (eq_attr "alternative" "8")
2801        (const_string "8")
2802        (const_string "*")))
2803    (set (attr "prefix")
2804      (if_then_else (eq_attr "type" "sselog1,ssemov")
2805        (const_string "maybe_vex")
2806        (const_string "orig")))
2807    (set (attr "prefix_data16")
2808      (if_then_else
2809        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2810             (eq_attr "mode" "V1DF"))
2811        (const_string "1")
2812        (const_string "*")))
2813    (set (attr "mode")
2814         (cond [(eq_attr "alternative" "3,4,7")
2815                  (const_string "SI")
2816                (eq_attr "alternative" "5,6,8,17,18")
2817                  (const_string "DI")
2819                /* xorps is one byte shorter for non-AVX targets.  */
2820                (eq_attr "alternative" "9,13")
2821                  (cond [(not (match_test "TARGET_SSE2"))
2822                           (const_string "V4SF")
2823                         (match_test "TARGET_AVX")
2824                           (const_string "V2DF")
2825                         (match_test "optimize_function_for_size_p (cfun)")
2826                           (const_string "V4SF")
2827                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
2828                           (const_string "TI")
2829                        ]
2830                        (const_string "V2DF"))
2832                /* For architectures resolving dependencies on
2833                   whole SSE registers use movapd to break dependency
2834                   chains, otherwise use short move to avoid extra work.  */
2836                /* movaps is one byte shorter for non-AVX targets.  */
2837                (eq_attr "alternative" "10,14")
2838                  (cond [(ior (not (match_test "TARGET_SSE2"))
2839                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2840                           (const_string "V4SF")
2841                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2842                           (const_string "V2DF")
2843                         (match_test "TARGET_AVX")
2844                           (const_string "DF")
2845                         (match_test "optimize_function_for_size_p (cfun)")
2846                           (const_string "V4SF")
2847                        ]
2848                        (const_string "DF"))
2850                /* For architectures resolving dependencies on register
2851                   parts we may avoid extra work to zero out upper part
2852                   of register.  */
2853                (eq_attr "alternative" "11,15")
2854                  (cond [(not (match_test "TARGET_SSE2"))
2855                           (const_string "V2SF")
2856                         (match_test "TARGET_AVX")
2857                           (const_string "DF")
2858                         (match_test "TARGET_SSE_SPLIT_REGS")
2859                           (const_string "V1DF")
2860                        ]
2861                        (const_string "DF"))
2863                (and (eq_attr "alternative" "12,16")
2864                     (not (match_test "TARGET_SSE2")))
2865                  (const_string "V2SF")
2866               ]
2867               (const_string "DF")))])
2869 (define_insn "*movsf_internal"
2870   [(set (match_operand:SF 0 "nonimmediate_operand"
2871           "=Yf*f,m   ,Yf*f,?r ,?m,x,x,x,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
2872         (match_operand:SF 1 "general_operand"
2873           "Yf*fm,Yf*f,G   ,rmF,rF,C,x,m,x,Yj,r  ,*y ,m  ,*y,*Yn,r"))]
2874   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2875    && (!can_create_pseudo_p ()
2876        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2877        || GET_CODE (operands[1]) != CONST_DOUBLE
2878        || (optimize_function_for_size_p (cfun)
2879            && ((!TARGET_SSE_MATH
2880                 && standard_80387_constant_p (operands[1]) > 0)
2881                || (TARGET_SSE_MATH
2882                    && standard_sse_constant_p (operands[1]))))
2883        || memory_operand (operands[0], SFmode))"
2885   switch (get_attr_type (insn))
2886     {
2887     case TYPE_FMOV:
2888       if (which_alternative == 2)
2889         return standard_80387_constant_opcode (operands[1]);
2890       return output_387_reg_move (insn, operands);
2892     case TYPE_IMOV:
2893       return "mov{l}\t{%1, %0|%0, %1}";
2895     case TYPE_SSELOG1:
2896       return standard_sse_constant_opcode (insn, operands[1]);
2898     case TYPE_SSEMOV:
2899       switch (get_attr_mode (insn))
2900         {
2901         case MODE_SF:
2902           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2903             return "vmovss\t{%1, %0, %0|%0, %0, %1}";
2904           return "%vmovss\t{%1, %0|%0, %1}";
2906         case MODE_V4SF:
2907           return "%vmovaps\t{%1, %0|%0, %1}";
2909         case MODE_SI:
2910           return "%vmovd\t{%1, %0|%0, %1}";
2912         default:
2913           gcc_unreachable ();
2914         }
2916     case TYPE_MMXMOV:
2917       switch (get_attr_mode (insn))
2918         {
2919         case MODE_DI:
2920           return "movq\t{%1, %0|%0, %1}";
2921         case MODE_SI:
2922           return "movd\t{%1, %0|%0, %1}";
2924         default:
2925           gcc_unreachable ();
2926         }
2928     default:
2929       gcc_unreachable ();
2930     }
2932   [(set (attr "type")
2933         (cond [(eq_attr "alternative" "0,1,2")
2934                  (const_string "fmov")
2935                (eq_attr "alternative" "3,4")
2936                  (const_string "imov")
2937                (eq_attr "alternative" "5")
2938                  (const_string "sselog1")
2939                (eq_attr "alternative" "11,12,13,14,15")
2940                  (const_string "mmxmov")
2941               ]
2942               (const_string "ssemov")))
2943    (set (attr "prefix")
2944      (if_then_else (eq_attr "type" "sselog1,ssemov")
2945        (const_string "maybe_vex")
2946        (const_string "orig")))
2947    (set (attr "prefix_data16")
2948      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2949        (const_string "1")
2950        (const_string "*")))
2951    (set (attr "mode")
2952         (cond [(eq_attr "alternative" "3,4,9,10,14,15")
2953                  (const_string "SI")
2954                (eq_attr "alternative" "11")
2955                  (const_string "DI")
2956                (eq_attr "alternative" "5")
2957                  (cond [(not (match_test "TARGET_SSE2"))
2958                           (const_string "V4SF")
2959                         (match_test "TARGET_AVX")
2960                           (const_string "V4SF")
2961                         (match_test "optimize_function_for_size_p (cfun)")
2962                           (const_string "V4SF")
2963                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
2964                           (const_string "TI")
2965                        ]
2966                        (const_string "V4SF"))
2968                /* For architectures resolving dependencies on
2969                   whole SSE registers use APS move to break dependency
2970                   chains, otherwise use short move to avoid extra work.
2972                   Do the same for architectures resolving dependencies on
2973                   the parts.  While in DF mode it is better to always handle
2974                   just register parts, the SF mode is different due to lack
2975                   of instructions to load just part of the register.  It is
2976                   better to maintain the whole registers in single format
2977                   to avoid problems on using packed logical operations.  */
2978                (and (eq_attr "alternative" "6")
2979                     (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2980                          (match_test "TARGET_SSE_SPLIT_REGS")))
2981                  (const_string "V4SF")
2982               ]
2983               (const_string "SF")))])
2985 (define_split
2986   [(set (match_operand 0 "any_fp_register_operand")
2987         (match_operand 1 "memory_operand"))]
2988   "reload_completed
2989    && (GET_MODE (operands[0]) == TFmode
2990        || GET_MODE (operands[0]) == XFmode
2991        || GET_MODE (operands[0]) == DFmode
2992        || GET_MODE (operands[0]) == SFmode)
2993    && (operands[2] = find_constant_src (insn))"
2994   [(set (match_dup 0) (match_dup 2))]
2996   rtx c = operands[2];
2997   int r = REGNO (operands[0]);
2999   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3000       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3001     FAIL;
3004 (define_split
3005   [(set (match_operand 0 "any_fp_register_operand")
3006         (float_extend (match_operand 1 "memory_operand")))]
3007   "reload_completed
3008    && (GET_MODE (operands[0]) == TFmode
3009        || GET_MODE (operands[0]) == XFmode
3010        || GET_MODE (operands[0]) == DFmode)
3011    && (operands[2] = find_constant_src (insn))"
3012   [(set (match_dup 0) (match_dup 2))]
3014   rtx c = operands[2];
3015   int r = REGNO (operands[0]);
3017   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3018       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3019     FAIL;
3022 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3023 (define_split
3024   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3025         (match_operand:X87MODEF 1 "immediate_operand"))]
3026   "reload_completed
3027    && (standard_80387_constant_p (operands[1]) == 8
3028        || standard_80387_constant_p (operands[1]) == 9)"
3029   [(set (match_dup 0)(match_dup 1))
3030    (set (match_dup 0)
3031         (neg:X87MODEF (match_dup 0)))]
3033   REAL_VALUE_TYPE r;
3035   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3036   if (real_isnegzero (&r))
3037     operands[1] = CONST0_RTX (<MODE>mode);
3038   else
3039     operands[1] = CONST1_RTX (<MODE>mode);
3042 (define_split
3043   [(set (match_operand 0 "nonimmediate_operand")
3044         (match_operand 1 "general_operand"))]
3045   "reload_completed
3046    && (GET_MODE (operands[0]) == TFmode
3047        || GET_MODE (operands[0]) == XFmode
3048        || GET_MODE (operands[0]) == DFmode)
3049    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3050   [(const_int 0)]
3051   "ix86_split_long_move (operands); DONE;")
3053 (define_insn "swapxf"
3054   [(set (match_operand:XF 0 "register_operand" "+f")
3055         (match_operand:XF 1 "register_operand" "+f"))
3056    (set (match_dup 1)
3057         (match_dup 0))]
3058   "TARGET_80387"
3060   if (STACK_TOP_P (operands[0]))
3061     return "fxch\t%1";
3062   else
3063     return "fxch\t%0";
3065   [(set_attr "type" "fxch")
3066    (set_attr "mode" "XF")])
3068 (define_insn "*swap<mode>"
3069   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3070         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3071    (set (match_dup 1)
3072         (match_dup 0))]
3073   "TARGET_80387 || reload_completed"
3075   if (STACK_TOP_P (operands[0]))
3076     return "fxch\t%1";
3077   else
3078     return "fxch\t%0";
3080   [(set_attr "type" "fxch")
3081    (set_attr "mode" "<MODE>")])
3083 ;; Zero extension instructions
3085 (define_expand "zero_extendsidi2"
3086   [(set (match_operand:DI 0 "nonimmediate_operand")
3087         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3089 (define_insn "*zero_extendsidi2"
3090   [(set (match_operand:DI 0 "nonimmediate_operand"
3091                         "=r,?r,?o,r   ,o,?*Ym,?!*y,?r ,?*Yi,?*x")
3092         (zero_extend:DI
3093          (match_operand:SI 1 "x86_64_zext_operand"
3094                         "0 ,rm,r ,rmWz,0,r   ,m   ,*Yj,r   ,m")))]
3095   ""
3097   switch (get_attr_type (insn))
3098     {
3099     case TYPE_IMOVX:
3100       if (ix86_use_lea_for_mov (insn, operands))
3101         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3102       else
3103         return "mov{l}\t{%1, %k0|%k0, %1}";
3105     case TYPE_MULTI:
3106       return "#";
3108     case TYPE_MMXMOV:
3109       return "movd\t{%1, %0|%0, %1}";
3111     case TYPE_SSEMOV:
3112       if (GENERAL_REG_P (operands[0]))
3113         return "%vmovd\t{%1, %k0|%k0, %1}";
3115       return "%vmovd\t{%1, %0|%0, %1}";
3117     default:
3118       gcc_unreachable ();
3119     }
3121   [(set (attr "isa")
3122      (cond [(eq_attr "alternative" "0,1,2")
3123               (const_string "nox64")
3124             (eq_attr "alternative" "3,7")
3125               (const_string "x64")
3126             (eq_attr "alternative" "9")
3127               (const_string "sse2")
3128            ]
3129            (const_string "*")))
3130    (set (attr "type")
3131      (cond [(eq_attr "alternative" "0,1,2,4")
3132               (const_string "multi")
3133             (eq_attr "alternative" "5,6")
3134               (const_string "mmxmov")
3135             (eq_attr "alternative" "7,8,9")
3136               (const_string "ssemov")
3137            ]
3138            (const_string "imovx")))
3139    (set (attr "prefix")
3140      (if_then_else (eq_attr "type" "ssemov")
3141        (const_string "maybe_vex")
3142        (const_string "orig")))
3143    (set (attr "prefix_0f")
3144      (if_then_else (eq_attr "type" "imovx")
3145        (const_string "0")
3146        (const_string "*")))
3147    (set (attr "mode")
3148      (cond [(eq_attr "alternative" "5,6")
3149               (const_string "DI")
3150             (eq_attr "alternative" "7,8,9")
3151               (const_string "TI")
3152            ]
3153            (const_string "SI")))])
3155 (define_split
3156   [(set (match_operand:DI 0 "memory_operand")
3157         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3158   "reload_completed"
3159   [(set (match_dup 4) (const_int 0))]
3160   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3162 (define_split
3163   [(set (match_operand:DI 0 "register_operand")
3164         (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3165   "!TARGET_64BIT && reload_completed
3166    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3167    && true_regnum (operands[0]) == true_regnum (operands[1])"
3168   [(set (match_dup 4) (const_int 0))]
3169   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3171 (define_split
3172   [(set (match_operand:DI 0 "nonimmediate_operand")
3173         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3174   "!TARGET_64BIT && reload_completed
3175    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3176    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3177   [(set (match_dup 3) (match_dup 1))
3178    (set (match_dup 4) (const_int 0))]
3179   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3181 (define_insn "zero_extend<mode>di2"
3182   [(set (match_operand:DI 0 "register_operand" "=r")
3183         (zero_extend:DI
3184          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3185   "TARGET_64BIT"
3186   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3187   [(set_attr "type" "imovx")
3188    (set_attr "mode" "SI")])
3190 (define_expand "zero_extend<mode>si2"
3191   [(set (match_operand:SI 0 "register_operand")
3192         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3193   ""
3195   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3196     {
3197       operands[1] = force_reg (<MODE>mode, operands[1]);
3198       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3199       DONE;
3200     }
3203 (define_insn_and_split "zero_extend<mode>si2_and"
3204   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3205         (zero_extend:SI
3206           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3207    (clobber (reg:CC FLAGS_REG))]
3208   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3209   "#"
3210   "&& reload_completed"
3211   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3212               (clobber (reg:CC FLAGS_REG))])]
3214   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3215     {
3216       ix86_expand_clear (operands[0]);
3218       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3219       emit_insn (gen_movstrict<mode>
3220                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3221       DONE;
3222     }
3224   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3226   [(set_attr "type" "alu1")
3227    (set_attr "mode" "SI")])
3229 (define_insn "*zero_extend<mode>si2"
3230   [(set (match_operand:SI 0 "register_operand" "=r")
3231         (zero_extend:SI
3232           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3233   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3234   "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3235   [(set_attr "type" "imovx")
3236    (set_attr "mode" "SI")])
3238 (define_expand "zero_extendqihi2"
3239   [(set (match_operand:HI 0 "register_operand")
3240         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3241   ""
3243   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3244     {
3245       operands[1] = force_reg (QImode, operands[1]);
3246       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3247       DONE;
3248     }
3251 (define_insn_and_split "zero_extendqihi2_and"
3252   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3253         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3254    (clobber (reg:CC FLAGS_REG))]
3255   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3256   "#"
3257   "&& reload_completed"
3258   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3259               (clobber (reg:CC FLAGS_REG))])]
3261   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3262     {
3263       ix86_expand_clear (operands[0]);
3265       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3266       emit_insn (gen_movstrictqi
3267                   (gen_lowpart (QImode, operands[0]), operands[1]));
3268       DONE;
3269     }
3271   operands[0] = gen_lowpart (SImode, operands[0]);
3273   [(set_attr "type" "alu1")
3274    (set_attr "mode" "SI")])
3276 ; zero extend to SImode to avoid partial register stalls
3277 (define_insn "*zero_extendqihi2"
3278   [(set (match_operand:HI 0 "register_operand" "=r")
3279         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3280   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3281   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3282   [(set_attr "type" "imovx")
3283    (set_attr "mode" "SI")])
3285 ;; Sign extension instructions
3287 (define_expand "extendsidi2"
3288   [(set (match_operand:DI 0 "register_operand")
3289         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3290   ""
3292   if (!TARGET_64BIT)
3293     {
3294       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3295       DONE;
3296     }
3299 (define_insn "*extendsidi2_rex64"
3300   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3301         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3302   "TARGET_64BIT"
3303   "@
3304    {cltq|cdqe}
3305    movs{lq|x}\t{%1, %0|%0, %1}"
3306   [(set_attr "type" "imovx")
3307    (set_attr "mode" "DI")
3308    (set_attr "prefix_0f" "0")
3309    (set_attr "modrm" "0,1")])
3311 (define_insn "extendsidi2_1"
3312   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3313         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3314    (clobber (reg:CC FLAGS_REG))
3315    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3316   "!TARGET_64BIT"
3317   "#")
3319 ;; Extend to memory case when source register does die.
3320 (define_split
3321   [(set (match_operand:DI 0 "memory_operand")
3322         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3323    (clobber (reg:CC FLAGS_REG))
3324    (clobber (match_operand:SI 2 "register_operand"))]
3325   "(reload_completed
3326     && dead_or_set_p (insn, operands[1])
3327     && !reg_mentioned_p (operands[1], operands[0]))"
3328   [(set (match_dup 3) (match_dup 1))
3329    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3330               (clobber (reg:CC FLAGS_REG))])
3331    (set (match_dup 4) (match_dup 1))]
3332   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3334 ;; Extend to memory case when source register does not die.
3335 (define_split
3336   [(set (match_operand:DI 0 "memory_operand")
3337         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3338    (clobber (reg:CC FLAGS_REG))
3339    (clobber (match_operand:SI 2 "register_operand"))]
3340   "reload_completed"
3341   [(const_int 0)]
3343   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3345   emit_move_insn (operands[3], operands[1]);
3347   /* Generate a cltd if possible and doing so it profitable.  */
3348   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3349       && true_regnum (operands[1]) == AX_REG
3350       && true_regnum (operands[2]) == DX_REG)
3351     {
3352       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3353     }
3354   else
3355     {
3356       emit_move_insn (operands[2], operands[1]);
3357       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3358     }
3359   emit_move_insn (operands[4], operands[2]);
3360   DONE;
3363 ;; Extend to register case.  Optimize case where source and destination
3364 ;; registers match and cases where we can use cltd.
3365 (define_split
3366   [(set (match_operand:DI 0 "register_operand")
3367         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3368    (clobber (reg:CC FLAGS_REG))
3369    (clobber (match_scratch:SI 2))]
3370   "reload_completed"
3371   [(const_int 0)]
3373   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3375   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3376     emit_move_insn (operands[3], operands[1]);
3378   /* Generate a cltd if possible and doing so it profitable.  */
3379   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3380       && true_regnum (operands[3]) == AX_REG
3381       && true_regnum (operands[4]) == DX_REG)
3382     {
3383       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3384       DONE;
3385     }
3387   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3388     emit_move_insn (operands[4], operands[1]);
3390   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3391   DONE;
3394 (define_insn "extend<mode>di2"
3395   [(set (match_operand:DI 0 "register_operand" "=r")
3396         (sign_extend:DI
3397          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3398   "TARGET_64BIT"
3399   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3400   [(set_attr "type" "imovx")
3401    (set_attr "mode" "DI")])
3403 (define_insn "extendhisi2"
3404   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3405         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3406   ""
3408   switch (get_attr_prefix_0f (insn))
3409     {
3410     case 0:
3411       return "{cwtl|cwde}";
3412     default:
3413       return "movs{wl|x}\t{%1, %0|%0, %1}";
3414     }
3416   [(set_attr "type" "imovx")
3417    (set_attr "mode" "SI")
3418    (set (attr "prefix_0f")
3419      ;; movsx is short decodable while cwtl is vector decoded.
3420      (if_then_else (and (eq_attr "cpu" "!k6")
3421                         (eq_attr "alternative" "0"))
3422         (const_string "0")
3423         (const_string "1")))
3424    (set (attr "modrm")
3425      (if_then_else (eq_attr "prefix_0f" "0")
3426         (const_string "0")
3427         (const_string "1")))])
3429 (define_insn "*extendhisi2_zext"
3430   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3431         (zero_extend:DI
3432          (sign_extend:SI
3433           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3434   "TARGET_64BIT"
3436   switch (get_attr_prefix_0f (insn))
3437     {
3438     case 0:
3439       return "{cwtl|cwde}";
3440     default:
3441       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3442     }
3444   [(set_attr "type" "imovx")
3445    (set_attr "mode" "SI")
3446    (set (attr "prefix_0f")
3447      ;; movsx is short decodable while cwtl is vector decoded.
3448      (if_then_else (and (eq_attr "cpu" "!k6")
3449                         (eq_attr "alternative" "0"))
3450         (const_string "0")
3451         (const_string "1")))
3452    (set (attr "modrm")
3453      (if_then_else (eq_attr "prefix_0f" "0")
3454         (const_string "0")
3455         (const_string "1")))])
3457 (define_insn "extendqisi2"
3458   [(set (match_operand:SI 0 "register_operand" "=r")
3459         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3460   ""
3461   "movs{bl|x}\t{%1, %0|%0, %1}"
3462    [(set_attr "type" "imovx")
3463     (set_attr "mode" "SI")])
3465 (define_insn "*extendqisi2_zext"
3466   [(set (match_operand:DI 0 "register_operand" "=r")
3467         (zero_extend:DI
3468           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3469   "TARGET_64BIT"
3470   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3471    [(set_attr "type" "imovx")
3472     (set_attr "mode" "SI")])
3474 (define_insn "extendqihi2"
3475   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3476         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3477   ""
3479   switch (get_attr_prefix_0f (insn))
3480     {
3481     case 0:
3482       return "{cbtw|cbw}";
3483     default:
3484       return "movs{bw|x}\t{%1, %0|%0, %1}";
3485     }
3487   [(set_attr "type" "imovx")
3488    (set_attr "mode" "HI")
3489    (set (attr "prefix_0f")
3490      ;; movsx is short decodable while cwtl is vector decoded.
3491      (if_then_else (and (eq_attr "cpu" "!k6")
3492                         (eq_attr "alternative" "0"))
3493         (const_string "0")
3494         (const_string "1")))
3495    (set (attr "modrm")
3496      (if_then_else (eq_attr "prefix_0f" "0")
3497         (const_string "0")
3498         (const_string "1")))])
3500 ;; Conversions between float and double.
3502 ;; These are all no-ops in the model used for the 80387.
3503 ;; So just emit moves.
3505 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3506 (define_split
3507   [(set (match_operand:DF 0 "push_operand")
3508         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3509   "reload_completed"
3510   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3511    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3513 (define_split
3514   [(set (match_operand:XF 0 "push_operand")
3515         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3516   "reload_completed"
3517   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3518    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3519   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3521 (define_expand "extendsfdf2"
3522   [(set (match_operand:DF 0 "nonimmediate_operand")
3523         (float_extend:DF (match_operand:SF 1 "general_operand")))]
3524   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3526   /* ??? Needed for compress_float_constant since all fp constants
3527      are TARGET_LEGITIMATE_CONSTANT_P.  */
3528   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3529     {
3530       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3531           && standard_80387_constant_p (operands[1]) > 0)
3532         {
3533           operands[1] = simplify_const_unary_operation
3534             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3535           emit_move_insn_1 (operands[0], operands[1]);
3536           DONE;
3537         }
3538       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3539     }
3542 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3543    cvtss2sd:
3544       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3545       cvtps2pd xmm2,xmm1
3546    We do the conversion post reload to avoid producing of 128bit spills
3547    that might lead to ICE on 32bit target.  The sequence unlikely combine
3548    anyway.  */
3549 (define_split
3550   [(set (match_operand:DF 0 "register_operand")
3551         (float_extend:DF
3552           (match_operand:SF 1 "nonimmediate_operand")))]
3553   "TARGET_USE_VECTOR_FP_CONVERTS
3554    && optimize_insn_for_speed_p ()
3555    && reload_completed && SSE_REG_P (operands[0])"
3556    [(set (match_dup 2)
3557          (float_extend:V2DF
3558            (vec_select:V2SF
3559              (match_dup 3)
3560              (parallel [(const_int 0) (const_int 1)]))))]
3562   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3563   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3564   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3565      Try to avoid move when unpacking can be done in source.  */
3566   if (REG_P (operands[1]))
3567     {
3568       /* If it is unsafe to overwrite upper half of source, we need
3569          to move to destination and unpack there.  */
3570       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3571            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3572           && true_regnum (operands[0]) != true_regnum (operands[1]))
3573         {
3574           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3575           emit_move_insn (tmp, operands[1]);
3576         }
3577       else
3578         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3579       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3580                                              operands[3]));
3581     }
3582   else
3583     emit_insn (gen_vec_setv4sf_0 (operands[3],
3584                                   CONST0_RTX (V4SFmode), operands[1]));
3587 (define_insn "*extendsfdf2_mixed"
3588   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3589         (float_extend:DF
3590           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3591   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3593   switch (which_alternative)
3594     {
3595     case 0:
3596     case 1:
3597       return output_387_reg_move (insn, operands);
3599     case 2:
3600       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3602     default:
3603       gcc_unreachable ();
3604     }
3606   [(set_attr "type" "fmov,fmov,ssecvt")
3607    (set_attr "prefix" "orig,orig,maybe_vex")
3608    (set_attr "mode" "SF,XF,DF")])
3610 (define_insn "*extendsfdf2_sse"
3611   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3612         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3613   "TARGET_SSE2 && TARGET_SSE_MATH"
3614   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3615   [(set_attr "type" "ssecvt")
3616    (set_attr "prefix" "maybe_vex")
3617    (set_attr "mode" "DF")])
3619 (define_insn "*extendsfdf2_i387"
3620   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3621         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3622   "TARGET_80387"
3623   "* return output_387_reg_move (insn, operands);"
3624   [(set_attr "type" "fmov")
3625    (set_attr "mode" "SF,XF")])
3627 (define_expand "extend<mode>xf2"
3628   [(set (match_operand:XF 0 "nonimmediate_operand")
3629         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3630   "TARGET_80387"
3632   /* ??? Needed for compress_float_constant since all fp constants
3633      are TARGET_LEGITIMATE_CONSTANT_P.  */
3634   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3635     {
3636       if (standard_80387_constant_p (operands[1]) > 0)
3637         {
3638           operands[1] = simplify_const_unary_operation
3639             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3640           emit_move_insn_1 (operands[0], operands[1]);
3641           DONE;
3642         }
3643       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3644     }
3647 (define_insn "*extend<mode>xf2_i387"
3648   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3649         (float_extend:XF
3650           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3651   "TARGET_80387"
3652   "* return output_387_reg_move (insn, operands);"
3653   [(set_attr "type" "fmov")
3654    (set_attr "mode" "<MODE>,XF")])
3656 ;; %%% This seems bad bad news.
3657 ;; This cannot output into an f-reg because there is no way to be sure
3658 ;; of truncating in that case.  Otherwise this is just like a simple move
3659 ;; insn.  So we pretend we can output to a reg in order to get better
3660 ;; register preferencing, but we really use a stack slot.
3662 ;; Conversion from DFmode to SFmode.
3664 (define_expand "truncdfsf2"
3665   [(set (match_operand:SF 0 "nonimmediate_operand")
3666         (float_truncate:SF
3667           (match_operand:DF 1 "nonimmediate_operand")))]
3668   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3670   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3671     ;
3672   else if (flag_unsafe_math_optimizations)
3673     ;
3674   else
3675     {
3676       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3677       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3678       DONE;
3679     }
3682 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3683    cvtsd2ss:
3684       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3685       cvtpd2ps xmm2,xmm1
3686    We do the conversion post reload to avoid producing of 128bit spills
3687    that might lead to ICE on 32bit target.  The sequence unlikely combine
3688    anyway.  */
3689 (define_split
3690   [(set (match_operand:SF 0 "register_operand")
3691         (float_truncate:SF
3692           (match_operand:DF 1 "nonimmediate_operand")))]
3693   "TARGET_USE_VECTOR_FP_CONVERTS
3694    && optimize_insn_for_speed_p ()
3695    && reload_completed && SSE_REG_P (operands[0])"
3696    [(set (match_dup 2)
3697          (vec_concat:V4SF
3698            (float_truncate:V2SF
3699              (match_dup 4))
3700            (match_dup 3)))]
3702   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3703   operands[3] = CONST0_RTX (V2SFmode);
3704   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3705   /* Use movsd for loading from memory, unpcklpd for registers.
3706      Try to avoid move when unpacking can be done in source, or SSE3
3707      movddup is available.  */
3708   if (REG_P (operands[1]))
3709     {
3710       if (!TARGET_SSE3
3711           && true_regnum (operands[0]) != true_regnum (operands[1])
3712           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3713               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3714         {
3715           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3716           emit_move_insn (tmp, operands[1]);
3717           operands[1] = tmp;
3718         }
3719       else if (!TARGET_SSE3)
3720         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3721       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
3722     }
3723   else
3724     emit_insn (gen_sse2_loadlpd (operands[4],
3725                                  CONST0_RTX (V2DFmode), operands[1]));
3728 (define_expand "truncdfsf2_with_temp"
3729   [(parallel [(set (match_operand:SF 0)
3730                    (float_truncate:SF (match_operand:DF 1)))
3731               (clobber (match_operand:SF 2))])])
3733 (define_insn "*truncdfsf_fast_mixed"
3734   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
3735         (float_truncate:SF
3736           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
3737   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3739   switch (which_alternative)
3740     {
3741     case 0:
3742       return output_387_reg_move (insn, operands);
3743     case 1:
3744       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
3745     default:
3746       gcc_unreachable ();
3747     }
3749   [(set_attr "type" "fmov,ssecvt")
3750    (set_attr "prefix" "orig,maybe_vex")
3751    (set_attr "mode" "SF")])
3753 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3754 ;; because nothing we do here is unsafe.
3755 (define_insn "*truncdfsf_fast_sse"
3756   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
3757         (float_truncate:SF
3758           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3759   "TARGET_SSE2 && TARGET_SSE_MATH"
3760   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
3761   [(set_attr "type" "ssecvt")
3762    (set_attr "prefix" "maybe_vex")
3763    (set_attr "mode" "SF")])
3765 (define_insn "*truncdfsf_fast_i387"
3766   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3767         (float_truncate:SF
3768           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3769   "TARGET_80387 && flag_unsafe_math_optimizations"
3770   "* return output_387_reg_move (insn, operands);"
3771   [(set_attr "type" "fmov")
3772    (set_attr "mode" "SF")])
3774 (define_insn "*truncdfsf_mixed"
3775   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
3776         (float_truncate:SF
3777           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
3778    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
3779   "TARGET_MIX_SSE_I387"
3781   switch (which_alternative)
3782     {
3783     case 0:
3784       return output_387_reg_move (insn, operands);
3785     case 1:
3786       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
3788     default:
3789       return "#";
3790     }
3792   [(set_attr "isa" "*,sse2,*,*,*")
3793    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
3794    (set_attr "unit" "*,*,i387,i387,i387")
3795    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
3796    (set_attr "mode" "SF")])
3798 (define_insn "*truncdfsf_i387"
3799   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
3800         (float_truncate:SF
3801           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
3802    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
3803   "TARGET_80387"
3805   switch (which_alternative)
3806     {
3807     case 0:
3808       return output_387_reg_move (insn, operands);
3810     default:
3811       return "#";
3812     }
3814   [(set_attr "type" "fmov,multi,multi,multi")
3815    (set_attr "unit" "*,i387,i387,i387")
3816    (set_attr "mode" "SF")])
3818 (define_insn "*truncdfsf2_i387_1"
3819   [(set (match_operand:SF 0 "memory_operand" "=m")
3820         (float_truncate:SF
3821           (match_operand:DF 1 "register_operand" "f")))]
3822   "TARGET_80387
3823    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3824    && !TARGET_MIX_SSE_I387"
3825   "* return output_387_reg_move (insn, operands);"
3826   [(set_attr "type" "fmov")
3827    (set_attr "mode" "SF")])
3829 (define_split
3830   [(set (match_operand:SF 0 "register_operand")
3831         (float_truncate:SF
3832          (match_operand:DF 1 "fp_register_operand")))
3833    (clobber (match_operand 2))]
3834   "reload_completed"
3835   [(set (match_dup 2) (match_dup 1))
3836    (set (match_dup 0) (match_dup 2))]
3837   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
3839 ;; Conversion from XFmode to {SF,DF}mode
3841 (define_expand "truncxf<mode>2"
3842   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
3843                    (float_truncate:MODEF
3844                      (match_operand:XF 1 "register_operand")))
3845               (clobber (match_dup 2))])]
3846   "TARGET_80387"
3848   if (flag_unsafe_math_optimizations)
3849     {
3850       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
3851       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
3852       if (reg != operands[0])
3853         emit_move_insn (operands[0], reg);
3854       DONE;
3855     }
3856   else
3857     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
3860 (define_insn "*truncxfsf2_mixed"
3861   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
3862         (float_truncate:SF
3863           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
3864    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
3865   "TARGET_80387"
3867   gcc_assert (!which_alternative);
3868   return output_387_reg_move (insn, operands);
3870   [(set_attr "type" "fmov,multi,multi,multi")
3871    (set_attr "unit" "*,i387,i387,i387")
3872    (set_attr "mode" "SF")])
3874 (define_insn "*truncxfdf2_mixed"
3875   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
3876         (float_truncate:DF
3877           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
3878    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
3879   "TARGET_80387"
3881   gcc_assert (!which_alternative);
3882   return output_387_reg_move (insn, operands);
3884   [(set_attr "isa" "*,*,sse2,*")
3885    (set_attr "type" "fmov,multi,multi,multi")
3886    (set_attr "unit" "*,i387,i387,i387")
3887    (set_attr "mode" "DF")])
3889 (define_insn "truncxf<mode>2_i387_noop"
3890   [(set (match_operand:MODEF 0 "register_operand" "=f")
3891         (float_truncate:MODEF
3892           (match_operand:XF 1 "register_operand" "f")))]
3893   "TARGET_80387 && flag_unsafe_math_optimizations"
3894   "* return output_387_reg_move (insn, operands);"
3895   [(set_attr "type" "fmov")
3896    (set_attr "mode" "<MODE>")])
3898 (define_insn "*truncxf<mode>2_i387"
3899   [(set (match_operand:MODEF 0 "memory_operand" "=m")
3900         (float_truncate:MODEF
3901           (match_operand:XF 1 "register_operand" "f")))]
3902   "TARGET_80387"
3903   "* return output_387_reg_move (insn, operands);"
3904   [(set_attr "type" "fmov")
3905    (set_attr "mode" "<MODE>")])
3907 (define_split
3908   [(set (match_operand:MODEF 0 "register_operand")
3909         (float_truncate:MODEF
3910           (match_operand:XF 1 "register_operand")))
3911    (clobber (match_operand:MODEF 2 "memory_operand"))]
3912   "TARGET_80387 && reload_completed"
3913   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
3914    (set (match_dup 0) (match_dup 2))])
3916 (define_split
3917   [(set (match_operand:MODEF 0 "memory_operand")
3918         (float_truncate:MODEF
3919           (match_operand:XF 1 "register_operand")))
3920    (clobber (match_operand:MODEF 2 "memory_operand"))]
3921   "TARGET_80387"
3922   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
3924 ;; Signed conversion to DImode.
3926 (define_expand "fix_truncxfdi2"
3927   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
3928                    (fix:DI (match_operand:XF 1 "register_operand")))
3929               (clobber (reg:CC FLAGS_REG))])]
3930   "TARGET_80387"
3932   if (TARGET_FISTTP)
3933    {
3934      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
3935      DONE;
3936    }
3939 (define_expand "fix_trunc<mode>di2"
3940   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
3941                    (fix:DI (match_operand:MODEF 1 "register_operand")))
3942               (clobber (reg:CC FLAGS_REG))])]
3943   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
3945   if (TARGET_FISTTP
3946       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
3947    {
3948      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
3949      DONE;
3950    }
3951   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
3952    {
3953      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
3954      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
3955      if (out != operands[0])
3956         emit_move_insn (operands[0], out);
3957      DONE;
3958    }
3961 ;; Signed conversion to SImode.
3963 (define_expand "fix_truncxfsi2"
3964   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
3965                    (fix:SI (match_operand:XF 1 "register_operand")))
3966               (clobber (reg:CC FLAGS_REG))])]
3967   "TARGET_80387"
3969   if (TARGET_FISTTP)
3970    {
3971      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
3972      DONE;
3973    }
3976 (define_expand "fix_trunc<mode>si2"
3977   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
3978                    (fix:SI (match_operand:MODEF 1 "register_operand")))
3979               (clobber (reg:CC FLAGS_REG))])]
3980   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
3982   if (TARGET_FISTTP
3983       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
3984    {
3985      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
3986      DONE;
3987    }
3988   if (SSE_FLOAT_MODE_P (<MODE>mode))
3989    {
3990      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
3991      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
3992      if (out != operands[0])
3993         emit_move_insn (operands[0], out);
3994      DONE;
3995    }
3998 ;; Signed conversion to HImode.
4000 (define_expand "fix_trunc<mode>hi2"
4001   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4002                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4003               (clobber (reg:CC FLAGS_REG))])]
4004   "TARGET_80387
4005    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4007   if (TARGET_FISTTP)
4008    {
4009      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4010      DONE;
4011    }
4014 ;; Unsigned conversion to SImode.
4016 (define_expand "fixuns_trunc<mode>si2"
4017   [(parallel
4018     [(set (match_operand:SI 0 "register_operand")
4019           (unsigned_fix:SI
4020             (match_operand:MODEF 1 "nonimmediate_operand")))
4021      (use (match_dup 2))
4022      (clobber (match_scratch:<ssevecmode> 3))
4023      (clobber (match_scratch:<ssevecmode> 4))])]
4024   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4026   enum machine_mode mode = <MODE>mode;
4027   enum machine_mode vecmode = <ssevecmode>mode;
4028   REAL_VALUE_TYPE TWO31r;
4029   rtx two31;
4031   if (optimize_insn_for_size_p ())
4032     FAIL;
4034   real_ldexp (&TWO31r, &dconst1, 31);
4035   two31 = const_double_from_real_value (TWO31r, mode);
4036   two31 = ix86_build_const_vector (vecmode, true, two31);
4037   operands[2] = force_reg (vecmode, two31);
4040 (define_insn_and_split "*fixuns_trunc<mode>_1"
4041   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4042         (unsigned_fix:SI
4043           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4044    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4045    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4046    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4047   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4048    && optimize_function_for_speed_p (cfun)"
4049   "#"
4050   "&& reload_completed"
4051   [(const_int 0)]
4053   ix86_split_convert_uns_si_sse (operands);
4054   DONE;
4057 ;; Unsigned conversion to HImode.
4058 ;; Without these patterns, we'll try the unsigned SI conversion which
4059 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4061 (define_expand "fixuns_trunc<mode>hi2"
4062   [(set (match_dup 2)
4063         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4064    (set (match_operand:HI 0 "nonimmediate_operand")
4065         (subreg:HI (match_dup 2) 0))]
4066   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4067   "operands[2] = gen_reg_rtx (SImode);")
4069 ;; When SSE is available, it is always faster to use it!
4070 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4071   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4072         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4073   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4074    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4075   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4076   [(set_attr "type" "sseicvt")
4077    (set_attr "prefix" "maybe_vex")
4078    (set (attr "prefix_rex")
4079         (if_then_else
4080           (match_test "<SWI48:MODE>mode == DImode")
4081           (const_string "1")
4082           (const_string "*")))
4083    (set_attr "mode" "<MODEF:MODE>")
4084    (set_attr "athlon_decode" "double,vector")
4085    (set_attr "amdfam10_decode" "double,double")
4086    (set_attr "bdver1_decode" "double,double")])
4088 ;; Avoid vector decoded forms of the instruction.
4089 (define_peephole2
4090   [(match_scratch:MODEF 2 "x")
4091    (set (match_operand:SWI48 0 "register_operand")
4092         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4093   "TARGET_AVOID_VECTOR_DECODE
4094    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4095    && optimize_insn_for_speed_p ()"
4096   [(set (match_dup 2) (match_dup 1))
4097    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4099 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4100   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4101         (fix:SWI248x (match_operand 1 "register_operand")))]
4102   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4103    && TARGET_FISTTP
4104    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4105          && (TARGET_64BIT || <MODE>mode != DImode))
4106         && TARGET_SSE_MATH)
4107    && can_create_pseudo_p ()"
4108   "#"
4109   "&& 1"
4110   [(const_int 0)]
4112   if (memory_operand (operands[0], VOIDmode))
4113     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4114   else
4115     {
4116       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4117       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4118                                                             operands[1],
4119                                                             operands[2]));
4120     }
4121   DONE;
4123   [(set_attr "type" "fisttp")
4124    (set_attr "mode" "<MODE>")])
4126 (define_insn "fix_trunc<mode>_i387_fisttp"
4127   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4128         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4129    (clobber (match_scratch:XF 2 "=&1f"))]
4130   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4131    && TARGET_FISTTP
4132    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4133          && (TARGET_64BIT || <MODE>mode != DImode))
4134         && TARGET_SSE_MATH)"
4135   "* return output_fix_trunc (insn, operands, true);"
4136   [(set_attr "type" "fisttp")
4137    (set_attr "mode" "<MODE>")])
4139 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4140   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4141         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4142    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4143    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4144   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4145    && TARGET_FISTTP
4146    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4147         && (TARGET_64BIT || <MODE>mode != DImode))
4148         && TARGET_SSE_MATH)"
4149   "#"
4150   [(set_attr "type" "fisttp")
4151    (set_attr "mode" "<MODE>")])
4153 (define_split
4154   [(set (match_operand:SWI248x 0 "register_operand")
4155         (fix:SWI248x (match_operand 1 "register_operand")))
4156    (clobber (match_operand:SWI248x 2 "memory_operand"))
4157    (clobber (match_scratch 3))]
4158   "reload_completed"
4159   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4160               (clobber (match_dup 3))])
4161    (set (match_dup 0) (match_dup 2))])
4163 (define_split
4164   [(set (match_operand:SWI248x 0 "memory_operand")
4165         (fix:SWI248x (match_operand 1 "register_operand")))
4166    (clobber (match_operand:SWI248x 2 "memory_operand"))
4167    (clobber (match_scratch 3))]
4168   "reload_completed"
4169   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4170               (clobber (match_dup 3))])])
4172 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4173 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4174 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4175 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4176 ;; function in i386.c.
4177 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4178   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4179         (fix:SWI248x (match_operand 1 "register_operand")))
4180    (clobber (reg:CC FLAGS_REG))]
4181   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4182    && !TARGET_FISTTP
4183    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4184          && (TARGET_64BIT || <MODE>mode != DImode))
4185    && can_create_pseudo_p ()"
4186   "#"
4187   "&& 1"
4188   [(const_int 0)]
4190   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4192   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4193   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4194   if (memory_operand (operands[0], VOIDmode))
4195     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4196                                          operands[2], operands[3]));
4197   else
4198     {
4199       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4200       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4201                                                      operands[2], operands[3],
4202                                                      operands[4]));
4203     }
4204   DONE;
4206   [(set_attr "type" "fistp")
4207    (set_attr "i387_cw" "trunc")
4208    (set_attr "mode" "<MODE>")])
4210 (define_insn "fix_truncdi_i387"
4211   [(set (match_operand:DI 0 "memory_operand" "=m")
4212         (fix:DI (match_operand 1 "register_operand" "f")))
4213    (use (match_operand:HI 2 "memory_operand" "m"))
4214    (use (match_operand:HI 3 "memory_operand" "m"))
4215    (clobber (match_scratch:XF 4 "=&1f"))]
4216   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4217    && !TARGET_FISTTP
4218    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4219   "* return output_fix_trunc (insn, operands, false);"
4220   [(set_attr "type" "fistp")
4221    (set_attr "i387_cw" "trunc")
4222    (set_attr "mode" "DI")])
4224 (define_insn "fix_truncdi_i387_with_temp"
4225   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4226         (fix:DI (match_operand 1 "register_operand" "f,f")))
4227    (use (match_operand:HI 2 "memory_operand" "m,m"))
4228    (use (match_operand:HI 3 "memory_operand" "m,m"))
4229    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4230    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4231   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4232    && !TARGET_FISTTP
4233    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4234   "#"
4235   [(set_attr "type" "fistp")
4236    (set_attr "i387_cw" "trunc")
4237    (set_attr "mode" "DI")])
4239 (define_split
4240   [(set (match_operand:DI 0 "register_operand")
4241         (fix:DI (match_operand 1 "register_operand")))
4242    (use (match_operand:HI 2 "memory_operand"))
4243    (use (match_operand:HI 3 "memory_operand"))
4244    (clobber (match_operand:DI 4 "memory_operand"))
4245    (clobber (match_scratch 5))]
4246   "reload_completed"
4247   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4248               (use (match_dup 2))
4249               (use (match_dup 3))
4250               (clobber (match_dup 5))])
4251    (set (match_dup 0) (match_dup 4))])
4253 (define_split
4254   [(set (match_operand:DI 0 "memory_operand")
4255         (fix:DI (match_operand 1 "register_operand")))
4256    (use (match_operand:HI 2 "memory_operand"))
4257    (use (match_operand:HI 3 "memory_operand"))
4258    (clobber (match_operand:DI 4 "memory_operand"))
4259    (clobber (match_scratch 5))]
4260   "reload_completed"
4261   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4262               (use (match_dup 2))
4263               (use (match_dup 3))
4264               (clobber (match_dup 5))])])
4266 (define_insn "fix_trunc<mode>_i387"
4267   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4268         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4269    (use (match_operand:HI 2 "memory_operand" "m"))
4270    (use (match_operand:HI 3 "memory_operand" "m"))]
4271   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4272    && !TARGET_FISTTP
4273    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4274   "* return output_fix_trunc (insn, operands, false);"
4275   [(set_attr "type" "fistp")
4276    (set_attr "i387_cw" "trunc")
4277    (set_attr "mode" "<MODE>")])
4279 (define_insn "fix_trunc<mode>_i387_with_temp"
4280   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4281         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4282    (use (match_operand:HI 2 "memory_operand" "m,m"))
4283    (use (match_operand:HI 3 "memory_operand" "m,m"))
4284    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4285   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4286    && !TARGET_FISTTP
4287    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4288   "#"
4289   [(set_attr "type" "fistp")
4290    (set_attr "i387_cw" "trunc")
4291    (set_attr "mode" "<MODE>")])
4293 (define_split
4294   [(set (match_operand:SWI24 0 "register_operand")
4295         (fix:SWI24 (match_operand 1 "register_operand")))
4296    (use (match_operand:HI 2 "memory_operand"))
4297    (use (match_operand:HI 3 "memory_operand"))
4298    (clobber (match_operand:SWI24 4 "memory_operand"))]
4299   "reload_completed"
4300   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4301               (use (match_dup 2))
4302               (use (match_dup 3))])
4303    (set (match_dup 0) (match_dup 4))])
4305 (define_split
4306   [(set (match_operand:SWI24 0 "memory_operand")
4307         (fix:SWI24 (match_operand 1 "register_operand")))
4308    (use (match_operand:HI 2 "memory_operand"))
4309    (use (match_operand:HI 3 "memory_operand"))
4310    (clobber (match_operand:SWI24 4 "memory_operand"))]
4311   "reload_completed"
4312   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4313               (use (match_dup 2))
4314               (use (match_dup 3))])])
4316 (define_insn "x86_fnstcw_1"
4317   [(set (match_operand:HI 0 "memory_operand" "=m")
4318         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4319   "TARGET_80387"
4320   "fnstcw\t%0"
4321   [(set (attr "length")
4322         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4323    (set_attr "mode" "HI")
4324    (set_attr "unit" "i387")
4325    (set_attr "bdver1_decode" "vector")])
4327 (define_insn "x86_fldcw_1"
4328   [(set (reg:HI FPCR_REG)
4329         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4330   "TARGET_80387"
4331   "fldcw\t%0"
4332   [(set (attr "length")
4333         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4334    (set_attr "mode" "HI")
4335    (set_attr "unit" "i387")
4336    (set_attr "athlon_decode" "vector")
4337    (set_attr "amdfam10_decode" "vector")
4338    (set_attr "bdver1_decode" "vector")])
4340 ;; Conversion between fixed point and floating point.
4342 ;; Even though we only accept memory inputs, the backend _really_
4343 ;; wants to be able to do this between registers.
4345 (define_expand "floathi<mode>2"
4346   [(set (match_operand:X87MODEF 0 "register_operand")
4347         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4348   "TARGET_80387
4349    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4350        || TARGET_MIX_SSE_I387)")
4352 ;; Pre-reload splitter to add memory clobber to the pattern.
4353 (define_insn_and_split "*floathi<mode>2_1"
4354   [(set (match_operand:X87MODEF 0 "register_operand")
4355         (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4356   "TARGET_80387
4357    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4358        || TARGET_MIX_SSE_I387)
4359    && can_create_pseudo_p ()"
4360   "#"
4361   "&& 1"
4362   [(parallel [(set (match_dup 0)
4363               (float:X87MODEF (match_dup 1)))
4364    (clobber (match_dup 2))])]
4365   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4367 (define_insn "*floathi<mode>2_i387_with_temp"
4368   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4369         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4370   (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4371   "TARGET_80387
4372    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4373        || TARGET_MIX_SSE_I387)"
4374   "#"
4375   [(set_attr "type" "fmov,multi")
4376    (set_attr "mode" "<MODE>")
4377    (set_attr "unit" "*,i387")
4378    (set_attr "fp_int_src" "true")])
4380 (define_insn "*floathi<mode>2_i387"
4381   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4382         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4383   "TARGET_80387
4384    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4385        || TARGET_MIX_SSE_I387)"
4386   "fild%Z1\t%1"
4387   [(set_attr "type" "fmov")
4388    (set_attr "mode" "<MODE>")
4389    (set_attr "fp_int_src" "true")])
4391 (define_split
4392   [(set (match_operand:X87MODEF 0 "register_operand")
4393         (float:X87MODEF (match_operand:HI 1 "register_operand")))
4394    (clobber (match_operand:HI 2 "memory_operand"))]
4395   "TARGET_80387
4396    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4397        || TARGET_MIX_SSE_I387)
4398    && reload_completed"
4399   [(set (match_dup 2) (match_dup 1))
4400    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4402 (define_split
4403   [(set (match_operand:X87MODEF 0 "register_operand")
4404         (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4405    (clobber (match_operand:HI 2 "memory_operand"))]
4406    "TARGET_80387
4407     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4408         || TARGET_MIX_SSE_I387)
4409     && reload_completed"
4410   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4412 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4413   [(set (match_operand:X87MODEF 0 "register_operand")
4414         (float:X87MODEF
4415           (match_operand:SWI48x 1 "nonimmediate_operand")))]
4416   "TARGET_80387
4417    || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4418        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4420   if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4421         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4422       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4423     {
4424       rtx reg = gen_reg_rtx (XFmode);
4425       rtx (*insn)(rtx, rtx);
4427       emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4429       if (<X87MODEF:MODE>mode == SFmode)
4430         insn = gen_truncxfsf2;
4431       else if (<X87MODEF:MODE>mode == DFmode)
4432         insn = gen_truncxfdf2;
4433       else
4434         gcc_unreachable ();
4436       emit_insn (insn (operands[0], reg));
4437       DONE;
4438     }
4441 ;; Pre-reload splitter to add memory clobber to the pattern.
4442 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4443   [(set (match_operand:X87MODEF 0 "register_operand")
4444         (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4445   "((TARGET_80387
4446      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4447      && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4448            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4449          || TARGET_MIX_SSE_I387))
4450     || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4451         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4452         && ((<SWI48x:MODE>mode == SImode
4453              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4454              && optimize_function_for_speed_p (cfun)
4455              && flag_trapping_math)
4456             || !(TARGET_INTER_UNIT_CONVERSIONS
4457                  || optimize_function_for_size_p (cfun)))))
4458    && can_create_pseudo_p ()"
4459   "#"
4460   "&& 1"
4461   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4462               (clobber (match_dup 2))])]
4464   operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4466   /* Avoid store forwarding (partial memory) stall penalty
4467      by passing DImode value through XMM registers.  */
4468   if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4469       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4470       && optimize_function_for_speed_p (cfun))
4471     {
4472       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4473                                                             operands[1],
4474                                                             operands[2]));
4475       DONE;
4476     }
4479 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4480   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4481         (float:MODEF
4482           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4483    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4484   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4485    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4486   "#"
4487   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4488    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4489    (set_attr "unit" "*,i387,*,*,*")
4490    (set_attr "athlon_decode" "*,*,double,direct,double")
4491    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4492    (set_attr "bdver1_decode" "*,*,double,direct,double")
4493    (set_attr "fp_int_src" "true")])
4495 (define_insn "*floatsi<mode>2_vector_mixed"
4496   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4497         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4498   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4499    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4500   "@
4501    fild%Z1\t%1
4502    #"
4503   [(set_attr "type" "fmov,sseicvt")
4504    (set_attr "mode" "<MODE>,<ssevecmode>")
4505    (set_attr "unit" "i387,*")
4506    (set_attr "athlon_decode" "*,direct")
4507    (set_attr "amdfam10_decode" "*,double")
4508    (set_attr "bdver1_decode" "*,direct")
4509    (set_attr "fp_int_src" "true")])
4511 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_with_temp"
4512   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4513         (float:MODEF
4514           (match_operand:SWI48 1 "nonimmediate_operand" "m,?r,r,m")))
4515    (clobber (match_operand:SWI48 2 "memory_operand" "=X,m,m,X"))]
4516   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4517   "#"
4518   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4519    (set_attr "mode" "<MODEF:MODE>")
4520    (set_attr "unit" "*,i387,*,*")
4521    (set_attr "athlon_decode" "*,*,double,direct")
4522    (set_attr "amdfam10_decode" "*,*,vector,double")
4523    (set_attr "bdver1_decode" "*,*,double,direct")
4524    (set_attr "fp_int_src" "true")])
4526 (define_split
4527   [(set (match_operand:MODEF 0 "register_operand")
4528         (float:MODEF (match_operand:SWI48 1 "register_operand")))
4529    (clobber (match_operand:SWI48 2 "memory_operand"))]
4530   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4531    && TARGET_INTER_UNIT_CONVERSIONS
4532    && reload_completed
4533    && (SSE_REG_P (operands[0])
4534        || (GET_CODE (operands[0]) == SUBREG
4535            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4536   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4538 (define_split
4539   [(set (match_operand:MODEF 0 "register_operand")
4540         (float:MODEF (match_operand:SWI48 1 "register_operand")))
4541    (clobber (match_operand:SWI48 2 "memory_operand"))]
4542   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4543    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4544    && reload_completed
4545    && (SSE_REG_P (operands[0])
4546        || (GET_CODE (operands[0]) == SUBREG
4547            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4548   [(set (match_dup 2) (match_dup 1))
4549    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4551 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_interunit"
4552   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4553         (float:MODEF
4554           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4555   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4556    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4557   "@
4558    fild%Z1\t%1
4559    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4560    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4561   [(set_attr "type" "fmov,sseicvt,sseicvt")
4562    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4563    (set_attr "mode" "<MODEF:MODE>")
4564    (set (attr "prefix_rex")
4565      (if_then_else
4566        (and (eq_attr "prefix" "maybe_vex")
4567             (match_test "<SWI48:MODE>mode == DImode"))
4568        (const_string "1")
4569        (const_string "*")))
4570    (set_attr "unit" "i387,*,*")
4571    (set_attr "athlon_decode" "*,double,direct")
4572    (set_attr "amdfam10_decode" "*,vector,double")
4573    (set_attr "bdver1_decode" "*,double,direct")
4574    (set_attr "fp_int_src" "true")])
4576 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_nointerunit"
4577   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4578         (float:MODEF
4579           (match_operand:SWI48 1 "memory_operand" "m,m")))]
4580   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4581    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4582   "@
4583    fild%Z1\t%1
4584    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4585   [(set_attr "type" "fmov,sseicvt")
4586    (set_attr "prefix" "orig,maybe_vex")
4587    (set_attr "mode" "<MODEF:MODE>")
4588    (set (attr "prefix_rex")
4589      (if_then_else
4590        (and (eq_attr "prefix" "maybe_vex")
4591             (match_test "<SWI48:MODE>mode == DImode"))
4592        (const_string "1")
4593        (const_string "*")))
4594    (set_attr "athlon_decode" "*,direct")
4595    (set_attr "amdfam10_decode" "*,double")
4596    (set_attr "bdver1_decode" "*,direct")
4597    (set_attr "fp_int_src" "true")])
4599 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4600   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4601         (float:MODEF
4602           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4603    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4604   "TARGET_SSE2 && TARGET_SSE_MATH
4605    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4606   "#"
4607   [(set_attr "type" "sseicvt")
4608    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4609    (set_attr "athlon_decode" "double,direct,double")
4610    (set_attr "amdfam10_decode" "vector,double,double")
4611    (set_attr "bdver1_decode" "double,direct,double")
4612    (set_attr "fp_int_src" "true")])
4614 (define_insn "*floatsi<mode>2_vector_sse"
4615   [(set (match_operand:MODEF 0 "register_operand" "=x")
4616         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4617   "TARGET_SSE2 && TARGET_SSE_MATH
4618    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4619   "#"
4620   [(set_attr "type" "sseicvt")
4621    (set_attr "mode" "<MODE>")
4622    (set_attr "athlon_decode" "direct")
4623    (set_attr "amdfam10_decode" "double")
4624    (set_attr "bdver1_decode" "direct")
4625    (set_attr "fp_int_src" "true")])
4627 (define_split
4628   [(set (match_operand:MODEF 0 "register_operand")
4629         (float:MODEF (match_operand:SI 1 "register_operand")))
4630    (clobber (match_operand:SI 2 "memory_operand"))]
4631   "TARGET_SSE2 && TARGET_SSE_MATH
4632    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4633    && reload_completed
4634    && (SSE_REG_P (operands[0])
4635        || (GET_CODE (operands[0]) == SUBREG
4636            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4637   [(const_int 0)]
4639   rtx op1 = operands[1];
4641   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4642                                      <MODE>mode, 0);
4643   if (GET_CODE (op1) == SUBREG)
4644     op1 = SUBREG_REG (op1);
4646   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES_TO_VEC)
4647     {
4648       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4649       emit_insn (gen_sse2_loadld (operands[4],
4650                                   CONST0_RTX (V4SImode), operands[1]));
4651     }
4652   /* We can ignore possible trapping value in the
4653      high part of SSE register for non-trapping math. */
4654   else if (SSE_REG_P (op1) && !flag_trapping_math)
4655     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4656   else
4657     {
4658       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4659       emit_move_insn (operands[2], operands[1]);
4660       emit_insn (gen_sse2_loadld (operands[4],
4661                                   CONST0_RTX (V4SImode), operands[2]));
4662     }
4663   if (<ssevecmode>mode == V4SFmode)
4664     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4665   else
4666     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4667   DONE;
4670 (define_split
4671   [(set (match_operand:MODEF 0 "register_operand")
4672         (float:MODEF (match_operand:SI 1 "memory_operand")))
4673    (clobber (match_operand:SI 2 "memory_operand"))]
4674   "TARGET_SSE2 && TARGET_SSE_MATH
4675    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4676    && reload_completed
4677    && (SSE_REG_P (operands[0])
4678        || (GET_CODE (operands[0]) == SUBREG
4679            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4680   [(const_int 0)]
4682   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4683                                      <MODE>mode, 0);
4684   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4686   emit_insn (gen_sse2_loadld (operands[4],
4687                               CONST0_RTX (V4SImode), operands[1]));
4688   if (<ssevecmode>mode == V4SFmode)
4689     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4690   else
4691     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4692   DONE;
4695 (define_split
4696   [(set (match_operand:MODEF 0 "register_operand")
4697         (float:MODEF (match_operand:SI 1 "register_operand")))]
4698   "TARGET_SSE2 && TARGET_SSE_MATH
4699    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4700    && reload_completed
4701    && (SSE_REG_P (operands[0])
4702        || (GET_CODE (operands[0]) == SUBREG
4703            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4704   [(const_int 0)]
4706   rtx op1 = operands[1];
4708   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4709                                      <MODE>mode, 0);
4710   if (GET_CODE (op1) == SUBREG)
4711     op1 = SUBREG_REG (op1);
4713   if (GENERAL_REG_P (op1))
4714     {
4715       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4716       if (TARGET_INTER_UNIT_MOVES_TO_VEC)
4717         emit_insn (gen_sse2_loadld (operands[4],
4718                                     CONST0_RTX (V4SImode), operands[1]));
4719       else
4720         {
4721           operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
4722                                               operands[1]);
4723           emit_insn (gen_sse2_loadld (operands[4],
4724                                       CONST0_RTX (V4SImode), operands[5]));
4725           ix86_free_from_memory (GET_MODE (operands[1]));
4726         }
4727     }
4728   /* We can ignore possible trapping value in the
4729      high part of SSE register for non-trapping math. */
4730   else if (SSE_REG_P (op1) && !flag_trapping_math)
4731     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4732   else
4733     gcc_unreachable ();
4734   if (<ssevecmode>mode == V4SFmode)
4735     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4736   else
4737     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4738   DONE;
4741 (define_split
4742   [(set (match_operand:MODEF 0 "register_operand")
4743         (float:MODEF (match_operand:SI 1 "memory_operand")))]
4744   "TARGET_SSE2 && TARGET_SSE_MATH
4745    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4746    && reload_completed
4747    && (SSE_REG_P (operands[0])
4748        || (GET_CODE (operands[0]) == SUBREG
4749            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4750   [(const_int 0)]
4752   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4753                                      <MODE>mode, 0);
4754   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4756   emit_insn (gen_sse2_loadld (operands[4],
4757                               CONST0_RTX (V4SImode), operands[1]));
4758   if (<ssevecmode>mode == V4SFmode)
4759     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4760   else
4761     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4762   DONE;
4765 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_with_temp"
4766   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
4767         (float:MODEF
4768           (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))
4769   (clobber (match_operand:SWI48 2 "memory_operand" "=m,X"))]
4770   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4771   "#"
4772   [(set_attr "type" "sseicvt")
4773    (set_attr "mode" "<MODEF:MODE>")
4774    (set_attr "athlon_decode" "double,direct")
4775    (set_attr "amdfam10_decode" "vector,double")
4776    (set_attr "bdver1_decode" "double,direct")
4777    (set_attr "btver2_decode" "double,double")
4778    (set_attr "fp_int_src" "true")])
4780 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_interunit"
4781   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
4782         (float:MODEF
4783           (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))]
4784   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4785    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4786   "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4787   [(set_attr "type" "sseicvt")
4788    (set_attr "prefix" "maybe_vex")
4789    (set_attr "mode" "<MODEF:MODE>")
4790    (set (attr "prefix_rex")
4791      (if_then_else
4792        (and (eq_attr "prefix" "maybe_vex")
4793             (match_test "<SWI48:MODE>mode == DImode"))
4794        (const_string "1")
4795        (const_string "*")))
4796    (set_attr "athlon_decode" "double,direct")
4797    (set_attr "amdfam10_decode" "vector,double")
4798    (set_attr "bdver1_decode" "double,direct")
4799    (set_attr "btver2_decode" "double,double")
4800    (set_attr "fp_int_src" "true")])
4802 (define_split
4803   [(set (match_operand:MODEF 0 "register_operand")
4804         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))
4805    (clobber (match_operand:SWI48 2 "memory_operand"))]
4806   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4807    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4808    && reload_completed
4809    && (SSE_REG_P (operands[0])
4810        || (GET_CODE (operands[0]) == SUBREG
4811            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4812   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4814 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_nointerunit"
4815   [(set (match_operand:MODEF 0 "register_operand" "=x")
4816         (float:MODEF
4817           (match_operand:SWI48 1 "memory_operand" "m")))]
4818   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4819    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4820   "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4821   [(set_attr "type" "sseicvt")
4822    (set_attr "prefix" "maybe_vex")
4823    (set_attr "mode" "<MODEF:MODE>")
4824    (set (attr "prefix_rex")
4825      (if_then_else
4826        (and (eq_attr "prefix" "maybe_vex")
4827             (match_test "<SWI48:MODE>mode == DImode"))
4828        (const_string "1")
4829        (const_string "*")))
4830    (set_attr "athlon_decode" "direct")
4831    (set_attr "amdfam10_decode" "double")
4832    (set_attr "bdver1_decode" "direct")
4833    (set_attr "fp_int_src" "true")])
4835 (define_split
4836   [(set (match_operand:MODEF 0 "register_operand")
4837         (float:MODEF (match_operand:SWI48 1 "register_operand")))
4838    (clobber (match_operand:SWI48 2 "memory_operand"))]
4839   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4840    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4841    && reload_completed
4842    && (SSE_REG_P (operands[0])
4843        || (GET_CODE (operands[0]) == SUBREG
4844            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4845   [(set (match_dup 2) (match_dup 1))
4846    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4848 (define_split
4849   [(set (match_operand:MODEF 0 "register_operand")
4850         (float:MODEF (match_operand:SWI48 1 "memory_operand")))
4851    (clobber (match_operand:SWI48 2 "memory_operand"))]
4852   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4853    && reload_completed
4854    && (SSE_REG_P (operands[0])
4855        || (GET_CODE (operands[0]) == SUBREG
4856            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4857   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4859 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
4860   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4861         (float:X87MODEF
4862           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
4863   (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
4864   "TARGET_80387
4865    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
4866   "@
4867    fild%Z1\t%1
4868    #"
4869   [(set_attr "type" "fmov,multi")
4870    (set_attr "mode" "<X87MODEF:MODE>")
4871    (set_attr "unit" "*,i387")
4872    (set_attr "fp_int_src" "true")])
4874 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
4875   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4876         (float:X87MODEF
4877           (match_operand:SWI48x 1 "memory_operand" "m")))]
4878   "TARGET_80387
4879    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
4880   "fild%Z1\t%1"
4881   [(set_attr "type" "fmov")
4882    (set_attr "mode" "<X87MODEF:MODE>")
4883    (set_attr "fp_int_src" "true")])
4885 (define_split
4886   [(set (match_operand:X87MODEF 0 "fp_register_operand")
4887         (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
4888    (clobber (match_operand:SWI48x 2 "memory_operand"))]
4889   "TARGET_80387
4890    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4891    && reload_completed"
4892   [(set (match_dup 2) (match_dup 1))
4893    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4895 (define_split
4896   [(set (match_operand:X87MODEF 0 "fp_register_operand")
4897         (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
4898    (clobber (match_operand:SWI48x 2 "memory_operand"))]
4899   "TARGET_80387
4900    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4901    && reload_completed"
4902   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4904 ;; Avoid store forwarding (partial memory) stall penalty
4905 ;; by passing DImode value through XMM registers.  */
4907 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
4908   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4909         (float:X87MODEF
4910           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
4911    (clobber (match_scratch:V4SI 3 "=X,x"))
4912    (clobber (match_scratch:V4SI 4 "=X,x"))
4913    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
4914   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4915    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4916    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
4917   "#"
4918   [(set_attr "type" "multi")
4919    (set_attr "mode" "<X87MODEF:MODE>")
4920    (set_attr "unit" "i387")
4921    (set_attr "fp_int_src" "true")])
4923 (define_split
4924   [(set (match_operand:X87MODEF 0 "fp_register_operand")
4925         (float:X87MODEF (match_operand:DI 1 "register_operand")))
4926    (clobber (match_scratch:V4SI 3))
4927    (clobber (match_scratch:V4SI 4))
4928    (clobber (match_operand:DI 2 "memory_operand"))]
4929   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4930    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4931    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4932    && reload_completed"
4933   [(set (match_dup 2) (match_dup 3))
4934    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4936   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
4937      Assemble the 64-bit DImode value in an xmm register.  */
4938   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
4939                               gen_rtx_SUBREG (SImode, operands[1], 0)));
4940   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
4941                               gen_rtx_SUBREG (SImode, operands[1], 4)));
4942   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
4943                                          operands[4]));
4945   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
4948 (define_split
4949   [(set (match_operand:X87MODEF 0 "fp_register_operand")
4950         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
4951    (clobber (match_scratch:V4SI 3))
4952    (clobber (match_scratch:V4SI 4))
4953    (clobber (match_operand:DI 2 "memory_operand"))]
4954   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4955    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4956    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4957    && reload_completed"
4958   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4960 ;; Avoid store forwarding (partial memory) stall penalty by extending
4961 ;; SImode value to DImode through XMM register instead of pushing two
4962 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES_TO_VEC
4963 ;; targets benefit from this optimization. Also note that fild
4964 ;; loads from memory only.
4966 (define_insn "*floatunssi<mode>2_1"
4967   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4968         (unsigned_float:X87MODEF
4969           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
4970    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
4971    (clobber (match_scratch:SI 3 "=X,x"))]
4972   "!TARGET_64BIT
4973    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4974    && TARGET_SSE"
4975   "#"
4976   [(set_attr "type" "multi")
4977    (set_attr "mode" "<MODE>")])
4979 (define_split
4980   [(set (match_operand:X87MODEF 0 "register_operand")
4981         (unsigned_float:X87MODEF
4982           (match_operand:SI 1 "register_operand")))
4983    (clobber (match_operand:DI 2 "memory_operand"))
4984    (clobber (match_scratch:SI 3))]
4985   "!TARGET_64BIT
4986    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4987    && TARGET_SSE
4988    && reload_completed"
4989   [(set (match_dup 2) (match_dup 1))
4990    (set (match_dup 0)
4991         (float:X87MODEF (match_dup 2)))]
4992   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
4994 (define_split
4995   [(set (match_operand:X87MODEF 0 "register_operand")
4996         (unsigned_float:X87MODEF
4997           (match_operand:SI 1 "memory_operand")))
4998    (clobber (match_operand:DI 2 "memory_operand"))
4999    (clobber (match_scratch:SI 3))]
5000   "!TARGET_64BIT
5001    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5002    && TARGET_SSE
5003    && reload_completed"
5004   [(set (match_dup 2) (match_dup 3))
5005    (set (match_dup 0)
5006         (float:X87MODEF (match_dup 2)))]
5008   emit_move_insn (operands[3], operands[1]);
5009   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5012 (define_expand "floatunssi<mode>2"
5013   [(parallel
5014      [(set (match_operand:X87MODEF 0 "register_operand")
5015            (unsigned_float:X87MODEF
5016              (match_operand:SI 1 "nonimmediate_operand")))
5017       (clobber (match_dup 2))
5018       (clobber (match_scratch:SI 3))])]
5019   "!TARGET_64BIT
5020    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5021         && TARGET_SSE)
5022        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5024   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5025     {
5026       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5027       DONE;
5028     }
5029   else
5030     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5033 (define_expand "floatunsdisf2"
5034   [(use (match_operand:SF 0 "register_operand"))
5035    (use (match_operand:DI 1 "nonimmediate_operand"))]
5036   "TARGET_64BIT && TARGET_SSE_MATH"
5037   "x86_emit_floatuns (operands); DONE;")
5039 (define_expand "floatunsdidf2"
5040   [(use (match_operand:DF 0 "register_operand"))
5041    (use (match_operand:DI 1 "nonimmediate_operand"))]
5042   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5043    && TARGET_SSE2 && TARGET_SSE_MATH"
5045   if (TARGET_64BIT)
5046     x86_emit_floatuns (operands);
5047   else
5048     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5049   DONE;
5052 ;; Load effective address instructions
5054 (define_insn_and_split "*lea<mode>"
5055   [(set (match_operand:SWI48 0 "register_operand" "=r")
5056         (match_operand:SWI48 1 "lea_address_operand" "p"))]
5057   ""
5059   if (SImode_address_operand (operands[1], VOIDmode))
5060     {
5061       gcc_assert (TARGET_64BIT);
5062       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5063     }
5064   else 
5065     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5067   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5068   [(const_int 0)]
5070   enum machine_mode mode = <MODE>mode;
5071   rtx pat;
5073   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5074      change operands[] array behind our back.  */
5075   pat = PATTERN (curr_insn);
5077   operands[0] = SET_DEST (pat);
5078   operands[1] = SET_SRC (pat);
5080   /* Emit all operations in SImode for zero-extended addresses.  Recall
5081      that x86_64 inheretly zero-extends SImode operations to DImode.  */
5082   if (SImode_address_operand (operands[1], VOIDmode))
5083     mode = SImode;
5085   ix86_split_lea_for_addr (curr_insn, operands, mode);
5086   DONE;
5088   [(set_attr "type" "lea")
5089    (set (attr "mode")
5090      (if_then_else
5091        (match_operand 1 "SImode_address_operand")
5092        (const_string "SI")
5093        (const_string "<MODE>")))])
5095 ;; Add instructions
5097 (define_expand "add<mode>3"
5098   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5099         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5100                     (match_operand:SDWIM 2 "<general_operand>")))]
5101   ""
5102   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5104 (define_insn_and_split "*add<dwi>3_doubleword"
5105   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5106         (plus:<DWI>
5107           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5108           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5109    (clobber (reg:CC FLAGS_REG))]
5110   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5111   "#"
5112   "reload_completed"
5113   [(parallel [(set (reg:CC FLAGS_REG)
5114                    (unspec:CC [(match_dup 1) (match_dup 2)]
5115                               UNSPEC_ADD_CARRY))
5116               (set (match_dup 0)
5117                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5118    (parallel [(set (match_dup 3)
5119                    (plus:DWIH
5120                      (match_dup 4)
5121                      (plus:DWIH
5122                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5123                        (match_dup 5))))
5124               (clobber (reg:CC FLAGS_REG))])]
5125   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5127 (define_insn "*add<mode>3_cc"
5128   [(set (reg:CC FLAGS_REG)
5129         (unspec:CC
5130           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5131            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5132           UNSPEC_ADD_CARRY))
5133    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5134         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5135   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5136   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5137   [(set_attr "type" "alu")
5138    (set_attr "mode" "<MODE>")])
5140 (define_insn "addqi3_cc"
5141   [(set (reg:CC FLAGS_REG)
5142         (unspec:CC
5143           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5144            (match_operand:QI 2 "general_operand" "qn,qm")]
5145           UNSPEC_ADD_CARRY))
5146    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5147         (plus:QI (match_dup 1) (match_dup 2)))]
5148   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5149   "add{b}\t{%2, %0|%0, %2}"
5150   [(set_attr "type" "alu")
5151    (set_attr "mode" "QI")])
5153 (define_insn "*add<mode>_1"
5154   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5155         (plus:SWI48
5156           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5157           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5158    (clobber (reg:CC FLAGS_REG))]
5159   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5161   switch (get_attr_type (insn))
5162     {
5163     case TYPE_LEA:
5164       return "#";
5166     case TYPE_INCDEC:
5167       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5168       if (operands[2] == const1_rtx)
5169         return "inc{<imodesuffix>}\t%0";
5170       else
5171         {
5172           gcc_assert (operands[2] == constm1_rtx);
5173           return "dec{<imodesuffix>}\t%0";
5174         }
5176     default:
5177       /* For most processors, ADD is faster than LEA.  This alternative
5178          was added to use ADD as much as possible.  */
5179       if (which_alternative == 2)
5180         {
5181           rtx tmp;
5182           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5183         }
5184         
5185       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5186       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5187         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5189       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5190     }
5192   [(set (attr "type")
5193      (cond [(eq_attr "alternative" "3")
5194               (const_string "lea")
5195             (match_operand:SWI48 2 "incdec_operand")
5196               (const_string "incdec")
5197            ]
5198            (const_string "alu")))
5199    (set (attr "length_immediate")
5200       (if_then_else
5201         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5202         (const_string "1")
5203         (const_string "*")))
5204    (set_attr "mode" "<MODE>")])
5206 ;; It may seem that nonimmediate operand is proper one for operand 1.
5207 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5208 ;; we take care in ix86_binary_operator_ok to not allow two memory
5209 ;; operands so proper swapping will be done in reload.  This allow
5210 ;; patterns constructed from addsi_1 to match.
5212 (define_insn "addsi_1_zext"
5213   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5214         (zero_extend:DI
5215           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5216                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5217    (clobber (reg:CC FLAGS_REG))]
5218   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5220   switch (get_attr_type (insn))
5221     {
5222     case TYPE_LEA:
5223       return "#";
5225     case TYPE_INCDEC:
5226       if (operands[2] == const1_rtx)
5227         return "inc{l}\t%k0";
5228       else
5229         {
5230           gcc_assert (operands[2] == constm1_rtx);
5231           return "dec{l}\t%k0";
5232         }
5234     default:
5235       /* For most processors, ADD is faster than LEA.  This alternative
5236          was added to use ADD as much as possible.  */
5237       if (which_alternative == 1)
5238         {
5239           rtx tmp;
5240           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5241         }
5243       if (x86_maybe_negate_const_int (&operands[2], SImode))
5244         return "sub{l}\t{%2, %k0|%k0, %2}";
5246       return "add{l}\t{%2, %k0|%k0, %2}";
5247     }
5249   [(set (attr "type")
5250      (cond [(eq_attr "alternative" "2")
5251               (const_string "lea")
5252             (match_operand:SI 2 "incdec_operand")
5253               (const_string "incdec")
5254            ]
5255            (const_string "alu")))
5256    (set (attr "length_immediate")
5257       (if_then_else
5258         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5259         (const_string "1")
5260         (const_string "*")))
5261    (set_attr "mode" "SI")])
5263 (define_insn "*addhi_1"
5264   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5265         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5266                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5267    (clobber (reg:CC FLAGS_REG))]
5268   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5270   switch (get_attr_type (insn))
5271     {
5272     case TYPE_LEA:
5273       return "#";
5275     case TYPE_INCDEC:
5276       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5277       if (operands[2] == const1_rtx)
5278         return "inc{w}\t%0";
5279       else
5280         {
5281           gcc_assert (operands[2] == constm1_rtx);
5282           return "dec{w}\t%0";
5283         }
5285     default:
5286       /* For most processors, ADD is faster than LEA.  This alternative
5287          was added to use ADD as much as possible.  */
5288       if (which_alternative == 2)
5289         {
5290           rtx tmp;
5291           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5292         }
5294       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5295       if (x86_maybe_negate_const_int (&operands[2], HImode))
5296         return "sub{w}\t{%2, %0|%0, %2}";
5298       return "add{w}\t{%2, %0|%0, %2}";
5299     }
5301   [(set (attr "type")
5302      (cond [(eq_attr "alternative" "3")
5303               (const_string "lea")
5304             (match_operand:HI 2 "incdec_operand")
5305               (const_string "incdec")
5306            ]
5307            (const_string "alu")))
5308    (set (attr "length_immediate")
5309       (if_then_else
5310         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5311         (const_string "1")
5312         (const_string "*")))
5313    (set_attr "mode" "HI,HI,HI,SI")])
5315 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5316 (define_insn "*addqi_1"
5317   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5318         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5319                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5320    (clobber (reg:CC FLAGS_REG))]
5321   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5323   bool widen = (which_alternative == 3 || which_alternative == 4);
5325   switch (get_attr_type (insn))
5326     {
5327     case TYPE_LEA:
5328       return "#";
5330     case TYPE_INCDEC:
5331       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5332       if (operands[2] == const1_rtx)
5333         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5334       else
5335         {
5336           gcc_assert (operands[2] == constm1_rtx);
5337           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5338         }
5340     default:
5341       /* For most processors, ADD is faster than LEA.  These alternatives
5342          were added to use ADD as much as possible.  */
5343       if (which_alternative == 2 || which_alternative == 4)
5344         {
5345           rtx tmp;
5346           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5347         }
5349       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5350       if (x86_maybe_negate_const_int (&operands[2], QImode))
5351         {
5352           if (widen)
5353             return "sub{l}\t{%2, %k0|%k0, %2}";
5354           else
5355             return "sub{b}\t{%2, %0|%0, %2}";
5356         }
5357       if (widen)
5358         return "add{l}\t{%k2, %k0|%k0, %k2}";
5359       else
5360         return "add{b}\t{%2, %0|%0, %2}";
5361     }
5363   [(set (attr "type")
5364      (cond [(eq_attr "alternative" "5")
5365               (const_string "lea")
5366             (match_operand:QI 2 "incdec_operand")
5367               (const_string "incdec")
5368            ]
5369            (const_string "alu")))
5370    (set (attr "length_immediate")
5371       (if_then_else
5372         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5373         (const_string "1")
5374         (const_string "*")))
5375    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5377 (define_insn "*addqi_1_slp"
5378   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5379         (plus:QI (match_dup 0)
5380                  (match_operand:QI 1 "general_operand" "qn,qm")))
5381    (clobber (reg:CC FLAGS_REG))]
5382   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5383    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5385   switch (get_attr_type (insn))
5386     {
5387     case TYPE_INCDEC:
5388       if (operands[1] == const1_rtx)
5389         return "inc{b}\t%0";
5390       else
5391         {
5392           gcc_assert (operands[1] == constm1_rtx);
5393           return "dec{b}\t%0";
5394         }
5396     default:
5397       if (x86_maybe_negate_const_int (&operands[1], QImode))
5398         return "sub{b}\t{%1, %0|%0, %1}";
5400       return "add{b}\t{%1, %0|%0, %1}";
5401     }
5403   [(set (attr "type")
5404      (if_then_else (match_operand:QI 1 "incdec_operand")
5405         (const_string "incdec")
5406         (const_string "alu1")))
5407    (set (attr "memory")
5408      (if_then_else (match_operand 1 "memory_operand")
5409         (const_string "load")
5410         (const_string "none")))
5411    (set_attr "mode" "QI")])
5413 ;; Split non destructive adds if we cannot use lea.
5414 (define_split
5415   [(set (match_operand:SWI48 0 "register_operand")
5416         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5417                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5418    (clobber (reg:CC FLAGS_REG))]
5419   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5420   [(set (match_dup 0) (match_dup 1))
5421    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5422               (clobber (reg:CC FLAGS_REG))])])
5424 ;; Convert add to the lea pattern to avoid flags dependency.
5425 (define_split
5426   [(set (match_operand:SWI 0 "register_operand")
5427         (plus:SWI (match_operand:SWI 1 "register_operand")
5428                   (match_operand:SWI 2 "<nonmemory_operand>")))
5429    (clobber (reg:CC FLAGS_REG))]
5430   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5431   [(const_int 0)]
5433   enum machine_mode mode = <MODE>mode;
5434   rtx pat;
5436   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5437     { 
5438       mode = SImode; 
5439       operands[0] = gen_lowpart (mode, operands[0]);
5440       operands[1] = gen_lowpart (mode, operands[1]);
5441       operands[2] = gen_lowpart (mode, operands[2]);
5442     }
5444   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5446   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5447   DONE;
5450 ;; Split non destructive adds if we cannot use lea.
5451 (define_split
5452   [(set (match_operand:DI 0 "register_operand")
5453         (zero_extend:DI
5454           (plus:SI (match_operand:SI 1 "register_operand")
5455                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5456    (clobber (reg:CC FLAGS_REG))]
5457   "TARGET_64BIT
5458    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5459   [(set (match_dup 3) (match_dup 1))
5460    (parallel [(set (match_dup 0)
5461                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5462               (clobber (reg:CC FLAGS_REG))])]
5463   "operands[3] = gen_lowpart (SImode, operands[0]);")
5465 ;; Convert add to the lea pattern to avoid flags dependency.
5466 (define_split
5467   [(set (match_operand:DI 0 "register_operand")
5468         (zero_extend:DI
5469           (plus:SI (match_operand:SI 1 "register_operand")
5470                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5471    (clobber (reg:CC FLAGS_REG))]
5472   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5473   [(set (match_dup 0)
5474         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5476 (define_insn "*add<mode>_2"
5477   [(set (reg FLAGS_REG)
5478         (compare
5479           (plus:SWI
5480             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5481             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5482           (const_int 0)))
5483    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5484         (plus:SWI (match_dup 1) (match_dup 2)))]
5485   "ix86_match_ccmode (insn, CCGOCmode)
5486    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5488   switch (get_attr_type (insn))
5489     {
5490     case TYPE_INCDEC:
5491       if (operands[2] == const1_rtx)
5492         return "inc{<imodesuffix>}\t%0";
5493       else
5494         {
5495           gcc_assert (operands[2] == constm1_rtx);
5496           return "dec{<imodesuffix>}\t%0";
5497         }
5499     default:
5500       if (which_alternative == 2)
5501         {
5502           rtx tmp;
5503           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5504         }
5505         
5506       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5507       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5508         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5510       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5511     }
5513   [(set (attr "type")
5514      (if_then_else (match_operand:SWI 2 "incdec_operand")
5515         (const_string "incdec")
5516         (const_string "alu")))
5517    (set (attr "length_immediate")
5518       (if_then_else
5519         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5520         (const_string "1")
5521         (const_string "*")))
5522    (set_attr "mode" "<MODE>")])
5524 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5525 (define_insn "*addsi_2_zext"
5526   [(set (reg FLAGS_REG)
5527         (compare
5528           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5529                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5530           (const_int 0)))
5531    (set (match_operand:DI 0 "register_operand" "=r,r")
5532         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5533   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5534    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5536   switch (get_attr_type (insn))
5537     {
5538     case TYPE_INCDEC:
5539       if (operands[2] == const1_rtx)
5540         return "inc{l}\t%k0";
5541       else
5542         {
5543           gcc_assert (operands[2] == constm1_rtx);
5544           return "dec{l}\t%k0";
5545         }
5547     default:
5548       if (which_alternative == 1)
5549         {
5550           rtx tmp;
5551           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5552         }
5554       if (x86_maybe_negate_const_int (&operands[2], SImode))
5555         return "sub{l}\t{%2, %k0|%k0, %2}";
5557       return "add{l}\t{%2, %k0|%k0, %2}";
5558     }
5560   [(set (attr "type")
5561      (if_then_else (match_operand:SI 2 "incdec_operand")
5562         (const_string "incdec")
5563         (const_string "alu")))
5564    (set (attr "length_immediate")
5565       (if_then_else
5566         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5567         (const_string "1")
5568         (const_string "*")))
5569    (set_attr "mode" "SI")])
5571 (define_insn "*add<mode>_3"
5572   [(set (reg FLAGS_REG)
5573         (compare
5574           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5575           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5576    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5577   "ix86_match_ccmode (insn, CCZmode)
5578    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5580   switch (get_attr_type (insn))
5581     {
5582     case TYPE_INCDEC:
5583       if (operands[2] == const1_rtx)
5584         return "inc{<imodesuffix>}\t%0";
5585       else
5586         {
5587           gcc_assert (operands[2] == constm1_rtx);
5588           return "dec{<imodesuffix>}\t%0";
5589         }
5591     default:
5592       if (which_alternative == 1)
5593         {
5594           rtx tmp;
5595           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5596         }
5598       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5599       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5600         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5602       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5603     }
5605   [(set (attr "type")
5606      (if_then_else (match_operand:SWI 2 "incdec_operand")
5607         (const_string "incdec")
5608         (const_string "alu")))
5609    (set (attr "length_immediate")
5610       (if_then_else
5611         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5612         (const_string "1")
5613         (const_string "*")))
5614    (set_attr "mode" "<MODE>")])
5616 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5617 (define_insn "*addsi_3_zext"
5618   [(set (reg FLAGS_REG)
5619         (compare
5620           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5621           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5622    (set (match_operand:DI 0 "register_operand" "=r,r")
5623         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5624   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5625    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5627   switch (get_attr_type (insn))
5628     {
5629     case TYPE_INCDEC:
5630       if (operands[2] == const1_rtx)
5631         return "inc{l}\t%k0";
5632       else
5633         {
5634           gcc_assert (operands[2] == constm1_rtx);
5635           return "dec{l}\t%k0";
5636         }
5638     default:
5639       if (which_alternative == 1)
5640         {
5641           rtx tmp;
5642           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5643         }
5645       if (x86_maybe_negate_const_int (&operands[2], SImode))
5646         return "sub{l}\t{%2, %k0|%k0, %2}";
5648       return "add{l}\t{%2, %k0|%k0, %2}";
5649     }
5651   [(set (attr "type")
5652      (if_then_else (match_operand:SI 2 "incdec_operand")
5653         (const_string "incdec")
5654         (const_string "alu")))
5655    (set (attr "length_immediate")
5656       (if_then_else
5657         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5658         (const_string "1")
5659         (const_string "*")))
5660    (set_attr "mode" "SI")])
5662 ; For comparisons against 1, -1 and 128, we may generate better code
5663 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5664 ; is matched then.  We can't accept general immediate, because for
5665 ; case of overflows,  the result is messed up.
5666 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5667 ; only for comparisons not depending on it.
5669 (define_insn "*adddi_4"
5670   [(set (reg FLAGS_REG)
5671         (compare
5672           (match_operand:DI 1 "nonimmediate_operand" "0")
5673           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5674    (clobber (match_scratch:DI 0 "=rm"))]
5675   "TARGET_64BIT
5676    && ix86_match_ccmode (insn, CCGCmode)"
5678   switch (get_attr_type (insn))
5679     {
5680     case TYPE_INCDEC:
5681       if (operands[2] == constm1_rtx)
5682         return "inc{q}\t%0";
5683       else
5684         {
5685           gcc_assert (operands[2] == const1_rtx);
5686           return "dec{q}\t%0";
5687         }
5689     default:
5690       if (x86_maybe_negate_const_int (&operands[2], DImode))
5691         return "add{q}\t{%2, %0|%0, %2}";
5693       return "sub{q}\t{%2, %0|%0, %2}";
5694     }
5696   [(set (attr "type")
5697      (if_then_else (match_operand:DI 2 "incdec_operand")
5698         (const_string "incdec")
5699         (const_string "alu")))
5700    (set (attr "length_immediate")
5701       (if_then_else
5702         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5703         (const_string "1")
5704         (const_string "*")))
5705    (set_attr "mode" "DI")])
5707 ; For comparisons against 1, -1 and 128, we may generate better code
5708 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5709 ; is matched then.  We can't accept general immediate, because for
5710 ; case of overflows,  the result is messed up.
5711 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5712 ; only for comparisons not depending on it.
5714 (define_insn "*add<mode>_4"
5715   [(set (reg FLAGS_REG)
5716         (compare
5717           (match_operand:SWI124 1 "nonimmediate_operand" "0")
5718           (match_operand:SWI124 2 "const_int_operand" "n")))
5719    (clobber (match_scratch:SWI124 0 "=<r>m"))]
5720   "ix86_match_ccmode (insn, CCGCmode)"
5722   switch (get_attr_type (insn))
5723     {
5724     case TYPE_INCDEC:
5725       if (operands[2] == constm1_rtx)
5726         return "inc{<imodesuffix>}\t%0";
5727       else
5728         {
5729           gcc_assert (operands[2] == const1_rtx);
5730           return "dec{<imodesuffix>}\t%0";
5731         }
5733     default:
5734       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5735         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5737       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5738     }
5740   [(set (attr "type")
5741      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5742         (const_string "incdec")
5743         (const_string "alu")))
5744    (set (attr "length_immediate")
5745       (if_then_else
5746         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5747         (const_string "1")
5748         (const_string "*")))
5749    (set_attr "mode" "<MODE>")])
5751 (define_insn "*add<mode>_5"
5752   [(set (reg FLAGS_REG)
5753         (compare
5754           (plus:SWI
5755             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5756             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5757           (const_int 0)))
5758    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5759   "ix86_match_ccmode (insn, CCGOCmode)
5760    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5762   switch (get_attr_type (insn))
5763     {
5764     case TYPE_INCDEC:
5765       if (operands[2] == const1_rtx)
5766         return "inc{<imodesuffix>}\t%0";
5767       else
5768         {
5769           gcc_assert (operands[2] == constm1_rtx);
5770           return "dec{<imodesuffix>}\t%0";
5771         }
5773     default:
5774       if (which_alternative == 1)
5775         {
5776           rtx tmp;
5777           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5778         }
5780       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5781       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5782         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5784       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5785     }
5787   [(set (attr "type")
5788      (if_then_else (match_operand:SWI 2 "incdec_operand")
5789         (const_string "incdec")
5790         (const_string "alu")))
5791    (set (attr "length_immediate")
5792       (if_then_else
5793         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5794         (const_string "1")
5795         (const_string "*")))
5796    (set_attr "mode" "<MODE>")])
5798 (define_insn "addqi_ext_1"
5799   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5800                          (const_int 8)
5801                          (const_int 8))
5802         (plus:SI
5803           (zero_extract:SI
5804             (match_operand 1 "ext_register_operand" "0,0")
5805             (const_int 8)
5806             (const_int 8))
5807           (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5808    (clobber (reg:CC FLAGS_REG))]
5809   ""
5811   switch (get_attr_type (insn))
5812     {
5813     case TYPE_INCDEC:
5814       if (operands[2] == const1_rtx)
5815         return "inc{b}\t%h0";
5816       else
5817         {
5818           gcc_assert (operands[2] == constm1_rtx);
5819           return "dec{b}\t%h0";
5820         }
5822     default:
5823       return "add{b}\t{%2, %h0|%h0, %2}";
5824     }
5826   [(set_attr "isa" "*,nox64")
5827    (set (attr "type")
5828      (if_then_else (match_operand:QI 2 "incdec_operand")
5829         (const_string "incdec")
5830         (const_string "alu")))
5831    (set_attr "modrm" "1")
5832    (set_attr "mode" "QI")])
5834 (define_insn "*addqi_ext_2"
5835   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5836                          (const_int 8)
5837                          (const_int 8))
5838         (plus:SI
5839           (zero_extract:SI
5840             (match_operand 1 "ext_register_operand" "%0")
5841             (const_int 8)
5842             (const_int 8))
5843           (zero_extract:SI
5844             (match_operand 2 "ext_register_operand" "Q")
5845             (const_int 8)
5846             (const_int 8))))
5847    (clobber (reg:CC FLAGS_REG))]
5848   ""
5849   "add{b}\t{%h2, %h0|%h0, %h2}"
5850   [(set_attr "type" "alu")
5851    (set_attr "mode" "QI")])
5853 ;; The lea patterns for modes less than 32 bits need to be matched by
5854 ;; several insns converted to real lea by splitters.
5856 (define_insn_and_split "*lea_general_1"
5857   [(set (match_operand 0 "register_operand" "=r")
5858         (plus (plus (match_operand 1 "index_register_operand" "l")
5859                     (match_operand 2 "register_operand" "r"))
5860               (match_operand 3 "immediate_operand" "i")))]
5861   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5862    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5863    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5864    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5865    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5866        || GET_MODE (operands[3]) == VOIDmode)"
5867   "#"
5868   "&& reload_completed"
5869   [(const_int 0)]
5871   enum machine_mode mode = SImode;
5872   rtx pat;
5874   operands[0] = gen_lowpart (mode, operands[0]);
5875   operands[1] = gen_lowpart (mode, operands[1]);
5876   operands[2] = gen_lowpart (mode, operands[2]);
5877   operands[3] = gen_lowpart (mode, operands[3]);
5879   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
5880                       operands[3]);
5882   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5883   DONE;
5885   [(set_attr "type" "lea")
5886    (set_attr "mode" "SI")])
5888 (define_insn_and_split "*lea_general_2"
5889   [(set (match_operand 0 "register_operand" "=r")
5890         (plus (mult (match_operand 1 "index_register_operand" "l")
5891                     (match_operand 2 "const248_operand" "n"))
5892               (match_operand 3 "nonmemory_operand" "ri")))]
5893   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5894    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5895    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5896    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5897        || GET_MODE (operands[3]) == VOIDmode)"
5898   "#"
5899   "&& reload_completed"
5900   [(const_int 0)]
5902   enum machine_mode mode = SImode;
5903   rtx pat;
5905   operands[0] = gen_lowpart (mode, operands[0]);
5906   operands[1] = gen_lowpart (mode, operands[1]);
5907   operands[3] = gen_lowpart (mode, operands[3]);
5909   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
5910                       operands[3]);
5912   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5913   DONE;
5915   [(set_attr "type" "lea")
5916    (set_attr "mode" "SI")])
5918 (define_insn_and_split "*lea_general_3"
5919   [(set (match_operand 0 "register_operand" "=r")
5920         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5921                           (match_operand 2 "const248_operand" "n"))
5922                     (match_operand 3 "register_operand" "r"))
5923               (match_operand 4 "immediate_operand" "i")))]
5924   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5925    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5926    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5927    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5928   "#"
5929   "&& reload_completed"
5930   [(const_int 0)]
5932   enum machine_mode mode = SImode;
5933   rtx pat;
5935   operands[0] = gen_lowpart (mode, operands[0]);
5936   operands[1] = gen_lowpart (mode, operands[1]);
5937   operands[3] = gen_lowpart (mode, operands[3]);
5938   operands[4] = gen_lowpart (mode, operands[4]);
5940   pat = gen_rtx_PLUS (mode,
5941                       gen_rtx_PLUS (mode,
5942                                     gen_rtx_MULT (mode, operands[1],
5943                                                         operands[2]),
5944                                     operands[3]),
5945                       operands[4]);
5947   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5948   DONE;
5950   [(set_attr "type" "lea")
5951    (set_attr "mode" "SI")])
5953 (define_insn_and_split "*lea_general_4"
5954   [(set (match_operand 0 "register_operand" "=r")
5955         (any_or (ashift
5956                   (match_operand 1 "index_register_operand" "l")
5957                   (match_operand 2 "const_int_operand" "n"))
5958                 (match_operand 3 "const_int_operand" "n")))]
5959   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5960       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
5961     || GET_MODE (operands[0]) == SImode
5962     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
5963    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5964    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
5965    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
5966        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
5967   "#"
5968   "&& reload_completed"
5969   [(const_int 0)]
5971   enum machine_mode mode = GET_MODE (operands[0]);
5972   rtx pat;
5974   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5975     { 
5976       mode = SImode; 
5977       operands[0] = gen_lowpart (mode, operands[0]);
5978       operands[1] = gen_lowpart (mode, operands[1]);
5979     }
5981   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
5983   pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
5984                        INTVAL (operands[3]));
5986   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5987   DONE;
5989   [(set_attr "type" "lea")
5990    (set (attr "mode")
5991       (if_then_else (match_operand:DI 0)
5992         (const_string "DI")
5993         (const_string "SI")))])
5995 ;; Subtract instructions
5997 (define_expand "sub<mode>3"
5998   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5999         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6000                      (match_operand:SDWIM 2 "<general_operand>")))]
6001   ""
6002   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6004 (define_insn_and_split "*sub<dwi>3_doubleword"
6005   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6006         (minus:<DWI>
6007           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6008           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6009    (clobber (reg:CC FLAGS_REG))]
6010   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6011   "#"
6012   "reload_completed"
6013   [(parallel [(set (reg:CC FLAGS_REG)
6014                    (compare:CC (match_dup 1) (match_dup 2)))
6015               (set (match_dup 0)
6016                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6017    (parallel [(set (match_dup 3)
6018                    (minus:DWIH
6019                      (match_dup 4)
6020                      (plus:DWIH
6021                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6022                        (match_dup 5))))
6023               (clobber (reg:CC FLAGS_REG))])]
6024   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6026 (define_insn "*sub<mode>_1"
6027   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6028         (minus:SWI
6029           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6030           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6031    (clobber (reg:CC FLAGS_REG))]
6032   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6033   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6034   [(set_attr "type" "alu")
6035    (set_attr "mode" "<MODE>")])
6037 (define_insn "*subsi_1_zext"
6038   [(set (match_operand:DI 0 "register_operand" "=r")
6039         (zero_extend:DI
6040           (minus:SI (match_operand:SI 1 "register_operand" "0")
6041                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6042    (clobber (reg:CC FLAGS_REG))]
6043   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6044   "sub{l}\t{%2, %k0|%k0, %2}"
6045   [(set_attr "type" "alu")
6046    (set_attr "mode" "SI")])
6048 (define_insn "*subqi_1_slp"
6049   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6050         (minus:QI (match_dup 0)
6051                   (match_operand:QI 1 "general_operand" "qn,qm")))
6052    (clobber (reg:CC FLAGS_REG))]
6053   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6054    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6055   "sub{b}\t{%1, %0|%0, %1}"
6056   [(set_attr "type" "alu1")
6057    (set_attr "mode" "QI")])
6059 (define_insn "*sub<mode>_2"
6060   [(set (reg FLAGS_REG)
6061         (compare
6062           (minus:SWI
6063             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6064             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6065           (const_int 0)))
6066    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6067         (minus:SWI (match_dup 1) (match_dup 2)))]
6068   "ix86_match_ccmode (insn, CCGOCmode)
6069    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6070   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6071   [(set_attr "type" "alu")
6072    (set_attr "mode" "<MODE>")])
6074 (define_insn "*subsi_2_zext"
6075   [(set (reg FLAGS_REG)
6076         (compare
6077           (minus:SI (match_operand:SI 1 "register_operand" "0")
6078                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6079           (const_int 0)))
6080    (set (match_operand:DI 0 "register_operand" "=r")
6081         (zero_extend:DI
6082           (minus:SI (match_dup 1)
6083                     (match_dup 2))))]
6084   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6085    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6086   "sub{l}\t{%2, %k0|%k0, %2}"
6087   [(set_attr "type" "alu")
6088    (set_attr "mode" "SI")])
6090 (define_insn "*sub<mode>_3"
6091   [(set (reg FLAGS_REG)
6092         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6093                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6094    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6095         (minus:SWI (match_dup 1) (match_dup 2)))]
6096   "ix86_match_ccmode (insn, CCmode)
6097    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6098   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6099   [(set_attr "type" "alu")
6100    (set_attr "mode" "<MODE>")])
6102 (define_insn "*subsi_3_zext"
6103   [(set (reg FLAGS_REG)
6104         (compare (match_operand:SI 1 "register_operand" "0")
6105                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6106    (set (match_operand:DI 0 "register_operand" "=r")
6107         (zero_extend:DI
6108           (minus:SI (match_dup 1)
6109                     (match_dup 2))))]
6110   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6111    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6112   "sub{l}\t{%2, %1|%1, %2}"
6113   [(set_attr "type" "alu")
6114    (set_attr "mode" "SI")])
6116 ;; Add with carry and subtract with borrow
6118 (define_expand "<plusminus_insn><mode>3_carry"
6119   [(parallel
6120     [(set (match_operand:SWI 0 "nonimmediate_operand")
6121           (plusminus:SWI
6122             (match_operand:SWI 1 "nonimmediate_operand")
6123             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6124                        [(match_operand 3 "flags_reg_operand")
6125                         (const_int 0)])
6126                       (match_operand:SWI 2 "<general_operand>"))))
6127      (clobber (reg:CC FLAGS_REG))])]
6128   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6130 (define_insn "*<plusminus_insn><mode>3_carry"
6131   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6132         (plusminus:SWI
6133           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6134           (plus:SWI
6135             (match_operator 3 "ix86_carry_flag_operator"
6136              [(reg FLAGS_REG) (const_int 0)])
6137             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6138    (clobber (reg:CC FLAGS_REG))]
6139   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6140   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6141   [(set_attr "type" "alu")
6142    (set_attr "use_carry" "1")
6143    (set_attr "pent_pair" "pu")
6144    (set_attr "mode" "<MODE>")])
6146 (define_insn "*addsi3_carry_zext"
6147   [(set (match_operand:DI 0 "register_operand" "=r")
6148         (zero_extend:DI
6149           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6150                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6151                              [(reg FLAGS_REG) (const_int 0)])
6152                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6153    (clobber (reg:CC FLAGS_REG))]
6154   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6155   "adc{l}\t{%2, %k0|%k0, %2}"
6156   [(set_attr "type" "alu")
6157    (set_attr "use_carry" "1")
6158    (set_attr "pent_pair" "pu")
6159    (set_attr "mode" "SI")])
6161 (define_insn "*subsi3_carry_zext"
6162   [(set (match_operand:DI 0 "register_operand" "=r")
6163         (zero_extend:DI
6164           (minus:SI (match_operand:SI 1 "register_operand" "0")
6165                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6166                               [(reg FLAGS_REG) (const_int 0)])
6167                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6168    (clobber (reg:CC FLAGS_REG))]
6169   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6170   "sbb{l}\t{%2, %k0|%k0, %2}"
6171   [(set_attr "type" "alu")
6172    (set_attr "pent_pair" "pu")
6173    (set_attr "mode" "SI")])
6175 ;; ADCX instruction
6177 (define_insn "adcx<mode>3"
6178   [(set (reg:CCC FLAGS_REG)
6179         (compare:CCC
6180           (plus:SWI48
6181             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6182             (plus:SWI48
6183               (match_operator 4 "ix86_carry_flag_operator"
6184                [(match_operand 3 "flags_reg_operand") (const_int 0)])
6185               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6186           (const_int 0)))
6187    (set (match_operand:SWI48 0 "register_operand" "=r")
6188         (plus:SWI48 (match_dup 1)
6189                     (plus:SWI48 (match_op_dup 4
6190                                  [(match_dup 3) (const_int 0)])
6191                                 (match_dup 2))))]
6192   "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6193   "adcx\t{%2, %0|%0, %2}"
6194   [(set_attr "type" "alu")
6195    (set_attr "use_carry" "1")
6196    (set_attr "mode" "<MODE>")])
6198 ;; Overflow setting add and subtract instructions
6200 (define_insn "*add<mode>3_cconly_overflow"
6201   [(set (reg:CCC FLAGS_REG)
6202         (compare:CCC
6203           (plus:SWI
6204             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6205             (match_operand:SWI 2 "<general_operand>" "<g>"))
6206           (match_dup 1)))
6207    (clobber (match_scratch:SWI 0 "=<r>"))]
6208   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6209   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6210   [(set_attr "type" "alu")
6211    (set_attr "mode" "<MODE>")])
6213 (define_insn "*sub<mode>3_cconly_overflow"
6214   [(set (reg:CCC FLAGS_REG)
6215         (compare:CCC
6216           (minus:SWI
6217             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6218             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6219           (match_dup 0)))]
6220   ""
6221   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6222   [(set_attr "type" "icmp")
6223    (set_attr "mode" "<MODE>")])
6225 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6226   [(set (reg:CCC FLAGS_REG)
6227         (compare:CCC
6228             (plusminus:SWI
6229                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6230                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6231             (match_dup 1)))
6232    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6233         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6234   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6235   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6236   [(set_attr "type" "alu")
6237    (set_attr "mode" "<MODE>")])
6239 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6240   [(set (reg:CCC FLAGS_REG)
6241         (compare:CCC
6242           (plusminus:SI
6243             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6244             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6245           (match_dup 1)))
6246    (set (match_operand:DI 0 "register_operand" "=r")
6247         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6248   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6249   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6250   [(set_attr "type" "alu")
6251    (set_attr "mode" "SI")])
6253 ;; The patterns that match these are at the end of this file.
6255 (define_expand "<plusminus_insn>xf3"
6256   [(set (match_operand:XF 0 "register_operand")
6257         (plusminus:XF
6258           (match_operand:XF 1 "register_operand")
6259           (match_operand:XF 2 "register_operand")))]
6260   "TARGET_80387")
6262 (define_expand "<plusminus_insn><mode>3"
6263   [(set (match_operand:MODEF 0 "register_operand")
6264         (plusminus:MODEF
6265           (match_operand:MODEF 1 "register_operand")
6266           (match_operand:MODEF 2 "nonimmediate_operand")))]
6267   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6268     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6270 ;; Multiply instructions
6272 (define_expand "mul<mode>3"
6273   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6274                    (mult:SWIM248
6275                      (match_operand:SWIM248 1 "register_operand")
6276                      (match_operand:SWIM248 2 "<general_operand>")))
6277               (clobber (reg:CC FLAGS_REG))])])
6279 (define_expand "mulqi3"
6280   [(parallel [(set (match_operand:QI 0 "register_operand")
6281                    (mult:QI
6282                      (match_operand:QI 1 "register_operand")
6283                      (match_operand:QI 2 "nonimmediate_operand")))
6284               (clobber (reg:CC FLAGS_REG))])]
6285   "TARGET_QIMODE_MATH")
6287 ;; On AMDFAM10
6288 ;; IMUL reg32/64, reg32/64, imm8        Direct
6289 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6290 ;; IMUL reg32/64, reg32/64, imm32       Direct
6291 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6292 ;; IMUL reg32/64, reg32/64              Direct
6293 ;; IMUL reg32/64, mem32/64              Direct
6295 ;; On BDVER1, all above IMULs use DirectPath
6297 (define_insn "*mul<mode>3_1"
6298   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6299         (mult:SWI48
6300           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6301           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6302    (clobber (reg:CC FLAGS_REG))]
6303   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6304   "@
6305    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6306    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6307    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6308   [(set_attr "type" "imul")
6309    (set_attr "prefix_0f" "0,0,1")
6310    (set (attr "athlon_decode")
6311         (cond [(eq_attr "cpu" "athlon")
6312                   (const_string "vector")
6313                (eq_attr "alternative" "1")
6314                   (const_string "vector")
6315                (and (eq_attr "alternative" "2")
6316                     (match_operand 1 "memory_operand"))
6317                   (const_string "vector")]
6318               (const_string "direct")))
6319    (set (attr "amdfam10_decode")
6320         (cond [(and (eq_attr "alternative" "0,1")
6321                     (match_operand 1 "memory_operand"))
6322                   (const_string "vector")]
6323               (const_string "direct")))
6324    (set_attr "bdver1_decode" "direct")
6325    (set_attr "mode" "<MODE>")])
6327 (define_insn "*mulsi3_1_zext"
6328   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6329         (zero_extend:DI
6330           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6331                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6332    (clobber (reg:CC FLAGS_REG))]
6333   "TARGET_64BIT
6334    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6335   "@
6336    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6337    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6338    imul{l}\t{%2, %k0|%k0, %2}"
6339   [(set_attr "type" "imul")
6340    (set_attr "prefix_0f" "0,0,1")
6341    (set (attr "athlon_decode")
6342         (cond [(eq_attr "cpu" "athlon")
6343                   (const_string "vector")
6344                (eq_attr "alternative" "1")
6345                   (const_string "vector")
6346                (and (eq_attr "alternative" "2")
6347                     (match_operand 1 "memory_operand"))
6348                   (const_string "vector")]
6349               (const_string "direct")))
6350    (set (attr "amdfam10_decode")
6351         (cond [(and (eq_attr "alternative" "0,1")
6352                     (match_operand 1 "memory_operand"))
6353                   (const_string "vector")]
6354               (const_string "direct")))
6355    (set_attr "bdver1_decode" "direct")
6356    (set_attr "mode" "SI")])
6358 ;; On AMDFAM10
6359 ;; IMUL reg16, reg16, imm8      VectorPath
6360 ;; IMUL reg16, mem16, imm8      VectorPath
6361 ;; IMUL reg16, reg16, imm16     VectorPath
6362 ;; IMUL reg16, mem16, imm16     VectorPath
6363 ;; IMUL reg16, reg16            Direct
6364 ;; IMUL reg16, mem16            Direct
6366 ;; On BDVER1, all HI MULs use DoublePath
6368 (define_insn "*mulhi3_1"
6369   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6370         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6371                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6372    (clobber (reg:CC FLAGS_REG))]
6373   "TARGET_HIMODE_MATH
6374    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6375   "@
6376    imul{w}\t{%2, %1, %0|%0, %1, %2}
6377    imul{w}\t{%2, %1, %0|%0, %1, %2}
6378    imul{w}\t{%2, %0|%0, %2}"
6379   [(set_attr "type" "imul")
6380    (set_attr "prefix_0f" "0,0,1")
6381    (set (attr "athlon_decode")
6382         (cond [(eq_attr "cpu" "athlon")
6383                   (const_string "vector")
6384                (eq_attr "alternative" "1,2")
6385                   (const_string "vector")]
6386               (const_string "direct")))
6387    (set (attr "amdfam10_decode")
6388         (cond [(eq_attr "alternative" "0,1")
6389                   (const_string "vector")]
6390               (const_string "direct")))
6391    (set_attr "bdver1_decode" "double")
6392    (set_attr "mode" "HI")])
6394 ;;On AMDFAM10 and BDVER1
6395 ;; MUL reg8     Direct
6396 ;; MUL mem8     Direct
6398 (define_insn "*mulqi3_1"
6399   [(set (match_operand:QI 0 "register_operand" "=a")
6400         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6401                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6402    (clobber (reg:CC FLAGS_REG))]
6403   "TARGET_QIMODE_MATH
6404    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6405   "mul{b}\t%2"
6406   [(set_attr "type" "imul")
6407    (set_attr "length_immediate" "0")
6408    (set (attr "athlon_decode")
6409      (if_then_else (eq_attr "cpu" "athlon")
6410         (const_string "vector")
6411         (const_string "direct")))
6412    (set_attr "amdfam10_decode" "direct")
6413    (set_attr "bdver1_decode" "direct")
6414    (set_attr "mode" "QI")])
6416 (define_expand "<u>mul<mode><dwi>3"
6417   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6418                    (mult:<DWI>
6419                      (any_extend:<DWI>
6420                        (match_operand:DWIH 1 "nonimmediate_operand"))
6421                      (any_extend:<DWI>
6422                        (match_operand:DWIH 2 "register_operand"))))
6423               (clobber (reg:CC FLAGS_REG))])])
6425 (define_expand "<u>mulqihi3"
6426   [(parallel [(set (match_operand:HI 0 "register_operand")
6427                    (mult:HI
6428                      (any_extend:HI
6429                        (match_operand:QI 1 "nonimmediate_operand"))
6430                      (any_extend:HI
6431                        (match_operand:QI 2 "register_operand"))))
6432               (clobber (reg:CC FLAGS_REG))])]
6433   "TARGET_QIMODE_MATH")
6435 (define_insn "*bmi2_umulditi3_1"
6436   [(set (match_operand:DI 0 "register_operand" "=r")
6437         (mult:DI
6438           (match_operand:DI 2 "nonimmediate_operand" "%d")
6439           (match_operand:DI 3 "nonimmediate_operand" "rm")))
6440    (set (match_operand:DI 1 "register_operand" "=r")
6441         (truncate:DI
6442           (lshiftrt:TI
6443             (mult:TI (zero_extend:TI (match_dup 2))
6444                      (zero_extend:TI (match_dup 3)))
6445             (const_int 64))))]
6446   "TARGET_64BIT && TARGET_BMI2
6447    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6448   "mulx\t{%3, %0, %1|%1, %0, %3}"
6449   [(set_attr "type" "imulx")
6450    (set_attr "prefix" "vex")
6451    (set_attr "mode" "DI")])
6453 (define_insn "*bmi2_umulsidi3_1"
6454   [(set (match_operand:SI 0 "register_operand" "=r")
6455         (mult:SI
6456           (match_operand:SI 2 "nonimmediate_operand" "%d")
6457           (match_operand:SI 3 "nonimmediate_operand" "rm")))
6458    (set (match_operand:SI 1 "register_operand" "=r")
6459         (truncate:SI
6460           (lshiftrt:DI
6461             (mult:DI (zero_extend:DI (match_dup 2))
6462                      (zero_extend:DI (match_dup 3)))
6463             (const_int 32))))]
6464   "!TARGET_64BIT && TARGET_BMI2
6465    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6466   "mulx\t{%3, %0, %1|%1, %0, %3}"
6467   [(set_attr "type" "imulx")
6468    (set_attr "prefix" "vex")
6469    (set_attr "mode" "SI")])
6471 (define_insn "*umul<mode><dwi>3_1"
6472   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6473         (mult:<DWI>
6474           (zero_extend:<DWI>
6475             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6476           (zero_extend:<DWI>
6477             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6478    (clobber (reg:CC FLAGS_REG))]
6479   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6480   "@
6481    #
6482    mul{<imodesuffix>}\t%2"
6483   [(set_attr "isa" "bmi2,*")
6484    (set_attr "type" "imulx,imul")
6485    (set_attr "length_immediate" "*,0")
6486    (set (attr "athlon_decode")
6487         (cond [(eq_attr "alternative" "1")
6488                  (if_then_else (eq_attr "cpu" "athlon")
6489                    (const_string "vector")
6490                    (const_string "double"))]
6491               (const_string "*")))
6492    (set_attr "amdfam10_decode" "*,double")
6493    (set_attr "bdver1_decode" "*,direct")
6494    (set_attr "prefix" "vex,orig")
6495    (set_attr "mode" "<MODE>")])
6497 ;; Convert mul to the mulx pattern to avoid flags dependency.
6498 (define_split
6499  [(set (match_operand:<DWI> 0 "register_operand")
6500        (mult:<DWI>
6501          (zero_extend:<DWI>
6502            (match_operand:DWIH 1 "register_operand"))
6503          (zero_extend:<DWI>
6504            (match_operand:DWIH 2 "nonimmediate_operand"))))
6505   (clobber (reg:CC FLAGS_REG))]
6506  "TARGET_BMI2 && reload_completed
6507   && true_regnum (operands[1]) == DX_REG"
6508   [(parallel [(set (match_dup 3)
6509                    (mult:DWIH (match_dup 1) (match_dup 2)))
6510               (set (match_dup 4)
6511                    (truncate:DWIH
6512                      (lshiftrt:<DWI>
6513                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6514                                    (zero_extend:<DWI> (match_dup 2)))
6515                        (match_dup 5))))])]
6517   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6519   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6522 (define_insn "*mul<mode><dwi>3_1"
6523   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6524         (mult:<DWI>
6525           (sign_extend:<DWI>
6526             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6527           (sign_extend:<DWI>
6528             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6529    (clobber (reg:CC FLAGS_REG))]
6530   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6531   "imul{<imodesuffix>}\t%2"
6532   [(set_attr "type" "imul")
6533    (set_attr "length_immediate" "0")
6534    (set (attr "athlon_decode")
6535      (if_then_else (eq_attr "cpu" "athlon")
6536         (const_string "vector")
6537         (const_string "double")))
6538    (set_attr "amdfam10_decode" "double")
6539    (set_attr "bdver1_decode" "direct")
6540    (set_attr "mode" "<MODE>")])
6542 (define_insn "*<u>mulqihi3_1"
6543   [(set (match_operand:HI 0 "register_operand" "=a")
6544         (mult:HI
6545           (any_extend:HI
6546             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6547           (any_extend:HI
6548             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6549    (clobber (reg:CC FLAGS_REG))]
6550   "TARGET_QIMODE_MATH
6551    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6552   "<sgnprefix>mul{b}\t%2"
6553   [(set_attr "type" "imul")
6554    (set_attr "length_immediate" "0")
6555    (set (attr "athlon_decode")
6556      (if_then_else (eq_attr "cpu" "athlon")
6557         (const_string "vector")
6558         (const_string "direct")))
6559    (set_attr "amdfam10_decode" "direct")
6560    (set_attr "bdver1_decode" "direct")
6561    (set_attr "mode" "QI")])
6563 (define_expand "<s>mul<mode>3_highpart"
6564   [(parallel [(set (match_operand:SWI48 0 "register_operand")
6565                    (truncate:SWI48
6566                      (lshiftrt:<DWI>
6567                        (mult:<DWI>
6568                          (any_extend:<DWI>
6569                            (match_operand:SWI48 1 "nonimmediate_operand"))
6570                          (any_extend:<DWI>
6571                            (match_operand:SWI48 2 "register_operand")))
6572                        (match_dup 4))))
6573               (clobber (match_scratch:SWI48 3))
6574               (clobber (reg:CC FLAGS_REG))])]
6575   ""
6576   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6578 (define_insn "*<s>muldi3_highpart_1"
6579   [(set (match_operand:DI 0 "register_operand" "=d")
6580         (truncate:DI
6581           (lshiftrt:TI
6582             (mult:TI
6583               (any_extend:TI
6584                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6585               (any_extend:TI
6586                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6587             (const_int 64))))
6588    (clobber (match_scratch:DI 3 "=1"))
6589    (clobber (reg:CC FLAGS_REG))]
6590   "TARGET_64BIT
6591    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6592   "<sgnprefix>mul{q}\t%2"
6593   [(set_attr "type" "imul")
6594    (set_attr "length_immediate" "0")
6595    (set (attr "athlon_decode")
6596      (if_then_else (eq_attr "cpu" "athlon")
6597         (const_string "vector")
6598         (const_string "double")))
6599    (set_attr "amdfam10_decode" "double")
6600    (set_attr "bdver1_decode" "direct")
6601    (set_attr "mode" "DI")])
6603 (define_insn "*<s>mulsi3_highpart_1"
6604   [(set (match_operand:SI 0 "register_operand" "=d")
6605         (truncate:SI
6606           (lshiftrt:DI
6607             (mult:DI
6608               (any_extend:DI
6609                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6610               (any_extend:DI
6611                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6612             (const_int 32))))
6613    (clobber (match_scratch:SI 3 "=1"))
6614    (clobber (reg:CC FLAGS_REG))]
6615   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6616   "<sgnprefix>mul{l}\t%2"
6617   [(set_attr "type" "imul")
6618    (set_attr "length_immediate" "0")
6619    (set (attr "athlon_decode")
6620      (if_then_else (eq_attr "cpu" "athlon")
6621         (const_string "vector")
6622         (const_string "double")))
6623    (set_attr "amdfam10_decode" "double")
6624    (set_attr "bdver1_decode" "direct")
6625    (set_attr "mode" "SI")])
6627 (define_insn "*<s>mulsi3_highpart_zext"
6628   [(set (match_operand:DI 0 "register_operand" "=d")
6629         (zero_extend:DI (truncate:SI
6630           (lshiftrt:DI
6631             (mult:DI (any_extend:DI
6632                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6633                      (any_extend:DI
6634                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6635             (const_int 32)))))
6636    (clobber (match_scratch:SI 3 "=1"))
6637    (clobber (reg:CC FLAGS_REG))]
6638   "TARGET_64BIT
6639    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6640   "<sgnprefix>mul{l}\t%2"
6641   [(set_attr "type" "imul")
6642    (set_attr "length_immediate" "0")
6643    (set (attr "athlon_decode")
6644      (if_then_else (eq_attr "cpu" "athlon")
6645         (const_string "vector")
6646         (const_string "double")))
6647    (set_attr "amdfam10_decode" "double")
6648    (set_attr "bdver1_decode" "direct")
6649    (set_attr "mode" "SI")])
6651 ;; The patterns that match these are at the end of this file.
6653 (define_expand "mulxf3"
6654   [(set (match_operand:XF 0 "register_operand")
6655         (mult:XF (match_operand:XF 1 "register_operand")
6656                  (match_operand:XF 2 "register_operand")))]
6657   "TARGET_80387")
6659 (define_expand "mul<mode>3"
6660   [(set (match_operand:MODEF 0 "register_operand")
6661         (mult:MODEF (match_operand:MODEF 1 "register_operand")
6662                     (match_operand:MODEF 2 "nonimmediate_operand")))]
6663   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6664     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6666 ;; Divide instructions
6668 ;; The patterns that match these are at the end of this file.
6670 (define_expand "divxf3"
6671   [(set (match_operand:XF 0 "register_operand")
6672         (div:XF (match_operand:XF 1 "register_operand")
6673                 (match_operand:XF 2 "register_operand")))]
6674   "TARGET_80387")
6676 (define_expand "divdf3"
6677   [(set (match_operand:DF 0 "register_operand")
6678         (div:DF (match_operand:DF 1 "register_operand")
6679                 (match_operand:DF 2 "nonimmediate_operand")))]
6680    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6681     || (TARGET_SSE2 && TARGET_SSE_MATH)")
6683 (define_expand "divsf3"
6684   [(set (match_operand:SF 0 "register_operand")
6685         (div:SF (match_operand:SF 1 "register_operand")
6686                 (match_operand:SF 2 "nonimmediate_operand")))]
6687   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6688     || TARGET_SSE_MATH"
6690   if (TARGET_SSE_MATH
6691       && TARGET_RECIP_DIV
6692       && optimize_insn_for_speed_p ()
6693       && flag_finite_math_only && !flag_trapping_math
6694       && flag_unsafe_math_optimizations)
6695     {
6696       ix86_emit_swdivsf (operands[0], operands[1],
6697                          operands[2], SFmode);
6698       DONE;
6699     }
6702 ;; Divmod instructions.
6704 (define_expand "divmod<mode>4"
6705   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6706                    (div:SWIM248
6707                      (match_operand:SWIM248 1 "register_operand")
6708                      (match_operand:SWIM248 2 "nonimmediate_operand")))
6709               (set (match_operand:SWIM248 3 "register_operand")
6710                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
6711               (clobber (reg:CC FLAGS_REG))])])
6713 ;; Split with 8bit unsigned divide:
6714 ;;      if (dividend an divisor are in [0-255])
6715 ;;         use 8bit unsigned integer divide
6716 ;;       else
6717 ;;         use original integer divide
6718 (define_split
6719   [(set (match_operand:SWI48 0 "register_operand")
6720         (div:SWI48 (match_operand:SWI48 2 "register_operand")
6721                     (match_operand:SWI48 3 "nonimmediate_operand")))
6722    (set (match_operand:SWI48 1 "register_operand")
6723         (mod:SWI48 (match_dup 2) (match_dup 3)))
6724    (clobber (reg:CC FLAGS_REG))]
6725   "TARGET_USE_8BIT_IDIV
6726    && TARGET_QIMODE_MATH
6727    && can_create_pseudo_p ()
6728    && !optimize_insn_for_size_p ()"
6729   [(const_int 0)]
6730   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
6732 (define_insn_and_split "divmod<mode>4_1"
6733   [(set (match_operand:SWI48 0 "register_operand" "=a")
6734         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6735                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6736    (set (match_operand:SWI48 1 "register_operand" "=&d")
6737         (mod:SWI48 (match_dup 2) (match_dup 3)))
6738    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6739    (clobber (reg:CC FLAGS_REG))]
6740   ""
6741   "#"
6742   "reload_completed"
6743   [(parallel [(set (match_dup 1)
6744                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
6745               (clobber (reg:CC FLAGS_REG))])
6746    (parallel [(set (match_dup 0)
6747                    (div:SWI48 (match_dup 2) (match_dup 3)))
6748               (set (match_dup 1)
6749                    (mod:SWI48 (match_dup 2) (match_dup 3)))
6750               (use (match_dup 1))
6751               (clobber (reg:CC FLAGS_REG))])]
6753   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6755   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
6756     operands[4] = operands[2];
6757   else
6758     {
6759       /* Avoid use of cltd in favor of a mov+shift.  */
6760       emit_move_insn (operands[1], operands[2]);
6761       operands[4] = operands[1];
6762     }
6764   [(set_attr "type" "multi")
6765    (set_attr "mode" "<MODE>")])
6767 (define_insn_and_split "*divmod<mode>4"
6768   [(set (match_operand:SWIM248 0 "register_operand" "=a")
6769         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6770                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6771    (set (match_operand:SWIM248 1 "register_operand" "=&d")
6772         (mod:SWIM248 (match_dup 2) (match_dup 3)))
6773    (clobber (reg:CC FLAGS_REG))]
6774   ""
6775   "#"
6776   "reload_completed"
6777   [(parallel [(set (match_dup 1)
6778                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
6779               (clobber (reg:CC FLAGS_REG))])
6780    (parallel [(set (match_dup 0)
6781                    (div:SWIM248 (match_dup 2) (match_dup 3)))
6782               (set (match_dup 1)
6783                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
6784               (use (match_dup 1))
6785               (clobber (reg:CC FLAGS_REG))])]
6787   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6789   if (<MODE>mode != HImode
6790       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
6791     operands[4] = operands[2];
6792   else
6793     {
6794       /* Avoid use of cltd in favor of a mov+shift.  */
6795       emit_move_insn (operands[1], operands[2]);
6796       operands[4] = operands[1];
6797     }
6799   [(set_attr "type" "multi")
6800    (set_attr "mode" "<MODE>")])
6802 (define_insn "*divmod<mode>4_noext"
6803   [(set (match_operand:SWIM248 0 "register_operand" "=a")
6804         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6805                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6806    (set (match_operand:SWIM248 1 "register_operand" "=d")
6807         (mod:SWIM248 (match_dup 2) (match_dup 3)))
6808    (use (match_operand:SWIM248 4 "register_operand" "1"))
6809    (clobber (reg:CC FLAGS_REG))]
6810   ""
6811   "idiv{<imodesuffix>}\t%3"
6812   [(set_attr "type" "idiv")
6813    (set_attr "mode" "<MODE>")])
6815 (define_expand "divmodqi4"
6816   [(parallel [(set (match_operand:QI 0 "register_operand")
6817                    (div:QI
6818                      (match_operand:QI 1 "register_operand")
6819                      (match_operand:QI 2 "nonimmediate_operand")))
6820               (set (match_operand:QI 3 "register_operand")
6821                    (mod:QI (match_dup 1) (match_dup 2)))
6822               (clobber (reg:CC FLAGS_REG))])]
6823   "TARGET_QIMODE_MATH"
6825   rtx div, mod, insn;
6826   rtx tmp0, tmp1;
6827   
6828   tmp0 = gen_reg_rtx (HImode);
6829   tmp1 = gen_reg_rtx (HImode);
6831   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
6832      in AX.  */
6833   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
6834   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
6836   /* Extract remainder from AH.  */
6837   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
6838   insn = emit_move_insn (operands[3], tmp1);
6840   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
6841   set_unique_reg_note (insn, REG_EQUAL, mod);
6843   /* Extract quotient from AL.  */
6844   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
6846   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
6847   set_unique_reg_note (insn, REG_EQUAL, div);
6849   DONE;
6852 ;; Divide AX by r/m8, with result stored in
6853 ;; AL <- Quotient
6854 ;; AH <- Remainder
6855 ;; Change div/mod to HImode and extend the second argument to HImode
6856 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
6857 ;; combine may fail.
6858 (define_insn "divmodhiqi3"
6859   [(set (match_operand:HI 0 "register_operand" "=a")
6860         (ior:HI
6861           (ashift:HI
6862             (zero_extend:HI
6863               (truncate:QI
6864                 (mod:HI (match_operand:HI 1 "register_operand" "0")
6865                         (sign_extend:HI
6866                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
6867             (const_int 8))
6868           (zero_extend:HI
6869             (truncate:QI
6870               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
6871    (clobber (reg:CC FLAGS_REG))]
6872   "TARGET_QIMODE_MATH"
6873   "idiv{b}\t%2"
6874   [(set_attr "type" "idiv")
6875    (set_attr "mode" "QI")])
6877 (define_expand "udivmod<mode>4"
6878   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6879                    (udiv:SWIM248
6880                      (match_operand:SWIM248 1 "register_operand")
6881                      (match_operand:SWIM248 2 "nonimmediate_operand")))
6882               (set (match_operand:SWIM248 3 "register_operand")
6883                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
6884               (clobber (reg:CC FLAGS_REG))])])
6886 ;; Split with 8bit unsigned divide:
6887 ;;      if (dividend an divisor are in [0-255])
6888 ;;         use 8bit unsigned integer divide
6889 ;;       else
6890 ;;         use original integer divide
6891 (define_split
6892   [(set (match_operand:SWI48 0 "register_operand")
6893         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
6894                     (match_operand:SWI48 3 "nonimmediate_operand")))
6895    (set (match_operand:SWI48 1 "register_operand")
6896         (umod:SWI48 (match_dup 2) (match_dup 3)))
6897    (clobber (reg:CC FLAGS_REG))]
6898   "TARGET_USE_8BIT_IDIV
6899    && TARGET_QIMODE_MATH
6900    && can_create_pseudo_p ()
6901    && !optimize_insn_for_size_p ()"
6902   [(const_int 0)]
6903   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
6905 (define_insn_and_split "udivmod<mode>4_1"
6906   [(set (match_operand:SWI48 0 "register_operand" "=a")
6907         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6908                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6909    (set (match_operand:SWI48 1 "register_operand" "=&d")
6910         (umod:SWI48 (match_dup 2) (match_dup 3)))
6911    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6912    (clobber (reg:CC FLAGS_REG))]
6913   ""
6914   "#"
6915   "reload_completed"
6916   [(set (match_dup 1) (const_int 0))
6917    (parallel [(set (match_dup 0)
6918                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
6919               (set (match_dup 1)
6920                    (umod:SWI48 (match_dup 2) (match_dup 3)))
6921               (use (match_dup 1))
6922               (clobber (reg:CC FLAGS_REG))])]
6923   ""
6924   [(set_attr "type" "multi")
6925    (set_attr "mode" "<MODE>")])
6927 (define_insn_and_split "*udivmod<mode>4"
6928   [(set (match_operand:SWIM248 0 "register_operand" "=a")
6929         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6930                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6931    (set (match_operand:SWIM248 1 "register_operand" "=&d")
6932         (umod:SWIM248 (match_dup 2) (match_dup 3)))
6933    (clobber (reg:CC FLAGS_REG))]
6934   ""
6935   "#"
6936   "reload_completed"
6937   [(set (match_dup 1) (const_int 0))
6938    (parallel [(set (match_dup 0)
6939                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
6940               (set (match_dup 1)
6941                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
6942               (use (match_dup 1))
6943               (clobber (reg:CC FLAGS_REG))])]
6944   ""
6945   [(set_attr "type" "multi")
6946    (set_attr "mode" "<MODE>")])
6948 (define_insn "*udivmod<mode>4_noext"
6949   [(set (match_operand:SWIM248 0 "register_operand" "=a")
6950         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6951                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6952    (set (match_operand:SWIM248 1 "register_operand" "=d")
6953         (umod:SWIM248 (match_dup 2) (match_dup 3)))
6954    (use (match_operand:SWIM248 4 "register_operand" "1"))
6955    (clobber (reg:CC FLAGS_REG))]
6956   ""
6957   "div{<imodesuffix>}\t%3"
6958   [(set_attr "type" "idiv")
6959    (set_attr "mode" "<MODE>")])
6961 (define_expand "udivmodqi4"
6962   [(parallel [(set (match_operand:QI 0 "register_operand")
6963                    (udiv:QI
6964                      (match_operand:QI 1 "register_operand")
6965                      (match_operand:QI 2 "nonimmediate_operand")))
6966               (set (match_operand:QI 3 "register_operand")
6967                    (umod:QI (match_dup 1) (match_dup 2)))
6968               (clobber (reg:CC FLAGS_REG))])]
6969   "TARGET_QIMODE_MATH"
6971   rtx div, mod, insn;
6972   rtx tmp0, tmp1;
6973   
6974   tmp0 = gen_reg_rtx (HImode);
6975   tmp1 = gen_reg_rtx (HImode);
6977   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
6978      in AX.  */
6979   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
6980   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
6982   /* Extract remainder from AH.  */
6983   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
6984   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
6985   insn = emit_move_insn (operands[3], tmp1);
6987   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
6988   set_unique_reg_note (insn, REG_EQUAL, mod);
6990   /* Extract quotient from AL.  */
6991   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
6993   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
6994   set_unique_reg_note (insn, REG_EQUAL, div);
6996   DONE;
6999 (define_insn "udivmodhiqi3"
7000   [(set (match_operand:HI 0 "register_operand" "=a")
7001         (ior:HI
7002           (ashift:HI
7003             (zero_extend:HI
7004               (truncate:QI
7005                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7006                         (zero_extend:HI
7007                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7008             (const_int 8))
7009           (zero_extend:HI
7010             (truncate:QI
7011               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7012    (clobber (reg:CC FLAGS_REG))]
7013   "TARGET_QIMODE_MATH"
7014   "div{b}\t%2"
7015   [(set_attr "type" "idiv")
7016    (set_attr "mode" "QI")])
7018 ;; We cannot use div/idiv for double division, because it causes
7019 ;; "division by zero" on the overflow and that's not what we expect
7020 ;; from truncate.  Because true (non truncating) double division is
7021 ;; never generated, we can't create this insn anyway.
7023 ;(define_insn ""
7024 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7025 ;       (truncate:SI
7026 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7027 ;                  (zero_extend:DI
7028 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7029 ;   (set (match_operand:SI 3 "register_operand" "=d")
7030 ;       (truncate:SI
7031 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7032 ;   (clobber (reg:CC FLAGS_REG))]
7033 ;  ""
7034 ;  "div{l}\t{%2, %0|%0, %2}"
7035 ;  [(set_attr "type" "idiv")])
7037 ;;- Logical AND instructions
7039 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7040 ;; Note that this excludes ah.
7042 (define_expand "testsi_ccno_1"
7043   [(set (reg:CCNO FLAGS_REG)
7044         (compare:CCNO
7045           (and:SI (match_operand:SI 0 "nonimmediate_operand")
7046                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
7047           (const_int 0)))])
7049 (define_expand "testqi_ccz_1"
7050   [(set (reg:CCZ FLAGS_REG)
7051         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7052                              (match_operand:QI 1 "nonmemory_operand"))
7053                  (const_int 0)))])
7055 (define_expand "testdi_ccno_1"
7056   [(set (reg:CCNO FLAGS_REG)
7057         (compare:CCNO
7058           (and:DI (match_operand:DI 0 "nonimmediate_operand")
7059                   (match_operand:DI 1 "x86_64_szext_general_operand"))
7060           (const_int 0)))]
7061   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7063 (define_insn "*testdi_1"
7064   [(set (reg FLAGS_REG)
7065         (compare
7066          (and:DI
7067           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7068           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7069          (const_int 0)))]
7070   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7071    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7072   "@
7073    test{l}\t{%k1, %k0|%k0, %k1}
7074    test{l}\t{%k1, %k0|%k0, %k1}
7075    test{q}\t{%1, %0|%0, %1}
7076    test{q}\t{%1, %0|%0, %1}
7077    test{q}\t{%1, %0|%0, %1}"
7078   [(set_attr "type" "test")
7079    (set_attr "modrm" "0,1,0,1,1")
7080    (set_attr "mode" "SI,SI,DI,DI,DI")])
7082 (define_insn "*testqi_1_maybe_si"
7083   [(set (reg FLAGS_REG)
7084         (compare
7085           (and:QI
7086             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7087             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7088           (const_int 0)))]
7089    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7090     && ix86_match_ccmode (insn,
7091                          CONST_INT_P (operands[1])
7092                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7094   if (which_alternative == 3)
7095     {
7096       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7097         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7098       return "test{l}\t{%1, %k0|%k0, %1}";
7099     }
7100   return "test{b}\t{%1, %0|%0, %1}";
7102   [(set_attr "type" "test")
7103    (set_attr "modrm" "0,1,1,1")
7104    (set_attr "mode" "QI,QI,QI,SI")
7105    (set_attr "pent_pair" "uv,np,uv,np")])
7107 (define_insn "*test<mode>_1"
7108   [(set (reg FLAGS_REG)
7109         (compare
7110          (and:SWI124
7111           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7112           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7113          (const_int 0)))]
7114   "ix86_match_ccmode (insn, CCNOmode)
7115    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7116   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7117   [(set_attr "type" "test")
7118    (set_attr "modrm" "0,1,1")
7119    (set_attr "mode" "<MODE>")
7120    (set_attr "pent_pair" "uv,np,uv")])
7122 (define_expand "testqi_ext_ccno_0"
7123   [(set (reg:CCNO FLAGS_REG)
7124         (compare:CCNO
7125           (and:SI
7126             (zero_extract:SI
7127               (match_operand 0 "ext_register_operand")
7128               (const_int 8)
7129               (const_int 8))
7130             (match_operand 1 "const_int_operand"))
7131           (const_int 0)))])
7133 (define_insn "*testqi_ext_0"
7134   [(set (reg FLAGS_REG)
7135         (compare
7136           (and:SI
7137             (zero_extract:SI
7138               (match_operand 0 "ext_register_operand" "Q")
7139               (const_int 8)
7140               (const_int 8))
7141             (match_operand 1 "const_int_operand" "n"))
7142           (const_int 0)))]
7143   "ix86_match_ccmode (insn, CCNOmode)"
7144   "test{b}\t{%1, %h0|%h0, %1}"
7145   [(set_attr "type" "test")
7146    (set_attr "mode" "QI")
7147    (set_attr "length_immediate" "1")
7148    (set_attr "modrm" "1")
7149    (set_attr "pent_pair" "np")])
7151 (define_insn "*testqi_ext_1"
7152   [(set (reg FLAGS_REG)
7153         (compare
7154           (and:SI
7155             (zero_extract:SI
7156               (match_operand 0 "ext_register_operand" "Q,Q")
7157               (const_int 8)
7158               (const_int 8))
7159             (zero_extend:SI
7160               (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7161           (const_int 0)))]
7162   "ix86_match_ccmode (insn, CCNOmode)"
7163   "test{b}\t{%1, %h0|%h0, %1}"
7164   [(set_attr "isa" "*,nox64")
7165    (set_attr "type" "test")
7166    (set_attr "mode" "QI")])
7168 (define_insn "*testqi_ext_2"
7169   [(set (reg FLAGS_REG)
7170         (compare
7171           (and:SI
7172             (zero_extract:SI
7173               (match_operand 0 "ext_register_operand" "Q")
7174               (const_int 8)
7175               (const_int 8))
7176             (zero_extract:SI
7177               (match_operand 1 "ext_register_operand" "Q")
7178               (const_int 8)
7179               (const_int 8)))
7180           (const_int 0)))]
7181   "ix86_match_ccmode (insn, CCNOmode)"
7182   "test{b}\t{%h1, %h0|%h0, %h1}"
7183   [(set_attr "type" "test")
7184    (set_attr "mode" "QI")])
7186 ;; Combine likes to form bit extractions for some tests.  Humor it.
7187 (define_insn "*testqi_ext_3"
7188   [(set (reg FLAGS_REG)
7189         (compare (zero_extract:SWI48
7190                    (match_operand 0 "nonimmediate_operand" "rm")
7191                    (match_operand:SWI48 1 "const_int_operand")
7192                    (match_operand:SWI48 2 "const_int_operand"))
7193                  (const_int 0)))]
7194   "ix86_match_ccmode (insn, CCNOmode)
7195    && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7196        || GET_MODE (operands[0]) == SImode
7197        || GET_MODE (operands[0]) == HImode
7198        || GET_MODE (operands[0]) == QImode)
7199    /* Ensure that resulting mask is zero or sign extended operand.  */
7200    && INTVAL (operands[2]) >= 0
7201    && ((INTVAL (operands[1]) > 0
7202         && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7203        || (<MODE>mode == DImode
7204            && INTVAL (operands[1]) > 32
7205            && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7206   "#")
7208 (define_split
7209   [(set (match_operand 0 "flags_reg_operand")
7210         (match_operator 1 "compare_operator"
7211           [(zero_extract
7212              (match_operand 2 "nonimmediate_operand")
7213              (match_operand 3 "const_int_operand")
7214              (match_operand 4 "const_int_operand"))
7215            (const_int 0)]))]
7216   "ix86_match_ccmode (insn, CCNOmode)"
7217   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7219   rtx val = operands[2];
7220   HOST_WIDE_INT len = INTVAL (operands[3]);
7221   HOST_WIDE_INT pos = INTVAL (operands[4]);
7222   HOST_WIDE_INT mask;
7223   enum machine_mode mode, submode;
7225   mode = GET_MODE (val);
7226   if (MEM_P (val))
7227     {
7228       /* ??? Combine likes to put non-volatile mem extractions in QImode
7229          no matter the size of the test.  So find a mode that works.  */
7230       if (! MEM_VOLATILE_P (val))
7231         {
7232           mode = smallest_mode_for_size (pos + len, MODE_INT);
7233           val = adjust_address (val, mode, 0);
7234         }
7235     }
7236   else if (GET_CODE (val) == SUBREG
7237            && (submode = GET_MODE (SUBREG_REG (val)),
7238                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7239            && pos + len <= GET_MODE_BITSIZE (submode)
7240            && GET_MODE_CLASS (submode) == MODE_INT)
7241     {
7242       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7243       mode = submode;
7244       val = SUBREG_REG (val);
7245     }
7246   else if (mode == HImode && pos + len <= 8)
7247     {
7248       /* Small HImode tests can be converted to QImode.  */
7249       mode = QImode;
7250       val = gen_lowpart (QImode, val);
7251     }
7253   if (len == HOST_BITS_PER_WIDE_INT)
7254     mask = -1;
7255   else
7256     mask = ((HOST_WIDE_INT)1 << len) - 1;
7257   mask <<= pos;
7259   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7262 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7263 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7264 ;; this is relatively important trick.
7265 ;; Do the conversion only post-reload to avoid limiting of the register class
7266 ;; to QI regs.
7267 (define_split
7268   [(set (match_operand 0 "flags_reg_operand")
7269         (match_operator 1 "compare_operator"
7270           [(and (match_operand 2 "register_operand")
7271                 (match_operand 3 "const_int_operand"))
7272            (const_int 0)]))]
7273    "reload_completed
7274     && QI_REG_P (operands[2])
7275     && GET_MODE (operands[2]) != QImode
7276     && ((ix86_match_ccmode (insn, CCZmode)
7277          && !(INTVAL (operands[3]) & ~(255 << 8)))
7278         || (ix86_match_ccmode (insn, CCNOmode)
7279             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7280   [(set (match_dup 0)
7281         (match_op_dup 1
7282           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7283                    (match_dup 3))
7284            (const_int 0)]))]
7286   operands[2] = gen_lowpart (SImode, operands[2]);
7287   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7290 (define_split
7291   [(set (match_operand 0 "flags_reg_operand")
7292         (match_operator 1 "compare_operator"
7293           [(and (match_operand 2 "nonimmediate_operand")
7294                 (match_operand 3 "const_int_operand"))
7295            (const_int 0)]))]
7296    "reload_completed
7297     && GET_MODE (operands[2]) != QImode
7298     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7299     && ((ix86_match_ccmode (insn, CCZmode)
7300          && !(INTVAL (operands[3]) & ~255))
7301         || (ix86_match_ccmode (insn, CCNOmode)
7302             && !(INTVAL (operands[3]) & ~127)))"
7303   [(set (match_dup 0)
7304         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7305                          (const_int 0)]))]
7307   operands[2] = gen_lowpart (QImode, operands[2]);
7308   operands[3] = gen_lowpart (QImode, operands[3]);
7311 ;; %%% This used to optimize known byte-wide and operations to memory,
7312 ;; and sometimes to QImode registers.  If this is considered useful,
7313 ;; it should be done with splitters.
7315 (define_expand "and<mode>3"
7316   [(set (match_operand:SWIM 0 "nonimmediate_operand")
7317         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7318                   (match_operand:SWIM 2 "<general_szext_operand>")))]
7319   ""
7321   enum machine_mode mode = <MODE>mode;
7322   rtx (*insn) (rtx, rtx);
7324   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7325     {
7326       HOST_WIDE_INT ival = INTVAL (operands[2]);
7328       if (ival == (HOST_WIDE_INT) 0xffffffff)
7329         mode = SImode;
7330       else if (ival == 0xffff)
7331         mode = HImode;
7332       else if (ival == 0xff)
7333         mode = QImode;
7334       }
7336   if (mode == <MODE>mode)
7337     {
7338       ix86_expand_binary_operator (AND, <MODE>mode, operands);
7339       DONE;
7340     }
7342   if (<MODE>mode == DImode)
7343     insn = (mode == SImode)
7344            ? gen_zero_extendsidi2
7345            : (mode == HImode)
7346            ? gen_zero_extendhidi2
7347            : gen_zero_extendqidi2;
7348   else if (<MODE>mode == SImode)
7349     insn = (mode == HImode)
7350            ? gen_zero_extendhisi2
7351            : gen_zero_extendqisi2;
7352   else if (<MODE>mode == HImode)
7353     insn = gen_zero_extendqihi2;
7354   else
7355     gcc_unreachable ();
7357   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7358   DONE;
7361 (define_insn "*anddi_1"
7362   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7363         (and:DI
7364          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7365          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7366    (clobber (reg:CC FLAGS_REG))]
7367   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7369   switch (get_attr_type (insn))
7370     {
7371     case TYPE_IMOVX:
7372       return "#";
7374     default:
7375       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7376       if (get_attr_mode (insn) == MODE_SI)
7377         return "and{l}\t{%k2, %k0|%k0, %k2}";
7378       else
7379         return "and{q}\t{%2, %0|%0, %2}";
7380     }
7382   [(set_attr "type" "alu,alu,alu,imovx")
7383    (set_attr "length_immediate" "*,*,*,0")
7384    (set (attr "prefix_rex")
7385      (if_then_else
7386        (and (eq_attr "type" "imovx")
7387             (and (match_test "INTVAL (operands[2]) == 0xff")
7388                  (match_operand 1 "ext_QIreg_operand")))
7389        (const_string "1")
7390        (const_string "*")))
7391    (set_attr "mode" "SI,DI,DI,SI")])
7393 (define_insn "*andsi_1"
7394   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7395         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7396                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7397    (clobber (reg:CC FLAGS_REG))]
7398   "ix86_binary_operator_ok (AND, SImode, operands)"
7400   switch (get_attr_type (insn))
7401     {
7402     case TYPE_IMOVX:
7403       return "#";
7405     default:
7406       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7407       return "and{l}\t{%2, %0|%0, %2}";
7408     }
7410   [(set_attr "type" "alu,alu,imovx")
7411    (set (attr "prefix_rex")
7412      (if_then_else
7413        (and (eq_attr "type" "imovx")
7414             (and (match_test "INTVAL (operands[2]) == 0xff")
7415                  (match_operand 1 "ext_QIreg_operand")))
7416        (const_string "1")
7417        (const_string "*")))
7418    (set_attr "length_immediate" "*,*,0")
7419    (set_attr "mode" "SI")])
7421 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7422 (define_insn "*andsi_1_zext"
7423   [(set (match_operand:DI 0 "register_operand" "=r")
7424         (zero_extend:DI
7425           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7426                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7427    (clobber (reg:CC FLAGS_REG))]
7428   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7429   "and{l}\t{%2, %k0|%k0, %2}"
7430   [(set_attr "type" "alu")
7431    (set_attr "mode" "SI")])
7433 (define_insn "*andhi_1"
7434   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7435         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7436                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7437    (clobber (reg:CC FLAGS_REG))]
7438   "ix86_binary_operator_ok (AND, HImode, operands)"
7440   switch (get_attr_type (insn))
7441     {
7442     case TYPE_IMOVX:
7443       return "#";
7445     default:
7446       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7447       return "and{w}\t{%2, %0|%0, %2}";
7448     }
7450   [(set_attr "type" "alu,alu,imovx")
7451    (set_attr "length_immediate" "*,*,0")
7452    (set (attr "prefix_rex")
7453      (if_then_else
7454        (and (eq_attr "type" "imovx")
7455             (match_operand 1 "ext_QIreg_operand"))
7456        (const_string "1")
7457        (const_string "*")))
7458    (set_attr "mode" "HI,HI,SI")])
7460 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7461 (define_insn "*andqi_1"
7462   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7463         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7464                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7465    (clobber (reg:CC FLAGS_REG))]
7466   "ix86_binary_operator_ok (AND, QImode, operands)"
7467   "@
7468    and{b}\t{%2, %0|%0, %2}
7469    and{b}\t{%2, %0|%0, %2}
7470    and{l}\t{%k2, %k0|%k0, %k2}"
7471   [(set_attr "type" "alu")
7472    (set_attr "mode" "QI,QI,SI")])
7474 (define_insn "*andqi_1_slp"
7475   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7476         (and:QI (match_dup 0)
7477                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7478    (clobber (reg:CC FLAGS_REG))]
7479   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7480    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7481   "and{b}\t{%1, %0|%0, %1}"
7482   [(set_attr "type" "alu1")
7483    (set_attr "mode" "QI")])
7485 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7486 (define_split
7487   [(set (match_operand:DI 0 "register_operand")
7488         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7489                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7490    (clobber (reg:CC FLAGS_REG))]
7491   "TARGET_64BIT"
7492   [(parallel [(set (match_dup 0)
7493                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7494               (clobber (reg:CC FLAGS_REG))])]
7495   "operands[2] = gen_lowpart (SImode, operands[2]);")
7497 (define_split
7498   [(set (match_operand:SWI248 0 "register_operand")
7499         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7500                     (match_operand:SWI248 2 "const_int_operand")))
7501    (clobber (reg:CC FLAGS_REG))]
7502   "reload_completed
7503    && true_regnum (operands[0]) != true_regnum (operands[1])"
7504   [(const_int 0)]
7506   HOST_WIDE_INT ival = INTVAL (operands[2]);
7507   enum machine_mode mode;
7508   rtx (*insn) (rtx, rtx);
7510   if (ival == (HOST_WIDE_INT) 0xffffffff)
7511     mode = SImode;
7512   else if (ival == 0xffff)
7513     mode = HImode;
7514   else
7515     {
7516       gcc_assert (ival == 0xff);
7517       mode = QImode;
7518     }
7520   if (<MODE>mode == DImode)
7521     insn = (mode == SImode)
7522            ? gen_zero_extendsidi2
7523            : (mode == HImode)
7524            ? gen_zero_extendhidi2
7525            : gen_zero_extendqidi2;
7526   else
7527     {
7528       if (<MODE>mode != SImode)
7529         /* Zero extend to SImode to avoid partial register stalls.  */
7530         operands[0] = gen_lowpart (SImode, operands[0]);
7532       insn = (mode == HImode)
7533              ? gen_zero_extendhisi2
7534              : gen_zero_extendqisi2;
7535     }
7536   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7537   DONE;
7540 (define_split
7541   [(set (match_operand 0 "register_operand")
7542         (and (match_dup 0)
7543              (const_int -65536)))
7544    (clobber (reg:CC FLAGS_REG))]
7545   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7546     || optimize_function_for_size_p (cfun)"
7547   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7548   "operands[1] = gen_lowpart (HImode, operands[0]);")
7550 (define_split
7551   [(set (match_operand 0 "ext_register_operand")
7552         (and (match_dup 0)
7553              (const_int -256)))
7554    (clobber (reg:CC FLAGS_REG))]
7555   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7556    && reload_completed"
7557   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7558   "operands[1] = gen_lowpart (QImode, operands[0]);")
7560 (define_split
7561   [(set (match_operand 0 "ext_register_operand")
7562         (and (match_dup 0)
7563              (const_int -65281)))
7564    (clobber (reg:CC FLAGS_REG))]
7565   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7566    && reload_completed"
7567   [(parallel [(set (zero_extract:SI (match_dup 0)
7568                                     (const_int 8)
7569                                     (const_int 8))
7570                    (xor:SI
7571                      (zero_extract:SI (match_dup 0)
7572                                       (const_int 8)
7573                                       (const_int 8))
7574                      (zero_extract:SI (match_dup 0)
7575                                       (const_int 8)
7576                                       (const_int 8))))
7577               (clobber (reg:CC FLAGS_REG))])]
7578   "operands[0] = gen_lowpart (SImode, operands[0]);")
7580 (define_insn "*anddi_2"
7581   [(set (reg FLAGS_REG)
7582         (compare
7583          (and:DI
7584           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7585           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7586          (const_int 0)))
7587    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7588         (and:DI (match_dup 1) (match_dup 2)))]
7589   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7590    && ix86_binary_operator_ok (AND, DImode, operands)"
7591   "@
7592    and{l}\t{%k2, %k0|%k0, %k2}
7593    and{q}\t{%2, %0|%0, %2}
7594    and{q}\t{%2, %0|%0, %2}"
7595   [(set_attr "type" "alu")
7596    (set_attr "mode" "SI,DI,DI")])
7598 (define_insn "*andqi_2_maybe_si"
7599   [(set (reg FLAGS_REG)
7600         (compare (and:QI
7601                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7602                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7603                  (const_int 0)))
7604    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7605         (and:QI (match_dup 1) (match_dup 2)))]
7606   "ix86_binary_operator_ok (AND, QImode, operands)
7607    && ix86_match_ccmode (insn,
7608                          CONST_INT_P (operands[2])
7609                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7611   if (which_alternative == 2)
7612     {
7613       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7614         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7615       return "and{l}\t{%2, %k0|%k0, %2}";
7616     }
7617   return "and{b}\t{%2, %0|%0, %2}";
7619   [(set_attr "type" "alu")
7620    (set_attr "mode" "QI,QI,SI")])
7622 (define_insn "*and<mode>_2"
7623   [(set (reg FLAGS_REG)
7624         (compare (and:SWI124
7625                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7626                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7627                  (const_int 0)))
7628    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7629         (and:SWI124 (match_dup 1) (match_dup 2)))]
7630   "ix86_match_ccmode (insn, CCNOmode)
7631    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7632   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7633   [(set_attr "type" "alu")
7634    (set_attr "mode" "<MODE>")])
7636 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7637 (define_insn "*andsi_2_zext"
7638   [(set (reg FLAGS_REG)
7639         (compare (and:SI
7640                   (match_operand:SI 1 "nonimmediate_operand" "%0")
7641                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
7642                  (const_int 0)))
7643    (set (match_operand:DI 0 "register_operand" "=r")
7644         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7645   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7646    && ix86_binary_operator_ok (AND, SImode, operands)"
7647   "and{l}\t{%2, %k0|%k0, %2}"
7648   [(set_attr "type" "alu")
7649    (set_attr "mode" "SI")])
7651 (define_insn "*andqi_2_slp"
7652   [(set (reg FLAGS_REG)
7653         (compare (and:QI
7654                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7655                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7656                  (const_int 0)))
7657    (set (strict_low_part (match_dup 0))
7658         (and:QI (match_dup 0) (match_dup 1)))]
7659   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7660    && ix86_match_ccmode (insn, CCNOmode)
7661    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7662   "and{b}\t{%1, %0|%0, %1}"
7663   [(set_attr "type" "alu1")
7664    (set_attr "mode" "QI")])
7666 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7667 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
7668 ;; for a QImode operand, which of course failed.
7669 (define_insn "andqi_ext_0"
7670   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7671                          (const_int 8)
7672                          (const_int 8))
7673         (and:SI
7674           (zero_extract:SI
7675             (match_operand 1 "ext_register_operand" "0")
7676             (const_int 8)
7677             (const_int 8))
7678           (match_operand 2 "const_int_operand" "n")))
7679    (clobber (reg:CC FLAGS_REG))]
7680   ""
7681   "and{b}\t{%2, %h0|%h0, %2}"
7682   [(set_attr "type" "alu")
7683    (set_attr "length_immediate" "1")
7684    (set_attr "modrm" "1")
7685    (set_attr "mode" "QI")])
7687 ;; Generated by peephole translating test to and.  This shows up
7688 ;; often in fp comparisons.
7689 (define_insn "*andqi_ext_0_cc"
7690   [(set (reg FLAGS_REG)
7691         (compare
7692           (and:SI
7693             (zero_extract:SI
7694               (match_operand 1 "ext_register_operand" "0")
7695               (const_int 8)
7696               (const_int 8))
7697             (match_operand 2 "const_int_operand" "n"))
7698           (const_int 0)))
7699    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7700                          (const_int 8)
7701                          (const_int 8))
7702         (and:SI
7703           (zero_extract:SI
7704             (match_dup 1)
7705             (const_int 8)
7706             (const_int 8))
7707           (match_dup 2)))]
7708   "ix86_match_ccmode (insn, CCNOmode)"
7709   "and{b}\t{%2, %h0|%h0, %2}"
7710   [(set_attr "type" "alu")
7711    (set_attr "length_immediate" "1")
7712    (set_attr "modrm" "1")
7713    (set_attr "mode" "QI")])
7715 (define_insn "*andqi_ext_1"
7716   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
7717                          (const_int 8)
7718                          (const_int 8))
7719         (and:SI
7720           (zero_extract:SI
7721             (match_operand 1 "ext_register_operand" "0,0")
7722             (const_int 8)
7723             (const_int 8))
7724           (zero_extend:SI
7725             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
7726    (clobber (reg:CC FLAGS_REG))]
7727   ""
7728   "and{b}\t{%2, %h0|%h0, %2}"
7729   [(set_attr "isa" "*,nox64")
7730    (set_attr "type" "alu")
7731    (set_attr "length_immediate" "0")
7732    (set_attr "mode" "QI")])
7734 (define_insn "*andqi_ext_2"
7735   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7736                          (const_int 8)
7737                          (const_int 8))
7738         (and:SI
7739           (zero_extract:SI
7740             (match_operand 1 "ext_register_operand" "%0")
7741             (const_int 8)
7742             (const_int 8))
7743           (zero_extract:SI
7744             (match_operand 2 "ext_register_operand" "Q")
7745             (const_int 8)
7746             (const_int 8))))
7747    (clobber (reg:CC FLAGS_REG))]
7748   ""
7749   "and{b}\t{%h2, %h0|%h0, %h2}"
7750   [(set_attr "type" "alu")
7751    (set_attr "length_immediate" "0")
7752    (set_attr "mode" "QI")])
7754 ;; Convert wide AND instructions with immediate operand to shorter QImode
7755 ;; equivalents when possible.
7756 ;; Don't do the splitting with memory operands, since it introduces risk
7757 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
7758 ;; for size, but that can (should?) be handled by generic code instead.
7759 (define_split
7760   [(set (match_operand 0 "register_operand")
7761         (and (match_operand 1 "register_operand")
7762              (match_operand 2 "const_int_operand")))
7763    (clobber (reg:CC FLAGS_REG))]
7764    "reload_completed
7765     && QI_REG_P (operands[0])
7766     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7767     && !(~INTVAL (operands[2]) & ~(255 << 8))
7768     && GET_MODE (operands[0]) != QImode"
7769   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
7770                    (and:SI (zero_extract:SI (match_dup 1)
7771                                             (const_int 8) (const_int 8))
7772                            (match_dup 2)))
7773               (clobber (reg:CC FLAGS_REG))])]
7775   operands[0] = gen_lowpart (SImode, operands[0]);
7776   operands[1] = gen_lowpart (SImode, operands[1]);
7777   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
7780 ;; Since AND can be encoded with sign extended immediate, this is only
7781 ;; profitable when 7th bit is not set.
7782 (define_split
7783   [(set (match_operand 0 "register_operand")
7784         (and (match_operand 1 "general_operand")
7785              (match_operand 2 "const_int_operand")))
7786    (clobber (reg:CC FLAGS_REG))]
7787    "reload_completed
7788     && ANY_QI_REG_P (operands[0])
7789     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7790     && !(~INTVAL (operands[2]) & ~255)
7791     && !(INTVAL (operands[2]) & 128)
7792     && GET_MODE (operands[0]) != QImode"
7793   [(parallel [(set (strict_low_part (match_dup 0))
7794                    (and:QI (match_dup 1)
7795                            (match_dup 2)))
7796               (clobber (reg:CC FLAGS_REG))])]
7798   operands[0] = gen_lowpart (QImode, operands[0]);
7799   operands[1] = gen_lowpart (QImode, operands[1]);
7800   operands[2] = gen_lowpart (QImode, operands[2]);
7803 ;; Logical inclusive and exclusive OR instructions
7805 ;; %%% This used to optimize known byte-wide and operations to memory.
7806 ;; If this is considered useful, it should be done with splitters.
7808 (define_expand "<code><mode>3"
7809   [(set (match_operand:SWIM 0 "nonimmediate_operand")
7810         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7811                      (match_operand:SWIM 2 "<general_operand>")))]
7812   ""
7813   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
7815 (define_insn "*<code><mode>_1"
7816   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
7817         (any_or:SWI248
7818          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
7819          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
7820    (clobber (reg:CC FLAGS_REG))]
7821   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7822   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7823   [(set_attr "type" "alu")
7824    (set_attr "mode" "<MODE>")])
7826 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7827 (define_insn "*<code>qi_1"
7828   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
7829         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7830                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
7831    (clobber (reg:CC FLAGS_REG))]
7832   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
7833   "@
7834    <logic>{b}\t{%2, %0|%0, %2}
7835    <logic>{b}\t{%2, %0|%0, %2}
7836    <logic>{l}\t{%k2, %k0|%k0, %k2}"
7837   [(set_attr "type" "alu")
7838    (set_attr "mode" "QI,QI,SI")])
7840 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7841 (define_insn "*<code>si_1_zext"
7842   [(set (match_operand:DI 0 "register_operand" "=r")
7843         (zero_extend:DI
7844          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7845                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7846    (clobber (reg:CC FLAGS_REG))]
7847   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7848   "<logic>{l}\t{%2, %k0|%k0, %2}"
7849   [(set_attr "type" "alu")
7850    (set_attr "mode" "SI")])
7852 (define_insn "*<code>si_1_zext_imm"
7853   [(set (match_operand:DI 0 "register_operand" "=r")
7854         (any_or:DI
7855          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
7856          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
7857    (clobber (reg:CC FLAGS_REG))]
7858   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7859   "<logic>{l}\t{%2, %k0|%k0, %2}"
7860   [(set_attr "type" "alu")
7861    (set_attr "mode" "SI")])
7863 (define_insn "*<code>qi_1_slp"
7864   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
7865         (any_or:QI (match_dup 0)
7866                    (match_operand:QI 1 "general_operand" "qmn,qn")))
7867    (clobber (reg:CC FLAGS_REG))]
7868   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7869    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7870   "<logic>{b}\t{%1, %0|%0, %1}"
7871   [(set_attr "type" "alu1")
7872    (set_attr "mode" "QI")])
7874 (define_insn "*<code><mode>_2"
7875   [(set (reg FLAGS_REG)
7876         (compare (any_or:SWI
7877                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7878                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
7879                  (const_int 0)))
7880    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
7881         (any_or:SWI (match_dup 1) (match_dup 2)))]
7882   "ix86_match_ccmode (insn, CCNOmode)
7883    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7884   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7885   [(set_attr "type" "alu")
7886    (set_attr "mode" "<MODE>")])
7888 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7889 ;; ??? Special case for immediate operand is missing - it is tricky.
7890 (define_insn "*<code>si_2_zext"
7891   [(set (reg FLAGS_REG)
7892         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7893                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
7894                  (const_int 0)))
7895    (set (match_operand:DI 0 "register_operand" "=r")
7896         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
7897   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7898    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7899   "<logic>{l}\t{%2, %k0|%k0, %2}"
7900   [(set_attr "type" "alu")
7901    (set_attr "mode" "SI")])
7903 (define_insn "*<code>si_2_zext_imm"
7904   [(set (reg FLAGS_REG)
7905         (compare (any_or:SI
7906                   (match_operand:SI 1 "nonimmediate_operand" "%0")
7907                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
7908                  (const_int 0)))
7909    (set (match_operand:DI 0 "register_operand" "=r")
7910         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
7911   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7912    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7913   "<logic>{l}\t{%2, %k0|%k0, %2}"
7914   [(set_attr "type" "alu")
7915    (set_attr "mode" "SI")])
7917 (define_insn "*<code>qi_2_slp"
7918   [(set (reg FLAGS_REG)
7919         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7920                             (match_operand:QI 1 "general_operand" "qmn,qn"))
7921                  (const_int 0)))
7922    (set (strict_low_part (match_dup 0))
7923         (any_or:QI (match_dup 0) (match_dup 1)))]
7924   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7925    && ix86_match_ccmode (insn, CCNOmode)
7926    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7927   "<logic>{b}\t{%1, %0|%0, %1}"
7928   [(set_attr "type" "alu1")
7929    (set_attr "mode" "QI")])
7931 (define_insn "*<code><mode>_3"
7932   [(set (reg FLAGS_REG)
7933         (compare (any_or:SWI
7934                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
7935                   (match_operand:SWI 2 "<general_operand>" "<g>"))
7936                  (const_int 0)))
7937    (clobber (match_scratch:SWI 0 "=<r>"))]
7938   "ix86_match_ccmode (insn, CCNOmode)
7939    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7940   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7941   [(set_attr "type" "alu")
7942    (set_attr "mode" "<MODE>")])
7944 (define_insn "*<code>qi_ext_0"
7945   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7946                          (const_int 8)
7947                          (const_int 8))
7948         (any_or:SI
7949           (zero_extract:SI
7950             (match_operand 1 "ext_register_operand" "0")
7951             (const_int 8)
7952             (const_int 8))
7953           (match_operand 2 "const_int_operand" "n")))
7954    (clobber (reg:CC FLAGS_REG))]
7955   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7956   "<logic>{b}\t{%2, %h0|%h0, %2}"
7957   [(set_attr "type" "alu")
7958    (set_attr "length_immediate" "1")
7959    (set_attr "modrm" "1")
7960    (set_attr "mode" "QI")])
7962 (define_insn "*<code>qi_ext_1"
7963   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
7964                          (const_int 8)
7965                          (const_int 8))
7966         (any_or:SI
7967           (zero_extract:SI
7968             (match_operand 1 "ext_register_operand" "0,0")
7969             (const_int 8)
7970             (const_int 8))
7971           (zero_extend:SI
7972             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
7973    (clobber (reg:CC FLAGS_REG))]
7974   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7975   "<logic>{b}\t{%2, %h0|%h0, %2}"
7976   [(set_attr "isa" "*,nox64")
7977    (set_attr "type" "alu")
7978    (set_attr "length_immediate" "0")
7979    (set_attr "mode" "QI")])
7981 (define_insn "*<code>qi_ext_2"
7982   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7983                          (const_int 8)
7984                          (const_int 8))
7985         (any_or:SI
7986           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
7987                            (const_int 8)
7988                            (const_int 8))
7989           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
7990                            (const_int 8)
7991                            (const_int 8))))
7992    (clobber (reg:CC FLAGS_REG))]
7993   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7994   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
7995   [(set_attr "type" "alu")
7996    (set_attr "length_immediate" "0")
7997    (set_attr "mode" "QI")])
7999 (define_split
8000   [(set (match_operand 0 "register_operand")
8001         (any_or (match_operand 1 "register_operand")
8002                 (match_operand 2 "const_int_operand")))
8003    (clobber (reg:CC FLAGS_REG))]
8004    "reload_completed
8005     && QI_REG_P (operands[0])
8006     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8007     && !(INTVAL (operands[2]) & ~(255 << 8))
8008     && GET_MODE (operands[0]) != QImode"
8009   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8010                    (any_or:SI (zero_extract:SI (match_dup 1)
8011                                                (const_int 8) (const_int 8))
8012                               (match_dup 2)))
8013               (clobber (reg:CC FLAGS_REG))])]
8015   operands[0] = gen_lowpart (SImode, operands[0]);
8016   operands[1] = gen_lowpart (SImode, operands[1]);
8017   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8020 ;; Since OR can be encoded with sign extended immediate, this is only
8021 ;; profitable when 7th bit is set.
8022 (define_split
8023   [(set (match_operand 0 "register_operand")
8024         (any_or (match_operand 1 "general_operand")
8025                 (match_operand 2 "const_int_operand")))
8026    (clobber (reg:CC FLAGS_REG))]
8027    "reload_completed
8028     && ANY_QI_REG_P (operands[0])
8029     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8030     && !(INTVAL (operands[2]) & ~255)
8031     && (INTVAL (operands[2]) & 128)
8032     && GET_MODE (operands[0]) != QImode"
8033   [(parallel [(set (strict_low_part (match_dup 0))
8034                    (any_or:QI (match_dup 1)
8035                               (match_dup 2)))
8036               (clobber (reg:CC FLAGS_REG))])]
8038   operands[0] = gen_lowpart (QImode, operands[0]);
8039   operands[1] = gen_lowpart (QImode, operands[1]);
8040   operands[2] = gen_lowpart (QImode, operands[2]);
8043 (define_expand "xorqi_cc_ext_1"
8044   [(parallel [
8045      (set (reg:CCNO FLAGS_REG)
8046           (compare:CCNO
8047             (xor:SI
8048               (zero_extract:SI
8049                 (match_operand 1 "ext_register_operand")
8050                 (const_int 8)
8051                 (const_int 8))
8052               (match_operand:QI 2 "const_int_operand"))
8053             (const_int 0)))
8054      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8055                            (const_int 8)
8056                            (const_int 8))
8057           (xor:SI
8058             (zero_extract:SI
8059              (match_dup 1)
8060              (const_int 8)
8061              (const_int 8))
8062             (match_dup 2)))])])
8064 (define_insn "*xorqi_cc_ext_1"
8065   [(set (reg FLAGS_REG)
8066         (compare
8067           (xor:SI
8068             (zero_extract:SI
8069               (match_operand 1 "ext_register_operand" "0,0")
8070               (const_int 8)
8071               (const_int 8))
8072             (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8073           (const_int 0)))
8074    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8075                          (const_int 8)
8076                          (const_int 8))
8077         (xor:SI
8078           (zero_extract:SI
8079            (match_dup 1)
8080            (const_int 8)
8081            (const_int 8))
8082           (match_dup 2)))]
8083   "ix86_match_ccmode (insn, CCNOmode)"
8084   "xor{b}\t{%2, %h0|%h0, %2}"
8085   [(set_attr "isa" "*,nox64")
8086    (set_attr "type" "alu")
8087    (set_attr "modrm" "1")
8088    (set_attr "mode" "QI")])
8090 ;; Negation instructions
8092 (define_expand "neg<mode>2"
8093   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8094         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8095   ""
8096   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8098 (define_insn_and_split "*neg<dwi>2_doubleword"
8099   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8100         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8101    (clobber (reg:CC FLAGS_REG))]
8102   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8103   "#"
8104   "reload_completed"
8105   [(parallel
8106     [(set (reg:CCZ FLAGS_REG)
8107           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8108      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8109    (parallel
8110     [(set (match_dup 2)
8111           (plus:DWIH (match_dup 3)
8112                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8113                                 (const_int 0))))
8114      (clobber (reg:CC FLAGS_REG))])
8115    (parallel
8116     [(set (match_dup 2)
8117           (neg:DWIH (match_dup 2)))
8118      (clobber (reg:CC FLAGS_REG))])]
8119   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8121 (define_insn "*neg<mode>2_1"
8122   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8123         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8124    (clobber (reg:CC FLAGS_REG))]
8125   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8126   "neg{<imodesuffix>}\t%0"
8127   [(set_attr "type" "negnot")
8128    (set_attr "mode" "<MODE>")])
8130 ;; Combine is quite creative about this pattern.
8131 (define_insn "*negsi2_1_zext"
8132   [(set (match_operand:DI 0 "register_operand" "=r")
8133         (lshiftrt:DI
8134           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8135                              (const_int 32)))
8136         (const_int 32)))
8137    (clobber (reg:CC FLAGS_REG))]
8138   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8139   "neg{l}\t%k0"
8140   [(set_attr "type" "negnot")
8141    (set_attr "mode" "SI")])
8143 ;; The problem with neg is that it does not perform (compare x 0),
8144 ;; it really performs (compare 0 x), which leaves us with the zero
8145 ;; flag being the only useful item.
8147 (define_insn "*neg<mode>2_cmpz"
8148   [(set (reg:CCZ FLAGS_REG)
8149         (compare:CCZ
8150           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8151                    (const_int 0)))
8152    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8153         (neg:SWI (match_dup 1)))]
8154   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8155   "neg{<imodesuffix>}\t%0"
8156   [(set_attr "type" "negnot")
8157    (set_attr "mode" "<MODE>")])
8159 (define_insn "*negsi2_cmpz_zext"
8160   [(set (reg:CCZ FLAGS_REG)
8161         (compare:CCZ
8162           (lshiftrt:DI
8163             (neg:DI (ashift:DI
8164                       (match_operand:DI 1 "register_operand" "0")
8165                       (const_int 32)))
8166             (const_int 32))
8167           (const_int 0)))
8168    (set (match_operand:DI 0 "register_operand" "=r")
8169         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8170                                         (const_int 32)))
8171                      (const_int 32)))]
8172   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8173   "neg{l}\t%k0"
8174   [(set_attr "type" "negnot")
8175    (set_attr "mode" "SI")])
8177 ;; Changing of sign for FP values is doable using integer unit too.
8179 (define_expand "<code><mode>2"
8180   [(set (match_operand:X87MODEF 0 "register_operand")
8181         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8182   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8183   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8185 (define_insn "*absneg<mode>2_mixed"
8186   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8187         (match_operator:MODEF 3 "absneg_operator"
8188           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8189    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8190    (clobber (reg:CC FLAGS_REG))]
8191   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8192   "#")
8194 (define_insn "*absneg<mode>2_sse"
8195   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8196         (match_operator:MODEF 3 "absneg_operator"
8197           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8198    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8199    (clobber (reg:CC FLAGS_REG))]
8200   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8201   "#")
8203 (define_insn "*absneg<mode>2_i387"
8204   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8205         (match_operator:X87MODEF 3 "absneg_operator"
8206           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8207    (use (match_operand 2))
8208    (clobber (reg:CC FLAGS_REG))]
8209   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8210   "#")
8212 (define_expand "<code>tf2"
8213   [(set (match_operand:TF 0 "register_operand")
8214         (absneg:TF (match_operand:TF 1 "register_operand")))]
8215   "TARGET_SSE"
8216   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8218 (define_insn "*absnegtf2_sse"
8219   [(set (match_operand:TF 0 "register_operand" "=x,x")
8220         (match_operator:TF 3 "absneg_operator"
8221           [(match_operand:TF 1 "register_operand" "0,x")]))
8222    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8223    (clobber (reg:CC FLAGS_REG))]
8224   "TARGET_SSE"
8225   "#")
8227 ;; Splitters for fp abs and neg.
8229 (define_split
8230   [(set (match_operand 0 "fp_register_operand")
8231         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8232    (use (match_operand 2))
8233    (clobber (reg:CC FLAGS_REG))]
8234   "reload_completed"
8235   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8237 (define_split
8238   [(set (match_operand 0 "register_operand")
8239         (match_operator 3 "absneg_operator"
8240           [(match_operand 1 "register_operand")]))
8241    (use (match_operand 2 "nonimmediate_operand"))
8242    (clobber (reg:CC FLAGS_REG))]
8243   "reload_completed && SSE_REG_P (operands[0])"
8244   [(set (match_dup 0) (match_dup 3))]
8246   enum machine_mode mode = GET_MODE (operands[0]);
8247   enum machine_mode vmode = GET_MODE (operands[2]);
8248   rtx tmp;
8250   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8251   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8252   if (operands_match_p (operands[0], operands[2]))
8253     {
8254       tmp = operands[1];
8255       operands[1] = operands[2];
8256       operands[2] = tmp;
8257     }
8258   if (GET_CODE (operands[3]) == ABS)
8259     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8260   else
8261     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8262   operands[3] = tmp;
8265 (define_split
8266   [(set (match_operand:SF 0 "register_operand")
8267         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8268    (use (match_operand:V4SF 2))
8269    (clobber (reg:CC FLAGS_REG))]
8270   "reload_completed"
8271   [(parallel [(set (match_dup 0) (match_dup 1))
8272               (clobber (reg:CC FLAGS_REG))])]
8274   rtx tmp;
8275   operands[0] = gen_lowpart (SImode, operands[0]);
8276   if (GET_CODE (operands[1]) == ABS)
8277     {
8278       tmp = gen_int_mode (0x7fffffff, SImode);
8279       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8280     }
8281   else
8282     {
8283       tmp = gen_int_mode (0x80000000, SImode);
8284       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8285     }
8286   operands[1] = tmp;
8289 (define_split
8290   [(set (match_operand:DF 0 "register_operand")
8291         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8292    (use (match_operand 2))
8293    (clobber (reg:CC FLAGS_REG))]
8294   "reload_completed"
8295   [(parallel [(set (match_dup 0) (match_dup 1))
8296               (clobber (reg:CC FLAGS_REG))])]
8298   rtx tmp;
8299   if (TARGET_64BIT)
8300     {
8301       tmp = gen_lowpart (DImode, operands[0]);
8302       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8303       operands[0] = tmp;
8305       if (GET_CODE (operands[1]) == ABS)
8306         tmp = const0_rtx;
8307       else
8308         tmp = gen_rtx_NOT (DImode, tmp);
8309     }
8310   else
8311     {
8312       operands[0] = gen_highpart (SImode, operands[0]);
8313       if (GET_CODE (operands[1]) == ABS)
8314         {
8315           tmp = gen_int_mode (0x7fffffff, SImode);
8316           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8317         }
8318       else
8319         {
8320           tmp = gen_int_mode (0x80000000, SImode);
8321           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8322         }
8323     }
8324   operands[1] = tmp;
8327 (define_split
8328   [(set (match_operand:XF 0 "register_operand")
8329         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8330    (use (match_operand 2))
8331    (clobber (reg:CC FLAGS_REG))]
8332   "reload_completed"
8333   [(parallel [(set (match_dup 0) (match_dup 1))
8334               (clobber (reg:CC FLAGS_REG))])]
8336   rtx tmp;
8337   operands[0] = gen_rtx_REG (SImode,
8338                              true_regnum (operands[0])
8339                              + (TARGET_64BIT ? 1 : 2));
8340   if (GET_CODE (operands[1]) == ABS)
8341     {
8342       tmp = GEN_INT (0x7fff);
8343       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8344     }
8345   else
8346     {
8347       tmp = GEN_INT (0x8000);
8348       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8349     }
8350   operands[1] = tmp;
8353 ;; Conditionalize these after reload. If they match before reload, we
8354 ;; lose the clobber and ability to use integer instructions.
8356 (define_insn "*<code><mode>2_1"
8357   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8358         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8359   "TARGET_80387
8360    && (reload_completed
8361        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8362   "f<absneg_mnemonic>"
8363   [(set_attr "type" "fsgn")
8364    (set_attr "mode" "<MODE>")])
8366 (define_insn "*<code>extendsfdf2"
8367   [(set (match_operand:DF 0 "register_operand" "=f")
8368         (absneg:DF (float_extend:DF
8369                      (match_operand:SF 1 "register_operand" "0"))))]
8370   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8371   "f<absneg_mnemonic>"
8372   [(set_attr "type" "fsgn")
8373    (set_attr "mode" "DF")])
8375 (define_insn "*<code>extendsfxf2"
8376   [(set (match_operand:XF 0 "register_operand" "=f")
8377         (absneg:XF (float_extend:XF
8378                      (match_operand:SF 1 "register_operand" "0"))))]
8379   "TARGET_80387"
8380   "f<absneg_mnemonic>"
8381   [(set_attr "type" "fsgn")
8382    (set_attr "mode" "XF")])
8384 (define_insn "*<code>extenddfxf2"
8385   [(set (match_operand:XF 0 "register_operand" "=f")
8386         (absneg:XF (float_extend:XF
8387                      (match_operand:DF 1 "register_operand" "0"))))]
8388   "TARGET_80387"
8389   "f<absneg_mnemonic>"
8390   [(set_attr "type" "fsgn")
8391    (set_attr "mode" "XF")])
8393 ;; Copysign instructions
8395 (define_mode_iterator CSGNMODE [SF DF TF])
8396 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8398 (define_expand "copysign<mode>3"
8399   [(match_operand:CSGNMODE 0 "register_operand")
8400    (match_operand:CSGNMODE 1 "nonmemory_operand")
8401    (match_operand:CSGNMODE 2 "register_operand")]
8402   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8403    || (TARGET_SSE && (<MODE>mode == TFmode))"
8404   "ix86_expand_copysign (operands); DONE;")
8406 (define_insn_and_split "copysign<mode>3_const"
8407   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8408         (unspec:CSGNMODE
8409           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8410            (match_operand:CSGNMODE 2 "register_operand" "0")
8411            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8412           UNSPEC_COPYSIGN))]
8413   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8414    || (TARGET_SSE && (<MODE>mode == TFmode))"
8415   "#"
8416   "&& reload_completed"
8417   [(const_int 0)]
8418   "ix86_split_copysign_const (operands); DONE;")
8420 (define_insn "copysign<mode>3_var"
8421   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8422         (unspec:CSGNMODE
8423           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8424            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8425            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8426            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8427           UNSPEC_COPYSIGN))
8428    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8429   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8430    || (TARGET_SSE && (<MODE>mode == TFmode))"
8431   "#")
8433 (define_split
8434   [(set (match_operand:CSGNMODE 0 "register_operand")
8435         (unspec:CSGNMODE
8436           [(match_operand:CSGNMODE 2 "register_operand")
8437            (match_operand:CSGNMODE 3 "register_operand")
8438            (match_operand:<CSGNVMODE> 4)
8439            (match_operand:<CSGNVMODE> 5)]
8440           UNSPEC_COPYSIGN))
8441    (clobber (match_scratch:<CSGNVMODE> 1))]
8442   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8443     || (TARGET_SSE && (<MODE>mode == TFmode)))
8444    && reload_completed"
8445   [(const_int 0)]
8446   "ix86_split_copysign_var (operands); DONE;")
8448 ;; One complement instructions
8450 (define_expand "one_cmpl<mode>2"
8451   [(set (match_operand:SWIM 0 "nonimmediate_operand")
8452         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8453   ""
8454   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8456 (define_insn "*one_cmpl<mode>2_1"
8457   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8458         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8459   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8460   "not{<imodesuffix>}\t%0"
8461   [(set_attr "type" "negnot")
8462    (set_attr "mode" "<MODE>")])
8464 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8465 (define_insn "*one_cmplqi2_1"
8466   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8467         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8468   "ix86_unary_operator_ok (NOT, QImode, operands)"
8469   "@
8470    not{b}\t%0
8471    not{l}\t%k0"
8472   [(set_attr "type" "negnot")
8473    (set_attr "mode" "QI,SI")])
8475 ;; ??? Currently never generated - xor is used instead.
8476 (define_insn "*one_cmplsi2_1_zext"
8477   [(set (match_operand:DI 0 "register_operand" "=r")
8478         (zero_extend:DI
8479           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8480   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8481   "not{l}\t%k0"
8482   [(set_attr "type" "negnot")
8483    (set_attr "mode" "SI")])
8485 (define_insn "*one_cmpl<mode>2_2"
8486   [(set (reg FLAGS_REG)
8487         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8488                  (const_int 0)))
8489    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8490         (not:SWI (match_dup 1)))]
8491   "ix86_match_ccmode (insn, CCNOmode)
8492    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8493   "#"
8494   [(set_attr "type" "alu1")
8495    (set_attr "mode" "<MODE>")])
8497 (define_split
8498   [(set (match_operand 0 "flags_reg_operand")
8499         (match_operator 2 "compare_operator"
8500           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
8501            (const_int 0)]))
8502    (set (match_operand:SWI 1 "nonimmediate_operand")
8503         (not:SWI (match_dup 3)))]
8504   "ix86_match_ccmode (insn, CCNOmode)"
8505   [(parallel [(set (match_dup 0)
8506                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8507                                     (const_int 0)]))
8508               (set (match_dup 1)
8509                    (xor:SWI (match_dup 3) (const_int -1)))])])
8511 ;; ??? Currently never generated - xor is used instead.
8512 (define_insn "*one_cmplsi2_2_zext"
8513   [(set (reg FLAGS_REG)
8514         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8515                  (const_int 0)))
8516    (set (match_operand:DI 0 "register_operand" "=r")
8517         (zero_extend:DI (not:SI (match_dup 1))))]
8518   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8519    && ix86_unary_operator_ok (NOT, SImode, operands)"
8520   "#"
8521   [(set_attr "type" "alu1")
8522    (set_attr "mode" "SI")])
8524 (define_split
8525   [(set (match_operand 0 "flags_reg_operand")
8526         (match_operator 2 "compare_operator"
8527           [(not:SI (match_operand:SI 3 "register_operand"))
8528            (const_int 0)]))
8529    (set (match_operand:DI 1 "register_operand")
8530         (zero_extend:DI (not:SI (match_dup 3))))]
8531   "ix86_match_ccmode (insn, CCNOmode)"
8532   [(parallel [(set (match_dup 0)
8533                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8534                                     (const_int 0)]))
8535               (set (match_dup 1)
8536                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8538 ;; Shift instructions
8540 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8541 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8542 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8543 ;; from the assembler input.
8545 ;; This instruction shifts the target reg/mem as usual, but instead of
8546 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8547 ;; is a left shift double, bits are taken from the high order bits of
8548 ;; reg, else if the insn is a shift right double, bits are taken from the
8549 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8550 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8552 ;; Since sh[lr]d does not change the `reg' operand, that is done
8553 ;; separately, making all shifts emit pairs of shift double and normal
8554 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8555 ;; support a 63 bit shift, each shift where the count is in a reg expands
8556 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8558 ;; If the shift count is a constant, we need never emit more than one
8559 ;; shift pair, instead using moves and sign extension for counts greater
8560 ;; than 31.
8562 (define_expand "ashl<mode>3"
8563   [(set (match_operand:SDWIM 0 "<shift_operand>")
8564         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
8565                       (match_operand:QI 2 "nonmemory_operand")))]
8566   ""
8567   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8569 (define_insn "*ashl<mode>3_doubleword"
8570   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8571         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8572                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8573    (clobber (reg:CC FLAGS_REG))]
8574   ""
8575   "#"
8576   [(set_attr "type" "multi")])
8578 (define_split
8579   [(set (match_operand:DWI 0 "register_operand")
8580         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
8581                     (match_operand:QI 2 "nonmemory_operand")))
8582    (clobber (reg:CC FLAGS_REG))]
8583   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8584   [(const_int 0)]
8585   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8587 ;; By default we don't ask for a scratch register, because when DWImode
8588 ;; values are manipulated, registers are already at a premium.  But if
8589 ;; we have one handy, we won't turn it away.
8591 (define_peephole2
8592   [(match_scratch:DWIH 3 "r")
8593    (parallel [(set (match_operand:<DWI> 0 "register_operand")
8594                    (ashift:<DWI>
8595                      (match_operand:<DWI> 1 "nonmemory_operand")
8596                      (match_operand:QI 2 "nonmemory_operand")))
8597               (clobber (reg:CC FLAGS_REG))])
8598    (match_dup 3)]
8599   "TARGET_CMOVE"
8600   [(const_int 0)]
8601   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8603 (define_insn "x86_64_shld"
8604   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8605         (ior:DI (ashift:DI (match_dup 0)
8606                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
8607                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8608                   (minus:QI (const_int 64) (match_dup 2)))))
8609    (clobber (reg:CC FLAGS_REG))]
8610   "TARGET_64BIT"
8611   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8612   [(set_attr "type" "ishift")
8613    (set_attr "prefix_0f" "1")
8614    (set_attr "mode" "DI")
8615    (set_attr "athlon_decode" "vector")
8616    (set_attr "amdfam10_decode" "vector")
8617    (set_attr "bdver1_decode" "vector")])
8619 (define_insn "x86_shld"
8620   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8621         (ior:SI (ashift:SI (match_dup 0)
8622                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
8623                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8624                   (minus:QI (const_int 32) (match_dup 2)))))
8625    (clobber (reg:CC FLAGS_REG))]
8626   ""
8627   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8628   [(set_attr "type" "ishift")
8629    (set_attr "prefix_0f" "1")
8630    (set_attr "mode" "SI")
8631    (set_attr "pent_pair" "np")
8632    (set_attr "athlon_decode" "vector")
8633    (set_attr "amdfam10_decode" "vector")
8634    (set_attr "bdver1_decode" "vector")])
8636 (define_expand "x86_shift<mode>_adj_1"
8637   [(set (reg:CCZ FLAGS_REG)
8638         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
8639                              (match_dup 4))
8640                      (const_int 0)))
8641    (set (match_operand:SWI48 0 "register_operand")
8642         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8643                             (match_operand:SWI48 1 "register_operand")
8644                             (match_dup 0)))
8645    (set (match_dup 1)
8646         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8647                             (match_operand:SWI48 3 "register_operand")
8648                             (match_dup 1)))]
8649   "TARGET_CMOVE"
8650   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8652 (define_expand "x86_shift<mode>_adj_2"
8653   [(use (match_operand:SWI48 0 "register_operand"))
8654    (use (match_operand:SWI48 1 "register_operand"))
8655    (use (match_operand:QI 2 "register_operand"))]
8656   ""
8658   rtx label = gen_label_rtx ();
8659   rtx tmp;
8661   emit_insn (gen_testqi_ccz_1 (operands[2],
8662                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
8664   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
8665   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8666   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
8667                               gen_rtx_LABEL_REF (VOIDmode, label),
8668                               pc_rtx);
8669   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
8670   JUMP_LABEL (tmp) = label;
8672   emit_move_insn (operands[0], operands[1]);
8673   ix86_expand_clear (operands[1]);
8675   emit_label (label);
8676   LABEL_NUSES (label) = 1;
8678   DONE;
8681 ;; Avoid useless masking of count operand.
8682 (define_insn "*ashl<mode>3_mask"
8683   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8684         (ashift:SWI48
8685           (match_operand:SWI48 1 "nonimmediate_operand" "0")
8686           (subreg:QI
8687             (and:SI
8688               (match_operand:SI 2 "register_operand" "c")
8689               (match_operand:SI 3 "const_int_operand" "n")) 0)))
8690    (clobber (reg:CC FLAGS_REG))]
8691   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
8692    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
8693       == GET_MODE_BITSIZE (<MODE>mode)-1"
8695   return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
8697   [(set_attr "type" "ishift")
8698    (set_attr "mode" "<MODE>")])
8700 (define_insn "*bmi2_ashl<mode>3_1"
8701   [(set (match_operand:SWI48 0 "register_operand" "=r")
8702         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
8703                       (match_operand:SWI48 2 "register_operand" "r")))]
8704   "TARGET_BMI2"
8705   "shlx\t{%2, %1, %0|%0, %1, %2}"
8706   [(set_attr "type" "ishiftx")
8707    (set_attr "mode" "<MODE>")])
8709 (define_insn "*ashl<mode>3_1"
8710   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
8711         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
8712                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
8713    (clobber (reg:CC FLAGS_REG))]
8714   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
8716   switch (get_attr_type (insn))
8717     {
8718     case TYPE_LEA:
8719     case TYPE_ISHIFTX:
8720       return "#";
8722     case TYPE_ALU:
8723       gcc_assert (operands[2] == const1_rtx);
8724       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8725       return "add{<imodesuffix>}\t%0, %0";
8727     default:
8728       if (operands[2] == const1_rtx
8729           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8730         return "sal{<imodesuffix>}\t%0";
8731       else
8732         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
8733     }
8735   [(set_attr "isa" "*,*,bmi2")
8736    (set (attr "type")
8737      (cond [(eq_attr "alternative" "1")
8738               (const_string "lea")
8739             (eq_attr "alternative" "2")
8740               (const_string "ishiftx")
8741             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
8742                       (match_operand 0 "register_operand"))
8743                  (match_operand 2 "const1_operand"))
8744               (const_string "alu")
8745            ]
8746            (const_string "ishift")))
8747    (set (attr "length_immediate")
8748      (if_then_else
8749        (ior (eq_attr "type" "alu")
8750             (and (eq_attr "type" "ishift")
8751                  (and (match_operand 2 "const1_operand")
8752                       (ior (match_test "TARGET_SHIFT1")
8753                            (match_test "optimize_function_for_size_p (cfun)")))))
8754        (const_string "0")
8755        (const_string "*")))
8756    (set_attr "mode" "<MODE>")])
8758 ;; Convert shift to the shiftx pattern to avoid flags dependency.
8759 (define_split
8760   [(set (match_operand:SWI48 0 "register_operand")
8761         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
8762                       (match_operand:QI 2 "register_operand")))
8763    (clobber (reg:CC FLAGS_REG))]
8764   "TARGET_BMI2 && reload_completed"
8765   [(set (match_dup 0)
8766         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
8767   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
8769 (define_insn "*bmi2_ashlsi3_1_zext"
8770   [(set (match_operand:DI 0 "register_operand" "=r")
8771         (zero_extend:DI
8772           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
8773                      (match_operand:SI 2 "register_operand" "r"))))]
8774   "TARGET_64BIT && TARGET_BMI2"
8775   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
8776   [(set_attr "type" "ishiftx")
8777    (set_attr "mode" "SI")])
8779 (define_insn "*ashlsi3_1_zext"
8780   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8781         (zero_extend:DI
8782           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
8783                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
8784    (clobber (reg:CC FLAGS_REG))]
8785   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
8787   switch (get_attr_type (insn))
8788     {
8789     case TYPE_LEA:
8790     case TYPE_ISHIFTX:
8791       return "#";
8793     case TYPE_ALU:
8794       gcc_assert (operands[2] == const1_rtx);
8795       return "add{l}\t%k0, %k0";
8797     default:
8798       if (operands[2] == const1_rtx
8799           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8800         return "sal{l}\t%k0";
8801       else
8802         return "sal{l}\t{%2, %k0|%k0, %2}";
8803     }
8805   [(set_attr "isa" "*,*,bmi2")
8806    (set (attr "type")
8807      (cond [(eq_attr "alternative" "1")
8808               (const_string "lea")
8809             (eq_attr "alternative" "2")
8810               (const_string "ishiftx")
8811             (and (match_test "TARGET_DOUBLE_WITH_ADD")
8812                  (match_operand 2 "const1_operand"))
8813               (const_string "alu")
8814            ]
8815            (const_string "ishift")))
8816    (set (attr "length_immediate")
8817      (if_then_else
8818        (ior (eq_attr "type" "alu")
8819             (and (eq_attr "type" "ishift")
8820                  (and (match_operand 2 "const1_operand")
8821                       (ior (match_test "TARGET_SHIFT1")
8822                            (match_test "optimize_function_for_size_p (cfun)")))))
8823        (const_string "0")
8824        (const_string "*")))
8825    (set_attr "mode" "SI")])
8827 ;; Convert shift to the shiftx pattern to avoid flags dependency.
8828 (define_split
8829   [(set (match_operand:DI 0 "register_operand")
8830         (zero_extend:DI
8831           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
8832                      (match_operand:QI 2 "register_operand"))))
8833    (clobber (reg:CC FLAGS_REG))]
8834   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
8835   [(set (match_dup 0)
8836         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
8837   "operands[2] = gen_lowpart (SImode, operands[2]);")
8839 (define_insn "*ashlhi3_1"
8840   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
8841         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
8842                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
8843    (clobber (reg:CC FLAGS_REG))]
8844   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
8846   switch (get_attr_type (insn))
8847     {
8848     case TYPE_LEA:
8849       return "#";
8851     case TYPE_ALU:
8852       gcc_assert (operands[2] == const1_rtx);
8853       return "add{w}\t%0, %0";
8855     default:
8856       if (operands[2] == const1_rtx
8857           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8858         return "sal{w}\t%0";
8859       else
8860         return "sal{w}\t{%2, %0|%0, %2}";
8861     }
8863   [(set (attr "type")
8864      (cond [(eq_attr "alternative" "1")
8865               (const_string "lea")
8866             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
8867                       (match_operand 0 "register_operand"))
8868                  (match_operand 2 "const1_operand"))
8869               (const_string "alu")
8870            ]
8871            (const_string "ishift")))
8872    (set (attr "length_immediate")
8873      (if_then_else
8874        (ior (eq_attr "type" "alu")
8875             (and (eq_attr "type" "ishift")
8876                  (and (match_operand 2 "const1_operand")
8877                       (ior (match_test "TARGET_SHIFT1")
8878                            (match_test "optimize_function_for_size_p (cfun)")))))
8879        (const_string "0")
8880        (const_string "*")))
8881    (set_attr "mode" "HI,SI")])
8883 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8884 (define_insn "*ashlqi3_1"
8885   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
8886         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
8887                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
8888    (clobber (reg:CC FLAGS_REG))]
8889   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
8891   switch (get_attr_type (insn))
8892     {
8893     case TYPE_LEA:
8894       return "#";
8896     case TYPE_ALU:
8897       gcc_assert (operands[2] == const1_rtx);
8898       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
8899         return "add{l}\t%k0, %k0";
8900       else
8901         return "add{b}\t%0, %0";
8903     default:
8904       if (operands[2] == const1_rtx
8905           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8906         {
8907           if (get_attr_mode (insn) == MODE_SI)
8908             return "sal{l}\t%k0";
8909           else
8910             return "sal{b}\t%0";
8911         }
8912       else
8913         {
8914           if (get_attr_mode (insn) == MODE_SI)
8915             return "sal{l}\t{%2, %k0|%k0, %2}";
8916           else
8917             return "sal{b}\t{%2, %0|%0, %2}";
8918         }
8919     }
8921   [(set (attr "type")
8922      (cond [(eq_attr "alternative" "2")
8923               (const_string "lea")
8924             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
8925                       (match_operand 0 "register_operand"))
8926                  (match_operand 2 "const1_operand"))
8927               (const_string "alu")
8928            ]
8929            (const_string "ishift")))
8930    (set (attr "length_immediate")
8931      (if_then_else
8932        (ior (eq_attr "type" "alu")
8933             (and (eq_attr "type" "ishift")
8934                  (and (match_operand 2 "const1_operand")
8935                       (ior (match_test "TARGET_SHIFT1")
8936                            (match_test "optimize_function_for_size_p (cfun)")))))
8937        (const_string "0")
8938        (const_string "*")))
8939    (set_attr "mode" "QI,SI,SI")])
8941 (define_insn "*ashlqi3_1_slp"
8942   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
8943         (ashift:QI (match_dup 0)
8944                    (match_operand:QI 1 "nonmemory_operand" "cI")))
8945    (clobber (reg:CC FLAGS_REG))]
8946   "(optimize_function_for_size_p (cfun)
8947     || !TARGET_PARTIAL_FLAG_REG_STALL
8948     || (operands[1] == const1_rtx
8949         && (TARGET_SHIFT1
8950             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
8952   switch (get_attr_type (insn))
8953     {
8954     case TYPE_ALU:
8955       gcc_assert (operands[1] == const1_rtx);
8956       return "add{b}\t%0, %0";
8958     default:
8959       if (operands[1] == const1_rtx
8960           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8961         return "sal{b}\t%0";
8962       else
8963         return "sal{b}\t{%1, %0|%0, %1}";
8964     }
8966   [(set (attr "type")
8967      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
8968                       (match_operand 0 "register_operand"))
8969                  (match_operand 1 "const1_operand"))
8970               (const_string "alu")
8971            ]
8972            (const_string "ishift1")))
8973    (set (attr "length_immediate")
8974      (if_then_else
8975        (ior (eq_attr "type" "alu")
8976             (and (eq_attr "type" "ishift1")
8977                  (and (match_operand 1 "const1_operand")
8978                       (ior (match_test "TARGET_SHIFT1")
8979                            (match_test "optimize_function_for_size_p (cfun)")))))
8980        (const_string "0")
8981        (const_string "*")))
8982    (set_attr "mode" "QI")])
8984 ;; Convert ashift to the lea pattern to avoid flags dependency.
8985 (define_split
8986   [(set (match_operand 0 "register_operand")
8987         (ashift (match_operand 1 "index_register_operand")
8988                 (match_operand:QI 2 "const_int_operand")))
8989    (clobber (reg:CC FLAGS_REG))]
8990   "GET_MODE (operands[0]) == GET_MODE (operands[1])
8991    && reload_completed
8992    && true_regnum (operands[0]) != true_regnum (operands[1])"
8993   [(const_int 0)]
8995   enum machine_mode mode = GET_MODE (operands[0]);
8996   rtx pat;
8998   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
8999     { 
9000       mode = SImode; 
9001       operands[0] = gen_lowpart (mode, operands[0]);
9002       operands[1] = gen_lowpart (mode, operands[1]);
9003     }
9005   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9007   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9009   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9010   DONE;
9013 ;; Convert ashift to the lea pattern to avoid flags dependency.
9014 (define_split
9015   [(set (match_operand:DI 0 "register_operand")
9016         (zero_extend:DI
9017           (ashift:SI (match_operand:SI 1 "index_register_operand")
9018                      (match_operand:QI 2 "const_int_operand"))))
9019    (clobber (reg:CC FLAGS_REG))]
9020   "TARGET_64BIT && reload_completed
9021    && true_regnum (operands[0]) != true_regnum (operands[1])"
9022   [(set (match_dup 0)
9023         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9025   operands[1] = gen_lowpart (SImode, operands[1]);
9026   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9029 ;; This pattern can't accept a variable shift count, since shifts by
9030 ;; zero don't affect the flags.  We assume that shifts by constant
9031 ;; zero are optimized away.
9032 (define_insn "*ashl<mode>3_cmp"
9033   [(set (reg FLAGS_REG)
9034         (compare
9035           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9036                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9037           (const_int 0)))
9038    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9039         (ashift:SWI (match_dup 1) (match_dup 2)))]
9040   "(optimize_function_for_size_p (cfun)
9041     || !TARGET_PARTIAL_FLAG_REG_STALL
9042     || (operands[2] == const1_rtx
9043         && (TARGET_SHIFT1
9044             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9045    && ix86_match_ccmode (insn, CCGOCmode)
9046    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9048   switch (get_attr_type (insn))
9049     {
9050     case TYPE_ALU:
9051       gcc_assert (operands[2] == const1_rtx);
9052       return "add{<imodesuffix>}\t%0, %0";
9054     default:
9055       if (operands[2] == const1_rtx
9056           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9057         return "sal{<imodesuffix>}\t%0";
9058       else
9059         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9060     }
9062   [(set (attr "type")
9063      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9064                       (match_operand 0 "register_operand"))
9065                  (match_operand 2 "const1_operand"))
9066               (const_string "alu")
9067            ]
9068            (const_string "ishift")))
9069    (set (attr "length_immediate")
9070      (if_then_else
9071        (ior (eq_attr "type" "alu")
9072             (and (eq_attr "type" "ishift")
9073                  (and (match_operand 2 "const1_operand")
9074                       (ior (match_test "TARGET_SHIFT1")
9075                            (match_test "optimize_function_for_size_p (cfun)")))))
9076        (const_string "0")
9077        (const_string "*")))
9078    (set_attr "mode" "<MODE>")])
9080 (define_insn "*ashlsi3_cmp_zext"
9081   [(set (reg FLAGS_REG)
9082         (compare
9083           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9084                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9085           (const_int 0)))
9086    (set (match_operand:DI 0 "register_operand" "=r")
9087         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9088   "TARGET_64BIT
9089    && (optimize_function_for_size_p (cfun)
9090        || !TARGET_PARTIAL_FLAG_REG_STALL
9091        || (operands[2] == const1_rtx
9092            && (TARGET_SHIFT1
9093                || TARGET_DOUBLE_WITH_ADD)))
9094    && ix86_match_ccmode (insn, CCGOCmode)
9095    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9097   switch (get_attr_type (insn))
9098     {
9099     case TYPE_ALU:
9100       gcc_assert (operands[2] == const1_rtx);
9101       return "add{l}\t%k0, %k0";
9103     default:
9104       if (operands[2] == const1_rtx
9105           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9106         return "sal{l}\t%k0";
9107       else
9108         return "sal{l}\t{%2, %k0|%k0, %2}";
9109     }
9111   [(set (attr "type")
9112      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9113                  (match_operand 2 "const1_operand"))
9114               (const_string "alu")
9115            ]
9116            (const_string "ishift")))
9117    (set (attr "length_immediate")
9118      (if_then_else
9119        (ior (eq_attr "type" "alu")
9120             (and (eq_attr "type" "ishift")
9121                  (and (match_operand 2 "const1_operand")
9122                       (ior (match_test "TARGET_SHIFT1")
9123                            (match_test "optimize_function_for_size_p (cfun)")))))
9124        (const_string "0")
9125        (const_string "*")))
9126    (set_attr "mode" "SI")])
9128 (define_insn "*ashl<mode>3_cconly"
9129   [(set (reg FLAGS_REG)
9130         (compare
9131           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9132                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9133           (const_int 0)))
9134    (clobber (match_scratch:SWI 0 "=<r>"))]
9135   "(optimize_function_for_size_p (cfun)
9136     || !TARGET_PARTIAL_FLAG_REG_STALL
9137     || (operands[2] == const1_rtx
9138         && (TARGET_SHIFT1
9139             || TARGET_DOUBLE_WITH_ADD)))
9140    && ix86_match_ccmode (insn, CCGOCmode)"
9142   switch (get_attr_type (insn))
9143     {
9144     case TYPE_ALU:
9145       gcc_assert (operands[2] == const1_rtx);
9146       return "add{<imodesuffix>}\t%0, %0";
9148     default:
9149       if (operands[2] == const1_rtx
9150           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9151         return "sal{<imodesuffix>}\t%0";
9152       else
9153         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9154     }
9156   [(set (attr "type")
9157      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9158                       (match_operand 0 "register_operand"))
9159                  (match_operand 2 "const1_operand"))
9160               (const_string "alu")
9161            ]
9162            (const_string "ishift")))
9163    (set (attr "length_immediate")
9164      (if_then_else
9165        (ior (eq_attr "type" "alu")
9166             (and (eq_attr "type" "ishift")
9167                  (and (match_operand 2 "const1_operand")
9168                       (ior (match_test "TARGET_SHIFT1")
9169                            (match_test "optimize_function_for_size_p (cfun)")))))
9170        (const_string "0")
9171        (const_string "*")))
9172    (set_attr "mode" "<MODE>")])
9174 ;; See comment above `ashl<mode>3' about how this works.
9176 (define_expand "<shift_insn><mode>3"
9177   [(set (match_operand:SDWIM 0 "<shift_operand>")
9178         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9179                            (match_operand:QI 2 "nonmemory_operand")))]
9180   ""
9181   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9183 ;; Avoid useless masking of count operand.
9184 (define_insn "*<shift_insn><mode>3_mask"
9185   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9186         (any_shiftrt:SWI48
9187           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9188           (subreg:QI
9189             (and:SI
9190               (match_operand:SI 2 "register_operand" "c")
9191               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9192    (clobber (reg:CC FLAGS_REG))]
9193   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9194    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9195       == GET_MODE_BITSIZE (<MODE>mode)-1"
9197   return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9199   [(set_attr "type" "ishift")
9200    (set_attr "mode" "<MODE>")])
9202 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9203   [(set (match_operand:DWI 0 "register_operand" "=r")
9204         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9205                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9206    (clobber (reg:CC FLAGS_REG))]
9207   ""
9208   "#"
9209   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9210   [(const_int 0)]
9211   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9212   [(set_attr "type" "multi")])
9214 ;; By default we don't ask for a scratch register, because when DWImode
9215 ;; values are manipulated, registers are already at a premium.  But if
9216 ;; we have one handy, we won't turn it away.
9218 (define_peephole2
9219   [(match_scratch:DWIH 3 "r")
9220    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9221                    (any_shiftrt:<DWI>
9222                      (match_operand:<DWI> 1 "register_operand")
9223                      (match_operand:QI 2 "nonmemory_operand")))
9224               (clobber (reg:CC FLAGS_REG))])
9225    (match_dup 3)]
9226   "TARGET_CMOVE"
9227   [(const_int 0)]
9228   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9230 (define_insn "x86_64_shrd"
9231   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9232         (ior:DI (ashiftrt:DI (match_dup 0)
9233                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9234                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9235                   (minus:QI (const_int 64) (match_dup 2)))))
9236    (clobber (reg:CC FLAGS_REG))]
9237   "TARGET_64BIT"
9238   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9239   [(set_attr "type" "ishift")
9240    (set_attr "prefix_0f" "1")
9241    (set_attr "mode" "DI")
9242    (set_attr "athlon_decode" "vector")
9243    (set_attr "amdfam10_decode" "vector")
9244    (set_attr "bdver1_decode" "vector")])
9246 (define_insn "x86_shrd"
9247   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9248         (ior:SI (ashiftrt:SI (match_dup 0)
9249                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9250                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9251                   (minus:QI (const_int 32) (match_dup 2)))))
9252    (clobber (reg:CC FLAGS_REG))]
9253   ""
9254   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9255   [(set_attr "type" "ishift")
9256    (set_attr "prefix_0f" "1")
9257    (set_attr "mode" "SI")
9258    (set_attr "pent_pair" "np")
9259    (set_attr "athlon_decode" "vector")
9260    (set_attr "amdfam10_decode" "vector")
9261    (set_attr "bdver1_decode" "vector")])
9263 (define_insn "ashrdi3_cvt"
9264   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9265         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9266                      (match_operand:QI 2 "const_int_operand")))
9267    (clobber (reg:CC FLAGS_REG))]
9268   "TARGET_64BIT && INTVAL (operands[2]) == 63
9269    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9270    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9271   "@
9272    {cqto|cqo}
9273    sar{q}\t{%2, %0|%0, %2}"
9274   [(set_attr "type" "imovx,ishift")
9275    (set_attr "prefix_0f" "0,*")
9276    (set_attr "length_immediate" "0,*")
9277    (set_attr "modrm" "0,1")
9278    (set_attr "mode" "DI")])
9280 (define_insn "ashrsi3_cvt"
9281   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9282         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9283                      (match_operand:QI 2 "const_int_operand")))
9284    (clobber (reg:CC FLAGS_REG))]
9285   "INTVAL (operands[2]) == 31
9286    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9287    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9288   "@
9289    {cltd|cdq}
9290    sar{l}\t{%2, %0|%0, %2}"
9291   [(set_attr "type" "imovx,ishift")
9292    (set_attr "prefix_0f" "0,*")
9293    (set_attr "length_immediate" "0,*")
9294    (set_attr "modrm" "0,1")
9295    (set_attr "mode" "SI")])
9297 (define_insn "*ashrsi3_cvt_zext"
9298   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9299         (zero_extend:DI
9300           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9301                        (match_operand:QI 2 "const_int_operand"))))
9302    (clobber (reg:CC FLAGS_REG))]
9303   "TARGET_64BIT && INTVAL (operands[2]) == 31
9304    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9305    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9306   "@
9307    {cltd|cdq}
9308    sar{l}\t{%2, %k0|%k0, %2}"
9309   [(set_attr "type" "imovx,ishift")
9310    (set_attr "prefix_0f" "0,*")
9311    (set_attr "length_immediate" "0,*")
9312    (set_attr "modrm" "0,1")
9313    (set_attr "mode" "SI")])
9315 (define_expand "x86_shift<mode>_adj_3"
9316   [(use (match_operand:SWI48 0 "register_operand"))
9317    (use (match_operand:SWI48 1 "register_operand"))
9318    (use (match_operand:QI 2 "register_operand"))]
9319   ""
9321   rtx label = gen_label_rtx ();
9322   rtx tmp;
9324   emit_insn (gen_testqi_ccz_1 (operands[2],
9325                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9327   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9328   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9329   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9330                               gen_rtx_LABEL_REF (VOIDmode, label),
9331                               pc_rtx);
9332   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9333   JUMP_LABEL (tmp) = label;
9335   emit_move_insn (operands[0], operands[1]);
9336   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9337                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9338   emit_label (label);
9339   LABEL_NUSES (label) = 1;
9341   DONE;
9344 (define_insn "*bmi2_<shift_insn><mode>3_1"
9345   [(set (match_operand:SWI48 0 "register_operand" "=r")
9346         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9347                            (match_operand:SWI48 2 "register_operand" "r")))]
9348   "TARGET_BMI2"
9349   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9350   [(set_attr "type" "ishiftx")
9351    (set_attr "mode" "<MODE>")])
9353 (define_insn "*<shift_insn><mode>3_1"
9354   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9355         (any_shiftrt:SWI48
9356           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9357           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9358    (clobber (reg:CC FLAGS_REG))]
9359   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9361   switch (get_attr_type (insn))
9362     {
9363     case TYPE_ISHIFTX:
9364       return "#";
9366     default:
9367       if (operands[2] == const1_rtx
9368           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9369         return "<shift>{<imodesuffix>}\t%0";
9370       else
9371         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9372     }
9374   [(set_attr "isa" "*,bmi2")
9375    (set_attr "type" "ishift,ishiftx")
9376    (set (attr "length_immediate")
9377      (if_then_else
9378        (and (match_operand 2 "const1_operand")
9379             (ior (match_test "TARGET_SHIFT1")
9380                  (match_test "optimize_function_for_size_p (cfun)")))
9381        (const_string "0")
9382        (const_string "*")))
9383    (set_attr "mode" "<MODE>")])
9385 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9386 (define_split
9387   [(set (match_operand:SWI48 0 "register_operand")
9388         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9389                            (match_operand:QI 2 "register_operand")))
9390    (clobber (reg:CC FLAGS_REG))]
9391   "TARGET_BMI2 && reload_completed"
9392   [(set (match_dup 0)
9393         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9394   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9396 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9397   [(set (match_operand:DI 0 "register_operand" "=r")
9398         (zero_extend:DI
9399           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9400                           (match_operand:SI 2 "register_operand" "r"))))]
9401   "TARGET_64BIT && TARGET_BMI2"
9402   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9403   [(set_attr "type" "ishiftx")
9404    (set_attr "mode" "SI")])
9406 (define_insn "*<shift_insn>si3_1_zext"
9407   [(set (match_operand:DI 0 "register_operand" "=r,r")
9408         (zero_extend:DI
9409           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9410                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9411    (clobber (reg:CC FLAGS_REG))]
9412   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9414   switch (get_attr_type (insn))
9415     {
9416     case TYPE_ISHIFTX:
9417       return "#";
9419     default:
9420       if (operands[2] == const1_rtx
9421           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9422         return "<shift>{l}\t%k0";
9423       else
9424         return "<shift>{l}\t{%2, %k0|%k0, %2}";
9425     }
9427   [(set_attr "isa" "*,bmi2")
9428    (set_attr "type" "ishift,ishiftx")
9429    (set (attr "length_immediate")
9430      (if_then_else
9431        (and (match_operand 2 "const1_operand")
9432             (ior (match_test "TARGET_SHIFT1")
9433                  (match_test "optimize_function_for_size_p (cfun)")))
9434        (const_string "0")
9435        (const_string "*")))
9436    (set_attr "mode" "SI")])
9438 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9439 (define_split
9440   [(set (match_operand:DI 0 "register_operand")
9441         (zero_extend:DI
9442           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9443                           (match_operand:QI 2 "register_operand"))))
9444    (clobber (reg:CC FLAGS_REG))]
9445   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9446   [(set (match_dup 0)
9447         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9448   "operands[2] = gen_lowpart (SImode, operands[2]);")
9450 (define_insn "*<shift_insn><mode>3_1"
9451   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9452         (any_shiftrt:SWI12
9453           (match_operand:SWI12 1 "nonimmediate_operand" "0")
9454           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9455    (clobber (reg:CC FLAGS_REG))]
9456   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9458   if (operands[2] == const1_rtx
9459       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9460     return "<shift>{<imodesuffix>}\t%0";
9461   else
9462     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9464   [(set_attr "type" "ishift")
9465    (set (attr "length_immediate")
9466      (if_then_else
9467        (and (match_operand 2 "const1_operand")
9468             (ior (match_test "TARGET_SHIFT1")
9469                  (match_test "optimize_function_for_size_p (cfun)")))
9470        (const_string "0")
9471        (const_string "*")))
9472    (set_attr "mode" "<MODE>")])
9474 (define_insn "*<shift_insn>qi3_1_slp"
9475   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9476         (any_shiftrt:QI (match_dup 0)
9477                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9478    (clobber (reg:CC FLAGS_REG))]
9479   "(optimize_function_for_size_p (cfun)
9480     || !TARGET_PARTIAL_REG_STALL
9481     || (operands[1] == const1_rtx
9482         && TARGET_SHIFT1))"
9484   if (operands[1] == const1_rtx
9485       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9486     return "<shift>{b}\t%0";
9487   else
9488     return "<shift>{b}\t{%1, %0|%0, %1}";
9490   [(set_attr "type" "ishift1")
9491    (set (attr "length_immediate")
9492      (if_then_else
9493        (and (match_operand 1 "const1_operand")
9494             (ior (match_test "TARGET_SHIFT1")
9495                  (match_test "optimize_function_for_size_p (cfun)")))
9496        (const_string "0")
9497        (const_string "*")))
9498    (set_attr "mode" "QI")])
9500 ;; This pattern can't accept a variable shift count, since shifts by
9501 ;; zero don't affect the flags.  We assume that shifts by constant
9502 ;; zero are optimized away.
9503 (define_insn "*<shift_insn><mode>3_cmp"
9504   [(set (reg FLAGS_REG)
9505         (compare
9506           (any_shiftrt:SWI
9507             (match_operand:SWI 1 "nonimmediate_operand" "0")
9508             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9509           (const_int 0)))
9510    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9511         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9512   "(optimize_function_for_size_p (cfun)
9513     || !TARGET_PARTIAL_FLAG_REG_STALL
9514     || (operands[2] == const1_rtx
9515         && TARGET_SHIFT1))
9516    && ix86_match_ccmode (insn, CCGOCmode)
9517    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9519   if (operands[2] == const1_rtx
9520       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9521     return "<shift>{<imodesuffix>}\t%0";
9522   else
9523     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9525   [(set_attr "type" "ishift")
9526    (set (attr "length_immediate")
9527      (if_then_else
9528        (and (match_operand 2 "const1_operand")
9529             (ior (match_test "TARGET_SHIFT1")
9530                  (match_test "optimize_function_for_size_p (cfun)")))
9531        (const_string "0")
9532        (const_string "*")))
9533    (set_attr "mode" "<MODE>")])
9535 (define_insn "*<shift_insn>si3_cmp_zext"
9536   [(set (reg FLAGS_REG)
9537         (compare
9538           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9539                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
9540           (const_int 0)))
9541    (set (match_operand:DI 0 "register_operand" "=r")
9542         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9543   "TARGET_64BIT
9544    && (optimize_function_for_size_p (cfun)
9545        || !TARGET_PARTIAL_FLAG_REG_STALL
9546        || (operands[2] == const1_rtx
9547            && TARGET_SHIFT1))
9548    && ix86_match_ccmode (insn, CCGOCmode)
9549    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9551   if (operands[2] == const1_rtx
9552       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9553     return "<shift>{l}\t%k0";
9554   else
9555     return "<shift>{l}\t{%2, %k0|%k0, %2}";
9557   [(set_attr "type" "ishift")
9558    (set (attr "length_immediate")
9559      (if_then_else
9560        (and (match_operand 2 "const1_operand")
9561             (ior (match_test "TARGET_SHIFT1")
9562                  (match_test "optimize_function_for_size_p (cfun)")))
9563        (const_string "0")
9564        (const_string "*")))
9565    (set_attr "mode" "SI")])
9567 (define_insn "*<shift_insn><mode>3_cconly"
9568   [(set (reg FLAGS_REG)
9569         (compare
9570           (any_shiftrt:SWI
9571             (match_operand:SWI 1 "register_operand" "0")
9572             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9573           (const_int 0)))
9574    (clobber (match_scratch:SWI 0 "=<r>"))]
9575   "(optimize_function_for_size_p (cfun)
9576     || !TARGET_PARTIAL_FLAG_REG_STALL
9577     || (operands[2] == const1_rtx
9578         && TARGET_SHIFT1))
9579    && ix86_match_ccmode (insn, CCGOCmode)"
9581   if (operands[2] == const1_rtx
9582       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9583     return "<shift>{<imodesuffix>}\t%0";
9584   else
9585     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9587   [(set_attr "type" "ishift")
9588    (set (attr "length_immediate")
9589      (if_then_else
9590        (and (match_operand 2 "const1_operand")
9591             (ior (match_test "TARGET_SHIFT1")
9592                  (match_test "optimize_function_for_size_p (cfun)")))
9593        (const_string "0")
9594        (const_string "*")))
9595    (set_attr "mode" "<MODE>")])
9597 ;; Rotate instructions
9599 (define_expand "<rotate_insn>ti3"
9600   [(set (match_operand:TI 0 "register_operand")
9601         (any_rotate:TI (match_operand:TI 1 "register_operand")
9602                        (match_operand:QI 2 "nonmemory_operand")))]
9603   "TARGET_64BIT"
9605   if (const_1_to_63_operand (operands[2], VOIDmode))
9606     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9607                 (operands[0], operands[1], operands[2]));
9608   else
9609     FAIL;
9611   DONE;
9614 (define_expand "<rotate_insn>di3"
9615   [(set (match_operand:DI 0 "shiftdi_operand")
9616         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
9617                        (match_operand:QI 2 "nonmemory_operand")))]
9618  ""
9620   if (TARGET_64BIT)
9621     ix86_expand_binary_operator (<CODE>, DImode, operands);
9622   else if (const_1_to_31_operand (operands[2], VOIDmode))
9623     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9624                 (operands[0], operands[1], operands[2]));
9625   else
9626     FAIL;
9628   DONE;
9631 (define_expand "<rotate_insn><mode>3"
9632   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
9633         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
9634                             (match_operand:QI 2 "nonmemory_operand")))]
9635   ""
9636   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9638 ;; Avoid useless masking of count operand.
9639 (define_insn "*<rotate_insn><mode>3_mask"
9640   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9641         (any_rotate:SWI48
9642           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9643           (subreg:QI
9644             (and:SI
9645               (match_operand:SI 2 "register_operand" "c")
9646               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9647    (clobber (reg:CC FLAGS_REG))]
9648   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9649    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9650       == GET_MODE_BITSIZE (<MODE>mode)-1"
9652   return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9654   [(set_attr "type" "rotate")
9655    (set_attr "mode" "<MODE>")])
9657 ;; Implement rotation using two double-precision
9658 ;; shift instructions and a scratch register.
9660 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
9661  [(set (match_operand:<DWI> 0 "register_operand" "=r")
9662        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9663                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9664   (clobber (reg:CC FLAGS_REG))
9665   (clobber (match_scratch:DWIH 3 "=&r"))]
9666  ""
9667  "#"
9668  "reload_completed"
9669  [(set (match_dup 3) (match_dup 4))
9670   (parallel
9671    [(set (match_dup 4)
9672          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
9673                    (lshiftrt:DWIH (match_dup 5)
9674                                   (minus:QI (match_dup 6) (match_dup 2)))))
9675     (clobber (reg:CC FLAGS_REG))])
9676   (parallel
9677    [(set (match_dup 5)
9678          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
9679                    (lshiftrt:DWIH (match_dup 3)
9680                                   (minus:QI (match_dup 6) (match_dup 2)))))
9681     (clobber (reg:CC FLAGS_REG))])]
9683   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9685   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
9688 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
9689  [(set (match_operand:<DWI> 0 "register_operand" "=r")
9690        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9691                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9692   (clobber (reg:CC FLAGS_REG))
9693   (clobber (match_scratch:DWIH 3 "=&r"))]
9694  ""
9695  "#"
9696  "reload_completed"
9697  [(set (match_dup 3) (match_dup 4))
9698   (parallel
9699    [(set (match_dup 4)
9700          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
9701                    (ashift:DWIH (match_dup 5)
9702                                 (minus:QI (match_dup 6) (match_dup 2)))))
9703     (clobber (reg:CC FLAGS_REG))])
9704   (parallel
9705    [(set (match_dup 5)
9706          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
9707                    (ashift:DWIH (match_dup 3)
9708                                 (minus:QI (match_dup 6) (match_dup 2)))))
9709     (clobber (reg:CC FLAGS_REG))])]
9711   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9713   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
9716 (define_insn "*bmi2_rorx<mode>3_1"
9717   [(set (match_operand:SWI48 0 "register_operand" "=r")
9718         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9719                         (match_operand:QI 2 "immediate_operand" "<S>")))]
9720   "TARGET_BMI2"
9721   "rorx\t{%2, %1, %0|%0, %1, %2}"
9722   [(set_attr "type" "rotatex")
9723    (set_attr "mode" "<MODE>")])
9725 (define_insn "*<rotate_insn><mode>3_1"
9726   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9727         (any_rotate:SWI48
9728           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9729           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
9730    (clobber (reg:CC FLAGS_REG))]
9731   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9733   switch (get_attr_type (insn))
9734     {
9735     case TYPE_ROTATEX:
9736       return "#";
9738     default:
9739       if (operands[2] == const1_rtx
9740           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9741         return "<rotate>{<imodesuffix>}\t%0";
9742       else
9743         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
9744     }
9746   [(set_attr "isa" "*,bmi2")
9747    (set_attr "type" "rotate,rotatex")
9748    (set (attr "length_immediate")
9749      (if_then_else
9750        (and (eq_attr "type" "rotate")
9751             (and (match_operand 2 "const1_operand")
9752                  (ior (match_test "TARGET_SHIFT1")
9753                       (match_test "optimize_function_for_size_p (cfun)"))))
9754        (const_string "0")
9755        (const_string "*")))
9756    (set_attr "mode" "<MODE>")])
9758 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
9759 (define_split
9760   [(set (match_operand:SWI48 0 "register_operand")
9761         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9762                       (match_operand:QI 2 "immediate_operand")))
9763    (clobber (reg:CC FLAGS_REG))]
9764   "TARGET_BMI2 && reload_completed"
9765   [(set (match_dup 0)
9766         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
9768   operands[2]
9769     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
9772 (define_split
9773   [(set (match_operand:SWI48 0 "register_operand")
9774         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9775                         (match_operand:QI 2 "immediate_operand")))
9776    (clobber (reg:CC FLAGS_REG))]
9777   "TARGET_BMI2 && reload_completed"
9778   [(set (match_dup 0)
9779         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
9781 (define_insn "*bmi2_rorxsi3_1_zext"
9782   [(set (match_operand:DI 0 "register_operand" "=r")
9783         (zero_extend:DI
9784           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9785                        (match_operand:QI 2 "immediate_operand" "I"))))]
9786   "TARGET_64BIT && TARGET_BMI2"
9787   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
9788   [(set_attr "type" "rotatex")
9789    (set_attr "mode" "SI")])
9791 (define_insn "*<rotate_insn>si3_1_zext"
9792   [(set (match_operand:DI 0 "register_operand" "=r,r")
9793         (zero_extend:DI
9794           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9795                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
9796    (clobber (reg:CC FLAGS_REG))]
9797   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9799   switch (get_attr_type (insn))
9800     {
9801     case TYPE_ROTATEX:
9802       return "#";
9804     default:
9805       if (operands[2] == const1_rtx
9806           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9807         return "<rotate>{l}\t%k0";
9808       else
9809         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
9810     }
9812   [(set_attr "isa" "*,bmi2")
9813    (set_attr "type" "rotate,rotatex")
9814    (set (attr "length_immediate")
9815      (if_then_else
9816        (and (eq_attr "type" "rotate")
9817             (and (match_operand 2 "const1_operand")
9818                  (ior (match_test "TARGET_SHIFT1")
9819                       (match_test "optimize_function_for_size_p (cfun)"))))
9820        (const_string "0")
9821        (const_string "*")))
9822    (set_attr "mode" "SI")])
9824 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
9825 (define_split
9826   [(set (match_operand:DI 0 "register_operand")
9827         (zero_extend:DI
9828           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
9829                      (match_operand:QI 2 "immediate_operand"))))
9830    (clobber (reg:CC FLAGS_REG))]
9831   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9832   [(set (match_dup 0)
9833         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
9835   operands[2]
9836     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
9839 (define_split
9840   [(set (match_operand:DI 0 "register_operand")
9841         (zero_extend:DI
9842           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
9843                        (match_operand:QI 2 "immediate_operand"))))
9844    (clobber (reg:CC FLAGS_REG))]
9845   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9846   [(set (match_dup 0)
9847         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
9849 (define_insn "*<rotate_insn><mode>3_1"
9850   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9851         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9852                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9853    (clobber (reg:CC FLAGS_REG))]
9854   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9856   if (operands[2] == const1_rtx
9857       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9858     return "<rotate>{<imodesuffix>}\t%0";
9859   else
9860     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
9862   [(set_attr "type" "rotate")
9863    (set (attr "length_immediate")
9864      (if_then_else
9865        (and (match_operand 2 "const1_operand")
9866             (ior (match_test "TARGET_SHIFT1")
9867                  (match_test "optimize_function_for_size_p (cfun)")))
9868        (const_string "0")
9869        (const_string "*")))
9870    (set_attr "mode" "<MODE>")])
9872 (define_insn "*<rotate_insn>qi3_1_slp"
9873   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9874         (any_rotate:QI (match_dup 0)
9875                        (match_operand:QI 1 "nonmemory_operand" "cI")))
9876    (clobber (reg:CC FLAGS_REG))]
9877   "(optimize_function_for_size_p (cfun)
9878     || !TARGET_PARTIAL_REG_STALL
9879     || (operands[1] == const1_rtx
9880         && TARGET_SHIFT1))"
9882   if (operands[1] == const1_rtx
9883       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9884     return "<rotate>{b}\t%0";
9885   else
9886     return "<rotate>{b}\t{%1, %0|%0, %1}";
9888   [(set_attr "type" "rotate1")
9889    (set (attr "length_immediate")
9890      (if_then_else
9891        (and (match_operand 1 "const1_operand")
9892             (ior (match_test "TARGET_SHIFT1")
9893                  (match_test "optimize_function_for_size_p (cfun)")))
9894        (const_string "0")
9895        (const_string "*")))
9896    (set_attr "mode" "QI")])
9898 (define_split
9899  [(set (match_operand:HI 0 "register_operand")
9900        (any_rotate:HI (match_dup 0) (const_int 8)))
9901   (clobber (reg:CC FLAGS_REG))]
9902  "reload_completed
9903   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
9904  [(parallel [(set (strict_low_part (match_dup 0))
9905                   (bswap:HI (match_dup 0)))
9906              (clobber (reg:CC FLAGS_REG))])])
9908 ;; Bit set / bit test instructions
9910 (define_expand "extv"
9911   [(set (match_operand:SI 0 "register_operand")
9912         (sign_extract:SI (match_operand:SI 1 "register_operand")
9913                          (match_operand:SI 2 "const8_operand")
9914                          (match_operand:SI 3 "const8_operand")))]
9915   ""
9917   /* Handle extractions from %ah et al.  */
9918   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
9919     FAIL;
9921   /* From mips.md: extract_bit_field doesn't verify that our source
9922      matches the predicate, so check it again here.  */
9923   if (! ext_register_operand (operands[1], VOIDmode))
9924     FAIL;
9927 (define_expand "extzv"
9928   [(set (match_operand:SI 0 "register_operand")
9929         (zero_extract:SI (match_operand 1 "ext_register_operand")
9930                          (match_operand:SI 2 "const8_operand")
9931                          (match_operand:SI 3 "const8_operand")))]
9932   ""
9934   /* Handle extractions from %ah et al.  */
9935   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
9936     FAIL;
9938   /* From mips.md: extract_bit_field doesn't verify that our source
9939      matches the predicate, so check it again here.  */
9940   if (! ext_register_operand (operands[1], VOIDmode))
9941     FAIL;
9944 (define_expand "insv"
9945   [(set (zero_extract (match_operand 0 "register_operand")
9946                       (match_operand 1 "const_int_operand")
9947                       (match_operand 2 "const_int_operand"))
9948         (match_operand 3 "register_operand"))]
9949   ""
9951   rtx (*gen_mov_insv_1) (rtx, rtx);
9953   if (ix86_expand_pinsr (operands))
9954     DONE;
9956   /* Handle insertions to %ah et al.  */
9957   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
9958     FAIL;
9960   /* From mips.md: insert_bit_field doesn't verify that our source
9961      matches the predicate, so check it again here.  */
9962   if (! ext_register_operand (operands[0], VOIDmode))
9963     FAIL;
9965   gen_mov_insv_1 = (TARGET_64BIT
9966                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
9968   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
9969   DONE;
9972 ;; %%% bts, btr, btc, bt.
9973 ;; In general these instructions are *slow* when applied to memory,
9974 ;; since they enforce atomic operation.  When applied to registers,
9975 ;; it depends on the cpu implementation.  They're never faster than
9976 ;; the corresponding and/ior/xor operations, so with 32-bit there's
9977 ;; no point.  But in 64-bit, we can't hold the relevant immediates
9978 ;; within the instruction itself, so operating on bits in the high
9979 ;; 32-bits of a register becomes easier.
9981 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
9982 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
9983 ;; negdf respectively, so they can never be disabled entirely.
9985 (define_insn "*btsq"
9986   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
9987                          (const_int 1)
9988                          (match_operand:DI 1 "const_0_to_63_operand"))
9989         (const_int 1))
9990    (clobber (reg:CC FLAGS_REG))]
9991   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
9992   "bts{q}\t{%1, %0|%0, %1}"
9993   [(set_attr "type" "alu1")
9994    (set_attr "prefix_0f" "1")
9995    (set_attr "mode" "DI")])
9997 (define_insn "*btrq"
9998   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
9999                          (const_int 1)
10000                          (match_operand:DI 1 "const_0_to_63_operand"))
10001         (const_int 0))
10002    (clobber (reg:CC FLAGS_REG))]
10003   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10004   "btr{q}\t{%1, %0|%0, %1}"
10005   [(set_attr "type" "alu1")
10006    (set_attr "prefix_0f" "1")
10007    (set_attr "mode" "DI")])
10009 (define_insn "*btcq"
10010   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10011                          (const_int 1)
10012                          (match_operand:DI 1 "const_0_to_63_operand"))
10013         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10014    (clobber (reg:CC FLAGS_REG))]
10015   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10016   "btc{q}\t{%1, %0|%0, %1}"
10017   [(set_attr "type" "alu1")
10018    (set_attr "prefix_0f" "1")
10019    (set_attr "mode" "DI")])
10021 ;; Allow Nocona to avoid these instructions if a register is available.
10023 (define_peephole2
10024   [(match_scratch:DI 2 "r")
10025    (parallel [(set (zero_extract:DI
10026                      (match_operand:DI 0 "register_operand")
10027                      (const_int 1)
10028                      (match_operand:DI 1 "const_0_to_63_operand"))
10029                    (const_int 1))
10030               (clobber (reg:CC FLAGS_REG))])]
10031   "TARGET_64BIT && !TARGET_USE_BT"
10032   [(const_int 0)]
10034   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10035   rtx op1;
10037   if (HOST_BITS_PER_WIDE_INT >= 64)
10038     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10039   else if (i < HOST_BITS_PER_WIDE_INT)
10040     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10041   else
10042     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10044   op1 = immed_double_const (lo, hi, DImode);
10045   if (i >= 31)
10046     {
10047       emit_move_insn (operands[2], op1);
10048       op1 = operands[2];
10049     }
10051   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10052   DONE;
10055 (define_peephole2
10056   [(match_scratch:DI 2 "r")
10057    (parallel [(set (zero_extract:DI
10058                      (match_operand:DI 0 "register_operand")
10059                      (const_int 1)
10060                      (match_operand:DI 1 "const_0_to_63_operand"))
10061                    (const_int 0))
10062               (clobber (reg:CC FLAGS_REG))])]
10063   "TARGET_64BIT && !TARGET_USE_BT"
10064   [(const_int 0)]
10066   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10067   rtx op1;
10069   if (HOST_BITS_PER_WIDE_INT >= 64)
10070     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10071   else if (i < HOST_BITS_PER_WIDE_INT)
10072     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10073   else
10074     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10076   op1 = immed_double_const (~lo, ~hi, DImode);
10077   if (i >= 32)
10078     {
10079       emit_move_insn (operands[2], op1);
10080       op1 = operands[2];
10081     }
10083   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10084   DONE;
10087 (define_peephole2
10088   [(match_scratch:DI 2 "r")
10089    (parallel [(set (zero_extract:DI
10090                      (match_operand:DI 0 "register_operand")
10091                      (const_int 1)
10092                      (match_operand:DI 1 "const_0_to_63_operand"))
10093               (not:DI (zero_extract:DI
10094                         (match_dup 0) (const_int 1) (match_dup 1))))
10095               (clobber (reg:CC FLAGS_REG))])]
10096   "TARGET_64BIT && !TARGET_USE_BT"
10097   [(const_int 0)]
10099   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10100   rtx op1;
10102   if (HOST_BITS_PER_WIDE_INT >= 64)
10103     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10104   else if (i < HOST_BITS_PER_WIDE_INT)
10105     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10106   else
10107     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10109   op1 = immed_double_const (lo, hi, DImode);
10110   if (i >= 31)
10111     {
10112       emit_move_insn (operands[2], op1);
10113       op1 = operands[2];
10114     }
10116   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10117   DONE;
10120 (define_insn "*bt<mode>"
10121   [(set (reg:CCC FLAGS_REG)
10122         (compare:CCC
10123           (zero_extract:SWI48
10124             (match_operand:SWI48 0 "register_operand" "r")
10125             (const_int 1)
10126             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10127           (const_int 0)))]
10128   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10129   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10130   [(set_attr "type" "alu1")
10131    (set_attr "prefix_0f" "1")
10132    (set_attr "mode" "<MODE>")])
10134 ;; Store-flag instructions.
10136 ;; For all sCOND expanders, also expand the compare or test insn that
10137 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10139 (define_insn_and_split "*setcc_di_1"
10140   [(set (match_operand:DI 0 "register_operand" "=q")
10141         (match_operator:DI 1 "ix86_comparison_operator"
10142           [(reg FLAGS_REG) (const_int 0)]))]
10143   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10144   "#"
10145   "&& reload_completed"
10146   [(set (match_dup 2) (match_dup 1))
10147    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10149   PUT_MODE (operands[1], QImode);
10150   operands[2] = gen_lowpart (QImode, operands[0]);
10153 (define_insn_and_split "*setcc_si_1_and"
10154   [(set (match_operand:SI 0 "register_operand" "=q")
10155         (match_operator:SI 1 "ix86_comparison_operator"
10156           [(reg FLAGS_REG) (const_int 0)]))
10157    (clobber (reg:CC FLAGS_REG))]
10158   "!TARGET_PARTIAL_REG_STALL
10159    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10160   "#"
10161   "&& reload_completed"
10162   [(set (match_dup 2) (match_dup 1))
10163    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10164               (clobber (reg:CC FLAGS_REG))])]
10166   PUT_MODE (operands[1], QImode);
10167   operands[2] = gen_lowpart (QImode, operands[0]);
10170 (define_insn_and_split "*setcc_si_1_movzbl"
10171   [(set (match_operand:SI 0 "register_operand" "=q")
10172         (match_operator:SI 1 "ix86_comparison_operator"
10173           [(reg FLAGS_REG) (const_int 0)]))]
10174   "!TARGET_PARTIAL_REG_STALL
10175    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10176   "#"
10177   "&& reload_completed"
10178   [(set (match_dup 2) (match_dup 1))
10179    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10181   PUT_MODE (operands[1], QImode);
10182   operands[2] = gen_lowpart (QImode, operands[0]);
10185 (define_insn "*setcc_qi"
10186   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10187         (match_operator:QI 1 "ix86_comparison_operator"
10188           [(reg FLAGS_REG) (const_int 0)]))]
10189   ""
10190   "set%C1\t%0"
10191   [(set_attr "type" "setcc")
10192    (set_attr "mode" "QI")])
10194 (define_insn "*setcc_qi_slp"
10195   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10196         (match_operator:QI 1 "ix86_comparison_operator"
10197           [(reg FLAGS_REG) (const_int 0)]))]
10198   ""
10199   "set%C1\t%0"
10200   [(set_attr "type" "setcc")
10201    (set_attr "mode" "QI")])
10203 ;; In general it is not safe to assume too much about CCmode registers,
10204 ;; so simplify-rtx stops when it sees a second one.  Under certain
10205 ;; conditions this is safe on x86, so help combine not create
10207 ;;      seta    %al
10208 ;;      testb   %al, %al
10209 ;;      sete    %al
10211 (define_split
10212   [(set (match_operand:QI 0 "nonimmediate_operand")
10213         (ne:QI (match_operator 1 "ix86_comparison_operator"
10214                  [(reg FLAGS_REG) (const_int 0)])
10215             (const_int 0)))]
10216   ""
10217   [(set (match_dup 0) (match_dup 1))]
10218   "PUT_MODE (operands[1], QImode);")
10220 (define_split
10221   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10222         (ne:QI (match_operator 1 "ix86_comparison_operator"
10223                  [(reg FLAGS_REG) (const_int 0)])
10224             (const_int 0)))]
10225   ""
10226   [(set (match_dup 0) (match_dup 1))]
10227   "PUT_MODE (operands[1], QImode);")
10229 (define_split
10230   [(set (match_operand:QI 0 "nonimmediate_operand")
10231         (eq:QI (match_operator 1 "ix86_comparison_operator"
10232                  [(reg FLAGS_REG) (const_int 0)])
10233             (const_int 0)))]
10234   ""
10235   [(set (match_dup 0) (match_dup 1))]
10237   rtx new_op1 = copy_rtx (operands[1]);
10238   operands[1] = new_op1;
10239   PUT_MODE (new_op1, QImode);
10240   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10241                                              GET_MODE (XEXP (new_op1, 0))));
10243   /* Make sure that (a) the CCmode we have for the flags is strong
10244      enough for the reversed compare or (b) we have a valid FP compare.  */
10245   if (! ix86_comparison_operator (new_op1, VOIDmode))
10246     FAIL;
10249 (define_split
10250   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10251         (eq:QI (match_operator 1 "ix86_comparison_operator"
10252                  [(reg FLAGS_REG) (const_int 0)])
10253             (const_int 0)))]
10254   ""
10255   [(set (match_dup 0) (match_dup 1))]
10257   rtx new_op1 = copy_rtx (operands[1]);
10258   operands[1] = new_op1;
10259   PUT_MODE (new_op1, QImode);
10260   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10261                                              GET_MODE (XEXP (new_op1, 0))));
10263   /* Make sure that (a) the CCmode we have for the flags is strong
10264      enough for the reversed compare or (b) we have a valid FP compare.  */
10265   if (! ix86_comparison_operator (new_op1, VOIDmode))
10266     FAIL;
10269 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10270 ;; subsequent logical operations are used to imitate conditional moves.
10271 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10272 ;; it directly.
10274 (define_insn "setcc_<mode>_sse"
10275   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10276         (match_operator:MODEF 3 "sse_comparison_operator"
10277           [(match_operand:MODEF 1 "register_operand" "0,x")
10278            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10279   "SSE_FLOAT_MODE_P (<MODE>mode)"
10280   "@
10281    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10282    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10283   [(set_attr "isa" "noavx,avx")
10284    (set_attr "type" "ssecmp")
10285    (set_attr "length_immediate" "1")
10286    (set_attr "prefix" "orig,vex")
10287    (set_attr "mode" "<MODE>")])
10289 ;; Basic conditional jump instructions.
10290 ;; We ignore the overflow flag for signed branch instructions.
10292 (define_insn "*jcc_1"
10293   [(set (pc)
10294         (if_then_else (match_operator 1 "ix86_comparison_operator"
10295                                       [(reg FLAGS_REG) (const_int 0)])
10296                       (label_ref (match_operand 0))
10297                       (pc)))]
10298   ""
10299   "%+j%C1\t%l0"
10300   [(set_attr "type" "ibr")
10301    (set_attr "modrm" "0")
10302    (set (attr "length")
10303            (if_then_else (and (ge (minus (match_dup 0) (pc))
10304                                   (const_int -126))
10305                               (lt (minus (match_dup 0) (pc))
10306                                   (const_int 128)))
10307              (const_int 2)
10308              (const_int 6)))])
10310 (define_insn "*jcc_2"
10311   [(set (pc)
10312         (if_then_else (match_operator 1 "ix86_comparison_operator"
10313                                       [(reg FLAGS_REG) (const_int 0)])
10314                       (pc)
10315                       (label_ref (match_operand 0))))]
10316   ""
10317   "%+j%c1\t%l0"
10318   [(set_attr "type" "ibr")
10319    (set_attr "modrm" "0")
10320    (set (attr "length")
10321            (if_then_else (and (ge (minus (match_dup 0) (pc))
10322                                   (const_int -126))
10323                               (lt (minus (match_dup 0) (pc))
10324                                   (const_int 128)))
10325              (const_int 2)
10326              (const_int 6)))])
10328 ;; In general it is not safe to assume too much about CCmode registers,
10329 ;; so simplify-rtx stops when it sees a second one.  Under certain
10330 ;; conditions this is safe on x86, so help combine not create
10332 ;;      seta    %al
10333 ;;      testb   %al, %al
10334 ;;      je      Lfoo
10336 (define_split
10337   [(set (pc)
10338         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10339                                       [(reg FLAGS_REG) (const_int 0)])
10340                           (const_int 0))
10341                       (label_ref (match_operand 1))
10342                       (pc)))]
10343   ""
10344   [(set (pc)
10345         (if_then_else (match_dup 0)
10346                       (label_ref (match_dup 1))
10347                       (pc)))]
10348   "PUT_MODE (operands[0], VOIDmode);")
10350 (define_split
10351   [(set (pc)
10352         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10353                                       [(reg FLAGS_REG) (const_int 0)])
10354                           (const_int 0))
10355                       (label_ref (match_operand 1))
10356                       (pc)))]
10357   ""
10358   [(set (pc)
10359         (if_then_else (match_dup 0)
10360                       (label_ref (match_dup 1))
10361                       (pc)))]
10363   rtx new_op0 = copy_rtx (operands[0]);
10364   operands[0] = new_op0;
10365   PUT_MODE (new_op0, VOIDmode);
10366   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10367                                              GET_MODE (XEXP (new_op0, 0))));
10369   /* Make sure that (a) the CCmode we have for the flags is strong
10370      enough for the reversed compare or (b) we have a valid FP compare.  */
10371   if (! ix86_comparison_operator (new_op0, VOIDmode))
10372     FAIL;
10375 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10376 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10377 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10378 ;; appropriate modulo of the bit offset value.
10380 (define_insn_and_split "*jcc_bt<mode>"
10381   [(set (pc)
10382         (if_then_else (match_operator 0 "bt_comparison_operator"
10383                         [(zero_extract:SWI48
10384                            (match_operand:SWI48 1 "register_operand" "r")
10385                            (const_int 1)
10386                            (zero_extend:SI
10387                              (match_operand:QI 2 "register_operand" "r")))
10388                          (const_int 0)])
10389                       (label_ref (match_operand 3))
10390                       (pc)))
10391    (clobber (reg:CC FLAGS_REG))]
10392   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10393   "#"
10394   "&& 1"
10395   [(set (reg:CCC FLAGS_REG)
10396         (compare:CCC
10397           (zero_extract:SWI48
10398             (match_dup 1)
10399             (const_int 1)
10400             (match_dup 2))
10401           (const_int 0)))
10402    (set (pc)
10403         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10404                       (label_ref (match_dup 3))
10405                       (pc)))]
10407   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10409   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10412 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10413 ;; also for DImode, this is what combine produces.
10414 (define_insn_and_split "*jcc_bt<mode>_mask"
10415   [(set (pc)
10416         (if_then_else (match_operator 0 "bt_comparison_operator"
10417                         [(zero_extract:SWI48
10418                            (match_operand:SWI48 1 "register_operand" "r")
10419                            (const_int 1)
10420                            (and:SI
10421                              (match_operand:SI 2 "register_operand" "r")
10422                              (match_operand:SI 3 "const_int_operand" "n")))])
10423                       (label_ref (match_operand 4))
10424                       (pc)))
10425    (clobber (reg:CC FLAGS_REG))]
10426   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10427    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10428       == GET_MODE_BITSIZE (<MODE>mode)-1"
10429   "#"
10430   "&& 1"
10431   [(set (reg:CCC FLAGS_REG)
10432         (compare:CCC
10433           (zero_extract:SWI48
10434             (match_dup 1)
10435             (const_int 1)
10436             (match_dup 2))
10437           (const_int 0)))
10438    (set (pc)
10439         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10440                       (label_ref (match_dup 4))
10441                       (pc)))]
10443   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10445   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10448 (define_insn_and_split "*jcc_btsi_1"
10449   [(set (pc)
10450         (if_then_else (match_operator 0 "bt_comparison_operator"
10451                         [(and:SI
10452                            (lshiftrt:SI
10453                              (match_operand:SI 1 "register_operand" "r")
10454                              (match_operand:QI 2 "register_operand" "r"))
10455                            (const_int 1))
10456                          (const_int 0)])
10457                       (label_ref (match_operand 3))
10458                       (pc)))
10459    (clobber (reg:CC FLAGS_REG))]
10460   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10461   "#"
10462   "&& 1"
10463   [(set (reg:CCC FLAGS_REG)
10464         (compare:CCC
10465           (zero_extract:SI
10466             (match_dup 1)
10467             (const_int 1)
10468             (match_dup 2))
10469           (const_int 0)))
10470    (set (pc)
10471         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10472                       (label_ref (match_dup 3))
10473                       (pc)))]
10475   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10477   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10480 ;; avoid useless masking of bit offset operand
10481 (define_insn_and_split "*jcc_btsi_mask_1"
10482   [(set (pc)
10483         (if_then_else
10484           (match_operator 0 "bt_comparison_operator"
10485             [(and:SI
10486                (lshiftrt:SI
10487                  (match_operand:SI 1 "register_operand" "r")
10488                  (subreg:QI
10489                    (and:SI
10490                      (match_operand:SI 2 "register_operand" "r")
10491                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10492                (const_int 1))
10493              (const_int 0)])
10494           (label_ref (match_operand 4))
10495           (pc)))
10496    (clobber (reg:CC FLAGS_REG))]
10497   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10498    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10499   "#"
10500   "&& 1"
10501   [(set (reg:CCC FLAGS_REG)
10502         (compare:CCC
10503           (zero_extract:SI
10504             (match_dup 1)
10505             (const_int 1)
10506             (match_dup 2))
10507           (const_int 0)))
10508    (set (pc)
10509         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10510                       (label_ref (match_dup 4))
10511                       (pc)))]
10512   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10514 ;; Define combination compare-and-branch fp compare instructions to help
10515 ;; combine.
10517 (define_insn "*jcc<mode>_0_i387"
10518   [(set (pc)
10519         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10520                         [(match_operand:X87MODEF 1 "register_operand" "f")
10521                          (match_operand:X87MODEF 2 "const0_operand")])
10522           (label_ref (match_operand 3))
10523           (pc)))
10524    (clobber (reg:CCFP FPSR_REG))
10525    (clobber (reg:CCFP FLAGS_REG))
10526    (clobber (match_scratch:HI 4 "=a"))]
10527   "TARGET_80387 && !TARGET_CMOVE"
10528   "#")
10530 (define_insn "*jcc<mode>_0_r_i387"
10531   [(set (pc)
10532         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10533                         [(match_operand:X87MODEF 1 "register_operand" "f")
10534                          (match_operand:X87MODEF 2 "const0_operand")])
10535           (pc)
10536           (label_ref (match_operand 3))))
10537    (clobber (reg:CCFP FPSR_REG))
10538    (clobber (reg:CCFP FLAGS_REG))
10539    (clobber (match_scratch:HI 4 "=a"))]
10540   "TARGET_80387 && !TARGET_CMOVE"
10541   "#")
10543 (define_insn "*jccxf_i387"
10544   [(set (pc)
10545         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10546                         [(match_operand:XF 1 "register_operand" "f")
10547                          (match_operand:XF 2 "register_operand" "f")])
10548           (label_ref (match_operand 3))
10549           (pc)))
10550    (clobber (reg:CCFP FPSR_REG))
10551    (clobber (reg:CCFP FLAGS_REG))
10552    (clobber (match_scratch:HI 4 "=a"))]
10553   "TARGET_80387 && !TARGET_CMOVE"
10554   "#")
10556 (define_insn "*jccxf_r_i387"
10557   [(set (pc)
10558         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10559                         [(match_operand:XF 1 "register_operand" "f")
10560                          (match_operand:XF 2 "register_operand" "f")])
10561           (pc)
10562           (label_ref (match_operand 3))))
10563    (clobber (reg:CCFP FPSR_REG))
10564    (clobber (reg:CCFP FLAGS_REG))
10565    (clobber (match_scratch:HI 4 "=a"))]
10566   "TARGET_80387 && !TARGET_CMOVE"
10567   "#")
10569 (define_insn "*jcc<mode>_i387"
10570   [(set (pc)
10571         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10572                         [(match_operand:MODEF 1 "register_operand" "f")
10573                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
10574           (label_ref (match_operand 3))
10575           (pc)))
10576    (clobber (reg:CCFP FPSR_REG))
10577    (clobber (reg:CCFP FLAGS_REG))
10578    (clobber (match_scratch:HI 4 "=a"))]
10579   "TARGET_80387 && !TARGET_CMOVE"
10580   "#")
10582 (define_insn "*jcc<mode>_r_i387"
10583   [(set (pc)
10584         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10585                         [(match_operand:MODEF 1 "register_operand" "f")
10586                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
10587           (pc)
10588           (label_ref (match_operand 3))))
10589    (clobber (reg:CCFP FPSR_REG))
10590    (clobber (reg:CCFP FLAGS_REG))
10591    (clobber (match_scratch:HI 4 "=a"))]
10592   "TARGET_80387 && !TARGET_CMOVE"
10593   "#")
10595 (define_insn "*jccu<mode>_i387"
10596   [(set (pc)
10597         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
10598                         [(match_operand:X87MODEF 1 "register_operand" "f")
10599                          (match_operand:X87MODEF 2 "register_operand" "f")])
10600           (label_ref (match_operand 3))
10601           (pc)))
10602    (clobber (reg:CCFP FPSR_REG))
10603    (clobber (reg:CCFP FLAGS_REG))
10604    (clobber (match_scratch:HI 4 "=a"))]
10605   "TARGET_80387 && !TARGET_CMOVE"
10606   "#")
10608 (define_insn "*jccu<mode>_r_i387"
10609   [(set (pc)
10610         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
10611                         [(match_operand:X87MODEF 1 "register_operand" "f")
10612                          (match_operand:X87MODEF 2 "register_operand" "f")])
10613           (pc)
10614           (label_ref (match_operand 3))))
10615    (clobber (reg:CCFP FPSR_REG))
10616    (clobber (reg:CCFP FLAGS_REG))
10617    (clobber (match_scratch:HI 4 "=a"))]
10618   "TARGET_80387 && !TARGET_CMOVE"
10619   "#")
10621 (define_split
10622   [(set (pc)
10623         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10624                         [(match_operand:X87MODEF 1 "register_operand")
10625                          (match_operand:X87MODEF 2 "nonimmediate_operand")])
10626           (match_operand 3)
10627           (match_operand 4)))
10628    (clobber (reg:CCFP FPSR_REG))
10629    (clobber (reg:CCFP FLAGS_REG))]
10630   "TARGET_80387 && !TARGET_CMOVE
10631    && reload_completed"
10632   [(const_int 0)]
10634   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10635                         operands[3], operands[4], NULL_RTX, NULL_RTX);
10636   DONE;
10639 (define_split
10640   [(set (pc)
10641         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10642                         [(match_operand:X87MODEF 1 "register_operand")
10643                          (match_operand:X87MODEF 2 "general_operand")])
10644           (match_operand 3)
10645           (match_operand 4)))
10646    (clobber (reg:CCFP FPSR_REG))
10647    (clobber (reg:CCFP FLAGS_REG))
10648    (clobber (match_scratch:HI 5))]
10649   "TARGET_80387 && !TARGET_CMOVE
10650    && reload_completed"
10651   [(const_int 0)]
10653   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10654                         operands[3], operands[4], operands[5], NULL_RTX);
10655   DONE;
10658 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
10659 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10660 ;; with a precedence over other operators and is always put in the first
10661 ;; place. Swap condition and operands to match ficom instruction.
10663 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
10664   [(set (pc)
10665         (if_then_else
10666           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10667             [(match_operator:X87MODEF 1 "float_operator"
10668               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10669              (match_operand:X87MODEF 3 "register_operand" "f,f")])
10670           (label_ref (match_operand 4))
10671           (pc)))
10672    (clobber (reg:CCFP FPSR_REG))
10673    (clobber (reg:CCFP FLAGS_REG))
10674    (clobber (match_scratch:HI 5 "=a,a"))]
10675   "TARGET_80387 && !TARGET_CMOVE
10676    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
10677        || optimize_function_for_size_p (cfun))"
10678   "#")
10680 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
10681   [(set (pc)
10682         (if_then_else
10683           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10684             [(match_operator:X87MODEF 1 "float_operator"
10685               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10686              (match_operand:X87MODEF 3 "register_operand" "f,f")])
10687           (pc)
10688           (label_ref (match_operand 4))))
10689    (clobber (reg:CCFP FPSR_REG))
10690    (clobber (reg:CCFP FLAGS_REG))
10691    (clobber (match_scratch:HI 5 "=a,a"))]
10692   "TARGET_80387 && !TARGET_CMOVE
10693    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
10694        || optimize_function_for_size_p (cfun))"
10695   "#")
10697 (define_split
10698   [(set (pc)
10699         (if_then_else
10700           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10701             [(match_operator:X87MODEF 1 "float_operator"
10702               [(match_operand:SWI24 2 "memory_operand")])
10703              (match_operand:X87MODEF 3 "register_operand")])
10704           (match_operand 4)
10705           (match_operand 5)))
10706    (clobber (reg:CCFP FPSR_REG))
10707    (clobber (reg:CCFP FLAGS_REG))
10708    (clobber (match_scratch:HI 6))]
10709   "TARGET_80387 && !TARGET_CMOVE
10710    && reload_completed"
10711   [(const_int 0)]
10713   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
10714                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
10715                         operands[4], operands[5], operands[6], NULL_RTX);
10716   DONE;
10719 ;; %%% Kill this when reload knows how to do it.
10720 (define_split
10721   [(set (pc)
10722         (if_then_else
10723           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10724             [(match_operator:X87MODEF 1 "float_operator"
10725               [(match_operand:SWI24 2 "register_operand")])
10726              (match_operand:X87MODEF 3 "register_operand")])
10727           (match_operand 4)
10728           (match_operand 5)))
10729    (clobber (reg:CCFP FPSR_REG))
10730    (clobber (reg:CCFP FLAGS_REG))
10731    (clobber (match_scratch:HI 6))]
10732   "TARGET_80387 && !TARGET_CMOVE
10733    && reload_completed"
10734   [(const_int 0)]
10736   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10738   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
10739                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]),
10740                         operands[4], operands[5], operands[6], operands[2]);
10741   DONE;
10744 ;; Unconditional and other jump instructions
10746 (define_insn "jump"
10747   [(set (pc)
10748         (label_ref (match_operand 0)))]
10749   ""
10750   "jmp\t%l0"
10751   [(set_attr "type" "ibr")
10752    (set (attr "length")
10753            (if_then_else (and (ge (minus (match_dup 0) (pc))
10754                                   (const_int -126))
10755                               (lt (minus (match_dup 0) (pc))
10756                                   (const_int 128)))
10757              (const_int 2)
10758              (const_int 5)))
10759    (set_attr "modrm" "0")])
10761 (define_expand "indirect_jump"
10762   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
10763   ""
10765   if (TARGET_X32)
10766     operands[0] = convert_memory_address (word_mode, operands[0]);
10769 (define_insn "*indirect_jump"
10770   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
10771   ""
10772   "jmp\t%A0"
10773   [(set_attr "type" "ibr")
10774    (set_attr "length_immediate" "0")])
10776 (define_expand "tablejump"
10777   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
10778               (use (label_ref (match_operand 1)))])]
10779   ""
10781   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10782      relative.  Convert the relative address to an absolute address.  */
10783   if (flag_pic)
10784     {
10785       rtx op0, op1;
10786       enum rtx_code code;
10788       /* We can't use @GOTOFF for text labels on VxWorks;
10789          see gotoff_operand.  */
10790       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10791         {
10792           code = PLUS;
10793           op0 = operands[0];
10794           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10795         }
10796       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10797         {
10798           code = PLUS;
10799           op0 = operands[0];
10800           op1 = pic_offset_table_rtx;
10801         }
10802       else
10803         {
10804           code = MINUS;
10805           op0 = pic_offset_table_rtx;
10806           op1 = operands[0];
10807         }
10809       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
10810                                          OPTAB_DIRECT);
10811     }
10813   if (TARGET_X32)
10814     operands[0] = convert_memory_address (word_mode, operands[0]);
10817 (define_insn "*tablejump_1"
10818   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
10819    (use (label_ref (match_operand 1)))]
10820   ""
10821   "jmp\t%A0"
10822   [(set_attr "type" "ibr")
10823    (set_attr "length_immediate" "0")])
10825 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
10827 (define_peephole2
10828   [(set (reg FLAGS_REG) (match_operand 0))
10829    (set (match_operand:QI 1 "register_operand")
10830         (match_operator:QI 2 "ix86_comparison_operator"
10831           [(reg FLAGS_REG) (const_int 0)]))
10832    (set (match_operand 3 "q_regs_operand")
10833         (zero_extend (match_dup 1)))]
10834   "(peep2_reg_dead_p (3, operands[1])
10835     || operands_match_p (operands[1], operands[3]))
10836    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10837   [(set (match_dup 4) (match_dup 0))
10838    (set (strict_low_part (match_dup 5))
10839         (match_dup 2))]
10841   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10842   operands[5] = gen_lowpart (QImode, operands[3]);
10843   ix86_expand_clear (operands[3]);
10846 (define_peephole2
10847   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
10848               (match_operand 4)])
10849    (set (match_operand:QI 1 "register_operand")
10850         (match_operator:QI 2 "ix86_comparison_operator"
10851           [(reg FLAGS_REG) (const_int 0)]))
10852    (set (match_operand 3 "q_regs_operand")
10853         (zero_extend (match_dup 1)))]
10854   "(peep2_reg_dead_p (3, operands[1])
10855     || operands_match_p (operands[1], operands[3]))
10856    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10857   [(parallel [(set (match_dup 5) (match_dup 0))
10858               (match_dup 4)])
10859    (set (strict_low_part (match_dup 6))
10860         (match_dup 2))]
10862   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10863   operands[6] = gen_lowpart (QImode, operands[3]);
10864   ix86_expand_clear (operands[3]);
10867 ;; Similar, but match zero extend with andsi3.
10869 (define_peephole2
10870   [(set (reg FLAGS_REG) (match_operand 0))
10871    (set (match_operand:QI 1 "register_operand")
10872         (match_operator:QI 2 "ix86_comparison_operator"
10873           [(reg FLAGS_REG) (const_int 0)]))
10874    (parallel [(set (match_operand:SI 3 "q_regs_operand")
10875                    (and:SI (match_dup 3) (const_int 255)))
10876               (clobber (reg:CC FLAGS_REG))])]
10877   "REGNO (operands[1]) == REGNO (operands[3])
10878    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10879   [(set (match_dup 4) (match_dup 0))
10880    (set (strict_low_part (match_dup 5))
10881         (match_dup 2))]
10883   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10884   operands[5] = gen_lowpart (QImode, operands[3]);
10885   ix86_expand_clear (operands[3]);
10888 (define_peephole2
10889   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
10890               (match_operand 4)])
10891    (set (match_operand:QI 1 "register_operand")
10892         (match_operator:QI 2 "ix86_comparison_operator"
10893           [(reg FLAGS_REG) (const_int 0)]))
10894    (parallel [(set (match_operand 3 "q_regs_operand")
10895                    (zero_extend (match_dup 1)))
10896               (clobber (reg:CC FLAGS_REG))])]
10897   "(peep2_reg_dead_p (3, operands[1])
10898     || operands_match_p (operands[1], operands[3]))
10899    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10900   [(parallel [(set (match_dup 5) (match_dup 0))
10901               (match_dup 4)])
10902    (set (strict_low_part (match_dup 6))
10903         (match_dup 2))]
10905   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10906   operands[6] = gen_lowpart (QImode, operands[3]);
10907   ix86_expand_clear (operands[3]);
10910 ;; Call instructions.
10912 ;; The predicates normally associated with named expanders are not properly
10913 ;; checked for calls.  This is a bug in the generic code, but it isn't that
10914 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
10916 ;; P6 processors will jump to the address after the decrement when %esp
10917 ;; is used as a call operand, so they will execute return address as a code.
10918 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
10920 ;; Register constraint for call instruction.
10921 (define_mode_attr c [(SI "l") (DI "r")])
10923 ;; Call subroutine returning no value.
10925 (define_expand "call"
10926   [(call (match_operand:QI 0)
10927          (match_operand 1))
10928    (use (match_operand 2))]
10929   ""
10931   ix86_expand_call (NULL, operands[0], operands[1],
10932                     operands[2], NULL, false);
10933   DONE;
10936 (define_expand "sibcall"
10937   [(call (match_operand:QI 0)
10938          (match_operand 1))
10939    (use (match_operand 2))]
10940   ""
10942   ix86_expand_call (NULL, operands[0], operands[1],
10943                     operands[2], NULL, true);
10944   DONE;
10947 (define_insn "*call"
10948   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
10949          (match_operand 1))]
10950   "!SIBLING_CALL_P (insn)"
10951   "* return ix86_output_call_insn (insn, operands[0]);"
10952   [(set_attr "type" "call")])
10954 (define_insn "*call_rex64_ms_sysv"
10955   [(match_parallel 2 "call_rex64_ms_sysv_operation"
10956     [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
10957            (match_operand 1))
10958      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
10959   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
10960   "* return ix86_output_call_insn (insn, operands[0]);"
10961   [(set_attr "type" "call")])
10963 (define_insn "*sibcall"
10964   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
10965          (match_operand 1))]
10966   "SIBLING_CALL_P (insn)"
10967   "* return ix86_output_call_insn (insn, operands[0]);"
10968   [(set_attr "type" "call")])
10970 (define_expand "call_pop"
10971   [(parallel [(call (match_operand:QI 0)
10972                     (match_operand:SI 1))
10973               (set (reg:SI SP_REG)
10974                    (plus:SI (reg:SI SP_REG)
10975                             (match_operand:SI 3)))])]
10976   "!TARGET_64BIT"
10978   ix86_expand_call (NULL, operands[0], operands[1],
10979                     operands[2], operands[3], false);
10980   DONE;
10983 (define_insn "*call_pop"
10984   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
10985          (match_operand 1))
10986    (set (reg:SI SP_REG)
10987         (plus:SI (reg:SI SP_REG)
10988                  (match_operand:SI 2 "immediate_operand" "i")))]
10989   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
10990   "* return ix86_output_call_insn (insn, operands[0]);"
10991   [(set_attr "type" "call")])
10993 (define_insn "*sibcall_pop"
10994   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
10995          (match_operand 1))
10996    (set (reg:SI SP_REG)
10997         (plus:SI (reg:SI SP_REG)
10998                  (match_operand:SI 2 "immediate_operand" "i")))]
10999   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11000   "* return ix86_output_call_insn (insn, operands[0]);"
11001   [(set_attr "type" "call")])
11003 ;; Call subroutine, returning value in operand 0
11005 (define_expand "call_value"
11006   [(set (match_operand 0)
11007         (call (match_operand:QI 1)
11008               (match_operand 2)))
11009    (use (match_operand 3))]
11010   ""
11012   ix86_expand_call (operands[0], operands[1], operands[2],
11013                     operands[3], NULL, false);
11014   DONE;
11017 (define_expand "sibcall_value"
11018   [(set (match_operand 0)
11019         (call (match_operand:QI 1)
11020               (match_operand 2)))
11021    (use (match_operand 3))]
11022   ""
11024   ix86_expand_call (operands[0], operands[1], operands[2],
11025                     operands[3], NULL, true);
11026   DONE;
11029 (define_insn "*call_value"
11030   [(set (match_operand 0)
11031         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11032               (match_operand 2)))]
11033   "!SIBLING_CALL_P (insn)"
11034   "* return ix86_output_call_insn (insn, operands[1]);"
11035   [(set_attr "type" "callv")])
11037 (define_insn "*sibcall_value"
11038   [(set (match_operand 0)
11039         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11040               (match_operand 2)))]
11041   "SIBLING_CALL_P (insn)"
11042   "* return ix86_output_call_insn (insn, operands[1]);"
11043   [(set_attr "type" "callv")])
11045 (define_insn "*call_value_rex64_ms_sysv"
11046   [(match_parallel 3 "call_rex64_ms_sysv_operation"
11047     [(set (match_operand 0)
11048           (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11049                 (match_operand 2)))
11050      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11051  "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11052   "* return ix86_output_call_insn (insn, operands[1]);"
11053   [(set_attr "type" "callv")])
11055 (define_expand "call_value_pop"
11056   [(parallel [(set (match_operand 0)
11057                    (call (match_operand:QI 1)
11058                          (match_operand:SI 2)))
11059               (set (reg:SI SP_REG)
11060                    (plus:SI (reg:SI SP_REG)
11061                             (match_operand:SI 4)))])]
11062   "!TARGET_64BIT"
11064   ix86_expand_call (operands[0], operands[1], operands[2],
11065                     operands[3], operands[4], false);
11066   DONE;
11069 (define_insn "*call_value_pop"
11070   [(set (match_operand 0)
11071         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11072               (match_operand 2)))
11073    (set (reg:SI SP_REG)
11074         (plus:SI (reg:SI SP_REG)
11075                  (match_operand:SI 3 "immediate_operand" "i")))]
11076   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11077   "* return ix86_output_call_insn (insn, operands[1]);"
11078   [(set_attr "type" "callv")])
11080 (define_insn "*sibcall_value_pop"
11081   [(set (match_operand 0)
11082         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11083               (match_operand 2)))
11084    (set (reg:SI SP_REG)
11085         (plus:SI (reg:SI SP_REG)
11086                  (match_operand:SI 3 "immediate_operand" "i")))]
11087   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11088   "* return ix86_output_call_insn (insn, operands[1]);"
11089   [(set_attr "type" "callv")])
11091 ;; Call subroutine returning any type.
11093 (define_expand "untyped_call"
11094   [(parallel [(call (match_operand 0)
11095                     (const_int 0))
11096               (match_operand 1)
11097               (match_operand 2)])]
11098   ""
11100   int i;
11102   /* In order to give reg-stack an easier job in validating two
11103      coprocessor registers as containing a possible return value,
11104      simply pretend the untyped call returns a complex long double
11105      value. 
11107      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11108      and should have the default ABI.  */
11110   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11111                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11112                     operands[0], const0_rtx,
11113                     GEN_INT ((TARGET_64BIT
11114                               ? (ix86_abi == SYSV_ABI
11115                                  ? X86_64_SSE_REGPARM_MAX
11116                                  : X86_64_MS_SSE_REGPARM_MAX)
11117                               : X86_32_SSE_REGPARM_MAX)
11118                              - 1),
11119                     NULL, false);
11121   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11122     {
11123       rtx set = XVECEXP (operands[2], 0, i);
11124       emit_move_insn (SET_DEST (set), SET_SRC (set));
11125     }
11127   /* The optimizer does not know that the call sets the function value
11128      registers we stored in the result block.  We avoid problems by
11129      claiming that all hard registers are used and clobbered at this
11130      point.  */
11131   emit_insn (gen_blockage ());
11133   DONE;
11136 ;; Prologue and epilogue instructions
11138 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11139 ;; all of memory.  This blocks insns from being moved across this point.
11141 (define_insn "blockage"
11142   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11143   ""
11144   ""
11145   [(set_attr "length" "0")])
11147 ;; Do not schedule instructions accessing memory across this point.
11149 (define_expand "memory_blockage"
11150   [(set (match_dup 0)
11151         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11152   ""
11154   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11155   MEM_VOLATILE_P (operands[0]) = 1;
11158 (define_insn "*memory_blockage"
11159   [(set (match_operand:BLK 0)
11160         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11161   ""
11162   ""
11163   [(set_attr "length" "0")])
11165 ;; As USE insns aren't meaningful after reload, this is used instead
11166 ;; to prevent deleting instructions setting registers for PIC code
11167 (define_insn "prologue_use"
11168   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11169   ""
11170   ""
11171   [(set_attr "length" "0")])
11173 ;; Insn emitted into the body of a function to return from a function.
11174 ;; This is only done if the function's epilogue is known to be simple.
11175 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11177 (define_expand "return"
11178   [(simple_return)]
11179   "ix86_can_use_return_insn_p ()"
11181   if (crtl->args.pops_args)
11182     {
11183       rtx popc = GEN_INT (crtl->args.pops_args);
11184       emit_jump_insn (gen_simple_return_pop_internal (popc));
11185       DONE;
11186     }
11189 ;; We need to disable this for TARGET_SEH, as otherwise
11190 ;; shrink-wrapped prologue gets enabled too.  This might exceed
11191 ;; the maximum size of prologue in unwind information.
11193 (define_expand "simple_return"
11194   [(simple_return)]
11195   "!TARGET_SEH"
11197   if (crtl->args.pops_args)
11198     {
11199       rtx popc = GEN_INT (crtl->args.pops_args);
11200       emit_jump_insn (gen_simple_return_pop_internal (popc));
11201       DONE;
11202     }
11205 (define_insn "simple_return_internal"
11206   [(simple_return)]
11207   "reload_completed"
11208   "ret"
11209   [(set_attr "length" "1")
11210    (set_attr "atom_unit" "jeu")
11211    (set_attr "length_immediate" "0")
11212    (set_attr "modrm" "0")])
11214 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11215 ;; instruction Athlon and K8 have.
11217 (define_insn "simple_return_internal_long"
11218   [(simple_return)
11219    (unspec [(const_int 0)] UNSPEC_REP)]
11220   "reload_completed"
11221   "rep%; ret"
11222   [(set_attr "length" "2")
11223    (set_attr "atom_unit" "jeu")
11224    (set_attr "length_immediate" "0")
11225    (set_attr "prefix_rep" "1")
11226    (set_attr "modrm" "0")])
11228 (define_insn "simple_return_pop_internal"
11229   [(simple_return)
11230    (use (match_operand:SI 0 "const_int_operand"))]
11231   "reload_completed"
11232   "ret\t%0"
11233   [(set_attr "length" "3")
11234    (set_attr "atom_unit" "jeu")
11235    (set_attr "length_immediate" "2")
11236    (set_attr "modrm" "0")])
11238 (define_insn "simple_return_indirect_internal"
11239   [(simple_return)
11240    (use (match_operand:SI 0 "register_operand" "r"))]
11241   "reload_completed"
11242   "jmp\t%A0"
11243   [(set_attr "type" "ibr")
11244    (set_attr "length_immediate" "0")])
11246 (define_insn "nop"
11247   [(const_int 0)]
11248   ""
11249   "nop"
11250   [(set_attr "length" "1")
11251    (set_attr "length_immediate" "0")
11252    (set_attr "modrm" "0")])
11254 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11255 (define_insn "nops"
11256   [(unspec_volatile [(match_operand 0 "const_int_operand")]
11257                     UNSPECV_NOPS)]
11258   "reload_completed"
11260   int num = INTVAL (operands[0]);
11262   gcc_assert (IN_RANGE (num, 1, 8));
11264   while (num--)
11265     fputs ("\tnop\n", asm_out_file);
11267   return "";
11269   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11270    (set_attr "length_immediate" "0")
11271    (set_attr "modrm" "0")])
11273 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11274 ;; branch prediction penalty for the third jump in a 16-byte
11275 ;; block on K8.
11277 (define_insn "pad"
11278   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11279   ""
11281 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11282   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11283 #else
11284   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11285      The align insn is used to avoid 3 jump instructions in the row to improve
11286      branch prediction and the benefits hardly outweigh the cost of extra 8
11287      nops on the average inserted by full alignment pseudo operation.  */
11288 #endif
11289   return "";
11291   [(set_attr "length" "16")])
11293 (define_expand "prologue"
11294   [(const_int 0)]
11295   ""
11296   "ix86_expand_prologue (); DONE;")
11298 (define_insn "set_got"
11299   [(set (match_operand:SI 0 "register_operand" "=r")
11300         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11301    (clobber (reg:CC FLAGS_REG))]
11302   "!TARGET_64BIT"
11303   "* return output_set_got (operands[0], NULL_RTX);"
11304   [(set_attr "type" "multi")
11305    (set_attr "length" "12")])
11307 (define_insn "set_got_labelled"
11308   [(set (match_operand:SI 0 "register_operand" "=r")
11309         (unspec:SI [(label_ref (match_operand 1))]
11310          UNSPEC_SET_GOT))
11311    (clobber (reg:CC FLAGS_REG))]
11312   "!TARGET_64BIT"
11313   "* return output_set_got (operands[0], operands[1]);"
11314   [(set_attr "type" "multi")
11315    (set_attr "length" "12")])
11317 (define_insn "set_got_rex64"
11318   [(set (match_operand:DI 0 "register_operand" "=r")
11319         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11320   "TARGET_64BIT"
11321   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11322   [(set_attr "type" "lea")
11323    (set_attr "length_address" "4")
11324    (set_attr "mode" "DI")])
11326 (define_insn "set_rip_rex64"
11327   [(set (match_operand:DI 0 "register_operand" "=r")
11328         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
11329   "TARGET_64BIT"
11330   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11331   [(set_attr "type" "lea")
11332    (set_attr "length_address" "4")
11333    (set_attr "mode" "DI")])
11335 (define_insn "set_got_offset_rex64"
11336   [(set (match_operand:DI 0 "register_operand" "=r")
11337         (unspec:DI
11338           [(label_ref (match_operand 1))]
11339           UNSPEC_SET_GOT_OFFSET))]
11340   "TARGET_LP64"
11341   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11342   [(set_attr "type" "imov")
11343    (set_attr "length_immediate" "0")
11344    (set_attr "length_address" "8")
11345    (set_attr "mode" "DI")])
11347 (define_expand "epilogue"
11348   [(const_int 0)]
11349   ""
11350   "ix86_expand_epilogue (1); DONE;")
11352 (define_expand "sibcall_epilogue"
11353   [(const_int 0)]
11354   ""
11355   "ix86_expand_epilogue (0); DONE;")
11357 (define_expand "eh_return"
11358   [(use (match_operand 0 "register_operand"))]
11359   ""
11361   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11363   /* Tricky bit: we write the address of the handler to which we will
11364      be returning into someone else's stack frame, one word below the
11365      stack address we wish to restore.  */
11366   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11367   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
11368   tmp = gen_rtx_MEM (Pmode, tmp);
11369   emit_move_insn (tmp, ra);
11371   emit_jump_insn (gen_eh_return_internal ());
11372   emit_barrier ();
11373   DONE;
11376 (define_insn_and_split "eh_return_internal"
11377   [(eh_return)]
11378   ""
11379   "#"
11380   "epilogue_completed"
11381   [(const_int 0)]
11382   "ix86_expand_epilogue (2); DONE;")
11384 (define_insn "leave"
11385   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11386    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11387    (clobber (mem:BLK (scratch)))]
11388   "!TARGET_64BIT"
11389   "leave"
11390   [(set_attr "type" "leave")])
11392 (define_insn "leave_rex64"
11393   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11394    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11395    (clobber (mem:BLK (scratch)))]
11396   "TARGET_64BIT"
11397   "leave"
11398   [(set_attr "type" "leave")])
11400 ;; Handle -fsplit-stack.
11402 (define_expand "split_stack_prologue"
11403   [(const_int 0)]
11404   ""
11406   ix86_expand_split_stack_prologue ();
11407   DONE;
11410 ;; In order to support the call/return predictor, we use a return
11411 ;; instruction which the middle-end doesn't see.
11412 (define_insn "split_stack_return"
11413   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
11414                      UNSPECV_SPLIT_STACK_RETURN)]
11415   ""
11417   if (operands[0] == const0_rtx)
11418     return "ret";
11419   else
11420     return "ret\t%0";
11422   [(set_attr "atom_unit" "jeu")
11423    (set_attr "modrm" "0")
11424    (set (attr "length")
11425         (if_then_else (match_operand:SI 0 "const0_operand")
11426                       (const_int 1)
11427                       (const_int 3)))
11428    (set (attr "length_immediate")
11429         (if_then_else (match_operand:SI 0 "const0_operand")
11430                       (const_int 0)
11431                       (const_int 2)))])
11433 ;; If there are operand 0 bytes available on the stack, jump to
11434 ;; operand 1.
11436 (define_expand "split_stack_space_check"
11437   [(set (pc) (if_then_else
11438               (ltu (minus (reg SP_REG)
11439                           (match_operand 0 "register_operand"))
11440                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11441               (label_ref (match_operand 1))
11442               (pc)))]
11443   ""
11445   rtx reg, size, limit;
11447   reg = gen_reg_rtx (Pmode);
11448   size = force_reg (Pmode, operands[0]);
11449   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11450   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11451                           UNSPEC_STACK_CHECK);
11452   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11453   ix86_expand_branch (GEU, reg, limit, operands[1]);
11455   DONE;
11458 ;; Bit manipulation instructions.
11460 (define_expand "ffs<mode>2"
11461   [(set (match_dup 2) (const_int -1))
11462    (parallel [(set (match_dup 3) (match_dup 4))
11463               (set (match_operand:SWI48 0 "register_operand")
11464                    (ctz:SWI48
11465                      (match_operand:SWI48 1 "nonimmediate_operand")))])
11466    (set (match_dup 0) (if_then_else:SWI48
11467                         (eq (match_dup 3) (const_int 0))
11468                         (match_dup 2)
11469                         (match_dup 0)))
11470    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11471               (clobber (reg:CC FLAGS_REG))])]
11472   ""
11474   enum machine_mode flags_mode;
11476   if (<MODE>mode == SImode && !TARGET_CMOVE)
11477     {
11478       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11479       DONE;
11480     }
11482   flags_mode = TARGET_BMI ? CCCmode : CCZmode;
11484   operands[2] = gen_reg_rtx (<MODE>mode);
11485   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
11486   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
11489 (define_insn_and_split "ffssi2_no_cmove"
11490   [(set (match_operand:SI 0 "register_operand" "=r")
11491         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11492    (clobber (match_scratch:SI 2 "=&q"))
11493    (clobber (reg:CC FLAGS_REG))]
11494   "!TARGET_CMOVE"
11495   "#"
11496   "&& reload_completed"
11497   [(parallel [(set (match_dup 4) (match_dup 5))
11498               (set (match_dup 0) (ctz:SI (match_dup 1)))])
11499    (set (strict_low_part (match_dup 3))
11500         (eq:QI (match_dup 4) (const_int 0)))
11501    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11502               (clobber (reg:CC FLAGS_REG))])
11503    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11504               (clobber (reg:CC FLAGS_REG))])
11505    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11506               (clobber (reg:CC FLAGS_REG))])]
11508   enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
11510   operands[3] = gen_lowpart (QImode, operands[2]);
11511   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
11512   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
11514   ix86_expand_clear (operands[2]);
11517 (define_insn "*tzcnt<mode>_1"
11518   [(set (reg:CCC FLAGS_REG)
11519         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11520                      (const_int 0)))
11521    (set (match_operand:SWI48 0 "register_operand" "=r")
11522         (ctz:SWI48 (match_dup 1)))]
11523   "TARGET_BMI"
11524   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11525   [(set_attr "type" "alu1")
11526    (set_attr "prefix_0f" "1")
11527    (set_attr "prefix_rep" "1")
11528    (set_attr "btver2_decode" "double")
11529    (set_attr "mode" "<MODE>")])
11531 (define_insn "*bsf<mode>_1"
11532   [(set (reg:CCZ FLAGS_REG)
11533         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11534                      (const_int 0)))
11535    (set (match_operand:SWI48 0 "register_operand" "=r")
11536         (ctz:SWI48 (match_dup 1)))]
11537   ""
11538   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11539   [(set_attr "type" "alu1")
11540    (set_attr "prefix_0f" "1")
11541    (set_attr "btver2_decode" "double")
11542    (set_attr "mode" "<MODE>")])
11544 (define_insn "ctz<mode>2"
11545   [(set (match_operand:SWI248 0 "register_operand" "=r")
11546         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11547    (clobber (reg:CC FLAGS_REG))]
11548   ""
11550   if (TARGET_BMI)
11551     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11552   else if (optimize_function_for_size_p (cfun))
11553     ;
11554   else if (TARGET_GENERIC)
11555     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
11556     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11558   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11560   [(set_attr "type" "alu1")
11561    (set_attr "prefix_0f" "1")
11562    (set (attr "prefix_rep")
11563      (if_then_else
11564        (ior (match_test "TARGET_BMI")
11565             (and (not (match_test "optimize_function_for_size_p (cfun)"))
11566                  (match_test "TARGET_GENERIC")))
11567        (const_string "1")
11568        (const_string "0")))
11569    (set_attr "mode" "<MODE>")])
11571 (define_expand "clz<mode>2"
11572   [(parallel
11573      [(set (match_operand:SWI248 0 "register_operand")
11574            (minus:SWI248
11575              (match_dup 2)
11576              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
11577       (clobber (reg:CC FLAGS_REG))])
11578    (parallel
11579      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11580       (clobber (reg:CC FLAGS_REG))])]
11581   ""
11583   if (TARGET_LZCNT)
11584     {
11585       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
11586       DONE;
11587     }
11588   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11591 (define_insn "clz<mode>2_lzcnt"
11592   [(set (match_operand:SWI248 0 "register_operand" "=r")
11593         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11594    (clobber (reg:CC FLAGS_REG))]
11595   "TARGET_LZCNT"
11596   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11597   [(set_attr "prefix_rep" "1")
11598    (set_attr "type" "bitmanip")
11599    (set_attr "mode" "<MODE>")])
11601 ;; BMI instructions.
11602 (define_insn "*bmi_andn_<mode>"
11603   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
11604         (and:SWI48
11605           (not:SWI48
11606             (match_operand:SWI48 1 "register_operand" "r,r"))
11607             (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
11608    (clobber (reg:CC FLAGS_REG))]
11609   "TARGET_BMI"
11610   "andn\t{%2, %1, %0|%0, %1, %2}"
11611   [(set_attr "type" "bitmanip")
11612    (set_attr "btver2_decode" "direct, double")
11613    (set_attr "mode" "<MODE>")])
11615 (define_insn "bmi_bextr_<mode>"
11616   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
11617         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r,r")
11618                        (match_operand:SWI48 2 "nonimmediate_operand" "r,m")]
11619                        UNSPEC_BEXTR))
11620    (clobber (reg:CC FLAGS_REG))]
11621   "TARGET_BMI"
11622   "bextr\t{%2, %1, %0|%0, %1, %2}"
11623   [(set_attr "type" "bitmanip")
11624    (set_attr "btver2_decode" "direct, double")
11625    (set_attr "mode" "<MODE>")])
11627 (define_insn "*bmi_blsi_<mode>"
11628   [(set (match_operand:SWI48 0 "register_operand" "=r")
11629         (and:SWI48
11630           (neg:SWI48
11631             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11632           (match_dup 1)))
11633    (clobber (reg:CC FLAGS_REG))]
11634   "TARGET_BMI"
11635   "blsi\t{%1, %0|%0, %1}"
11636   [(set_attr "type" "bitmanip")
11637    (set_attr "btver2_decode" "double")
11638    (set_attr "mode" "<MODE>")])
11640 (define_insn "*bmi_blsmsk_<mode>"
11641   [(set (match_operand:SWI48 0 "register_operand" "=r")
11642         (xor:SWI48
11643           (plus:SWI48
11644             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11645             (const_int -1))
11646           (match_dup 1)))
11647    (clobber (reg:CC FLAGS_REG))]
11648   "TARGET_BMI"
11649   "blsmsk\t{%1, %0|%0, %1}"
11650   [(set_attr "type" "bitmanip")
11651    (set_attr "btver2_decode" "double")
11652    (set_attr "mode" "<MODE>")])
11654 (define_insn "*bmi_blsr_<mode>"
11655   [(set (match_operand:SWI48 0 "register_operand" "=r")
11656         (and:SWI48
11657           (plus:SWI48
11658             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11659             (const_int -1))
11660           (match_dup 1)))
11661    (clobber (reg:CC FLAGS_REG))]
11662    "TARGET_BMI"
11663    "blsr\t{%1, %0|%0, %1}"
11664   [(set_attr "type" "bitmanip")
11665    (set_attr "btver2_decode" "double")
11666    (set_attr "mode" "<MODE>")])
11668 ;; BMI2 instructions.
11669 (define_insn "bmi2_bzhi_<mode>3"
11670   [(set (match_operand:SWI48 0 "register_operand" "=r")
11671         (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
11672                    (lshiftrt:SWI48 (const_int -1)
11673                                    (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
11674    (clobber (reg:CC FLAGS_REG))]
11675   "TARGET_BMI2"
11676   "bzhi\t{%2, %1, %0|%0, %1, %2}"
11677   [(set_attr "type" "bitmanip")
11678    (set_attr "prefix" "vex")
11679    (set_attr "mode" "<MODE>")])
11681 (define_insn "bmi2_pdep_<mode>3"
11682   [(set (match_operand:SWI48 0 "register_operand" "=r")
11683         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
11684                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
11685                        UNSPEC_PDEP))]
11686   "TARGET_BMI2"
11687   "pdep\t{%2, %1, %0|%0, %1, %2}"
11688   [(set_attr "type" "bitmanip")
11689    (set_attr "prefix" "vex")
11690    (set_attr "mode" "<MODE>")])
11692 (define_insn "bmi2_pext_<mode>3"
11693   [(set (match_operand:SWI48 0 "register_operand" "=r")
11694         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
11695                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
11696                        UNSPEC_PEXT))]
11697   "TARGET_BMI2"
11698   "pext\t{%2, %1, %0|%0, %1, %2}"
11699   [(set_attr "type" "bitmanip")
11700    (set_attr "prefix" "vex")
11701    (set_attr "mode" "<MODE>")])
11703 ;; TBM instructions.
11704 (define_insn "tbm_bextri_<mode>"
11705   [(set (match_operand:SWI48 0 "register_operand" "=r")
11706         (zero_extract:SWI48
11707           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11708           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11709           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11710    (clobber (reg:CC FLAGS_REG))]
11711    "TARGET_TBM"
11713   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11714   return "bextr\t{%2, %1, %0|%0, %1, %2}";
11716   [(set_attr "type" "bitmanip")
11717    (set_attr "mode" "<MODE>")])
11719 (define_insn "*tbm_blcfill_<mode>"
11720   [(set (match_operand:SWI48 0 "register_operand" "=r")
11721         (and:SWI48
11722           (plus:SWI48
11723             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11724             (const_int 1))
11725           (match_dup 1)))
11726    (clobber (reg:CC FLAGS_REG))]
11727    "TARGET_TBM"
11728    "blcfill\t{%1, %0|%0, %1}"
11729   [(set_attr "type" "bitmanip")
11730    (set_attr "mode" "<MODE>")])
11732 (define_insn "*tbm_blci_<mode>"
11733   [(set (match_operand:SWI48 0 "register_operand" "=r")
11734         (ior:SWI48
11735           (not:SWI48
11736             (plus:SWI48
11737               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11738               (const_int 1)))
11739           (match_dup 1)))
11740    (clobber (reg:CC FLAGS_REG))]
11741    "TARGET_TBM"
11742    "blci\t{%1, %0|%0, %1}"
11743   [(set_attr "type" "bitmanip")
11744    (set_attr "mode" "<MODE>")])
11746 (define_insn "*tbm_blcic_<mode>"
11747   [(set (match_operand:SWI48 0 "register_operand" "=r")
11748         (and:SWI48
11749           (plus:SWI48
11750             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11751             (const_int 1))
11752           (not:SWI48
11753             (match_dup 1))))
11754    (clobber (reg:CC FLAGS_REG))]
11755    "TARGET_TBM"
11756    "blcic\t{%1, %0|%0, %1}"
11757   [(set_attr "type" "bitmanip")
11758    (set_attr "mode" "<MODE>")])
11760 (define_insn "*tbm_blcmsk_<mode>"
11761   [(set (match_operand:SWI48 0 "register_operand" "=r")
11762         (xor:SWI48
11763           (plus:SWI48
11764             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11765             (const_int 1))
11766           (match_dup 1)))
11767    (clobber (reg:CC FLAGS_REG))]
11768    "TARGET_TBM"
11769    "blcmsk\t{%1, %0|%0, %1}"
11770   [(set_attr "type" "bitmanip")
11771    (set_attr "mode" "<MODE>")])
11773 (define_insn "*tbm_blcs_<mode>"
11774   [(set (match_operand:SWI48 0 "register_operand" "=r")
11775         (ior:SWI48
11776           (plus:SWI48
11777             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11778             (const_int 1))
11779           (match_dup 1)))
11780    (clobber (reg:CC FLAGS_REG))]
11781    "TARGET_TBM"
11782    "blcs\t{%1, %0|%0, %1}"
11783   [(set_attr "type" "bitmanip")
11784    (set_attr "mode" "<MODE>")])
11786 (define_insn "*tbm_blsfill_<mode>"
11787   [(set (match_operand:SWI48 0 "register_operand" "=r")
11788         (ior:SWI48
11789           (plus:SWI48
11790             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11791             (const_int -1))
11792           (match_dup 1)))
11793    (clobber (reg:CC FLAGS_REG))]
11794    "TARGET_TBM"
11795    "blsfill\t{%1, %0|%0, %1}"
11796   [(set_attr "type" "bitmanip")
11797    (set_attr "mode" "<MODE>")])
11799 (define_insn "*tbm_blsic_<mode>"
11800   [(set (match_operand:SWI48 0 "register_operand" "=r")
11801         (ior:SWI48
11802           (plus:SWI48
11803             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11804             (const_int -1))
11805           (not:SWI48
11806             (match_dup 1))))
11807    (clobber (reg:CC FLAGS_REG))]
11808    "TARGET_TBM"
11809    "blsic\t{%1, %0|%0, %1}"
11810   [(set_attr "type" "bitmanip")
11811    (set_attr "mode" "<MODE>")])
11813 (define_insn "*tbm_t1mskc_<mode>"
11814   [(set (match_operand:SWI48 0 "register_operand" "=r")
11815         (ior:SWI48
11816           (plus:SWI48
11817             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11818             (const_int 1))
11819           (not:SWI48
11820             (match_dup 1))))
11821    (clobber (reg:CC FLAGS_REG))]
11822    "TARGET_TBM"
11823    "t1mskc\t{%1, %0|%0, %1}"
11824   [(set_attr "type" "bitmanip")
11825    (set_attr "mode" "<MODE>")])
11827 (define_insn "*tbm_tzmsk_<mode>"
11828   [(set (match_operand:SWI48 0 "register_operand" "=r")
11829         (and:SWI48
11830           (plus:SWI48
11831             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11832             (const_int -1))
11833           (not:SWI48
11834             (match_dup 1))))
11835    (clobber (reg:CC FLAGS_REG))]
11836    "TARGET_TBM"
11837    "tzmsk\t{%1, %0|%0, %1}"
11838   [(set_attr "type" "bitmanip")
11839    (set_attr "mode" "<MODE>")])
11841 (define_insn "bsr_rex64"
11842   [(set (match_operand:DI 0 "register_operand" "=r")
11843         (minus:DI (const_int 63)
11844                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11845    (clobber (reg:CC FLAGS_REG))]
11846   "TARGET_64BIT"
11847   "bsr{q}\t{%1, %0|%0, %1}"
11848   [(set_attr "type" "alu1")
11849    (set_attr "prefix_0f" "1")
11850    (set_attr "mode" "DI")])
11852 (define_insn "bsr"
11853   [(set (match_operand:SI 0 "register_operand" "=r")
11854         (minus:SI (const_int 31)
11855                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11856    (clobber (reg:CC FLAGS_REG))]
11857   ""
11858   "bsr{l}\t{%1, %0|%0, %1}"
11859   [(set_attr "type" "alu1")
11860    (set_attr "prefix_0f" "1")
11861    (set_attr "mode" "SI")])
11863 (define_insn "*bsrhi"
11864   [(set (match_operand:HI 0 "register_operand" "=r")
11865         (minus:HI (const_int 15)
11866                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11867    (clobber (reg:CC FLAGS_REG))]
11868   ""
11869   "bsr{w}\t{%1, %0|%0, %1}"
11870   [(set_attr "type" "alu1")
11871    (set_attr "prefix_0f" "1")
11872    (set_attr "mode" "HI")])
11874 (define_insn "popcount<mode>2"
11875   [(set (match_operand:SWI248 0 "register_operand" "=r")
11876         (popcount:SWI248
11877           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11878    (clobber (reg:CC FLAGS_REG))]
11879   "TARGET_POPCNT"
11881 #if TARGET_MACHO
11882   return "popcnt\t{%1, %0|%0, %1}";
11883 #else
11884   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11885 #endif
11887   [(set_attr "prefix_rep" "1")
11888    (set_attr "type" "bitmanip")
11889    (set_attr "mode" "<MODE>")])
11891 (define_insn "*popcount<mode>2_cmp"
11892   [(set (reg FLAGS_REG)
11893         (compare
11894           (popcount:SWI248
11895             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11896           (const_int 0)))
11897    (set (match_operand:SWI248 0 "register_operand" "=r")
11898         (popcount:SWI248 (match_dup 1)))]
11899   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11901 #if TARGET_MACHO
11902   return "popcnt\t{%1, %0|%0, %1}";
11903 #else
11904   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11905 #endif
11907   [(set_attr "prefix_rep" "1")
11908    (set_attr "type" "bitmanip")
11909    (set_attr "mode" "<MODE>")])
11911 (define_insn "*popcountsi2_cmp_zext"
11912   [(set (reg FLAGS_REG)
11913         (compare
11914           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11915           (const_int 0)))
11916    (set (match_operand:DI 0 "register_operand" "=r")
11917         (zero_extend:DI(popcount:SI (match_dup 1))))]
11918   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11920 #if TARGET_MACHO
11921   return "popcnt\t{%1, %0|%0, %1}";
11922 #else
11923   return "popcnt{l}\t{%1, %0|%0, %1}";
11924 #endif
11926   [(set_attr "prefix_rep" "1")
11927    (set_attr "type" "bitmanip")
11928    (set_attr "mode" "SI")])
11930 (define_expand "bswapdi2"
11931   [(set (match_operand:DI 0 "register_operand")
11932         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
11933   "TARGET_64BIT"
11935   if (!TARGET_MOVBE)
11936     operands[1] = force_reg (DImode, operands[1]);
11939 (define_expand "bswapsi2"
11940   [(set (match_operand:SI 0 "register_operand")
11941         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
11942   ""
11944   if (TARGET_MOVBE)
11945     ;
11946   else if (TARGET_BSWAP)
11947     operands[1] = force_reg (SImode, operands[1]);
11948   else
11949     {
11950       rtx x = operands[0];
11952       emit_move_insn (x, operands[1]);
11953       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11954       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
11955       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11956       DONE;
11957     }
11960 (define_insn "*bswap<mode>2_movbe"
11961   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
11962         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
11963   "TARGET_MOVBE
11964    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11965   "@
11966     bswap\t%0
11967     movbe\t{%1, %0|%0, %1}
11968     movbe\t{%1, %0|%0, %1}"
11969   [(set_attr "type" "bitmanip,imov,imov")
11970    (set_attr "modrm" "0,1,1")
11971    (set_attr "prefix_0f" "*,1,1")
11972    (set_attr "prefix_extra" "*,1,1")
11973    (set_attr "mode" "<MODE>")])
11975 (define_insn "*bswap<mode>2"
11976   [(set (match_operand:SWI48 0 "register_operand" "=r")
11977         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
11978   "TARGET_BSWAP"
11979   "bswap\t%0"
11980   [(set_attr "type" "bitmanip")
11981    (set_attr "modrm" "0")
11982    (set_attr "mode" "<MODE>")])
11984 (define_insn "*bswaphi_lowpart_1"
11985   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
11986         (bswap:HI (match_dup 0)))
11987    (clobber (reg:CC FLAGS_REG))]
11988   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
11989   "@
11990     xchg{b}\t{%h0, %b0|%b0, %h0}
11991     rol{w}\t{$8, %0|%0, 8}"
11992   [(set_attr "length" "2,4")
11993    (set_attr "mode" "QI,HI")])
11995 (define_insn "bswaphi_lowpart"
11996   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
11997         (bswap:HI (match_dup 0)))
11998    (clobber (reg:CC FLAGS_REG))]
11999   ""
12000   "rol{w}\t{$8, %0|%0, 8}"
12001   [(set_attr "length" "4")
12002    (set_attr "mode" "HI")])
12004 (define_expand "paritydi2"
12005   [(set (match_operand:DI 0 "register_operand")
12006         (parity:DI (match_operand:DI 1 "register_operand")))]
12007   "! TARGET_POPCNT"
12009   rtx scratch = gen_reg_rtx (QImode);
12010   rtx cond;
12012   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12013                                 NULL_RTX, operands[1]));
12015   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12016                          gen_rtx_REG (CCmode, FLAGS_REG),
12017                          const0_rtx);
12018   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12020   if (TARGET_64BIT)
12021     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12022   else
12023     {
12024       rtx tmp = gen_reg_rtx (SImode);
12026       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12027       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12028     }
12029   DONE;
12032 (define_expand "paritysi2"
12033   [(set (match_operand:SI 0 "register_operand")
12034         (parity:SI (match_operand:SI 1 "register_operand")))]
12035   "! TARGET_POPCNT"
12037   rtx scratch = gen_reg_rtx (QImode);
12038   rtx cond;
12040   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12042   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12043                          gen_rtx_REG (CCmode, FLAGS_REG),
12044                          const0_rtx);
12045   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12047   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12048   DONE;
12051 (define_insn_and_split "paritydi2_cmp"
12052   [(set (reg:CC FLAGS_REG)
12053         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12054                    UNSPEC_PARITY))
12055    (clobber (match_scratch:DI 0 "=r"))
12056    (clobber (match_scratch:SI 1 "=&r"))
12057    (clobber (match_scratch:HI 2 "=Q"))]
12058   "! TARGET_POPCNT"
12059   "#"
12060   "&& reload_completed"
12061   [(parallel
12062      [(set (match_dup 1)
12063            (xor:SI (match_dup 1) (match_dup 4)))
12064       (clobber (reg:CC FLAGS_REG))])
12065    (parallel
12066      [(set (reg:CC FLAGS_REG)
12067            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12068       (clobber (match_dup 1))
12069       (clobber (match_dup 2))])]
12071   operands[4] = gen_lowpart (SImode, operands[3]);
12073   if (TARGET_64BIT)
12074     {
12075       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12076       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12077     }
12078   else
12079     operands[1] = gen_highpart (SImode, operands[3]);
12082 (define_insn_and_split "paritysi2_cmp"
12083   [(set (reg:CC FLAGS_REG)
12084         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12085                    UNSPEC_PARITY))
12086    (clobber (match_scratch:SI 0 "=r"))
12087    (clobber (match_scratch:HI 1 "=&Q"))]
12088   "! TARGET_POPCNT"
12089   "#"
12090   "&& reload_completed"
12091   [(parallel
12092      [(set (match_dup 1)
12093            (xor:HI (match_dup 1) (match_dup 3)))
12094       (clobber (reg:CC FLAGS_REG))])
12095    (parallel
12096      [(set (reg:CC FLAGS_REG)
12097            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12098       (clobber (match_dup 1))])]
12100   operands[3] = gen_lowpart (HImode, operands[2]);
12102   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12103   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12106 (define_insn "*parityhi2_cmp"
12107   [(set (reg:CC FLAGS_REG)
12108         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12109                    UNSPEC_PARITY))
12110    (clobber (match_scratch:HI 0 "=Q"))]
12111   "! TARGET_POPCNT"
12112   "xor{b}\t{%h0, %b0|%b0, %h0}"
12113   [(set_attr "length" "2")
12114    (set_attr "mode" "HI")])
12117 ;; Thread-local storage patterns for ELF.
12119 ;; Note that these code sequences must appear exactly as shown
12120 ;; in order to allow linker relaxation.
12122 (define_insn "*tls_global_dynamic_32_gnu"
12123   [(set (match_operand:SI 0 "register_operand" "=a")
12124         (unspec:SI
12125          [(match_operand:SI 1 "register_operand" "b")
12126           (match_operand 2 "tls_symbolic_operand")
12127           (match_operand 3 "constant_call_address_operand" "z")]
12128          UNSPEC_TLS_GD))
12129    (clobber (match_scratch:SI 4 "=d"))
12130    (clobber (match_scratch:SI 5 "=c"))
12131    (clobber (reg:CC FLAGS_REG))]
12132   "!TARGET_64BIT && TARGET_GNU_TLS"
12134   output_asm_insn
12135     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12136   if (TARGET_SUN_TLS)
12137 #ifdef HAVE_AS_IX86_TLSGDPLT
12138     return "call\t%a2@tlsgdplt";
12139 #else
12140     return "call\t%p3@plt";
12141 #endif
12142   return "call\t%P3";
12144   [(set_attr "type" "multi")
12145    (set_attr "length" "12")])
12147 (define_expand "tls_global_dynamic_32"
12148   [(parallel
12149     [(set (match_operand:SI 0 "register_operand")
12150           (unspec:SI [(match_operand:SI 2 "register_operand")
12151                       (match_operand 1 "tls_symbolic_operand")
12152                       (match_operand 3 "constant_call_address_operand")]
12153                      UNSPEC_TLS_GD))
12154      (clobber (match_scratch:SI 4))
12155      (clobber (match_scratch:SI 5))
12156      (clobber (reg:CC FLAGS_REG))])])
12158 (define_insn "*tls_global_dynamic_64_<mode>"
12159   [(set (match_operand:P 0 "register_operand" "=a")
12160         (call:P
12161          (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12162          (match_operand 3)))
12163    (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12164              UNSPEC_TLS_GD)]
12165   "TARGET_64BIT"
12167   if (!TARGET_X32)
12168     fputs (ASM_BYTE "0x66\n", asm_out_file);
12169   output_asm_insn
12170     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12171   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12172   fputs ("\trex64\n", asm_out_file);
12173   if (TARGET_SUN_TLS)
12174     return "call\t%p2@plt";
12175   return "call\t%P2";
12177   [(set_attr "type" "multi")
12178    (set (attr "length")
12179         (symbol_ref "TARGET_X32 ? 15 : 16"))])
12181 (define_expand "tls_global_dynamic_64_<mode>"
12182   [(parallel
12183     [(set (match_operand:P 0 "register_operand")
12184           (call:P
12185            (mem:QI (match_operand 2 "constant_call_address_operand"))
12186            (const_int 0)))
12187      (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12188                UNSPEC_TLS_GD)])]
12189   "TARGET_64BIT")
12191 (define_insn "*tls_local_dynamic_base_32_gnu"
12192   [(set (match_operand:SI 0 "register_operand" "=a")
12193         (unspec:SI
12194          [(match_operand:SI 1 "register_operand" "b")
12195           (match_operand 2 "constant_call_address_operand" "z")]
12196          UNSPEC_TLS_LD_BASE))
12197    (clobber (match_scratch:SI 3 "=d"))
12198    (clobber (match_scratch:SI 4 "=c"))
12199    (clobber (reg:CC FLAGS_REG))]
12200   "!TARGET_64BIT && TARGET_GNU_TLS"
12202   output_asm_insn
12203     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12204   if (TARGET_SUN_TLS)
12205 #ifdef HAVE_AS_IX86_TLSLDMPLT
12206     return "call\t%&@tlsldmplt";
12207 #else
12208     return "call\t%p2@plt";
12209 #endif
12210   return "call\t%P2";
12212   [(set_attr "type" "multi")
12213    (set_attr "length" "11")])
12215 (define_expand "tls_local_dynamic_base_32"
12216   [(parallel
12217      [(set (match_operand:SI 0 "register_operand")
12218            (unspec:SI
12219             [(match_operand:SI 1 "register_operand")
12220              (match_operand 2 "constant_call_address_operand")]
12221             UNSPEC_TLS_LD_BASE))
12222       (clobber (match_scratch:SI 3))
12223       (clobber (match_scratch:SI 4))
12224       (clobber (reg:CC FLAGS_REG))])])
12226 (define_insn "*tls_local_dynamic_base_64_<mode>"
12227   [(set (match_operand:P 0 "register_operand" "=a")
12228         (call:P
12229          (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12230          (match_operand 2)))
12231    (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12232   "TARGET_64BIT"
12234   output_asm_insn
12235     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12236   if (TARGET_SUN_TLS)
12237     return "call\t%p1@plt";
12238   return "call\t%P1";
12240   [(set_attr "type" "multi")
12241    (set_attr "length" "12")])
12243 (define_expand "tls_local_dynamic_base_64_<mode>"
12244   [(parallel
12245      [(set (match_operand:P 0 "register_operand")
12246            (call:P
12247             (mem:QI (match_operand 1 "constant_call_address_operand"))
12248             (const_int 0)))
12249       (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12250   "TARGET_64BIT")
12252 ;; Local dynamic of a single variable is a lose.  Show combine how
12253 ;; to convert that back to global dynamic.
12255 (define_insn_and_split "*tls_local_dynamic_32_once"
12256   [(set (match_operand:SI 0 "register_operand" "=a")
12257         (plus:SI
12258          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12259                      (match_operand 2 "constant_call_address_operand" "z")]
12260                     UNSPEC_TLS_LD_BASE)
12261          (const:SI (unspec:SI
12262                     [(match_operand 3 "tls_symbolic_operand")]
12263                     UNSPEC_DTPOFF))))
12264    (clobber (match_scratch:SI 4 "=d"))
12265    (clobber (match_scratch:SI 5 "=c"))
12266    (clobber (reg:CC FLAGS_REG))]
12267   ""
12268   "#"
12269   ""
12270   [(parallel
12271      [(set (match_dup 0)
12272            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12273                       UNSPEC_TLS_GD))
12274       (clobber (match_dup 4))
12275       (clobber (match_dup 5))
12276       (clobber (reg:CC FLAGS_REG))])])
12278 ;; Segment register for the thread base ptr load
12279 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12281 ;; Load and add the thread base pointer from %<tp_seg>:0.
12282 (define_insn "*load_tp_x32"
12283   [(set (match_operand:SI 0 "register_operand" "=r")
12284         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12285   "TARGET_X32"
12286   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12287   [(set_attr "type" "imov")
12288    (set_attr "modrm" "0")
12289    (set_attr "length" "7")
12290    (set_attr "memory" "load")
12291    (set_attr "imm_disp" "false")])
12293 (define_insn "*load_tp_x32_zext"
12294   [(set (match_operand:DI 0 "register_operand" "=r")
12295         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12296   "TARGET_X32"
12297   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12298   [(set_attr "type" "imov")
12299    (set_attr "modrm" "0")
12300    (set_attr "length" "7")
12301    (set_attr "memory" "load")
12302    (set_attr "imm_disp" "false")])
12304 (define_insn "*load_tp_<mode>"
12305   [(set (match_operand:P 0 "register_operand" "=r")
12306         (unspec:P [(const_int 0)] UNSPEC_TP))]
12307   "!TARGET_X32"
12308   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12309   [(set_attr "type" "imov")
12310    (set_attr "modrm" "0")
12311    (set_attr "length" "7")
12312    (set_attr "memory" "load")
12313    (set_attr "imm_disp" "false")])
12315 (define_insn "*add_tp_x32"
12316   [(set (match_operand:SI 0 "register_operand" "=r")
12317         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12318                  (match_operand:SI 1 "register_operand" "0")))
12319    (clobber (reg:CC FLAGS_REG))]
12320   "TARGET_X32"
12321   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12322   [(set_attr "type" "alu")
12323    (set_attr "modrm" "0")
12324    (set_attr "length" "7")
12325    (set_attr "memory" "load")
12326    (set_attr "imm_disp" "false")])
12328 (define_insn "*add_tp_x32_zext"
12329   [(set (match_operand:DI 0 "register_operand" "=r")
12330         (zero_extend:DI
12331           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12332                    (match_operand:SI 1 "register_operand" "0"))))
12333    (clobber (reg:CC FLAGS_REG))]
12334   "TARGET_X32"
12335   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12336   [(set_attr "type" "alu")
12337    (set_attr "modrm" "0")
12338    (set_attr "length" "7")
12339    (set_attr "memory" "load")
12340    (set_attr "imm_disp" "false")])
12342 (define_insn "*add_tp_<mode>"
12343   [(set (match_operand:P 0 "register_operand" "=r")
12344         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12345                 (match_operand:P 1 "register_operand" "0")))
12346    (clobber (reg:CC FLAGS_REG))]
12347   "!TARGET_X32"
12348   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12349   [(set_attr "type" "alu")
12350    (set_attr "modrm" "0")
12351    (set_attr "length" "7")
12352    (set_attr "memory" "load")
12353    (set_attr "imm_disp" "false")])
12355 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12356 ;; %rax as destination of the initial executable code sequence.
12357 (define_insn "tls_initial_exec_64_sun"
12358   [(set (match_operand:DI 0 "register_operand" "=a")
12359         (unspec:DI
12360          [(match_operand 1 "tls_symbolic_operand")]
12361          UNSPEC_TLS_IE_SUN))
12362    (clobber (reg:CC FLAGS_REG))]
12363   "TARGET_64BIT && TARGET_SUN_TLS"
12365   output_asm_insn
12366     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12367   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12369   [(set_attr "type" "multi")])
12371 ;; GNU2 TLS patterns can be split.
12373 (define_expand "tls_dynamic_gnu2_32"
12374   [(set (match_dup 3)
12375         (plus:SI (match_operand:SI 2 "register_operand")
12376                  (const:SI
12377                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
12378                              UNSPEC_TLSDESC))))
12379    (parallel
12380     [(set (match_operand:SI 0 "register_operand")
12381           (unspec:SI [(match_dup 1) (match_dup 3)
12382                       (match_dup 2) (reg:SI SP_REG)]
12383                       UNSPEC_TLSDESC))
12384      (clobber (reg:CC FLAGS_REG))])]
12385   "!TARGET_64BIT && TARGET_GNU2_TLS"
12387   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12388   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12391 (define_insn "*tls_dynamic_gnu2_lea_32"
12392   [(set (match_operand:SI 0 "register_operand" "=r")
12393         (plus:SI (match_operand:SI 1 "register_operand" "b")
12394                  (const:SI
12395                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
12396                               UNSPEC_TLSDESC))))]
12397   "!TARGET_64BIT && TARGET_GNU2_TLS"
12398   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12399   [(set_attr "type" "lea")
12400    (set_attr "mode" "SI")
12401    (set_attr "length" "6")
12402    (set_attr "length_address" "4")])
12404 (define_insn "*tls_dynamic_gnu2_call_32"
12405   [(set (match_operand:SI 0 "register_operand" "=a")
12406         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
12407                     (match_operand:SI 2 "register_operand" "0")
12408                     ;; we have to make sure %ebx still points to the GOT
12409                     (match_operand:SI 3 "register_operand" "b")
12410                     (reg:SI SP_REG)]
12411                    UNSPEC_TLSDESC))
12412    (clobber (reg:CC FLAGS_REG))]
12413   "!TARGET_64BIT && TARGET_GNU2_TLS"
12414   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12415   [(set_attr "type" "call")
12416    (set_attr "length" "2")
12417    (set_attr "length_address" "0")])
12419 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12420   [(set (match_operand:SI 0 "register_operand" "=&a")
12421         (plus:SI
12422          (unspec:SI [(match_operand 3 "tls_modbase_operand")
12423                      (match_operand:SI 4)
12424                      (match_operand:SI 2 "register_operand" "b")
12425                      (reg:SI SP_REG)]
12426                     UNSPEC_TLSDESC)
12427          (const:SI (unspec:SI
12428                     [(match_operand 1 "tls_symbolic_operand")]
12429                     UNSPEC_DTPOFF))))
12430    (clobber (reg:CC FLAGS_REG))]
12431   "!TARGET_64BIT && TARGET_GNU2_TLS"
12432   "#"
12433   ""
12434   [(set (match_dup 0) (match_dup 5))]
12436   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12437   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12440 (define_expand "tls_dynamic_gnu2_64"
12441   [(set (match_dup 2)
12442         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12443                    UNSPEC_TLSDESC))
12444    (parallel
12445     [(set (match_operand:DI 0 "register_operand")
12446           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12447                      UNSPEC_TLSDESC))
12448      (clobber (reg:CC FLAGS_REG))])]
12449   "TARGET_64BIT && TARGET_GNU2_TLS"
12451   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12452   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12455 (define_insn "*tls_dynamic_gnu2_lea_64"
12456   [(set (match_operand:DI 0 "register_operand" "=r")
12457         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12458                    UNSPEC_TLSDESC))]
12459   "TARGET_64BIT && TARGET_GNU2_TLS"
12460   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12461   [(set_attr "type" "lea")
12462    (set_attr "mode" "DI")
12463    (set_attr "length" "7")
12464    (set_attr "length_address" "4")])
12466 (define_insn "*tls_dynamic_gnu2_call_64"
12467   [(set (match_operand:DI 0 "register_operand" "=a")
12468         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
12469                     (match_operand:DI 2 "register_operand" "0")
12470                     (reg:DI SP_REG)]
12471                    UNSPEC_TLSDESC))
12472    (clobber (reg:CC FLAGS_REG))]
12473   "TARGET_64BIT && TARGET_GNU2_TLS"
12474   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12475   [(set_attr "type" "call")
12476    (set_attr "length" "2")
12477    (set_attr "length_address" "0")])
12479 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12480   [(set (match_operand:DI 0 "register_operand" "=&a")
12481         (plus:DI
12482          (unspec:DI [(match_operand 2 "tls_modbase_operand")
12483                      (match_operand:DI 3)
12484                      (reg:DI SP_REG)]
12485                     UNSPEC_TLSDESC)
12486          (const:DI (unspec:DI
12487                     [(match_operand 1 "tls_symbolic_operand")]
12488                     UNSPEC_DTPOFF))))
12489    (clobber (reg:CC FLAGS_REG))]
12490   "TARGET_64BIT && TARGET_GNU2_TLS"
12491   "#"
12492   ""
12493   [(set (match_dup 0) (match_dup 4))]
12495   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12496   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12499 ;; These patterns match the binary 387 instructions for addM3, subM3,
12500 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12501 ;; SFmode.  The first is the normal insn, the second the same insn but
12502 ;; with one operand a conversion, and the third the same insn but with
12503 ;; the other operand a conversion.  The conversion may be SFmode or
12504 ;; SImode if the target mode DFmode, but only SImode if the target mode
12505 ;; is SFmode.
12507 ;; Gcc is slightly more smart about handling normal two address instructions
12508 ;; so use special patterns for add and mull.
12510 (define_insn "*fop_<mode>_comm_mixed"
12511   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12512         (match_operator:MODEF 3 "binary_fp_operator"
12513           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12514            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12515   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12516    && COMMUTATIVE_ARITH_P (operands[3])
12517    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12518   "* return output_387_binary_op (insn, operands);"
12519   [(set (attr "type")
12520         (if_then_else (eq_attr "alternative" "1,2")
12521            (if_then_else (match_operand:MODEF 3 "mult_operator")
12522               (const_string "ssemul")
12523               (const_string "sseadd"))
12524            (if_then_else (match_operand:MODEF 3 "mult_operator")
12525               (const_string "fmul")
12526               (const_string "fop"))))
12527    (set_attr "isa" "*,noavx,avx")
12528    (set_attr "prefix" "orig,orig,vex")
12529    (set_attr "mode" "<MODE>")])
12531 (define_insn "*fop_<mode>_comm_sse"
12532   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12533         (match_operator:MODEF 3 "binary_fp_operator"
12534           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12535            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12536   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12537    && COMMUTATIVE_ARITH_P (operands[3])
12538    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12539   "* return output_387_binary_op (insn, operands);"
12540   [(set (attr "type")
12541         (if_then_else (match_operand:MODEF 3 "mult_operator")
12542            (const_string "ssemul")
12543            (const_string "sseadd")))
12544    (set_attr "isa" "noavx,avx")
12545    (set_attr "prefix" "orig,vex")
12546    (set_attr "mode" "<MODE>")])
12548 (define_insn "*fop_<mode>_comm_i387"
12549   [(set (match_operand:MODEF 0 "register_operand" "=f")
12550         (match_operator:MODEF 3 "binary_fp_operator"
12551           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12552            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12553   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12554    && COMMUTATIVE_ARITH_P (operands[3])
12555    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12556   "* return output_387_binary_op (insn, operands);"
12557   [(set (attr "type")
12558         (if_then_else (match_operand:MODEF 3 "mult_operator")
12559            (const_string "fmul")
12560            (const_string "fop")))
12561    (set_attr "mode" "<MODE>")])
12563 (define_insn "*fop_<mode>_1_mixed"
12564   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12565         (match_operator:MODEF 3 "binary_fp_operator"
12566           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12567            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12568   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12569    && !COMMUTATIVE_ARITH_P (operands[3])
12570    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12571   "* return output_387_binary_op (insn, operands);"
12572   [(set (attr "type")
12573         (cond [(and (eq_attr "alternative" "2,3")
12574                     (match_operand:MODEF 3 "mult_operator"))
12575                  (const_string "ssemul")
12576                (and (eq_attr "alternative" "2,3")
12577                     (match_operand:MODEF 3 "div_operator"))
12578                  (const_string "ssediv")
12579                (eq_attr "alternative" "2,3")
12580                  (const_string "sseadd")
12581                (match_operand:MODEF 3 "mult_operator")
12582                  (const_string "fmul")
12583                (match_operand:MODEF 3 "div_operator")
12584                  (const_string "fdiv")
12585               ]
12586               (const_string "fop")))
12587    (set_attr "isa" "*,*,noavx,avx")
12588    (set_attr "prefix" "orig,orig,orig,vex")
12589    (set_attr "mode" "<MODE>")])
12591 (define_insn "*rcpsf2_sse"
12592   [(set (match_operand:SF 0 "register_operand" "=x")
12593         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12594                    UNSPEC_RCP))]
12595   "TARGET_SSE_MATH"
12596   "%vrcpss\t{%1, %d0|%d0, %1}"
12597   [(set_attr "type" "sse")
12598    (set_attr "atom_sse_attr" "rcp")
12599    (set_attr "btver2_sse_attr" "rcp")
12600    (set_attr "prefix" "maybe_vex")
12601    (set_attr "mode" "SF")])
12603 (define_insn "*fop_<mode>_1_sse"
12604   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12605         (match_operator:MODEF 3 "binary_fp_operator"
12606           [(match_operand:MODEF 1 "register_operand" "0,x")
12607            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12608   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12609    && !COMMUTATIVE_ARITH_P (operands[3])"
12610   "* return output_387_binary_op (insn, operands);"
12611   [(set (attr "type")
12612         (cond [(match_operand:MODEF 3 "mult_operator")
12613                  (const_string "ssemul")
12614                (match_operand:MODEF 3 "div_operator")
12615                  (const_string "ssediv")
12616               ]
12617               (const_string "sseadd")))
12618    (set_attr "isa" "noavx,avx")
12619    (set_attr "prefix" "orig,vex")
12620    (set_attr "mode" "<MODE>")])
12622 ;; This pattern is not fully shadowed by the pattern above.
12623 (define_insn "*fop_<mode>_1_i387"
12624   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12625         (match_operator:MODEF 3 "binary_fp_operator"
12626           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12627            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12628   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12629    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12630    && !COMMUTATIVE_ARITH_P (operands[3])
12631    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12632   "* return output_387_binary_op (insn, operands);"
12633   [(set (attr "type")
12634         (cond [(match_operand:MODEF 3 "mult_operator")
12635                  (const_string "fmul")
12636                (match_operand:MODEF 3 "div_operator")
12637                  (const_string "fdiv")
12638               ]
12639               (const_string "fop")))
12640    (set_attr "mode" "<MODE>")])
12642 ;; ??? Add SSE splitters for these!
12643 (define_insn "*fop_<MODEF:mode>_2_i387"
12644   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12645         (match_operator:MODEF 3 "binary_fp_operator"
12646           [(float:MODEF
12647              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12648            (match_operand:MODEF 2 "register_operand" "0,0")]))]
12649   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12650    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12651    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12652   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12653   [(set (attr "type")
12654         (cond [(match_operand:MODEF 3 "mult_operator")
12655                  (const_string "fmul")
12656                (match_operand:MODEF 3 "div_operator")
12657                  (const_string "fdiv")
12658               ]
12659               (const_string "fop")))
12660    (set_attr "fp_int_src" "true")
12661    (set_attr "mode" "<SWI24:MODE>")])
12663 (define_insn "*fop_<MODEF:mode>_3_i387"
12664   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12665         (match_operator:MODEF 3 "binary_fp_operator"
12666           [(match_operand:MODEF 1 "register_operand" "0,0")
12667            (float:MODEF
12668              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12669   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12670    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12671    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12672   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12673   [(set (attr "type")
12674         (cond [(match_operand:MODEF 3 "mult_operator")
12675                  (const_string "fmul")
12676                (match_operand:MODEF 3 "div_operator")
12677                  (const_string "fdiv")
12678               ]
12679               (const_string "fop")))
12680    (set_attr "fp_int_src" "true")
12681    (set_attr "mode" "<MODE>")])
12683 (define_insn "*fop_df_4_i387"
12684   [(set (match_operand:DF 0 "register_operand" "=f,f")
12685         (match_operator:DF 3 "binary_fp_operator"
12686            [(float_extend:DF
12687              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12688             (match_operand:DF 2 "register_operand" "0,f")]))]
12689   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12690    && !(TARGET_SSE2 && TARGET_SSE_MATH)
12691    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12692   "* return output_387_binary_op (insn, operands);"
12693   [(set (attr "type")
12694         (cond [(match_operand:DF 3 "mult_operator")
12695                  (const_string "fmul")
12696                (match_operand:DF 3 "div_operator")
12697                  (const_string "fdiv")
12698               ]
12699               (const_string "fop")))
12700    (set_attr "mode" "SF")])
12702 (define_insn "*fop_df_5_i387"
12703   [(set (match_operand:DF 0 "register_operand" "=f,f")
12704         (match_operator:DF 3 "binary_fp_operator"
12705           [(match_operand:DF 1 "register_operand" "0,f")
12706            (float_extend:DF
12707             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12708   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12709    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12710   "* return output_387_binary_op (insn, operands);"
12711   [(set (attr "type")
12712         (cond [(match_operand:DF 3 "mult_operator")
12713                  (const_string "fmul")
12714                (match_operand:DF 3 "div_operator")
12715                  (const_string "fdiv")
12716               ]
12717               (const_string "fop")))
12718    (set_attr "mode" "SF")])
12720 (define_insn "*fop_df_6_i387"
12721   [(set (match_operand:DF 0 "register_operand" "=f,f")
12722         (match_operator:DF 3 "binary_fp_operator"
12723           [(float_extend:DF
12724             (match_operand:SF 1 "register_operand" "0,f"))
12725            (float_extend:DF
12726             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12727   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12728    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12729   "* return output_387_binary_op (insn, operands);"
12730   [(set (attr "type")
12731         (cond [(match_operand:DF 3 "mult_operator")
12732                  (const_string "fmul")
12733                (match_operand:DF 3 "div_operator")
12734                  (const_string "fdiv")
12735               ]
12736               (const_string "fop")))
12737    (set_attr "mode" "SF")])
12739 (define_insn "*fop_xf_comm_i387"
12740   [(set (match_operand:XF 0 "register_operand" "=f")
12741         (match_operator:XF 3 "binary_fp_operator"
12742                         [(match_operand:XF 1 "register_operand" "%0")
12743                          (match_operand:XF 2 "register_operand" "f")]))]
12744   "TARGET_80387
12745    && COMMUTATIVE_ARITH_P (operands[3])"
12746   "* return output_387_binary_op (insn, operands);"
12747   [(set (attr "type")
12748         (if_then_else (match_operand:XF 3 "mult_operator")
12749            (const_string "fmul")
12750            (const_string "fop")))
12751    (set_attr "mode" "XF")])
12753 (define_insn "*fop_xf_1_i387"
12754   [(set (match_operand:XF 0 "register_operand" "=f,f")
12755         (match_operator:XF 3 "binary_fp_operator"
12756                         [(match_operand:XF 1 "register_operand" "0,f")
12757                          (match_operand:XF 2 "register_operand" "f,0")]))]
12758   "TARGET_80387
12759    && !COMMUTATIVE_ARITH_P (operands[3])"
12760   "* return output_387_binary_op (insn, operands);"
12761   [(set (attr "type")
12762         (cond [(match_operand:XF 3 "mult_operator")
12763                  (const_string "fmul")
12764                (match_operand:XF 3 "div_operator")
12765                  (const_string "fdiv")
12766               ]
12767               (const_string "fop")))
12768    (set_attr "mode" "XF")])
12770 (define_insn "*fop_xf_2_i387"
12771   [(set (match_operand:XF 0 "register_operand" "=f,f")
12772         (match_operator:XF 3 "binary_fp_operator"
12773           [(float:XF
12774              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12775            (match_operand:XF 2 "register_operand" "0,0")]))]
12776   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12777   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12778   [(set (attr "type")
12779         (cond [(match_operand:XF 3 "mult_operator")
12780                  (const_string "fmul")
12781                (match_operand:XF 3 "div_operator")
12782                  (const_string "fdiv")
12783               ]
12784               (const_string "fop")))
12785    (set_attr "fp_int_src" "true")
12786    (set_attr "mode" "<MODE>")])
12788 (define_insn "*fop_xf_3_i387"
12789   [(set (match_operand:XF 0 "register_operand" "=f,f")
12790         (match_operator:XF 3 "binary_fp_operator"
12791           [(match_operand:XF 1 "register_operand" "0,0")
12792            (float:XF
12793              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12794   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12795   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12796   [(set (attr "type")
12797         (cond [(match_operand:XF 3 "mult_operator")
12798                  (const_string "fmul")
12799                (match_operand:XF 3 "div_operator")
12800                  (const_string "fdiv")
12801               ]
12802               (const_string "fop")))
12803    (set_attr "fp_int_src" "true")
12804    (set_attr "mode" "<MODE>")])
12806 (define_insn "*fop_xf_4_i387"
12807   [(set (match_operand:XF 0 "register_operand" "=f,f")
12808         (match_operator:XF 3 "binary_fp_operator"
12809            [(float_extend:XF
12810               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12811             (match_operand:XF 2 "register_operand" "0,f")]))]
12812   "TARGET_80387"
12813   "* return output_387_binary_op (insn, operands);"
12814   [(set (attr "type")
12815         (cond [(match_operand:XF 3 "mult_operator")
12816                  (const_string "fmul")
12817                (match_operand:XF 3 "div_operator")
12818                  (const_string "fdiv")
12819               ]
12820               (const_string "fop")))
12821    (set_attr "mode" "<MODE>")])
12823 (define_insn "*fop_xf_5_i387"
12824   [(set (match_operand:XF 0 "register_operand" "=f,f")
12825         (match_operator:XF 3 "binary_fp_operator"
12826           [(match_operand:XF 1 "register_operand" "0,f")
12827            (float_extend:XF
12828              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12829   "TARGET_80387"
12830   "* return output_387_binary_op (insn, operands);"
12831   [(set (attr "type")
12832         (cond [(match_operand:XF 3 "mult_operator")
12833                  (const_string "fmul")
12834                (match_operand:XF 3 "div_operator")
12835                  (const_string "fdiv")
12836               ]
12837               (const_string "fop")))
12838    (set_attr "mode" "<MODE>")])
12840 (define_insn "*fop_xf_6_i387"
12841   [(set (match_operand:XF 0 "register_operand" "=f,f")
12842         (match_operator:XF 3 "binary_fp_operator"
12843           [(float_extend:XF
12844              (match_operand:MODEF 1 "register_operand" "0,f"))
12845            (float_extend:XF
12846              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12847   "TARGET_80387"
12848   "* return output_387_binary_op (insn, operands);"
12849   [(set (attr "type")
12850         (cond [(match_operand:XF 3 "mult_operator")
12851                  (const_string "fmul")
12852                (match_operand:XF 3 "div_operator")
12853                  (const_string "fdiv")
12854               ]
12855               (const_string "fop")))
12856    (set_attr "mode" "<MODE>")])
12858 (define_split
12859   [(set (match_operand 0 "register_operand")
12860         (match_operator 3 "binary_fp_operator"
12861            [(float (match_operand:SWI24 1 "register_operand"))
12862             (match_operand 2 "register_operand")]))]
12863   "reload_completed
12864    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12865    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12866   [(const_int 0)]
12868   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12869   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12870   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12871                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
12872                                           GET_MODE (operands[3]),
12873                                           operands[4],
12874                                           operands[2])));
12875   ix86_free_from_memory (GET_MODE (operands[1]));
12876   DONE;
12879 (define_split
12880   [(set (match_operand 0 "register_operand")
12881         (match_operator 3 "binary_fp_operator"
12882            [(match_operand 1 "register_operand")
12883             (float (match_operand:SWI24 2 "register_operand"))]))]
12884   "reload_completed
12885    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12886    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12887   [(const_int 0)]
12889   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12890   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12891   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12892                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
12893                                           GET_MODE (operands[3]),
12894                                           operands[1],
12895                                           operands[4])));
12896   ix86_free_from_memory (GET_MODE (operands[2]));
12897   DONE;
12900 ;; FPU special functions.
12902 ;; This pattern implements a no-op XFmode truncation for
12903 ;; all fancy i386 XFmode math functions.
12905 (define_insn "truncxf<mode>2_i387_noop_unspec"
12906   [(set (match_operand:MODEF 0 "register_operand" "=f")
12907         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12908         UNSPEC_TRUNC_NOOP))]
12909   "TARGET_USE_FANCY_MATH_387"
12910   "* return output_387_reg_move (insn, operands);"
12911   [(set_attr "type" "fmov")
12912    (set_attr "mode" "<MODE>")])
12914 (define_insn "sqrtxf2"
12915   [(set (match_operand:XF 0 "register_operand" "=f")
12916         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12917   "TARGET_USE_FANCY_MATH_387"
12918   "fsqrt"
12919   [(set_attr "type" "fpspc")
12920    (set_attr "mode" "XF")
12921    (set_attr "athlon_decode" "direct")
12922    (set_attr "amdfam10_decode" "direct")
12923    (set_attr "bdver1_decode" "direct")])
12925 (define_insn "sqrt_extend<mode>xf2_i387"
12926   [(set (match_operand:XF 0 "register_operand" "=f")
12927         (sqrt:XF
12928           (float_extend:XF
12929             (match_operand:MODEF 1 "register_operand" "0"))))]
12930   "TARGET_USE_FANCY_MATH_387"
12931   "fsqrt"
12932   [(set_attr "type" "fpspc")
12933    (set_attr "mode" "XF")
12934    (set_attr "athlon_decode" "direct")
12935    (set_attr "amdfam10_decode" "direct")
12936    (set_attr "bdver1_decode" "direct")])
12938 (define_insn "*rsqrtsf2_sse"
12939   [(set (match_operand:SF 0 "register_operand" "=x")
12940         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12941                    UNSPEC_RSQRT))]
12942   "TARGET_SSE_MATH"
12943   "%vrsqrtss\t{%1, %d0|%d0, %1}"
12944   [(set_attr "type" "sse")
12945    (set_attr "atom_sse_attr" "rcp")
12946    (set_attr "btver2_sse_attr" "rcp")
12947    (set_attr "prefix" "maybe_vex")
12948    (set_attr "mode" "SF")])
12950 (define_expand "rsqrtsf2"
12951   [(set (match_operand:SF 0 "register_operand")
12952         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
12953                    UNSPEC_RSQRT))]
12954   "TARGET_SSE_MATH"
12956   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
12957   DONE;
12960 (define_insn "*sqrt<mode>2_sse"
12961   [(set (match_operand:MODEF 0 "register_operand" "=x")
12962         (sqrt:MODEF
12963           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
12964   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
12965   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
12966   [(set_attr "type" "sse")
12967    (set_attr "atom_sse_attr" "sqrt")
12968    (set_attr "btver2_sse_attr" "sqrt")
12969    (set_attr "prefix" "maybe_vex")
12970    (set_attr "mode" "<MODE>")
12971    (set_attr "athlon_decode" "*")
12972    (set_attr "amdfam10_decode" "*")
12973    (set_attr "bdver1_decode" "*")])
12975 (define_expand "sqrt<mode>2"
12976   [(set (match_operand:MODEF 0 "register_operand")
12977         (sqrt:MODEF
12978           (match_operand:MODEF 1 "nonimmediate_operand")))]
12979   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
12980    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12982   if (<MODE>mode == SFmode
12983       && TARGET_SSE_MATH
12984       && TARGET_RECIP_SQRT
12985       && !optimize_function_for_size_p (cfun)
12986       && flag_finite_math_only && !flag_trapping_math
12987       && flag_unsafe_math_optimizations)
12988     {
12989       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
12990       DONE;
12991     }
12993   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
12994     {
12995       rtx op0 = gen_reg_rtx (XFmode);
12996       rtx op1 = force_reg (<MODE>mode, operands[1]);
12998       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
12999       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13000       DONE;
13001    }
13004 (define_insn "fpremxf4_i387"
13005   [(set (match_operand:XF 0 "register_operand" "=f")
13006         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13007                     (match_operand:XF 3 "register_operand" "1")]
13008                    UNSPEC_FPREM_F))
13009    (set (match_operand:XF 1 "register_operand" "=u")
13010         (unspec:XF [(match_dup 2) (match_dup 3)]
13011                    UNSPEC_FPREM_U))
13012    (set (reg:CCFP FPSR_REG)
13013         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13014                      UNSPEC_C2_FLAG))]
13015   "TARGET_USE_FANCY_MATH_387"
13016   "fprem"
13017   [(set_attr "type" "fpspc")
13018    (set_attr "mode" "XF")])
13020 (define_expand "fmodxf3"
13021   [(use (match_operand:XF 0 "register_operand"))
13022    (use (match_operand:XF 1 "general_operand"))
13023    (use (match_operand:XF 2 "general_operand"))]
13024   "TARGET_USE_FANCY_MATH_387"
13026   rtx label = gen_label_rtx ();
13028   rtx op1 = gen_reg_rtx (XFmode);
13029   rtx op2 = gen_reg_rtx (XFmode);
13031   emit_move_insn (op2, operands[2]);
13032   emit_move_insn (op1, operands[1]);
13034   emit_label (label);
13035   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13036   ix86_emit_fp_unordered_jump (label);
13037   LABEL_NUSES (label) = 1;
13039   emit_move_insn (operands[0], op1);
13040   DONE;
13043 (define_expand "fmod<mode>3"
13044   [(use (match_operand:MODEF 0 "register_operand"))
13045    (use (match_operand:MODEF 1 "general_operand"))
13046    (use (match_operand:MODEF 2 "general_operand"))]
13047   "TARGET_USE_FANCY_MATH_387"
13049   rtx (*gen_truncxf) (rtx, rtx);
13051   rtx label = gen_label_rtx ();
13053   rtx op1 = gen_reg_rtx (XFmode);
13054   rtx op2 = gen_reg_rtx (XFmode);
13056   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13057   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13059   emit_label (label);
13060   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13061   ix86_emit_fp_unordered_jump (label);
13062   LABEL_NUSES (label) = 1;
13064   /* Truncate the result properly for strict SSE math.  */
13065   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13066       && !TARGET_MIX_SSE_I387)
13067     gen_truncxf = gen_truncxf<mode>2;
13068   else
13069     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13071   emit_insn (gen_truncxf (operands[0], op1));
13072   DONE;
13075 (define_insn "fprem1xf4_i387"
13076   [(set (match_operand:XF 0 "register_operand" "=f")
13077         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13078                     (match_operand:XF 3 "register_operand" "1")]
13079                    UNSPEC_FPREM1_F))
13080    (set (match_operand:XF 1 "register_operand" "=u")
13081         (unspec:XF [(match_dup 2) (match_dup 3)]
13082                    UNSPEC_FPREM1_U))
13083    (set (reg:CCFP FPSR_REG)
13084         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13085                      UNSPEC_C2_FLAG))]
13086   "TARGET_USE_FANCY_MATH_387"
13087   "fprem1"
13088   [(set_attr "type" "fpspc")
13089    (set_attr "mode" "XF")])
13091 (define_expand "remainderxf3"
13092   [(use (match_operand:XF 0 "register_operand"))
13093    (use (match_operand:XF 1 "general_operand"))
13094    (use (match_operand:XF 2 "general_operand"))]
13095   "TARGET_USE_FANCY_MATH_387"
13097   rtx label = gen_label_rtx ();
13099   rtx op1 = gen_reg_rtx (XFmode);
13100   rtx op2 = gen_reg_rtx (XFmode);
13102   emit_move_insn (op2, operands[2]);
13103   emit_move_insn (op1, operands[1]);
13105   emit_label (label);
13106   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13107   ix86_emit_fp_unordered_jump (label);
13108   LABEL_NUSES (label) = 1;
13110   emit_move_insn (operands[0], op1);
13111   DONE;
13114 (define_expand "remainder<mode>3"
13115   [(use (match_operand:MODEF 0 "register_operand"))
13116    (use (match_operand:MODEF 1 "general_operand"))
13117    (use (match_operand:MODEF 2 "general_operand"))]
13118   "TARGET_USE_FANCY_MATH_387"
13120   rtx (*gen_truncxf) (rtx, rtx);
13122   rtx label = gen_label_rtx ();
13124   rtx op1 = gen_reg_rtx (XFmode);
13125   rtx op2 = gen_reg_rtx (XFmode);
13127   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13128   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13130   emit_label (label);
13132   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13133   ix86_emit_fp_unordered_jump (label);
13134   LABEL_NUSES (label) = 1;
13136   /* Truncate the result properly for strict SSE math.  */
13137   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13138       && !TARGET_MIX_SSE_I387)
13139     gen_truncxf = gen_truncxf<mode>2;
13140   else
13141     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13143   emit_insn (gen_truncxf (operands[0], op1));
13144   DONE;
13147 (define_int_iterator SINCOS
13148         [UNSPEC_SIN
13149          UNSPEC_COS])
13151 (define_int_attr sincos
13152         [(UNSPEC_SIN "sin")
13153          (UNSPEC_COS "cos")])
13155 (define_insn "*<sincos>xf2_i387"
13156   [(set (match_operand:XF 0 "register_operand" "=f")
13157         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13158                    SINCOS))]
13159   "TARGET_USE_FANCY_MATH_387
13160    && flag_unsafe_math_optimizations"
13161   "f<sincos>"
13162   [(set_attr "type" "fpspc")
13163    (set_attr "mode" "XF")])
13165 (define_insn "*<sincos>_extend<mode>xf2_i387"
13166   [(set (match_operand:XF 0 "register_operand" "=f")
13167         (unspec:XF [(float_extend:XF
13168                       (match_operand:MODEF 1 "register_operand" "0"))]
13169                    SINCOS))]
13170   "TARGET_USE_FANCY_MATH_387
13171    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13172        || TARGET_MIX_SSE_I387)
13173    && flag_unsafe_math_optimizations"
13174   "f<sincos>"
13175   [(set_attr "type" "fpspc")
13176    (set_attr "mode" "XF")])
13178 ;; When sincos pattern is defined, sin and cos builtin functions will be
13179 ;; expanded to sincos pattern with one of its outputs left unused.
13180 ;; CSE pass will figure out if two sincos patterns can be combined,
13181 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13182 ;; depending on the unused output.
13184 (define_insn "sincosxf3"
13185   [(set (match_operand:XF 0 "register_operand" "=f")
13186         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13187                    UNSPEC_SINCOS_COS))
13188    (set (match_operand:XF 1 "register_operand" "=u")
13189         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13190   "TARGET_USE_FANCY_MATH_387
13191    && flag_unsafe_math_optimizations"
13192   "fsincos"
13193   [(set_attr "type" "fpspc")
13194    (set_attr "mode" "XF")])
13196 (define_split
13197   [(set (match_operand:XF 0 "register_operand")
13198         (unspec:XF [(match_operand:XF 2 "register_operand")]
13199                    UNSPEC_SINCOS_COS))
13200    (set (match_operand:XF 1 "register_operand")
13201         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13202   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13203    && can_create_pseudo_p ()"
13204   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13206 (define_split
13207   [(set (match_operand:XF 0 "register_operand")
13208         (unspec:XF [(match_operand:XF 2 "register_operand")]
13209                    UNSPEC_SINCOS_COS))
13210    (set (match_operand:XF 1 "register_operand")
13211         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13212   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13213    && can_create_pseudo_p ()"
13214   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13216 (define_insn "sincos_extend<mode>xf3_i387"
13217   [(set (match_operand:XF 0 "register_operand" "=f")
13218         (unspec:XF [(float_extend:XF
13219                       (match_operand:MODEF 2 "register_operand" "0"))]
13220                    UNSPEC_SINCOS_COS))
13221    (set (match_operand:XF 1 "register_operand" "=u")
13222         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13223   "TARGET_USE_FANCY_MATH_387
13224    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13225        || TARGET_MIX_SSE_I387)
13226    && flag_unsafe_math_optimizations"
13227   "fsincos"
13228   [(set_attr "type" "fpspc")
13229    (set_attr "mode" "XF")])
13231 (define_split
13232   [(set (match_operand:XF 0 "register_operand")
13233         (unspec:XF [(float_extend:XF
13234                       (match_operand:MODEF 2 "register_operand"))]
13235                    UNSPEC_SINCOS_COS))
13236    (set (match_operand:XF 1 "register_operand")
13237         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13238   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13239    && can_create_pseudo_p ()"
13240   [(set (match_dup 1)
13241         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13243 (define_split
13244   [(set (match_operand:XF 0 "register_operand")
13245         (unspec:XF [(float_extend:XF
13246                       (match_operand:MODEF 2 "register_operand"))]
13247                    UNSPEC_SINCOS_COS))
13248    (set (match_operand:XF 1 "register_operand")
13249         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13250   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13251    && can_create_pseudo_p ()"
13252   [(set (match_dup 0)
13253         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13255 (define_expand "sincos<mode>3"
13256   [(use (match_operand:MODEF 0 "register_operand"))
13257    (use (match_operand:MODEF 1 "register_operand"))
13258    (use (match_operand:MODEF 2 "register_operand"))]
13259   "TARGET_USE_FANCY_MATH_387
13260    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13261        || TARGET_MIX_SSE_I387)
13262    && flag_unsafe_math_optimizations"
13264   rtx op0 = gen_reg_rtx (XFmode);
13265   rtx op1 = gen_reg_rtx (XFmode);
13267   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13268   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13269   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13270   DONE;
13273 (define_insn "fptanxf4_i387"
13274   [(set (match_operand:XF 0 "register_operand" "=f")
13275         (match_operand:XF 3 "const_double_operand" "F"))
13276    (set (match_operand:XF 1 "register_operand" "=u")
13277         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13278                    UNSPEC_TAN))]
13279   "TARGET_USE_FANCY_MATH_387
13280    && flag_unsafe_math_optimizations
13281    && standard_80387_constant_p (operands[3]) == 2"
13282   "fptan"
13283   [(set_attr "type" "fpspc")
13284    (set_attr "mode" "XF")])
13286 (define_insn "fptan_extend<mode>xf4_i387"
13287   [(set (match_operand:MODEF 0 "register_operand" "=f")
13288         (match_operand:MODEF 3 "const_double_operand" "F"))
13289    (set (match_operand:XF 1 "register_operand" "=u")
13290         (unspec:XF [(float_extend:XF
13291                       (match_operand:MODEF 2 "register_operand" "0"))]
13292                    UNSPEC_TAN))]
13293   "TARGET_USE_FANCY_MATH_387
13294    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13295        || TARGET_MIX_SSE_I387)
13296    && flag_unsafe_math_optimizations
13297    && standard_80387_constant_p (operands[3]) == 2"
13298   "fptan"
13299   [(set_attr "type" "fpspc")
13300    (set_attr "mode" "XF")])
13302 (define_expand "tanxf2"
13303   [(use (match_operand:XF 0 "register_operand"))
13304    (use (match_operand:XF 1 "register_operand"))]
13305   "TARGET_USE_FANCY_MATH_387
13306    && flag_unsafe_math_optimizations"
13308   rtx one = gen_reg_rtx (XFmode);
13309   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13311   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13312   DONE;
13315 (define_expand "tan<mode>2"
13316   [(use (match_operand:MODEF 0 "register_operand"))
13317    (use (match_operand:MODEF 1 "register_operand"))]
13318   "TARGET_USE_FANCY_MATH_387
13319    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13320        || TARGET_MIX_SSE_I387)
13321    && flag_unsafe_math_optimizations"
13323   rtx op0 = gen_reg_rtx (XFmode);
13325   rtx one = gen_reg_rtx (<MODE>mode);
13326   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13328   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13329                                              operands[1], op2));
13330   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13331   DONE;
13334 (define_insn "*fpatanxf3_i387"
13335   [(set (match_operand:XF 0 "register_operand" "=f")
13336         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13337                     (match_operand:XF 2 "register_operand" "u")]
13338                    UNSPEC_FPATAN))
13339    (clobber (match_scratch:XF 3 "=2"))]
13340   "TARGET_USE_FANCY_MATH_387
13341    && flag_unsafe_math_optimizations"
13342   "fpatan"
13343   [(set_attr "type" "fpspc")
13344    (set_attr "mode" "XF")])
13346 (define_insn "fpatan_extend<mode>xf3_i387"
13347   [(set (match_operand:XF 0 "register_operand" "=f")
13348         (unspec:XF [(float_extend:XF
13349                       (match_operand:MODEF 1 "register_operand" "0"))
13350                     (float_extend:XF
13351                       (match_operand:MODEF 2 "register_operand" "u"))]
13352                    UNSPEC_FPATAN))
13353    (clobber (match_scratch:XF 3 "=2"))]
13354   "TARGET_USE_FANCY_MATH_387
13355    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13356        || TARGET_MIX_SSE_I387)
13357    && flag_unsafe_math_optimizations"
13358   "fpatan"
13359   [(set_attr "type" "fpspc")
13360    (set_attr "mode" "XF")])
13362 (define_expand "atan2xf3"
13363   [(parallel [(set (match_operand:XF 0 "register_operand")
13364                    (unspec:XF [(match_operand:XF 2 "register_operand")
13365                                (match_operand:XF 1 "register_operand")]
13366                               UNSPEC_FPATAN))
13367               (clobber (match_scratch:XF 3))])]
13368   "TARGET_USE_FANCY_MATH_387
13369    && flag_unsafe_math_optimizations")
13371 (define_expand "atan2<mode>3"
13372   [(use (match_operand:MODEF 0 "register_operand"))
13373    (use (match_operand:MODEF 1 "register_operand"))
13374    (use (match_operand:MODEF 2 "register_operand"))]
13375   "TARGET_USE_FANCY_MATH_387
13376    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13377        || TARGET_MIX_SSE_I387)
13378    && flag_unsafe_math_optimizations"
13380   rtx op0 = gen_reg_rtx (XFmode);
13382   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13383   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13384   DONE;
13387 (define_expand "atanxf2"
13388   [(parallel [(set (match_operand:XF 0 "register_operand")
13389                    (unspec:XF [(match_dup 2)
13390                                (match_operand:XF 1 "register_operand")]
13391                               UNSPEC_FPATAN))
13392               (clobber (match_scratch:XF 3))])]
13393   "TARGET_USE_FANCY_MATH_387
13394    && flag_unsafe_math_optimizations"
13396   operands[2] = gen_reg_rtx (XFmode);
13397   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13400 (define_expand "atan<mode>2"
13401   [(use (match_operand:MODEF 0 "register_operand"))
13402    (use (match_operand:MODEF 1 "register_operand"))]
13403   "TARGET_USE_FANCY_MATH_387
13404    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13405        || TARGET_MIX_SSE_I387)
13406    && flag_unsafe_math_optimizations"
13408   rtx op0 = gen_reg_rtx (XFmode);
13410   rtx op2 = gen_reg_rtx (<MODE>mode);
13411   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13413   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13414   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13415   DONE;
13418 (define_expand "asinxf2"
13419   [(set (match_dup 2)
13420         (mult:XF (match_operand:XF 1 "register_operand")
13421                  (match_dup 1)))
13422    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13423    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13424    (parallel [(set (match_operand:XF 0 "register_operand")
13425                    (unspec:XF [(match_dup 5) (match_dup 1)]
13426                               UNSPEC_FPATAN))
13427               (clobber (match_scratch:XF 6))])]
13428   "TARGET_USE_FANCY_MATH_387
13429    && flag_unsafe_math_optimizations"
13431   int i;
13433   if (optimize_insn_for_size_p ())
13434     FAIL;
13436   for (i = 2; i < 6; i++)
13437     operands[i] = gen_reg_rtx (XFmode);
13439   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13442 (define_expand "asin<mode>2"
13443   [(use (match_operand:MODEF 0 "register_operand"))
13444    (use (match_operand:MODEF 1 "general_operand"))]
13445  "TARGET_USE_FANCY_MATH_387
13446    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13447        || TARGET_MIX_SSE_I387)
13448    && flag_unsafe_math_optimizations"
13450   rtx op0 = gen_reg_rtx (XFmode);
13451   rtx op1 = gen_reg_rtx (XFmode);
13453   if (optimize_insn_for_size_p ())
13454     FAIL;
13456   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13457   emit_insn (gen_asinxf2 (op0, op1));
13458   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13459   DONE;
13462 (define_expand "acosxf2"
13463   [(set (match_dup 2)
13464         (mult:XF (match_operand:XF 1 "register_operand")
13465                  (match_dup 1)))
13466    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13467    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13468    (parallel [(set (match_operand:XF 0 "register_operand")
13469                    (unspec:XF [(match_dup 1) (match_dup 5)]
13470                               UNSPEC_FPATAN))
13471               (clobber (match_scratch:XF 6))])]
13472   "TARGET_USE_FANCY_MATH_387
13473    && flag_unsafe_math_optimizations"
13475   int i;
13477   if (optimize_insn_for_size_p ())
13478     FAIL;
13480   for (i = 2; i < 6; i++)
13481     operands[i] = gen_reg_rtx (XFmode);
13483   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13486 (define_expand "acos<mode>2"
13487   [(use (match_operand:MODEF 0 "register_operand"))
13488    (use (match_operand:MODEF 1 "general_operand"))]
13489  "TARGET_USE_FANCY_MATH_387
13490    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13491        || TARGET_MIX_SSE_I387)
13492    && flag_unsafe_math_optimizations"
13494   rtx op0 = gen_reg_rtx (XFmode);
13495   rtx op1 = gen_reg_rtx (XFmode);
13497   if (optimize_insn_for_size_p ())
13498     FAIL;
13500   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13501   emit_insn (gen_acosxf2 (op0, op1));
13502   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13503   DONE;
13506 (define_insn "fyl2xxf3_i387"
13507   [(set (match_operand:XF 0 "register_operand" "=f")
13508         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13509                     (match_operand:XF 2 "register_operand" "u")]
13510                    UNSPEC_FYL2X))
13511    (clobber (match_scratch:XF 3 "=2"))]
13512   "TARGET_USE_FANCY_MATH_387
13513    && flag_unsafe_math_optimizations"
13514   "fyl2x"
13515   [(set_attr "type" "fpspc")
13516    (set_attr "mode" "XF")])
13518 (define_insn "fyl2x_extend<mode>xf3_i387"
13519   [(set (match_operand:XF 0 "register_operand" "=f")
13520         (unspec:XF [(float_extend:XF
13521                       (match_operand:MODEF 1 "register_operand" "0"))
13522                     (match_operand:XF 2 "register_operand" "u")]
13523                    UNSPEC_FYL2X))
13524    (clobber (match_scratch:XF 3 "=2"))]
13525   "TARGET_USE_FANCY_MATH_387
13526    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13527        || TARGET_MIX_SSE_I387)
13528    && flag_unsafe_math_optimizations"
13529   "fyl2x"
13530   [(set_attr "type" "fpspc")
13531    (set_attr "mode" "XF")])
13533 (define_expand "logxf2"
13534   [(parallel [(set (match_operand:XF 0 "register_operand")
13535                    (unspec:XF [(match_operand:XF 1 "register_operand")
13536                                (match_dup 2)] UNSPEC_FYL2X))
13537               (clobber (match_scratch:XF 3))])]
13538   "TARGET_USE_FANCY_MATH_387
13539    && flag_unsafe_math_optimizations"
13541   operands[2] = gen_reg_rtx (XFmode);
13542   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13545 (define_expand "log<mode>2"
13546   [(use (match_operand:MODEF 0 "register_operand"))
13547    (use (match_operand:MODEF 1 "register_operand"))]
13548   "TARGET_USE_FANCY_MATH_387
13549    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13550        || TARGET_MIX_SSE_I387)
13551    && flag_unsafe_math_optimizations"
13553   rtx op0 = gen_reg_rtx (XFmode);
13555   rtx op2 = gen_reg_rtx (XFmode);
13556   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13558   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13559   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13560   DONE;
13563 (define_expand "log10xf2"
13564   [(parallel [(set (match_operand:XF 0 "register_operand")
13565                    (unspec:XF [(match_operand:XF 1 "register_operand")
13566                                (match_dup 2)] UNSPEC_FYL2X))
13567               (clobber (match_scratch:XF 3))])]
13568   "TARGET_USE_FANCY_MATH_387
13569    && flag_unsafe_math_optimizations"
13571   operands[2] = gen_reg_rtx (XFmode);
13572   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13575 (define_expand "log10<mode>2"
13576   [(use (match_operand:MODEF 0 "register_operand"))
13577    (use (match_operand:MODEF 1 "register_operand"))]
13578   "TARGET_USE_FANCY_MATH_387
13579    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13580        || TARGET_MIX_SSE_I387)
13581    && flag_unsafe_math_optimizations"
13583   rtx op0 = gen_reg_rtx (XFmode);
13585   rtx op2 = gen_reg_rtx (XFmode);
13586   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13588   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13589   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13590   DONE;
13593 (define_expand "log2xf2"
13594   [(parallel [(set (match_operand:XF 0 "register_operand")
13595                    (unspec:XF [(match_operand:XF 1 "register_operand")
13596                                (match_dup 2)] UNSPEC_FYL2X))
13597               (clobber (match_scratch:XF 3))])]
13598   "TARGET_USE_FANCY_MATH_387
13599    && flag_unsafe_math_optimizations"
13601   operands[2] = gen_reg_rtx (XFmode);
13602   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13605 (define_expand "log2<mode>2"
13606   [(use (match_operand:MODEF 0 "register_operand"))
13607    (use (match_operand:MODEF 1 "register_operand"))]
13608   "TARGET_USE_FANCY_MATH_387
13609    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13610        || TARGET_MIX_SSE_I387)
13611    && flag_unsafe_math_optimizations"
13613   rtx op0 = gen_reg_rtx (XFmode);
13615   rtx op2 = gen_reg_rtx (XFmode);
13616   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13618   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13619   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13620   DONE;
13623 (define_insn "fyl2xp1xf3_i387"
13624   [(set (match_operand:XF 0 "register_operand" "=f")
13625         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13626                     (match_operand:XF 2 "register_operand" "u")]
13627                    UNSPEC_FYL2XP1))
13628    (clobber (match_scratch:XF 3 "=2"))]
13629   "TARGET_USE_FANCY_MATH_387
13630    && flag_unsafe_math_optimizations"
13631   "fyl2xp1"
13632   [(set_attr "type" "fpspc")
13633    (set_attr "mode" "XF")])
13635 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13636   [(set (match_operand:XF 0 "register_operand" "=f")
13637         (unspec:XF [(float_extend:XF
13638                       (match_operand:MODEF 1 "register_operand" "0"))
13639                     (match_operand:XF 2 "register_operand" "u")]
13640                    UNSPEC_FYL2XP1))
13641    (clobber (match_scratch:XF 3 "=2"))]
13642   "TARGET_USE_FANCY_MATH_387
13643    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13644        || TARGET_MIX_SSE_I387)
13645    && flag_unsafe_math_optimizations"
13646   "fyl2xp1"
13647   [(set_attr "type" "fpspc")
13648    (set_attr "mode" "XF")])
13650 (define_expand "log1pxf2"
13651   [(use (match_operand:XF 0 "register_operand"))
13652    (use (match_operand:XF 1 "register_operand"))]
13653   "TARGET_USE_FANCY_MATH_387
13654    && flag_unsafe_math_optimizations"
13656   if (optimize_insn_for_size_p ())
13657     FAIL;
13659   ix86_emit_i387_log1p (operands[0], operands[1]);
13660   DONE;
13663 (define_expand "log1p<mode>2"
13664   [(use (match_operand:MODEF 0 "register_operand"))
13665    (use (match_operand:MODEF 1 "register_operand"))]
13666   "TARGET_USE_FANCY_MATH_387
13667    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13668        || TARGET_MIX_SSE_I387)
13669    && flag_unsafe_math_optimizations"
13671   rtx op0;
13673   if (optimize_insn_for_size_p ())
13674     FAIL;
13676   op0 = gen_reg_rtx (XFmode);
13678   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13680   ix86_emit_i387_log1p (op0, operands[1]);
13681   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13682   DONE;
13685 (define_insn "fxtractxf3_i387"
13686   [(set (match_operand:XF 0 "register_operand" "=f")
13687         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13688                    UNSPEC_XTRACT_FRACT))
13689    (set (match_operand:XF 1 "register_operand" "=u")
13690         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13691   "TARGET_USE_FANCY_MATH_387
13692    && flag_unsafe_math_optimizations"
13693   "fxtract"
13694   [(set_attr "type" "fpspc")
13695    (set_attr "mode" "XF")])
13697 (define_insn "fxtract_extend<mode>xf3_i387"
13698   [(set (match_operand:XF 0 "register_operand" "=f")
13699         (unspec:XF [(float_extend:XF
13700                       (match_operand:MODEF 2 "register_operand" "0"))]
13701                    UNSPEC_XTRACT_FRACT))
13702    (set (match_operand:XF 1 "register_operand" "=u")
13703         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13704   "TARGET_USE_FANCY_MATH_387
13705    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13706        || TARGET_MIX_SSE_I387)
13707    && flag_unsafe_math_optimizations"
13708   "fxtract"
13709   [(set_attr "type" "fpspc")
13710    (set_attr "mode" "XF")])
13712 (define_expand "logbxf2"
13713   [(parallel [(set (match_dup 2)
13714                    (unspec:XF [(match_operand:XF 1 "register_operand")]
13715                               UNSPEC_XTRACT_FRACT))
13716               (set (match_operand:XF 0 "register_operand")
13717                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13718   "TARGET_USE_FANCY_MATH_387
13719    && flag_unsafe_math_optimizations"
13720   "operands[2] = gen_reg_rtx (XFmode);")
13722 (define_expand "logb<mode>2"
13723   [(use (match_operand:MODEF 0 "register_operand"))
13724    (use (match_operand:MODEF 1 "register_operand"))]
13725   "TARGET_USE_FANCY_MATH_387
13726    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13727        || TARGET_MIX_SSE_I387)
13728    && flag_unsafe_math_optimizations"
13730   rtx op0 = gen_reg_rtx (XFmode);
13731   rtx op1 = gen_reg_rtx (XFmode);
13733   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13734   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13735   DONE;
13738 (define_expand "ilogbxf2"
13739   [(use (match_operand:SI 0 "register_operand"))
13740    (use (match_operand:XF 1 "register_operand"))]
13741   "TARGET_USE_FANCY_MATH_387
13742    && flag_unsafe_math_optimizations"
13744   rtx op0, op1;
13746   if (optimize_insn_for_size_p ())
13747     FAIL;
13749   op0 = gen_reg_rtx (XFmode);
13750   op1 = gen_reg_rtx (XFmode);
13752   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13753   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13754   DONE;
13757 (define_expand "ilogb<mode>2"
13758   [(use (match_operand:SI 0 "register_operand"))
13759    (use (match_operand:MODEF 1 "register_operand"))]
13760   "TARGET_USE_FANCY_MATH_387
13761    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13762        || TARGET_MIX_SSE_I387)
13763    && flag_unsafe_math_optimizations"
13765   rtx op0, op1;
13767   if (optimize_insn_for_size_p ())
13768     FAIL;
13770   op0 = gen_reg_rtx (XFmode);
13771   op1 = gen_reg_rtx (XFmode);
13773   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13774   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13775   DONE;
13778 (define_insn "*f2xm1xf2_i387"
13779   [(set (match_operand:XF 0 "register_operand" "=f")
13780         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13781                    UNSPEC_F2XM1))]
13782   "TARGET_USE_FANCY_MATH_387
13783    && flag_unsafe_math_optimizations"
13784   "f2xm1"
13785   [(set_attr "type" "fpspc")
13786    (set_attr "mode" "XF")])
13788 (define_insn "*fscalexf4_i387"
13789   [(set (match_operand:XF 0 "register_operand" "=f")
13790         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13791                     (match_operand:XF 3 "register_operand" "1")]
13792                    UNSPEC_FSCALE_FRACT))
13793    (set (match_operand:XF 1 "register_operand" "=u")
13794         (unspec:XF [(match_dup 2) (match_dup 3)]
13795                    UNSPEC_FSCALE_EXP))]
13796   "TARGET_USE_FANCY_MATH_387
13797    && flag_unsafe_math_optimizations"
13798   "fscale"
13799   [(set_attr "type" "fpspc")
13800    (set_attr "mode" "XF")])
13802 (define_expand "expNcorexf3"
13803   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
13804                                (match_operand:XF 2 "register_operand")))
13805    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13806    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13807    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13808    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13809    (parallel [(set (match_operand:XF 0 "register_operand")
13810                    (unspec:XF [(match_dup 8) (match_dup 4)]
13811                               UNSPEC_FSCALE_FRACT))
13812               (set (match_dup 9)
13813                    (unspec:XF [(match_dup 8) (match_dup 4)]
13814                               UNSPEC_FSCALE_EXP))])]
13815   "TARGET_USE_FANCY_MATH_387
13816    && flag_unsafe_math_optimizations"
13818   int i;
13820   if (optimize_insn_for_size_p ())
13821     FAIL;
13823   for (i = 3; i < 10; i++)
13824     operands[i] = gen_reg_rtx (XFmode);
13826   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
13829 (define_expand "expxf2"
13830   [(use (match_operand:XF 0 "register_operand"))
13831    (use (match_operand:XF 1 "register_operand"))]
13832   "TARGET_USE_FANCY_MATH_387
13833    && flag_unsafe_math_optimizations"
13835   rtx op2;
13837   if (optimize_insn_for_size_p ())
13838     FAIL;
13840   op2 = gen_reg_rtx (XFmode);
13841   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13843   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13844   DONE;
13847 (define_expand "exp<mode>2"
13848   [(use (match_operand:MODEF 0 "register_operand"))
13849    (use (match_operand:MODEF 1 "general_operand"))]
13850  "TARGET_USE_FANCY_MATH_387
13851    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13852        || TARGET_MIX_SSE_I387)
13853    && flag_unsafe_math_optimizations"
13855   rtx op0, op1;
13857   if (optimize_insn_for_size_p ())
13858     FAIL;
13860   op0 = gen_reg_rtx (XFmode);
13861   op1 = gen_reg_rtx (XFmode);
13863   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13864   emit_insn (gen_expxf2 (op0, op1));
13865   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13866   DONE;
13869 (define_expand "exp10xf2"
13870   [(use (match_operand:XF 0 "register_operand"))
13871    (use (match_operand:XF 1 "register_operand"))]
13872   "TARGET_USE_FANCY_MATH_387
13873    && flag_unsafe_math_optimizations"
13875   rtx op2;
13877   if (optimize_insn_for_size_p ())
13878     FAIL;
13880   op2 = gen_reg_rtx (XFmode);
13881   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13883   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13884   DONE;
13887 (define_expand "exp10<mode>2"
13888   [(use (match_operand:MODEF 0 "register_operand"))
13889    (use (match_operand:MODEF 1 "general_operand"))]
13890  "TARGET_USE_FANCY_MATH_387
13891    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13892        || TARGET_MIX_SSE_I387)
13893    && flag_unsafe_math_optimizations"
13895   rtx op0, op1;
13897   if (optimize_insn_for_size_p ())
13898     FAIL;
13900   op0 = gen_reg_rtx (XFmode);
13901   op1 = gen_reg_rtx (XFmode);
13903   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13904   emit_insn (gen_exp10xf2 (op0, op1));
13905   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13906   DONE;
13909 (define_expand "exp2xf2"
13910   [(use (match_operand:XF 0 "register_operand"))
13911    (use (match_operand:XF 1 "register_operand"))]
13912   "TARGET_USE_FANCY_MATH_387
13913    && flag_unsafe_math_optimizations"
13915   rtx op2;
13917   if (optimize_insn_for_size_p ())
13918     FAIL;
13920   op2 = gen_reg_rtx (XFmode);
13921   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
13923   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13924   DONE;
13927 (define_expand "exp2<mode>2"
13928   [(use (match_operand:MODEF 0 "register_operand"))
13929    (use (match_operand:MODEF 1 "general_operand"))]
13930  "TARGET_USE_FANCY_MATH_387
13931    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13932        || TARGET_MIX_SSE_I387)
13933    && flag_unsafe_math_optimizations"
13935   rtx op0, op1;
13937   if (optimize_insn_for_size_p ())
13938     FAIL;
13940   op0 = gen_reg_rtx (XFmode);
13941   op1 = gen_reg_rtx (XFmode);
13943   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13944   emit_insn (gen_exp2xf2 (op0, op1));
13945   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13946   DONE;
13949 (define_expand "expm1xf2"
13950   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
13951                                (match_dup 2)))
13952    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13953    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13954    (set (match_dup 9) (float_extend:XF (match_dup 13)))
13955    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13956    (parallel [(set (match_dup 7)
13957                    (unspec:XF [(match_dup 6) (match_dup 4)]
13958                               UNSPEC_FSCALE_FRACT))
13959               (set (match_dup 8)
13960                    (unspec:XF [(match_dup 6) (match_dup 4)]
13961                               UNSPEC_FSCALE_EXP))])
13962    (parallel [(set (match_dup 10)
13963                    (unspec:XF [(match_dup 9) (match_dup 8)]
13964                               UNSPEC_FSCALE_FRACT))
13965               (set (match_dup 11)
13966                    (unspec:XF [(match_dup 9) (match_dup 8)]
13967                               UNSPEC_FSCALE_EXP))])
13968    (set (match_dup 12) (minus:XF (match_dup 10)
13969                                  (float_extend:XF (match_dup 13))))
13970    (set (match_operand:XF 0 "register_operand")
13971         (plus:XF (match_dup 12) (match_dup 7)))]
13972   "TARGET_USE_FANCY_MATH_387
13973    && flag_unsafe_math_optimizations"
13975   int i;
13977   if (optimize_insn_for_size_p ())
13978     FAIL;
13980   for (i = 2; i < 13; i++)
13981     operands[i] = gen_reg_rtx (XFmode);
13983   operands[13]
13984     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
13986   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
13989 (define_expand "expm1<mode>2"
13990   [(use (match_operand:MODEF 0 "register_operand"))
13991    (use (match_operand:MODEF 1 "general_operand"))]
13992  "TARGET_USE_FANCY_MATH_387
13993    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13994        || TARGET_MIX_SSE_I387)
13995    && flag_unsafe_math_optimizations"
13997   rtx op0, op1;
13999   if (optimize_insn_for_size_p ())
14000     FAIL;
14002   op0 = gen_reg_rtx (XFmode);
14003   op1 = gen_reg_rtx (XFmode);
14005   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14006   emit_insn (gen_expm1xf2 (op0, op1));
14007   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14008   DONE;
14011 (define_expand "ldexpxf3"
14012   [(set (match_dup 3)
14013         (float:XF (match_operand:SI 2 "register_operand")))
14014    (parallel [(set (match_operand:XF 0 " register_operand")
14015                    (unspec:XF [(match_operand:XF 1 "register_operand")
14016                                (match_dup 3)]
14017                               UNSPEC_FSCALE_FRACT))
14018               (set (match_dup 4)
14019                    (unspec:XF [(match_dup 1) (match_dup 3)]
14020                               UNSPEC_FSCALE_EXP))])]
14021   "TARGET_USE_FANCY_MATH_387
14022    && flag_unsafe_math_optimizations"
14024   if (optimize_insn_for_size_p ())
14025     FAIL;
14027   operands[3] = gen_reg_rtx (XFmode);
14028   operands[4] = gen_reg_rtx (XFmode);
14031 (define_expand "ldexp<mode>3"
14032   [(use (match_operand:MODEF 0 "register_operand"))
14033    (use (match_operand:MODEF 1 "general_operand"))
14034    (use (match_operand:SI 2 "register_operand"))]
14035  "TARGET_USE_FANCY_MATH_387
14036    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14037        || TARGET_MIX_SSE_I387)
14038    && flag_unsafe_math_optimizations"
14040   rtx op0, op1;
14042   if (optimize_insn_for_size_p ())
14043     FAIL;
14045   op0 = gen_reg_rtx (XFmode);
14046   op1 = gen_reg_rtx (XFmode);
14048   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14049   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14050   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14051   DONE;
14054 (define_expand "scalbxf3"
14055   [(parallel [(set (match_operand:XF 0 " register_operand")
14056                    (unspec:XF [(match_operand:XF 1 "register_operand")
14057                                (match_operand:XF 2 "register_operand")]
14058                               UNSPEC_FSCALE_FRACT))
14059               (set (match_dup 3)
14060                    (unspec:XF [(match_dup 1) (match_dup 2)]
14061                               UNSPEC_FSCALE_EXP))])]
14062   "TARGET_USE_FANCY_MATH_387
14063    && flag_unsafe_math_optimizations"
14065   if (optimize_insn_for_size_p ())
14066     FAIL;
14068   operands[3] = gen_reg_rtx (XFmode);
14071 (define_expand "scalb<mode>3"
14072   [(use (match_operand:MODEF 0 "register_operand"))
14073    (use (match_operand:MODEF 1 "general_operand"))
14074    (use (match_operand:MODEF 2 "general_operand"))]
14075  "TARGET_USE_FANCY_MATH_387
14076    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14077        || TARGET_MIX_SSE_I387)
14078    && flag_unsafe_math_optimizations"
14080   rtx op0, op1, op2;
14082   if (optimize_insn_for_size_p ())
14083     FAIL;
14085   op0 = gen_reg_rtx (XFmode);
14086   op1 = gen_reg_rtx (XFmode);
14087   op2 = gen_reg_rtx (XFmode);
14089   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14090   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14091   emit_insn (gen_scalbxf3 (op0, op1, op2));
14092   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14093   DONE;
14096 (define_expand "significandxf2"
14097   [(parallel [(set (match_operand:XF 0 "register_operand")
14098                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14099                               UNSPEC_XTRACT_FRACT))
14100               (set (match_dup 2)
14101                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14102   "TARGET_USE_FANCY_MATH_387
14103    && flag_unsafe_math_optimizations"
14104   "operands[2] = gen_reg_rtx (XFmode);")
14106 (define_expand "significand<mode>2"
14107   [(use (match_operand:MODEF 0 "register_operand"))
14108    (use (match_operand:MODEF 1 "register_operand"))]
14109   "TARGET_USE_FANCY_MATH_387
14110    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14111        || TARGET_MIX_SSE_I387)
14112    && flag_unsafe_math_optimizations"
14114   rtx op0 = gen_reg_rtx (XFmode);
14115   rtx op1 = gen_reg_rtx (XFmode);
14117   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14118   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14119   DONE;
14123 (define_insn "sse4_1_round<mode>2"
14124   [(set (match_operand:MODEF 0 "register_operand" "=x")
14125         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14126                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14127                       UNSPEC_ROUND))]
14128   "TARGET_ROUND"
14129   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14130   [(set_attr "type" "ssecvt")
14131    (set_attr "prefix_extra" "1")
14132    (set_attr "prefix" "maybe_vex")
14133    (set_attr "mode" "<MODE>")])
14135 (define_insn "rintxf2"
14136   [(set (match_operand:XF 0 "register_operand" "=f")
14137         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14138                    UNSPEC_FRNDINT))]
14139   "TARGET_USE_FANCY_MATH_387
14140    && flag_unsafe_math_optimizations"
14141   "frndint"
14142   [(set_attr "type" "fpspc")
14143    (set_attr "mode" "XF")])
14145 (define_expand "rint<mode>2"
14146   [(use (match_operand:MODEF 0 "register_operand"))
14147    (use (match_operand:MODEF 1 "register_operand"))]
14148   "(TARGET_USE_FANCY_MATH_387
14149     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14150         || TARGET_MIX_SSE_I387)
14151     && flag_unsafe_math_optimizations)
14152    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14153        && !flag_trapping_math)"
14155   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14156       && !flag_trapping_math)
14157     {
14158       if (TARGET_ROUND)
14159         emit_insn (gen_sse4_1_round<mode>2
14160                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14161       else if (optimize_insn_for_size_p ())
14162         FAIL;
14163       else
14164         ix86_expand_rint (operands[0], operands[1]);
14165     }
14166   else
14167     {
14168       rtx op0 = gen_reg_rtx (XFmode);
14169       rtx op1 = gen_reg_rtx (XFmode);
14171       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14172       emit_insn (gen_rintxf2 (op0, op1));
14174       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14175     }
14176   DONE;
14179 (define_expand "round<mode>2"
14180   [(match_operand:X87MODEF 0 "register_operand")
14181    (match_operand:X87MODEF 1 "nonimmediate_operand")]
14182   "(TARGET_USE_FANCY_MATH_387
14183     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14184         || TARGET_MIX_SSE_I387)
14185     && flag_unsafe_math_optimizations)
14186    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14187        && !flag_trapping_math && !flag_rounding_math)"
14189   if (optimize_insn_for_size_p ())
14190     FAIL;
14192   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14193       && !flag_trapping_math && !flag_rounding_math)
14194     {
14195       if (TARGET_ROUND)
14196         {
14197           operands[1] = force_reg (<MODE>mode, operands[1]);
14198           ix86_expand_round_sse4 (operands[0], operands[1]);
14199         }
14200       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14201         ix86_expand_round (operands[0], operands[1]);
14202       else
14203         ix86_expand_rounddf_32 (operands[0], operands[1]);
14204     }
14205   else
14206     {
14207       operands[1] = force_reg (<MODE>mode, operands[1]);
14208       ix86_emit_i387_round (operands[0], operands[1]);
14209     }
14210   DONE;
14213 (define_insn_and_split "*fistdi2_1"
14214   [(set (match_operand:DI 0 "nonimmediate_operand")
14215         (unspec:DI [(match_operand:XF 1 "register_operand")]
14216                    UNSPEC_FIST))]
14217   "TARGET_USE_FANCY_MATH_387
14218    && can_create_pseudo_p ()"
14219   "#"
14220   "&& 1"
14221   [(const_int 0)]
14223   if (memory_operand (operands[0], VOIDmode))
14224     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14225   else
14226     {
14227       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14228       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14229                                          operands[2]));
14230     }
14231   DONE;
14233   [(set_attr "type" "fpspc")
14234    (set_attr "mode" "DI")])
14236 (define_insn "fistdi2"
14237   [(set (match_operand:DI 0 "memory_operand" "=m")
14238         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14239                    UNSPEC_FIST))
14240    (clobber (match_scratch:XF 2 "=&1f"))]
14241   "TARGET_USE_FANCY_MATH_387"
14242   "* return output_fix_trunc (insn, operands, false);"
14243   [(set_attr "type" "fpspc")
14244    (set_attr "mode" "DI")])
14246 (define_insn "fistdi2_with_temp"
14247   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14248         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14249                    UNSPEC_FIST))
14250    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14251    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14252   "TARGET_USE_FANCY_MATH_387"
14253   "#"
14254   [(set_attr "type" "fpspc")
14255    (set_attr "mode" "DI")])
14257 (define_split
14258   [(set (match_operand:DI 0 "register_operand")
14259         (unspec:DI [(match_operand:XF 1 "register_operand")]
14260                    UNSPEC_FIST))
14261    (clobber (match_operand:DI 2 "memory_operand"))
14262    (clobber (match_scratch 3))]
14263   "reload_completed"
14264   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14265               (clobber (match_dup 3))])
14266    (set (match_dup 0) (match_dup 2))])
14268 (define_split
14269   [(set (match_operand:DI 0 "memory_operand")
14270         (unspec:DI [(match_operand:XF 1 "register_operand")]
14271                    UNSPEC_FIST))
14272    (clobber (match_operand:DI 2 "memory_operand"))
14273    (clobber (match_scratch 3))]
14274   "reload_completed"
14275   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14276               (clobber (match_dup 3))])])
14278 (define_insn_and_split "*fist<mode>2_1"
14279   [(set (match_operand:SWI24 0 "register_operand")
14280         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14281                       UNSPEC_FIST))]
14282   "TARGET_USE_FANCY_MATH_387
14283    && can_create_pseudo_p ()"
14284   "#"
14285   "&& 1"
14286   [(const_int 0)]
14288   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14289   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14290                                         operands[2]));
14291   DONE;
14293   [(set_attr "type" "fpspc")
14294    (set_attr "mode" "<MODE>")])
14296 (define_insn "fist<mode>2"
14297   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14298         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14299                       UNSPEC_FIST))]
14300   "TARGET_USE_FANCY_MATH_387"
14301   "* return output_fix_trunc (insn, operands, false);"
14302   [(set_attr "type" "fpspc")
14303    (set_attr "mode" "<MODE>")])
14305 (define_insn "fist<mode>2_with_temp"
14306   [(set (match_operand:SWI24 0 "register_operand" "=r")
14307         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14308                       UNSPEC_FIST))
14309    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14310   "TARGET_USE_FANCY_MATH_387"
14311   "#"
14312   [(set_attr "type" "fpspc")
14313    (set_attr "mode" "<MODE>")])
14315 (define_split
14316   [(set (match_operand:SWI24 0 "register_operand")
14317         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14318                       UNSPEC_FIST))
14319    (clobber (match_operand:SWI24 2 "memory_operand"))]
14320   "reload_completed"
14321   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14322    (set (match_dup 0) (match_dup 2))])
14324 (define_split
14325   [(set (match_operand:SWI24 0 "memory_operand")
14326         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14327                       UNSPEC_FIST))
14328    (clobber (match_operand:SWI24 2 "memory_operand"))]
14329   "reload_completed"
14330   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14332 (define_expand "lrintxf<mode>2"
14333   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14334      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14335                      UNSPEC_FIST))]
14336   "TARGET_USE_FANCY_MATH_387")
14338 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
14339   [(set (match_operand:SWI48 0 "nonimmediate_operand")
14340      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
14341                    UNSPEC_FIX_NOTRUNC))]
14342   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
14344 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14345   [(match_operand:SWI248x 0 "nonimmediate_operand")
14346    (match_operand:X87MODEF 1 "register_operand")]
14347   "(TARGET_USE_FANCY_MATH_387
14348     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14349         || TARGET_MIX_SSE_I387)
14350     && flag_unsafe_math_optimizations)
14351    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14352        && <SWI248x:MODE>mode != HImode 
14353        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14354        && !flag_trapping_math && !flag_rounding_math)"
14356   if (optimize_insn_for_size_p ())
14357     FAIL;
14359   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14360       && <SWI248x:MODE>mode != HImode
14361       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14362       && !flag_trapping_math && !flag_rounding_math)
14363     ix86_expand_lround (operands[0], operands[1]);
14364   else
14365     ix86_emit_i387_round (operands[0], operands[1]);
14366   DONE;
14369 (define_int_iterator FRNDINT_ROUNDING
14370         [UNSPEC_FRNDINT_FLOOR
14371          UNSPEC_FRNDINT_CEIL
14372          UNSPEC_FRNDINT_TRUNC])
14374 (define_int_iterator FIST_ROUNDING
14375         [UNSPEC_FIST_FLOOR
14376          UNSPEC_FIST_CEIL])
14378 ;; Base name for define_insn
14379 (define_int_attr rounding_insn
14380         [(UNSPEC_FRNDINT_FLOOR "floor")
14381          (UNSPEC_FRNDINT_CEIL "ceil")
14382          (UNSPEC_FRNDINT_TRUNC "btrunc")
14383          (UNSPEC_FIST_FLOOR "floor")
14384          (UNSPEC_FIST_CEIL "ceil")])
14386 (define_int_attr rounding
14387         [(UNSPEC_FRNDINT_FLOOR "floor")
14388          (UNSPEC_FRNDINT_CEIL "ceil")
14389          (UNSPEC_FRNDINT_TRUNC "trunc")
14390          (UNSPEC_FIST_FLOOR "floor")
14391          (UNSPEC_FIST_CEIL "ceil")])
14393 (define_int_attr ROUNDING
14394         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
14395          (UNSPEC_FRNDINT_CEIL "CEIL")
14396          (UNSPEC_FRNDINT_TRUNC "TRUNC")
14397          (UNSPEC_FIST_FLOOR "FLOOR")
14398          (UNSPEC_FIST_CEIL "CEIL")])
14400 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14401 (define_insn_and_split "frndintxf2_<rounding>"
14402   [(set (match_operand:XF 0 "register_operand")
14403         (unspec:XF [(match_operand:XF 1 "register_operand")]
14404                    FRNDINT_ROUNDING))
14405    (clobber (reg:CC FLAGS_REG))]
14406   "TARGET_USE_FANCY_MATH_387
14407    && flag_unsafe_math_optimizations
14408    && can_create_pseudo_p ()"
14409   "#"
14410   "&& 1"
14411   [(const_int 0)]
14413   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
14415   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14416   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
14418   emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
14419                                              operands[2], operands[3]));
14420   DONE;
14422   [(set_attr "type" "frndint")
14423    (set_attr "i387_cw" "<rounding>")
14424    (set_attr "mode" "XF")])
14426 (define_insn "frndintxf2_<rounding>_i387"
14427   [(set (match_operand:XF 0 "register_operand" "=f")
14428         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14429                    FRNDINT_ROUNDING))
14430    (use (match_operand:HI 2 "memory_operand" "m"))
14431    (use (match_operand:HI 3 "memory_operand" "m"))]
14432   "TARGET_USE_FANCY_MATH_387
14433    && flag_unsafe_math_optimizations"
14434   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14435   [(set_attr "type" "frndint")
14436    (set_attr "i387_cw" "<rounding>")
14437    (set_attr "mode" "XF")])
14439 (define_expand "<rounding_insn>xf2"
14440   [(parallel [(set (match_operand:XF 0 "register_operand")
14441                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14442                               FRNDINT_ROUNDING))
14443               (clobber (reg:CC FLAGS_REG))])]
14444   "TARGET_USE_FANCY_MATH_387
14445    && flag_unsafe_math_optimizations
14446    && !optimize_insn_for_size_p ()")
14448 (define_expand "<rounding_insn><mode>2"
14449   [(parallel [(set (match_operand:MODEF 0 "register_operand")
14450                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
14451                                  FRNDINT_ROUNDING))
14452               (clobber (reg:CC FLAGS_REG))])]
14453   "(TARGET_USE_FANCY_MATH_387
14454     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14455         || TARGET_MIX_SSE_I387)
14456     && flag_unsafe_math_optimizations)
14457    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14458        && !flag_trapping_math)"
14460   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14461       && !flag_trapping_math)
14462     {
14463       if (TARGET_ROUND)
14464         emit_insn (gen_sse4_1_round<mode>2
14465                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
14466       else if (optimize_insn_for_size_p ())
14467         FAIL;
14468       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14469         {
14470           if (ROUND_<ROUNDING> == ROUND_FLOOR)
14471             ix86_expand_floorceil (operands[0], operands[1], true);
14472           else if (ROUND_<ROUNDING> == ROUND_CEIL)
14473             ix86_expand_floorceil (operands[0], operands[1], false);
14474           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
14475             ix86_expand_trunc (operands[0], operands[1]);
14476           else
14477             gcc_unreachable ();
14478         }
14479       else
14480         {
14481           if (ROUND_<ROUNDING> == ROUND_FLOOR)
14482             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14483           else if (ROUND_<ROUNDING> == ROUND_CEIL)
14484             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
14485           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
14486             ix86_expand_truncdf_32 (operands[0], operands[1]);
14487           else
14488             gcc_unreachable ();
14489         }
14490     }
14491   else
14492     {
14493       rtx op0, op1;
14495       if (optimize_insn_for_size_p ())
14496         FAIL;
14498       op0 = gen_reg_rtx (XFmode);
14499       op1 = gen_reg_rtx (XFmode);
14500       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14501       emit_insn (gen_frndintxf2_<rounding> (op0, op1));
14503       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14504     }
14505   DONE;
14508 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14509 (define_insn_and_split "frndintxf2_mask_pm"
14510   [(set (match_operand:XF 0 "register_operand")
14511         (unspec:XF [(match_operand:XF 1 "register_operand")]
14512                    UNSPEC_FRNDINT_MASK_PM))
14513    (clobber (reg:CC FLAGS_REG))]
14514   "TARGET_USE_FANCY_MATH_387
14515    && flag_unsafe_math_optimizations
14516    && can_create_pseudo_p ()"
14517   "#"
14518   "&& 1"
14519   [(const_int 0)]
14521   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14523   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14524   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14526   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14527                                           operands[2], operands[3]));
14528   DONE;
14530   [(set_attr "type" "frndint")
14531    (set_attr "i387_cw" "mask_pm")
14532    (set_attr "mode" "XF")])
14534 (define_insn "frndintxf2_mask_pm_i387"
14535   [(set (match_operand:XF 0 "register_operand" "=f")
14536         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14537                    UNSPEC_FRNDINT_MASK_PM))
14538    (use (match_operand:HI 2 "memory_operand" "m"))
14539    (use (match_operand:HI 3 "memory_operand" "m"))]
14540   "TARGET_USE_FANCY_MATH_387
14541    && flag_unsafe_math_optimizations"
14542   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14543   [(set_attr "type" "frndint")
14544    (set_attr "i387_cw" "mask_pm")
14545    (set_attr "mode" "XF")])
14547 (define_expand "nearbyintxf2"
14548   [(parallel [(set (match_operand:XF 0 "register_operand")
14549                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14550                               UNSPEC_FRNDINT_MASK_PM))
14551               (clobber (reg:CC FLAGS_REG))])]
14552   "TARGET_USE_FANCY_MATH_387
14553    && flag_unsafe_math_optimizations")
14555 (define_expand "nearbyint<mode>2"
14556   [(use (match_operand:MODEF 0 "register_operand"))
14557    (use (match_operand:MODEF 1 "register_operand"))]
14558   "TARGET_USE_FANCY_MATH_387
14559    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14560        || TARGET_MIX_SSE_I387)
14561    && flag_unsafe_math_optimizations"
14563   rtx op0 = gen_reg_rtx (XFmode);
14564   rtx op1 = gen_reg_rtx (XFmode);
14566   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14567   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
14569   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14570   DONE;
14573 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14574 (define_insn_and_split "*fist<mode>2_<rounding>_1"
14575   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14576         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14577                         FIST_ROUNDING))
14578    (clobber (reg:CC FLAGS_REG))]
14579   "TARGET_USE_FANCY_MATH_387
14580    && flag_unsafe_math_optimizations
14581    && can_create_pseudo_p ()"
14582   "#"
14583   "&& 1"
14584   [(const_int 0)]
14586   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
14588   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14589   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
14590   if (memory_operand (operands[0], VOIDmode))
14591     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
14592                                            operands[2], operands[3]));
14593   else
14594     {
14595       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14596       emit_insn (gen_fist<mode>2_<rounding>_with_temp
14597                   (operands[0], operands[1], operands[2],
14598                    operands[3], operands[4]));
14599     }
14600   DONE;
14602   [(set_attr "type" "fistp")
14603    (set_attr "i387_cw" "<rounding>")
14604    (set_attr "mode" "<MODE>")])
14606 (define_insn "fistdi2_<rounding>"
14607   [(set (match_operand:DI 0 "memory_operand" "=m")
14608         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14609                    FIST_ROUNDING))
14610    (use (match_operand:HI 2 "memory_operand" "m"))
14611    (use (match_operand:HI 3 "memory_operand" "m"))
14612    (clobber (match_scratch:XF 4 "=&1f"))]
14613   "TARGET_USE_FANCY_MATH_387
14614    && flag_unsafe_math_optimizations"
14615   "* return output_fix_trunc (insn, operands, false);"
14616   [(set_attr "type" "fistp")
14617    (set_attr "i387_cw" "<rounding>")
14618    (set_attr "mode" "DI")])
14620 (define_insn "fistdi2_<rounding>_with_temp"
14621   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14622         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14623                    FIST_ROUNDING))
14624    (use (match_operand:HI 2 "memory_operand" "m,m"))
14625    (use (match_operand:HI 3 "memory_operand" "m,m"))
14626    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14627    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14628   "TARGET_USE_FANCY_MATH_387
14629    && flag_unsafe_math_optimizations"
14630   "#"
14631   [(set_attr "type" "fistp")
14632    (set_attr "i387_cw" "<rounding>")
14633    (set_attr "mode" "DI")])
14635 (define_split
14636   [(set (match_operand:DI 0 "register_operand")
14637         (unspec:DI [(match_operand:XF 1 "register_operand")]
14638                    FIST_ROUNDING))
14639    (use (match_operand:HI 2 "memory_operand"))
14640    (use (match_operand:HI 3 "memory_operand"))
14641    (clobber (match_operand:DI 4 "memory_operand"))
14642    (clobber (match_scratch 5))]
14643   "reload_completed"
14644   [(parallel [(set (match_dup 4)
14645                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
14646               (use (match_dup 2))
14647               (use (match_dup 3))
14648               (clobber (match_dup 5))])
14649    (set (match_dup 0) (match_dup 4))])
14651 (define_split
14652   [(set (match_operand:DI 0 "memory_operand")
14653         (unspec:DI [(match_operand:XF 1 "register_operand")]
14654                    FIST_ROUNDING))
14655    (use (match_operand:HI 2 "memory_operand"))
14656    (use (match_operand:HI 3 "memory_operand"))
14657    (clobber (match_operand:DI 4 "memory_operand"))
14658    (clobber (match_scratch 5))]
14659   "reload_completed"
14660   [(parallel [(set (match_dup 0)
14661                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
14662               (use (match_dup 2))
14663               (use (match_dup 3))
14664               (clobber (match_dup 5))])])
14666 (define_insn "fist<mode>2_<rounding>"
14667   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14668         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14669                       FIST_ROUNDING))
14670    (use (match_operand:HI 2 "memory_operand" "m"))
14671    (use (match_operand:HI 3 "memory_operand" "m"))]
14672   "TARGET_USE_FANCY_MATH_387
14673    && flag_unsafe_math_optimizations"
14674   "* return output_fix_trunc (insn, operands, false);"
14675   [(set_attr "type" "fistp")
14676    (set_attr "i387_cw" "<rounding>")
14677    (set_attr "mode" "<MODE>")])
14679 (define_insn "fist<mode>2_<rounding>_with_temp"
14680   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14681         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14682                       FIST_ROUNDING))
14683    (use (match_operand:HI 2 "memory_operand" "m,m"))
14684    (use (match_operand:HI 3 "memory_operand" "m,m"))
14685    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14686   "TARGET_USE_FANCY_MATH_387
14687    && flag_unsafe_math_optimizations"
14688   "#"
14689   [(set_attr "type" "fistp")
14690    (set_attr "i387_cw" "<rounding>")
14691    (set_attr "mode" "<MODE>")])
14693 (define_split
14694   [(set (match_operand:SWI24 0 "register_operand")
14695         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14696                       FIST_ROUNDING))
14697    (use (match_operand:HI 2 "memory_operand"))
14698    (use (match_operand:HI 3 "memory_operand"))
14699    (clobber (match_operand:SWI24 4 "memory_operand"))]
14700   "reload_completed"
14701   [(parallel [(set (match_dup 4)
14702                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
14703               (use (match_dup 2))
14704               (use (match_dup 3))])
14705    (set (match_dup 0) (match_dup 4))])
14707 (define_split
14708   [(set (match_operand:SWI24 0 "memory_operand")
14709         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14710                       FIST_ROUNDING))
14711    (use (match_operand:HI 2 "memory_operand"))
14712    (use (match_operand:HI 3 "memory_operand"))
14713    (clobber (match_operand:SWI24 4 "memory_operand"))]
14714   "reload_completed"
14715   [(parallel [(set (match_dup 0)
14716                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
14717               (use (match_dup 2))
14718               (use (match_dup 3))])])
14720 (define_expand "l<rounding_insn>xf<mode>2"
14721   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14722                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14723                                    FIST_ROUNDING))
14724               (clobber (reg:CC FLAGS_REG))])]
14725   "TARGET_USE_FANCY_MATH_387
14726    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14727    && flag_unsafe_math_optimizations")
14729 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
14730   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
14731                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
14732                                  FIST_ROUNDING))
14733               (clobber (reg:CC FLAGS_REG))])]
14734   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14735    && !flag_trapping_math"
14737   if (TARGET_64BIT && optimize_insn_for_size_p ())
14738     FAIL;
14740   if (ROUND_<ROUNDING> == ROUND_FLOOR)
14741     ix86_expand_lfloorceil (operands[0], operands[1], true);
14742   else if (ROUND_<ROUNDING> == ROUND_CEIL)
14743     ix86_expand_lfloorceil (operands[0], operands[1], false);
14744   else
14745     gcc_unreachable ();
14747   DONE;
14750 (define_insn "fxam<mode>2_i387"
14751   [(set (match_operand:HI 0 "register_operand" "=a")
14752         (unspec:HI
14753           [(match_operand:X87MODEF 1 "register_operand" "f")]
14754           UNSPEC_FXAM))]
14755   "TARGET_USE_FANCY_MATH_387"
14756   "fxam\n\tfnstsw\t%0"
14757   [(set_attr "type" "multi")
14758    (set_attr "length" "4")
14759    (set_attr "unit" "i387")
14760    (set_attr "mode" "<MODE>")])
14762 (define_insn_and_split "fxam<mode>2_i387_with_temp"
14763   [(set (match_operand:HI 0 "register_operand")
14764         (unspec:HI
14765           [(match_operand:MODEF 1 "memory_operand")]
14766           UNSPEC_FXAM_MEM))]
14767   "TARGET_USE_FANCY_MATH_387
14768    && can_create_pseudo_p ()"
14769   "#"
14770   "&& 1"
14771   [(set (match_dup 2)(match_dup 1))
14772    (set (match_dup 0)
14773         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
14775   operands[2] = gen_reg_rtx (<MODE>mode);
14777   MEM_VOLATILE_P (operands[1]) = 1;
14779   [(set_attr "type" "multi")
14780    (set_attr "unit" "i387")
14781    (set_attr "mode" "<MODE>")])
14783 (define_expand "isinfxf2"
14784   [(use (match_operand:SI 0 "register_operand"))
14785    (use (match_operand:XF 1 "register_operand"))]
14786   "TARGET_USE_FANCY_MATH_387
14787    && TARGET_C99_FUNCTIONS"
14789   rtx mask = GEN_INT (0x45);
14790   rtx val = GEN_INT (0x05);
14792   rtx cond;
14794   rtx scratch = gen_reg_rtx (HImode);
14795   rtx res = gen_reg_rtx (QImode);
14797   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14799   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14800   emit_insn (gen_cmpqi_ext_3 (scratch, val));
14801   cond = gen_rtx_fmt_ee (EQ, QImode,
14802                          gen_rtx_REG (CCmode, FLAGS_REG),
14803                          const0_rtx);
14804   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14805   emit_insn (gen_zero_extendqisi2 (operands[0], res));
14806   DONE;
14809 (define_expand "isinf<mode>2"
14810   [(use (match_operand:SI 0 "register_operand"))
14811    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
14812   "TARGET_USE_FANCY_MATH_387
14813    && TARGET_C99_FUNCTIONS
14814    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14816   rtx mask = GEN_INT (0x45);
14817   rtx val = GEN_INT (0x05);
14819   rtx cond;
14821   rtx scratch = gen_reg_rtx (HImode);
14822   rtx res = gen_reg_rtx (QImode);
14824   /* Remove excess precision by forcing value through memory. */
14825   if (memory_operand (operands[1], VOIDmode))
14826     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
14827   else
14828     {
14829       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14831       emit_move_insn (temp, operands[1]);
14832       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
14833     }
14835   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14836   emit_insn (gen_cmpqi_ext_3 (scratch, val));
14837   cond = gen_rtx_fmt_ee (EQ, QImode,
14838                          gen_rtx_REG (CCmode, FLAGS_REG),
14839                          const0_rtx);
14840   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14841   emit_insn (gen_zero_extendqisi2 (operands[0], res));
14842   DONE;
14845 (define_expand "signbitxf2"
14846   [(use (match_operand:SI 0 "register_operand"))
14847    (use (match_operand:XF 1 "register_operand"))]
14848   "TARGET_USE_FANCY_MATH_387"
14850   rtx scratch = gen_reg_rtx (HImode);
14852   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14853   emit_insn (gen_andsi3 (operands[0],
14854              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
14855   DONE;
14858 (define_insn "movmsk_df"
14859   [(set (match_operand:SI 0 "register_operand" "=r")
14860         (unspec:SI
14861           [(match_operand:DF 1 "register_operand" "x")]
14862           UNSPEC_MOVMSK))]
14863   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
14864   "%vmovmskpd\t{%1, %0|%0, %1}"
14865   [(set_attr "type" "ssemov")
14866    (set_attr "prefix" "maybe_vex")
14867    (set_attr "mode" "DF")])
14869 ;; Use movmskpd in SSE mode to avoid store forwarding stall
14870 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
14871 (define_expand "signbitdf2"
14872   [(use (match_operand:SI 0 "register_operand"))
14873    (use (match_operand:DF 1 "register_operand"))]
14874   "TARGET_USE_FANCY_MATH_387
14875    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14877   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
14878     {
14879       emit_insn (gen_movmsk_df (operands[0], operands[1]));
14880       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
14881     }
14882   else
14883     {
14884       rtx scratch = gen_reg_rtx (HImode);
14886       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
14887       emit_insn (gen_andsi3 (operands[0],
14888                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
14889     }
14890   DONE;
14893 (define_expand "signbitsf2"
14894   [(use (match_operand:SI 0 "register_operand"))
14895    (use (match_operand:SF 1 "register_operand"))]
14896   "TARGET_USE_FANCY_MATH_387
14897    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
14899   rtx scratch = gen_reg_rtx (HImode);
14901   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
14902   emit_insn (gen_andsi3 (operands[0],
14903              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
14904   DONE;
14907 ;; Block operation instructions
14909 (define_insn "cld"
14910   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
14911   ""
14912   "cld"
14913   [(set_attr "length" "1")
14914    (set_attr "length_immediate" "0")
14915    (set_attr "modrm" "0")])
14917 (define_expand "movmem<mode>"
14918   [(use (match_operand:BLK 0 "memory_operand"))
14919    (use (match_operand:BLK 1 "memory_operand"))
14920    (use (match_operand:SWI48 2 "nonmemory_operand"))
14921    (use (match_operand:SWI48 3 "const_int_operand"))
14922    (use (match_operand:SI 4 "const_int_operand"))
14923    (use (match_operand:SI 5 "const_int_operand"))]
14924   ""
14926  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
14927                          operands[4], operands[5]))
14928    DONE;
14929  else
14930    FAIL;
14933 ;; Most CPUs don't like single string operations
14934 ;; Handle this case here to simplify previous expander.
14936 (define_expand "strmov"
14937   [(set (match_dup 4) (match_operand 3 "memory_operand"))
14938    (set (match_operand 1 "memory_operand") (match_dup 4))
14939    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
14940               (clobber (reg:CC FLAGS_REG))])
14941    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
14942               (clobber (reg:CC FLAGS_REG))])]
14943   ""
14945   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
14947   /* If .md ever supports :P for Pmode, these can be directly
14948      in the pattern above.  */
14949   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
14950   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
14952   /* Can't use this if the user has appropriated esi or edi.  */
14953   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
14954       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
14955     {
14956       emit_insn (gen_strmov_singleop (operands[0], operands[1],
14957                                       operands[2], operands[3],
14958                                       operands[5], operands[6]));
14959       DONE;
14960     }
14962   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
14965 (define_expand "strmov_singleop"
14966   [(parallel [(set (match_operand 1 "memory_operand")
14967                    (match_operand 3 "memory_operand"))
14968               (set (match_operand 0 "register_operand")
14969                    (match_operand 4))
14970               (set (match_operand 2 "register_operand")
14971                    (match_operand 5))])]
14972   ""
14973   "ix86_current_function_needs_cld = 1;")
14975 (define_insn "*strmovdi_rex_1"
14976   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
14977         (mem:DI (match_operand:P 3 "register_operand" "1")))
14978    (set (match_operand:P 0 "register_operand" "=D")
14979         (plus:P (match_dup 2)
14980                 (const_int 8)))
14981    (set (match_operand:P 1 "register_operand" "=S")
14982         (plus:P (match_dup 3)
14983                 (const_int 8)))]
14984   "TARGET_64BIT
14985    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
14986   "%^movsq"
14987   [(set_attr "type" "str")
14988    (set_attr "memory" "both")
14989    (set_attr "mode" "DI")])
14991 (define_insn "*strmovsi_1"
14992   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
14993         (mem:SI (match_operand:P 3 "register_operand" "1")))
14994    (set (match_operand:P 0 "register_operand" "=D")
14995         (plus:P (match_dup 2)
14996                 (const_int 4)))
14997    (set (match_operand:P 1 "register_operand" "=S")
14998         (plus:P (match_dup 3)
14999                 (const_int 4)))]
15000   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15001   "%^movs{l|d}"
15002   [(set_attr "type" "str")
15003    (set_attr "memory" "both")
15004    (set_attr "mode" "SI")])
15006 (define_insn "*strmovhi_1"
15007   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15008         (mem:HI (match_operand:P 3 "register_operand" "1")))
15009    (set (match_operand:P 0 "register_operand" "=D")
15010         (plus:P (match_dup 2)
15011                 (const_int 2)))
15012    (set (match_operand:P 1 "register_operand" "=S")
15013         (plus:P (match_dup 3)
15014                 (const_int 2)))]
15015   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15016   "%^movsw"
15017   [(set_attr "type" "str")
15018    (set_attr "memory" "both")
15019    (set_attr "mode" "HI")])
15021 (define_insn "*strmovqi_1"
15022   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15023         (mem:QI (match_operand:P 3 "register_operand" "1")))
15024    (set (match_operand:P 0 "register_operand" "=D")
15025         (plus:P (match_dup 2)
15026                 (const_int 1)))
15027    (set (match_operand:P 1 "register_operand" "=S")
15028         (plus:P (match_dup 3)
15029                 (const_int 1)))]
15030   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15031   "%^movsb"
15032   [(set_attr "type" "str")
15033    (set_attr "memory" "both")
15034    (set (attr "prefix_rex")
15035         (if_then_else
15036           (match_test "<P:MODE>mode == DImode")
15037           (const_string "0")
15038           (const_string "*")))
15039    (set_attr "mode" "QI")])
15041 (define_expand "rep_mov"
15042   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15043               (set (match_operand 0 "register_operand")
15044                    (match_operand 5))
15045               (set (match_operand 2 "register_operand")
15046                    (match_operand 6))
15047               (set (match_operand 1 "memory_operand")
15048                    (match_operand 3 "memory_operand"))
15049               (use (match_dup 4))])]
15050   ""
15051   "ix86_current_function_needs_cld = 1;")
15053 (define_insn "*rep_movdi_rex64"
15054   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15055    (set (match_operand:P 0 "register_operand" "=D")
15056         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15057                           (const_int 3))
15058                 (match_operand:P 3 "register_operand" "0")))
15059    (set (match_operand:P 1 "register_operand" "=S")
15060         (plus:P (ashift:P (match_dup 5) (const_int 3))
15061                 (match_operand:P 4 "register_operand" "1")))
15062    (set (mem:BLK (match_dup 3))
15063         (mem:BLK (match_dup 4)))
15064    (use (match_dup 5))]
15065   "TARGET_64BIT
15066    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15067   "%^rep{%;} movsq"
15068   [(set_attr "type" "str")
15069    (set_attr "prefix_rep" "1")
15070    (set_attr "memory" "both")
15071    (set_attr "mode" "DI")])
15073 (define_insn "*rep_movsi"
15074   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15075    (set (match_operand:P 0 "register_operand" "=D")
15076         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15077                           (const_int 2))
15078                  (match_operand:P 3 "register_operand" "0")))
15079    (set (match_operand:P 1 "register_operand" "=S")
15080         (plus:P (ashift:P (match_dup 5) (const_int 2))
15081                 (match_operand:P 4 "register_operand" "1")))
15082    (set (mem:BLK (match_dup 3))
15083         (mem:BLK (match_dup 4)))
15084    (use (match_dup 5))]
15085   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15086   "%^rep{%;} movs{l|d}"
15087   [(set_attr "type" "str")
15088    (set_attr "prefix_rep" "1")
15089    (set_attr "memory" "both")
15090    (set_attr "mode" "SI")])
15092 (define_insn "*rep_movqi"
15093   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15094    (set (match_operand:P 0 "register_operand" "=D")
15095         (plus:P (match_operand:P 3 "register_operand" "0")
15096                 (match_operand:P 5 "register_operand" "2")))
15097    (set (match_operand:P 1 "register_operand" "=S")
15098         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15099    (set (mem:BLK (match_dup 3))
15100         (mem:BLK (match_dup 4)))
15101    (use (match_dup 5))]
15102   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15103   "%^rep{%;} movsb"
15104   [(set_attr "type" "str")
15105    (set_attr "prefix_rep" "1")
15106    (set_attr "memory" "both")
15107    (set_attr "mode" "QI")])
15109 (define_expand "setmem<mode>"
15110    [(use (match_operand:BLK 0 "memory_operand"))
15111     (use (match_operand:SWI48 1 "nonmemory_operand"))
15112     (use (match_operand:QI 2 "nonmemory_operand"))
15113     (use (match_operand 3 "const_int_operand"))
15114     (use (match_operand:SI 4 "const_int_operand"))
15115     (use (match_operand:SI 5 "const_int_operand"))]
15116   ""
15118  if (ix86_expand_setmem (operands[0], operands[1],
15119                          operands[2], operands[3],
15120                          operands[4], operands[5]))
15121    DONE;
15122  else
15123    FAIL;
15126 ;; Most CPUs don't like single string operations
15127 ;; Handle this case here to simplify previous expander.
15129 (define_expand "strset"
15130   [(set (match_operand 1 "memory_operand")
15131         (match_operand 2 "register_operand"))
15132    (parallel [(set (match_operand 0 "register_operand")
15133                    (match_dup 3))
15134               (clobber (reg:CC FLAGS_REG))])]
15135   ""
15137   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15138     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15140   /* If .md ever supports :P for Pmode, this can be directly
15141      in the pattern above.  */
15142   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15143                               GEN_INT (GET_MODE_SIZE (GET_MODE
15144                                                       (operands[2]))));
15145   /* Can't use this if the user has appropriated eax or edi.  */
15146   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15147       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15148     {
15149       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15150                                       operands[3]));
15151       DONE;
15152     }
15155 (define_expand "strset_singleop"
15156   [(parallel [(set (match_operand 1 "memory_operand")
15157                    (match_operand 2 "register_operand"))
15158               (set (match_operand 0 "register_operand")
15159                    (match_operand 3))
15160               (unspec [(const_int 0)] UNSPEC_STOS)])]
15161   ""
15162   "ix86_current_function_needs_cld = 1;")
15164 (define_insn "*strsetdi_rex_1"
15165   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15166         (match_operand:DI 2 "register_operand" "a"))
15167    (set (match_operand:P 0 "register_operand" "=D")
15168         (plus:P (match_dup 1)
15169                 (const_int 8)))
15170    (unspec [(const_int 0)] UNSPEC_STOS)]
15171   "TARGET_64BIT
15172    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15173   "%^stosq"
15174   [(set_attr "type" "str")
15175    (set_attr "memory" "store")
15176    (set_attr "mode" "DI")])
15178 (define_insn "*strsetsi_1"
15179   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15180         (match_operand:SI 2 "register_operand" "a"))
15181    (set (match_operand:P 0 "register_operand" "=D")
15182         (plus:P (match_dup 1)
15183                 (const_int 4)))
15184    (unspec [(const_int 0)] UNSPEC_STOS)]
15185   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15186   "%^stos{l|d}"
15187   [(set_attr "type" "str")
15188    (set_attr "memory" "store")
15189    (set_attr "mode" "SI")])
15191 (define_insn "*strsethi_1"
15192   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15193         (match_operand:HI 2 "register_operand" "a"))
15194    (set (match_operand:P 0 "register_operand" "=D")
15195         (plus:P (match_dup 1)
15196                 (const_int 2)))
15197    (unspec [(const_int 0)] UNSPEC_STOS)]
15198   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15199   "%^stosw"
15200   [(set_attr "type" "str")
15201    (set_attr "memory" "store")
15202    (set_attr "mode" "HI")])
15204 (define_insn "*strsetqi_1"
15205   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15206         (match_operand:QI 2 "register_operand" "a"))
15207    (set (match_operand:P 0 "register_operand" "=D")
15208         (plus:P (match_dup 1)
15209                 (const_int 1)))
15210    (unspec [(const_int 0)] UNSPEC_STOS)]
15211   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15212   "%^stosb"
15213   [(set_attr "type" "str")
15214    (set_attr "memory" "store")
15215    (set (attr "prefix_rex")
15216         (if_then_else
15217           (match_test "<P:MODE>mode == DImode")
15218           (const_string "0")
15219           (const_string "*")))
15220    (set_attr "mode" "QI")])
15222 (define_expand "rep_stos"
15223   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15224               (set (match_operand 0 "register_operand")
15225                    (match_operand 4))
15226               (set (match_operand 2 "memory_operand") (const_int 0))
15227               (use (match_operand 3 "register_operand"))
15228               (use (match_dup 1))])]
15229   ""
15230   "ix86_current_function_needs_cld = 1;")
15232 (define_insn "*rep_stosdi_rex64"
15233   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15234    (set (match_operand:P 0 "register_operand" "=D")
15235         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15236                           (const_int 3))
15237                  (match_operand:P 3 "register_operand" "0")))
15238    (set (mem:BLK (match_dup 3))
15239         (const_int 0))
15240    (use (match_operand:DI 2 "register_operand" "a"))
15241    (use (match_dup 4))]
15242   "TARGET_64BIT
15243    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15244   "%^rep{%;} stosq"
15245   [(set_attr "type" "str")
15246    (set_attr "prefix_rep" "1")
15247    (set_attr "memory" "store")
15248    (set_attr "mode" "DI")])
15250 (define_insn "*rep_stossi"
15251   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15252    (set (match_operand:P 0 "register_operand" "=D")
15253         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15254                           (const_int 2))
15255                  (match_operand:P 3 "register_operand" "0")))
15256    (set (mem:BLK (match_dup 3))
15257         (const_int 0))
15258    (use (match_operand:SI 2 "register_operand" "a"))
15259    (use (match_dup 4))]
15260   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15261   "%^rep{%;} stos{l|d}"
15262   [(set_attr "type" "str")
15263    (set_attr "prefix_rep" "1")
15264    (set_attr "memory" "store")
15265    (set_attr "mode" "SI")])
15267 (define_insn "*rep_stosqi"
15268   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15269    (set (match_operand:P 0 "register_operand" "=D")
15270         (plus:P (match_operand:P 3 "register_operand" "0")
15271                 (match_operand:P 4 "register_operand" "1")))
15272    (set (mem:BLK (match_dup 3))
15273         (const_int 0))
15274    (use (match_operand:QI 2 "register_operand" "a"))
15275    (use (match_dup 4))]
15276   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15277   "%^rep{%;} stosb"
15278   [(set_attr "type" "str")
15279    (set_attr "prefix_rep" "1")
15280    (set_attr "memory" "store")
15281    (set (attr "prefix_rex")
15282         (if_then_else
15283           (match_test "<P:MODE>mode == DImode")
15284           (const_string "0")
15285           (const_string "*")))
15286    (set_attr "mode" "QI")])
15288 (define_expand "cmpstrnsi"
15289   [(set (match_operand:SI 0 "register_operand")
15290         (compare:SI (match_operand:BLK 1 "general_operand")
15291                     (match_operand:BLK 2 "general_operand")))
15292    (use (match_operand 3 "general_operand"))
15293    (use (match_operand 4 "immediate_operand"))]
15294   ""
15296   rtx addr1, addr2, out, outlow, count, countreg, align;
15298   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15299     FAIL;
15301   /* Can't use this if the user has appropriated ecx, esi or edi.  */
15302   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
15303     FAIL;
15305   out = operands[0];
15306   if (!REG_P (out))
15307     out = gen_reg_rtx (SImode);
15309   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
15310   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
15311   if (addr1 != XEXP (operands[1], 0))
15312     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15313   if (addr2 != XEXP (operands[2], 0))
15314     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15316   count = operands[3];
15317   countreg = ix86_zero_extend_to_Pmode (count);
15319   /* %%% Iff we are testing strict equality, we can use known alignment
15320      to good advantage.  This may be possible with combine, particularly
15321      once cc0 is dead.  */
15322   align = operands[4];
15324   if (CONST_INT_P (count))
15325     {
15326       if (INTVAL (count) == 0)
15327         {
15328           emit_move_insn (operands[0], const0_rtx);
15329           DONE;
15330         }
15331       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15332                                      operands[1], operands[2]));
15333     }
15334   else
15335     {
15336       rtx (*gen_cmp) (rtx, rtx);
15338       gen_cmp = (TARGET_64BIT
15339                  ? gen_cmpdi_1 : gen_cmpsi_1);
15341       emit_insn (gen_cmp (countreg, countreg));
15342       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15343                                   operands[1], operands[2]));
15344     }
15346   outlow = gen_lowpart (QImode, out);
15347   emit_insn (gen_cmpintqi (outlow));
15348   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15350   if (operands[0] != out)
15351     emit_move_insn (operands[0], out);
15353   DONE;
15356 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15358 (define_expand "cmpintqi"
15359   [(set (match_dup 1)
15360         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15361    (set (match_dup 2)
15362         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15363    (parallel [(set (match_operand:QI 0 "register_operand")
15364                    (minus:QI (match_dup 1)
15365                              (match_dup 2)))
15366               (clobber (reg:CC FLAGS_REG))])]
15367   ""
15369   operands[1] = gen_reg_rtx (QImode);
15370   operands[2] = gen_reg_rtx (QImode);
15373 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15374 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15376 (define_expand "cmpstrnqi_nz_1"
15377   [(parallel [(set (reg:CC FLAGS_REG)
15378                    (compare:CC (match_operand 4 "memory_operand")
15379                                (match_operand 5 "memory_operand")))
15380               (use (match_operand 2 "register_operand"))
15381               (use (match_operand:SI 3 "immediate_operand"))
15382               (clobber (match_operand 0 "register_operand"))
15383               (clobber (match_operand 1 "register_operand"))
15384               (clobber (match_dup 2))])]
15385   ""
15386   "ix86_current_function_needs_cld = 1;")
15388 (define_insn "*cmpstrnqi_nz_1"
15389   [(set (reg:CC FLAGS_REG)
15390         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15391                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15392    (use (match_operand:P 6 "register_operand" "2"))
15393    (use (match_operand:SI 3 "immediate_operand" "i"))
15394    (clobber (match_operand:P 0 "register_operand" "=S"))
15395    (clobber (match_operand:P 1 "register_operand" "=D"))
15396    (clobber (match_operand:P 2 "register_operand" "=c"))]
15397   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15398   "%^repz{%;} cmpsb"
15399   [(set_attr "type" "str")
15400    (set_attr "mode" "QI")
15401    (set (attr "prefix_rex")
15402         (if_then_else
15403           (match_test "<P:MODE>mode == DImode")
15404           (const_string "0")
15405           (const_string "*")))
15406    (set_attr "prefix_rep" "1")])
15408 ;; The same, but the count is not known to not be zero.
15410 (define_expand "cmpstrnqi_1"
15411   [(parallel [(set (reg:CC FLAGS_REG)
15412                 (if_then_else:CC (ne (match_operand 2 "register_operand")
15413                                      (const_int 0))
15414                   (compare:CC (match_operand 4 "memory_operand")
15415                               (match_operand 5 "memory_operand"))
15416                   (const_int 0)))
15417               (use (match_operand:SI 3 "immediate_operand"))
15418               (use (reg:CC FLAGS_REG))
15419               (clobber (match_operand 0 "register_operand"))
15420               (clobber (match_operand 1 "register_operand"))
15421               (clobber (match_dup 2))])]
15422   ""
15423   "ix86_current_function_needs_cld = 1;")
15425 (define_insn "*cmpstrnqi_1"
15426   [(set (reg:CC FLAGS_REG)
15427         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15428                              (const_int 0))
15429           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15430                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
15431           (const_int 0)))
15432    (use (match_operand:SI 3 "immediate_operand" "i"))
15433    (use (reg:CC FLAGS_REG))
15434    (clobber (match_operand:P 0 "register_operand" "=S"))
15435    (clobber (match_operand:P 1 "register_operand" "=D"))
15436    (clobber (match_operand:P 2 "register_operand" "=c"))]
15437   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15438   "%^repz{%;} cmpsb"
15439   [(set_attr "type" "str")
15440    (set_attr "mode" "QI")
15441    (set (attr "prefix_rex")
15442         (if_then_else
15443           (match_test "<P:MODE>mode == DImode")
15444           (const_string "0")
15445           (const_string "*")))
15446    (set_attr "prefix_rep" "1")])
15448 (define_expand "strlen<mode>"
15449   [(set (match_operand:P 0 "register_operand")
15450         (unspec:P [(match_operand:BLK 1 "general_operand")
15451                    (match_operand:QI 2 "immediate_operand")
15452                    (match_operand 3 "immediate_operand")]
15453                   UNSPEC_SCAS))]
15454   ""
15456  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15457    DONE;
15458  else
15459    FAIL;
15462 (define_expand "strlenqi_1"
15463   [(parallel [(set (match_operand 0 "register_operand")
15464                    (match_operand 2))
15465               (clobber (match_operand 1 "register_operand"))
15466               (clobber (reg:CC FLAGS_REG))])]
15467   ""
15468   "ix86_current_function_needs_cld = 1;")
15470 (define_insn "*strlenqi_1"
15471   [(set (match_operand:P 0 "register_operand" "=&c")
15472         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15473                    (match_operand:QI 2 "register_operand" "a")
15474                    (match_operand:P 3 "immediate_operand" "i")
15475                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15476    (clobber (match_operand:P 1 "register_operand" "=D"))
15477    (clobber (reg:CC FLAGS_REG))]
15478   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15479   "%^repnz{%;} scasb"
15480   [(set_attr "type" "str")
15481    (set_attr "mode" "QI")
15482    (set (attr "prefix_rex")
15483         (if_then_else
15484           (match_test "<P:MODE>mode == DImode")
15485           (const_string "0")
15486           (const_string "*")))
15487    (set_attr "prefix_rep" "1")])
15489 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
15490 ;; handled in combine, but it is not currently up to the task.
15491 ;; When used for their truth value, the cmpstrn* expanders generate
15492 ;; code like this:
15494 ;;   repz cmpsb
15495 ;;   seta       %al
15496 ;;   setb       %dl
15497 ;;   cmpb       %al, %dl
15498 ;;   jcc        label
15500 ;; The intermediate three instructions are unnecessary.
15502 ;; This one handles cmpstrn*_nz_1...
15503 (define_peephole2
15504   [(parallel[
15505      (set (reg:CC FLAGS_REG)
15506           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
15507                       (mem:BLK (match_operand 5 "register_operand"))))
15508      (use (match_operand 6 "register_operand"))
15509      (use (match_operand:SI 3 "immediate_operand"))
15510      (clobber (match_operand 0 "register_operand"))
15511      (clobber (match_operand 1 "register_operand"))
15512      (clobber (match_operand 2 "register_operand"))])
15513    (set (match_operand:QI 7 "register_operand")
15514         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15515    (set (match_operand:QI 8 "register_operand")
15516         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15517    (set (reg FLAGS_REG)
15518         (compare (match_dup 7) (match_dup 8)))
15519   ]
15520   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15521   [(parallel[
15522      (set (reg:CC FLAGS_REG)
15523           (compare:CC (mem:BLK (match_dup 4))
15524                       (mem:BLK (match_dup 5))))
15525      (use (match_dup 6))
15526      (use (match_dup 3))
15527      (clobber (match_dup 0))
15528      (clobber (match_dup 1))
15529      (clobber (match_dup 2))])])
15531 ;; ...and this one handles cmpstrn*_1.
15532 (define_peephole2
15533   [(parallel[
15534      (set (reg:CC FLAGS_REG)
15535           (if_then_else:CC (ne (match_operand 6 "register_operand")
15536                                (const_int 0))
15537             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
15538                         (mem:BLK (match_operand 5 "register_operand")))
15539             (const_int 0)))
15540      (use (match_operand:SI 3 "immediate_operand"))
15541      (use (reg:CC FLAGS_REG))
15542      (clobber (match_operand 0 "register_operand"))
15543      (clobber (match_operand 1 "register_operand"))
15544      (clobber (match_operand 2 "register_operand"))])
15545    (set (match_operand:QI 7 "register_operand")
15546         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15547    (set (match_operand:QI 8 "register_operand")
15548         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15549    (set (reg FLAGS_REG)
15550         (compare (match_dup 7) (match_dup 8)))
15551   ]
15552   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15553   [(parallel[
15554      (set (reg:CC FLAGS_REG)
15555           (if_then_else:CC (ne (match_dup 6)
15556                                (const_int 0))
15557             (compare:CC (mem:BLK (match_dup 4))
15558                         (mem:BLK (match_dup 5)))
15559             (const_int 0)))
15560      (use (match_dup 3))
15561      (use (reg:CC FLAGS_REG))
15562      (clobber (match_dup 0))
15563      (clobber (match_dup 1))
15564      (clobber (match_dup 2))])])
15566 ;; Conditional move instructions.
15568 (define_expand "mov<mode>cc"
15569   [(set (match_operand:SWIM 0 "register_operand")
15570         (if_then_else:SWIM (match_operand 1 "comparison_operator")
15571                            (match_operand:SWIM 2 "<general_operand>")
15572                            (match_operand:SWIM 3 "<general_operand>")))]
15573   ""
15574   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15576 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15577 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15578 ;; So just document what we're doing explicitly.
15580 (define_expand "x86_mov<mode>cc_0_m1"
15581   [(parallel
15582     [(set (match_operand:SWI48 0 "register_operand")
15583           (if_then_else:SWI48
15584             (match_operator:SWI48 2 "ix86_carry_flag_operator"
15585              [(match_operand 1 "flags_reg_operand")
15586               (const_int 0)])
15587             (const_int -1)
15588             (const_int 0)))
15589      (clobber (reg:CC FLAGS_REG))])])
15591 (define_insn "*x86_mov<mode>cc_0_m1"
15592   [(set (match_operand:SWI48 0 "register_operand" "=r")
15593         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15594                              [(reg FLAGS_REG) (const_int 0)])
15595           (const_int -1)
15596           (const_int 0)))
15597    (clobber (reg:CC FLAGS_REG))]
15598   ""
15599   "sbb{<imodesuffix>}\t%0, %0"
15600   ; Since we don't have the proper number of operands for an alu insn,
15601   ; fill in all the blanks.
15602   [(set_attr "type" "alu")
15603    (set_attr "use_carry" "1")
15604    (set_attr "pent_pair" "pu")
15605    (set_attr "memory" "none")
15606    (set_attr "imm_disp" "false")
15607    (set_attr "mode" "<MODE>")
15608    (set_attr "length_immediate" "0")])
15610 (define_insn "*x86_mov<mode>cc_0_m1_se"
15611   [(set (match_operand:SWI48 0 "register_operand" "=r")
15612         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15613                              [(reg FLAGS_REG) (const_int 0)])
15614                             (const_int 1)
15615                             (const_int 0)))
15616    (clobber (reg:CC FLAGS_REG))]
15617   ""
15618   "sbb{<imodesuffix>}\t%0, %0"
15619   [(set_attr "type" "alu")
15620    (set_attr "use_carry" "1")
15621    (set_attr "pent_pair" "pu")
15622    (set_attr "memory" "none")
15623    (set_attr "imm_disp" "false")
15624    (set_attr "mode" "<MODE>")
15625    (set_attr "length_immediate" "0")])
15627 (define_insn "*x86_mov<mode>cc_0_m1_neg"
15628   [(set (match_operand:SWI48 0 "register_operand" "=r")
15629         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15630                     [(reg FLAGS_REG) (const_int 0)])))
15631    (clobber (reg:CC FLAGS_REG))]
15632   ""
15633   "sbb{<imodesuffix>}\t%0, %0"
15634   [(set_attr "type" "alu")
15635    (set_attr "use_carry" "1")
15636    (set_attr "pent_pair" "pu")
15637    (set_attr "memory" "none")
15638    (set_attr "imm_disp" "false")
15639    (set_attr "mode" "<MODE>")
15640    (set_attr "length_immediate" "0")])
15642 (define_insn "*mov<mode>cc_noc"
15643   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
15644         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15645                                [(reg FLAGS_REG) (const_int 0)])
15646           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
15647           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
15648   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15649   "@
15650    cmov%O2%C1\t{%2, %0|%0, %2}
15651    cmov%O2%c1\t{%3, %0|%0, %3}"
15652   [(set_attr "type" "icmov")
15653    (set_attr "mode" "<MODE>")])
15655 ;; Don't do conditional moves with memory inputs.  This splitter helps
15656 ;; register starved x86_32 by forcing inputs into registers before reload.
15657 (define_split
15658   [(set (match_operand:SWI248 0 "register_operand")
15659         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15660                                [(reg FLAGS_REG) (const_int 0)])
15661           (match_operand:SWI248 2 "nonimmediate_operand")
15662           (match_operand:SWI248 3 "nonimmediate_operand")))]
15663   "!TARGET_64BIT && TARGET_CMOVE
15664    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15665    && (MEM_P (operands[2]) || MEM_P (operands[3]))
15666    && can_create_pseudo_p ()
15667    && optimize_insn_for_speed_p ()"
15668   [(set (match_dup 0)
15669         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
15671   if (MEM_P (operands[2]))
15672     operands[2] = force_reg (<MODE>mode, operands[2]);
15673   if (MEM_P (operands[3]))
15674     operands[3] = force_reg (<MODE>mode, operands[3]);
15677 (define_insn "*movqicc_noc"
15678   [(set (match_operand:QI 0 "register_operand" "=r,r")
15679         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
15680                            [(reg FLAGS_REG) (const_int 0)])
15681                       (match_operand:QI 2 "register_operand" "r,0")
15682                       (match_operand:QI 3 "register_operand" "0,r")))]
15683   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
15684   "#"
15685   [(set_attr "type" "icmov")
15686    (set_attr "mode" "QI")])
15688 (define_split
15689   [(set (match_operand:SWI12 0 "register_operand")
15690         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
15691                               [(reg FLAGS_REG) (const_int 0)])
15692                       (match_operand:SWI12 2 "register_operand")
15693                       (match_operand:SWI12 3 "register_operand")))]
15694   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
15695    && reload_completed"
15696   [(set (match_dup 0)
15697         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
15699   operands[0] = gen_lowpart (SImode, operands[0]);
15700   operands[2] = gen_lowpart (SImode, operands[2]);
15701   operands[3] = gen_lowpart (SImode, operands[3]);
15704 ;; Don't do conditional moves with memory inputs
15705 (define_peephole2
15706   [(match_scratch:SWI248 2 "r")
15707    (set (match_operand:SWI248 0 "register_operand")
15708         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15709                                [(reg FLAGS_REG) (const_int 0)])
15710           (match_dup 0)
15711           (match_operand:SWI248 3 "memory_operand")))]
15712   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15713    && optimize_insn_for_speed_p ()"
15714   [(set (match_dup 2) (match_dup 3))
15715    (set (match_dup 0)
15716         (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
15718 (define_peephole2
15719   [(match_scratch:SWI248 2 "r")
15720    (set (match_operand:SWI248 0 "register_operand")
15721         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15722                                [(reg FLAGS_REG) (const_int 0)])
15723           (match_operand:SWI248 3 "memory_operand")
15724           (match_dup 0)))]
15725   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15726    && optimize_insn_for_speed_p ()"
15727   [(set (match_dup 2) (match_dup 3))
15728    (set (match_dup 0)
15729         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
15731 (define_expand "mov<mode>cc"
15732   [(set (match_operand:X87MODEF 0 "register_operand")
15733         (if_then_else:X87MODEF
15734           (match_operand 1 "comparison_operator")
15735           (match_operand:X87MODEF 2 "register_operand")
15736           (match_operand:X87MODEF 3 "register_operand")))]
15737   "(TARGET_80387 && TARGET_CMOVE)
15738    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15739   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
15741 (define_insn "*movxfcc_1"
15742   [(set (match_operand:XF 0 "register_operand" "=f,f")
15743         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
15744                                 [(reg FLAGS_REG) (const_int 0)])
15745                       (match_operand:XF 2 "register_operand" "f,0")
15746                       (match_operand:XF 3 "register_operand" "0,f")))]
15747   "TARGET_80387 && TARGET_CMOVE"
15748   "@
15749    fcmov%F1\t{%2, %0|%0, %2}
15750    fcmov%f1\t{%3, %0|%0, %3}"
15751   [(set_attr "type" "fcmov")
15752    (set_attr "mode" "XF")])
15754 (define_insn "*movdfcc_1"
15755   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
15756         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15757                                 [(reg FLAGS_REG) (const_int 0)])
15758                       (match_operand:DF 2 "nonimmediate_operand"
15759                                                "f ,0,rm,0 ,rm,0")
15760                       (match_operand:DF 3 "nonimmediate_operand"
15761                                                "0 ,f,0 ,rm,0, rm")))]
15762   "TARGET_80387 && TARGET_CMOVE
15763    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15764   "@
15765    fcmov%F1\t{%2, %0|%0, %2}
15766    fcmov%f1\t{%3, %0|%0, %3}
15767    #
15768    #
15769    cmov%O2%C1\t{%2, %0|%0, %2}
15770    cmov%O2%c1\t{%3, %0|%0, %3}"
15771   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
15772    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
15773    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
15775 (define_split
15776   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
15777         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15778                                 [(reg FLAGS_REG) (const_int 0)])
15779                       (match_operand:DF 2 "nonimmediate_operand")
15780                       (match_operand:DF 3 "nonimmediate_operand")))]
15781   "!TARGET_64BIT && reload_completed"
15782   [(set (match_dup 2)
15783         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
15784    (set (match_dup 3)
15785         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
15787   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
15788   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
15791 (define_insn "*movsfcc_1_387"
15792   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
15793         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
15794                                 [(reg FLAGS_REG) (const_int 0)])
15795                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
15796                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
15797   "TARGET_80387 && TARGET_CMOVE
15798    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15799   "@
15800    fcmov%F1\t{%2, %0|%0, %2}
15801    fcmov%f1\t{%3, %0|%0, %3}
15802    cmov%O2%C1\t{%2, %0|%0, %2}
15803    cmov%O2%c1\t{%3, %0|%0, %3}"
15804   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15805    (set_attr "mode" "SF,SF,SI,SI")])
15807 ;; Don't do conditional moves with memory inputs.  This splitter helps
15808 ;; register starved x86_32 by forcing inputs into registers before reload.
15809 (define_split
15810   [(set (match_operand:MODEF 0 "register_operand")
15811         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
15812                               [(reg FLAGS_REG) (const_int 0)])
15813           (match_operand:MODEF 2 "nonimmediate_operand")
15814           (match_operand:MODEF 3 "nonimmediate_operand")))]
15815   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
15816    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15817    && (MEM_P (operands[2]) || MEM_P (operands[3]))
15818    && can_create_pseudo_p ()
15819    && optimize_insn_for_speed_p ()"
15820   [(set (match_dup 0)
15821         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
15823   if (MEM_P (operands[2]))
15824     operands[2] = force_reg (<MODE>mode, operands[2]);
15825   if (MEM_P (operands[3]))
15826     operands[3] = force_reg (<MODE>mode, operands[3]);
15829 ;; Don't do conditional moves with memory inputs
15830 (define_peephole2
15831   [(match_scratch:MODEF 2 "r")
15832    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
15833         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
15834                               [(reg FLAGS_REG) (const_int 0)])
15835           (match_dup 0)
15836           (match_operand:MODEF 3 "memory_operand")))]
15837   "(<MODE>mode != DFmode || TARGET_64BIT)
15838    && TARGET_80387 && TARGET_CMOVE
15839    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15840    && optimize_insn_for_speed_p ()"
15841   [(set (match_dup 2) (match_dup 3))
15842    (set (match_dup 0)
15843         (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
15845 (define_peephole2
15846   [(match_scratch:MODEF 2 "r")
15847    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
15848         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
15849                               [(reg FLAGS_REG) (const_int 0)])
15850           (match_operand:MODEF 3 "memory_operand")
15851           (match_dup 0)))]
15852   "(<MODE>mode != DFmode || TARGET_64BIT)
15853    && TARGET_80387 && TARGET_CMOVE
15854    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15855    && optimize_insn_for_speed_p ()"
15856   [(set (match_dup 2) (match_dup 3))
15857    (set (match_dup 0)
15858         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
15860 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
15861 ;; the scalar versions to have only XMM registers as operands.
15863 ;; XOP conditional move
15864 (define_insn "*xop_pcmov_<mode>"
15865   [(set (match_operand:MODEF 0 "register_operand" "=x")
15866         (if_then_else:MODEF
15867           (match_operand:MODEF 1 "register_operand" "x")
15868           (match_operand:MODEF 2 "register_operand" "x")
15869           (match_operand:MODEF 3 "register_operand" "x")))]
15870   "TARGET_XOP"
15871   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
15872   [(set_attr "type" "sse4arg")])
15874 ;; These versions of the min/max patterns are intentionally ignorant of
15875 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
15876 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
15877 ;; are undefined in this condition, we're certain this is correct.
15879 (define_insn "<code><mode>3"
15880   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
15881         (smaxmin:MODEF
15882           (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
15883           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
15884   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15885   "@
15886    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
15887    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
15888   [(set_attr "isa" "noavx,avx")
15889    (set_attr "prefix" "orig,vex")
15890    (set_attr "type" "sseadd")
15891    (set_attr "mode" "<MODE>")])
15893 ;; These versions of the min/max patterns implement exactly the operations
15894 ;;   min = (op1 < op2 ? op1 : op2)
15895 ;;   max = (!(op1 < op2) ? op1 : op2)
15896 ;; Their operands are not commutative, and thus they may be used in the
15897 ;; presence of -0.0 and NaN.
15899 (define_int_iterator IEEE_MAXMIN
15900         [UNSPEC_IEEE_MAX
15901          UNSPEC_IEEE_MIN])
15903 (define_int_attr ieee_maxmin
15904         [(UNSPEC_IEEE_MAX "max")
15905          (UNSPEC_IEEE_MIN "min")])
15907 (define_insn "*ieee_s<ieee_maxmin><mode>3"
15908   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
15909         (unspec:MODEF
15910           [(match_operand:MODEF 1 "register_operand" "0,x")
15911            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
15912           IEEE_MAXMIN))]
15913   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15914   "@
15915    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
15916    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
15917   [(set_attr "isa" "noavx,avx")
15918    (set_attr "prefix" "orig,vex")
15919    (set_attr "type" "sseadd")
15920    (set_attr "mode" "<MODE>")])
15922 ;; Make two stack loads independent:
15923 ;;   fld aa              fld aa
15924 ;;   fld %st(0)     ->   fld bb
15925 ;;   fmul bb             fmul %st(1), %st
15927 ;; Actually we only match the last two instructions for simplicity.
15928 (define_peephole2
15929   [(set (match_operand 0 "fp_register_operand")
15930         (match_operand 1 "fp_register_operand"))
15931    (set (match_dup 0)
15932         (match_operator 2 "binary_fp_operator"
15933            [(match_dup 0)
15934             (match_operand 3 "memory_operand")]))]
15935   "REGNO (operands[0]) != REGNO (operands[1])"
15936   [(set (match_dup 0) (match_dup 3))
15937    (set (match_dup 0) (match_dup 4))]
15939   ;; The % modifier is not operational anymore in peephole2's, so we have to
15940   ;; swap the operands manually in the case of addition and multiplication.
15942   rtx op0, op1;
15944   if (COMMUTATIVE_ARITH_P (operands[2]))
15945     op0 = operands[0], op1 = operands[1];
15946   else
15947     op0 = operands[1], op1 = operands[0];
15949   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
15950                                 GET_MODE (operands[2]),
15951                                 op0, op1);
15954 ;; Conditional addition patterns
15955 (define_expand "add<mode>cc"
15956   [(match_operand:SWI 0 "register_operand")
15957    (match_operand 1 "ordered_comparison_operator")
15958    (match_operand:SWI 2 "register_operand")
15959    (match_operand:SWI 3 "const_int_operand")]
15960   ""
15961   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
15963 ;; Misc patterns (?)
15965 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
15966 ;; Otherwise there will be nothing to keep
15968 ;; [(set (reg ebp) (reg esp))]
15969 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
15970 ;;  (clobber (eflags)]
15971 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
15973 ;; in proper program order.
15975 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
15976   [(set (match_operand:P 0 "register_operand" "=r,r")
15977         (plus:P (match_operand:P 1 "register_operand" "0,r")
15978                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
15979    (clobber (reg:CC FLAGS_REG))
15980    (clobber (mem:BLK (scratch)))]
15981   ""
15983   switch (get_attr_type (insn))
15984     {
15985     case TYPE_IMOV:
15986       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
15988     case TYPE_ALU:
15989       gcc_assert (rtx_equal_p (operands[0], operands[1]));
15990       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
15991         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
15993       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
15995     default:
15996       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
15997       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
15998     }
16000   [(set (attr "type")
16001         (cond [(and (eq_attr "alternative" "0")
16002                     (not (match_test "TARGET_OPT_AGU")))
16003                  (const_string "alu")
16004                (match_operand:<MODE> 2 "const0_operand")
16005                  (const_string "imov")
16006               ]
16007               (const_string "lea")))
16008    (set (attr "length_immediate")
16009         (cond [(eq_attr "type" "imov")
16010                  (const_string "0")
16011                (and (eq_attr "type" "alu")
16012                     (match_operand 2 "const128_operand"))
16013                  (const_string "1")
16014               ]
16015               (const_string "*")))
16016    (set_attr "mode" "<MODE>")])
16018 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16019   [(set (match_operand:P 0 "register_operand" "=r")
16020         (minus:P (match_operand:P 1 "register_operand" "0")
16021                  (match_operand:P 2 "register_operand" "r")))
16022    (clobber (reg:CC FLAGS_REG))
16023    (clobber (mem:BLK (scratch)))]
16024   ""
16025   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16026   [(set_attr "type" "alu")
16027    (set_attr "mode" "<MODE>")])
16029 (define_insn "allocate_stack_worker_probe_<mode>"
16030   [(set (match_operand:P 0 "register_operand" "=a")
16031         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16032                             UNSPECV_STACK_PROBE))
16033    (clobber (reg:CC FLAGS_REG))]
16034   "ix86_target_stack_probe ()"
16035   "call\t___chkstk_ms"
16036   [(set_attr "type" "multi")
16037    (set_attr "length" "5")])
16039 (define_expand "allocate_stack"
16040   [(match_operand 0 "register_operand")
16041    (match_operand 1 "general_operand")]
16042   "ix86_target_stack_probe ()"
16044   rtx x;
16046 #ifndef CHECK_STACK_LIMIT
16047 #define CHECK_STACK_LIMIT 0
16048 #endif
16050   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16051       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16052     x = operands[1];
16053   else
16054     {
16055       rtx (*insn) (rtx, rtx);
16057       x = copy_to_mode_reg (Pmode, operands[1]);
16059       insn = (TARGET_64BIT
16060               ? gen_allocate_stack_worker_probe_di
16061               : gen_allocate_stack_worker_probe_si);
16063       emit_insn (insn (x, x));
16064     }
16066   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16067                            stack_pointer_rtx, 0, OPTAB_DIRECT);
16069   if (x != stack_pointer_rtx)
16070     emit_move_insn (stack_pointer_rtx, x);
16072   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16073   DONE;
16076 ;; Use IOR for stack probes, this is shorter.
16077 (define_expand "probe_stack"
16078   [(match_operand 0 "memory_operand")]
16079   ""
16081   rtx (*gen_ior3) (rtx, rtx, rtx);
16083   gen_ior3 = (GET_MODE (operands[0]) == DImode
16084               ? gen_iordi3 : gen_iorsi3);
16086   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16087   DONE;
16090 (define_insn "adjust_stack_and_probe<mode>"
16091   [(set (match_operand:P 0 "register_operand" "=r")
16092         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16093                             UNSPECV_PROBE_STACK_RANGE))
16094    (set (reg:P SP_REG)
16095         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16096    (clobber (reg:CC FLAGS_REG))
16097    (clobber (mem:BLK (scratch)))]
16098   ""
16099   "* return output_adjust_stack_and_probe (operands[0]);"
16100   [(set_attr "type" "multi")])
16102 (define_insn "probe_stack_range<mode>"
16103   [(set (match_operand:P 0 "register_operand" "=r")
16104         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16105                             (match_operand:P 2 "const_int_operand" "n")]
16106                             UNSPECV_PROBE_STACK_RANGE))
16107    (clobber (reg:CC FLAGS_REG))]
16108   ""
16109   "* return output_probe_stack_range (operands[0], operands[2]);"
16110   [(set_attr "type" "multi")])
16112 (define_expand "builtin_setjmp_receiver"
16113   [(label_ref (match_operand 0))]
16114   "!TARGET_64BIT && flag_pic"
16116 #if TARGET_MACHO
16117   if (TARGET_MACHO)
16118     {
16119       rtx xops[3];
16120       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16121       rtx label_rtx = gen_label_rtx ();
16122       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16123       xops[0] = xops[1] = picreg;
16124       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16125       ix86_expand_binary_operator (MINUS, SImode, xops);
16126     }
16127   else
16128 #endif
16129     emit_insn (gen_set_got (pic_offset_table_rtx));
16130   DONE;
16133 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16135 (define_split
16136   [(set (match_operand 0 "register_operand")
16137         (match_operator 3 "promotable_binary_operator"
16138            [(match_operand 1 "register_operand")
16139             (match_operand 2 "aligned_operand")]))
16140    (clobber (reg:CC FLAGS_REG))]
16141   "! TARGET_PARTIAL_REG_STALL && reload_completed
16142    && ((GET_MODE (operands[0]) == HImode
16143         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16144             /* ??? next two lines just !satisfies_constraint_K (...) */
16145             || !CONST_INT_P (operands[2])
16146             || satisfies_constraint_K (operands[2])))
16147        || (GET_MODE (operands[0]) == QImode
16148            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16149   [(parallel [(set (match_dup 0)
16150                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16151               (clobber (reg:CC FLAGS_REG))])]
16153   operands[0] = gen_lowpart (SImode, operands[0]);
16154   operands[1] = gen_lowpart (SImode, operands[1]);
16155   if (GET_CODE (operands[3]) != ASHIFT)
16156     operands[2] = gen_lowpart (SImode, operands[2]);
16157   PUT_MODE (operands[3], SImode);
16160 ; Promote the QImode tests, as i386 has encoding of the AND
16161 ; instruction with 32-bit sign-extended immediate and thus the
16162 ; instruction size is unchanged, except in the %eax case for
16163 ; which it is increased by one byte, hence the ! optimize_size.
16164 (define_split
16165   [(set (match_operand 0 "flags_reg_operand")
16166         (match_operator 2 "compare_operator"
16167           [(and (match_operand 3 "aligned_operand")
16168                 (match_operand 4 "const_int_operand"))
16169            (const_int 0)]))
16170    (set (match_operand 1 "register_operand")
16171         (and (match_dup 3) (match_dup 4)))]
16172   "! TARGET_PARTIAL_REG_STALL && reload_completed
16173    && optimize_insn_for_speed_p ()
16174    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16175        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16176    /* Ensure that the operand will remain sign-extended immediate.  */
16177    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16178   [(parallel [(set (match_dup 0)
16179                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16180                                     (const_int 0)]))
16181               (set (match_dup 1)
16182                    (and:SI (match_dup 3) (match_dup 4)))])]
16184   operands[4]
16185     = gen_int_mode (INTVAL (operands[4])
16186                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16187   operands[1] = gen_lowpart (SImode, operands[1]);
16188   operands[3] = gen_lowpart (SImode, operands[3]);
16191 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16192 ; the TEST instruction with 32-bit sign-extended immediate and thus
16193 ; the instruction size would at least double, which is not what we
16194 ; want even with ! optimize_size.
16195 (define_split
16196   [(set (match_operand 0 "flags_reg_operand")
16197         (match_operator 1 "compare_operator"
16198           [(and (match_operand:HI 2 "aligned_operand")
16199                 (match_operand:HI 3 "const_int_operand"))
16200            (const_int 0)]))]
16201   "! TARGET_PARTIAL_REG_STALL && reload_completed
16202    && ! TARGET_FAST_PREFIX
16203    && optimize_insn_for_speed_p ()
16204    /* Ensure that the operand will remain sign-extended immediate.  */
16205    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16206   [(set (match_dup 0)
16207         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16208                          (const_int 0)]))]
16210   operands[3]
16211     = gen_int_mode (INTVAL (operands[3])
16212                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16213   operands[2] = gen_lowpart (SImode, operands[2]);
16216 (define_split
16217   [(set (match_operand 0 "register_operand")
16218         (neg (match_operand 1 "register_operand")))
16219    (clobber (reg:CC FLAGS_REG))]
16220   "! TARGET_PARTIAL_REG_STALL && reload_completed
16221    && (GET_MODE (operands[0]) == HImode
16222        || (GET_MODE (operands[0]) == QImode
16223            && (TARGET_PROMOTE_QImode
16224                || optimize_insn_for_size_p ())))"
16225   [(parallel [(set (match_dup 0)
16226                    (neg:SI (match_dup 1)))
16227               (clobber (reg:CC FLAGS_REG))])]
16229   operands[0] = gen_lowpart (SImode, operands[0]);
16230   operands[1] = gen_lowpart (SImode, operands[1]);
16233 (define_split
16234   [(set (match_operand 0 "register_operand")
16235         (not (match_operand 1 "register_operand")))]
16236   "! TARGET_PARTIAL_REG_STALL && reload_completed
16237    && (GET_MODE (operands[0]) == HImode
16238        || (GET_MODE (operands[0]) == QImode
16239            && (TARGET_PROMOTE_QImode
16240                || optimize_insn_for_size_p ())))"
16241   [(set (match_dup 0)
16242         (not:SI (match_dup 1)))]
16244   operands[0] = gen_lowpart (SImode, operands[0]);
16245   operands[1] = gen_lowpart (SImode, operands[1]);
16248 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16249 ;; transform a complex memory operation into two memory to register operations.
16251 ;; Don't push memory operands
16252 (define_peephole2
16253   [(set (match_operand:SWI 0 "push_operand")
16254         (match_operand:SWI 1 "memory_operand"))
16255    (match_scratch:SWI 2 "<r>")]
16256   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16257    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16258   [(set (match_dup 2) (match_dup 1))
16259    (set (match_dup 0) (match_dup 2))])
16261 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16262 ;; SImode pushes.
16263 (define_peephole2
16264   [(set (match_operand:SF 0 "push_operand")
16265         (match_operand:SF 1 "memory_operand"))
16266    (match_scratch:SF 2 "r")]
16267   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16268    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16269   [(set (match_dup 2) (match_dup 1))
16270    (set (match_dup 0) (match_dup 2))])
16272 ;; Don't move an immediate directly to memory when the instruction
16273 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16274 (define_peephole2
16275   [(match_scratch:SWI124 1 "<r>")
16276    (set (match_operand:SWI124 0 "memory_operand")
16277         (const_int 0))]
16278   "optimize_insn_for_speed_p ()
16279    && ((<MODE>mode == HImode
16280        && TARGET_LCP_STALL)
16281        || (!TARGET_USE_MOV0
16282           && TARGET_SPLIT_LONG_MOVES
16283           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16284    && peep2_regno_dead_p (0, FLAGS_REG)"
16285   [(parallel [(set (match_dup 2) (const_int 0))
16286               (clobber (reg:CC FLAGS_REG))])
16287    (set (match_dup 0) (match_dup 1))]
16288   "operands[2] = gen_lowpart (SImode, operands[1]);")
16290 (define_peephole2
16291   [(match_scratch:SWI124 2 "<r>")
16292    (set (match_operand:SWI124 0 "memory_operand")
16293         (match_operand:SWI124 1 "immediate_operand"))]
16294   "optimize_insn_for_speed_p ()
16295    && ((<MODE>mode == HImode
16296        && TARGET_LCP_STALL)
16297        || (TARGET_SPLIT_LONG_MOVES
16298           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16299   [(set (match_dup 2) (match_dup 1))
16300    (set (match_dup 0) (match_dup 2))])
16302 ;; Don't compare memory with zero, load and use a test instead.
16303 (define_peephole2
16304   [(set (match_operand 0 "flags_reg_operand")
16305         (match_operator 1 "compare_operator"
16306           [(match_operand:SI 2 "memory_operand")
16307            (const_int 0)]))
16308    (match_scratch:SI 3 "r")]
16309   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16310   [(set (match_dup 3) (match_dup 2))
16311    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16313 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16314 ;; Don't split NOTs with a displacement operand, because resulting XOR
16315 ;; will not be pairable anyway.
16317 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16318 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16319 ;; so this split helps here as well.
16321 ;; Note: Can't do this as a regular split because we can't get proper
16322 ;; lifetime information then.
16324 (define_peephole2
16325   [(set (match_operand:SWI124 0 "nonimmediate_operand")
16326         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
16327   "optimize_insn_for_speed_p ()
16328    && ((TARGET_NOT_UNPAIRABLE
16329         && (!MEM_P (operands[0])
16330             || !memory_displacement_operand (operands[0], <MODE>mode)))
16331        || (TARGET_NOT_VECTORMODE
16332            && long_memory_operand (operands[0], <MODE>mode)))
16333    && peep2_regno_dead_p (0, FLAGS_REG)"
16334   [(parallel [(set (match_dup 0)
16335                    (xor:SWI124 (match_dup 1) (const_int -1)))
16336               (clobber (reg:CC FLAGS_REG))])])
16338 ;; Non pairable "test imm, reg" instructions can be translated to
16339 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16340 ;; byte opcode instead of two, have a short form for byte operands),
16341 ;; so do it for other CPUs as well.  Given that the value was dead,
16342 ;; this should not create any new dependencies.  Pass on the sub-word
16343 ;; versions if we're concerned about partial register stalls.
16345 (define_peephole2
16346   [(set (match_operand 0 "flags_reg_operand")
16347         (match_operator 1 "compare_operator"
16348           [(and:SI (match_operand:SI 2 "register_operand")
16349                    (match_operand:SI 3 "immediate_operand"))
16350            (const_int 0)]))]
16351   "ix86_match_ccmode (insn, CCNOmode)
16352    && (true_regnum (operands[2]) != AX_REG
16353        || satisfies_constraint_K (operands[3]))
16354    && peep2_reg_dead_p (1, operands[2])"
16355   [(parallel
16356      [(set (match_dup 0)
16357            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16358                             (const_int 0)]))
16359       (set (match_dup 2)
16360            (and:SI (match_dup 2) (match_dup 3)))])])
16362 ;; We don't need to handle HImode case, because it will be promoted to SImode
16363 ;; on ! TARGET_PARTIAL_REG_STALL
16365 (define_peephole2
16366   [(set (match_operand 0 "flags_reg_operand")
16367         (match_operator 1 "compare_operator"
16368           [(and:QI (match_operand:QI 2 "register_operand")
16369                    (match_operand:QI 3 "immediate_operand"))
16370            (const_int 0)]))]
16371   "! TARGET_PARTIAL_REG_STALL
16372    && ix86_match_ccmode (insn, CCNOmode)
16373    && true_regnum (operands[2]) != AX_REG
16374    && peep2_reg_dead_p (1, operands[2])"
16375   [(parallel
16376      [(set (match_dup 0)
16377            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16378                             (const_int 0)]))
16379       (set (match_dup 2)
16380            (and:QI (match_dup 2) (match_dup 3)))])])
16382 (define_peephole2
16383   [(set (match_operand 0 "flags_reg_operand")
16384         (match_operator 1 "compare_operator"
16385           [(and:SI
16386              (zero_extract:SI
16387                (match_operand 2 "ext_register_operand")
16388                (const_int 8)
16389                (const_int 8))
16390              (match_operand 3 "const_int_operand"))
16391            (const_int 0)]))]
16392   "! TARGET_PARTIAL_REG_STALL
16393    && ix86_match_ccmode (insn, CCNOmode)
16394    && true_regnum (operands[2]) != AX_REG
16395    && peep2_reg_dead_p (1, operands[2])"
16396   [(parallel [(set (match_dup 0)
16397                    (match_op_dup 1
16398                      [(and:SI
16399                         (zero_extract:SI
16400                           (match_dup 2)
16401                           (const_int 8)
16402                           (const_int 8))
16403                         (match_dup 3))
16404                       (const_int 0)]))
16405               (set (zero_extract:SI (match_dup 2)
16406                                     (const_int 8)
16407                                     (const_int 8))
16408                    (and:SI
16409                      (zero_extract:SI
16410                        (match_dup 2)
16411                        (const_int 8)
16412                        (const_int 8))
16413                      (match_dup 3)))])])
16415 ;; Don't do logical operations with memory inputs.
16416 (define_peephole2
16417   [(match_scratch:SI 2 "r")
16418    (parallel [(set (match_operand:SI 0 "register_operand")
16419                    (match_operator:SI 3 "arith_or_logical_operator"
16420                      [(match_dup 0)
16421                       (match_operand:SI 1 "memory_operand")]))
16422               (clobber (reg:CC FLAGS_REG))])]
16423   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16424   [(set (match_dup 2) (match_dup 1))
16425    (parallel [(set (match_dup 0)
16426                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16427               (clobber (reg:CC FLAGS_REG))])])
16429 (define_peephole2
16430   [(match_scratch:SI 2 "r")
16431    (parallel [(set (match_operand:SI 0 "register_operand")
16432                    (match_operator:SI 3 "arith_or_logical_operator"
16433                      [(match_operand:SI 1 "memory_operand")
16434                       (match_dup 0)]))
16435               (clobber (reg:CC FLAGS_REG))])]
16436   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16437   [(set (match_dup 2) (match_dup 1))
16438    (parallel [(set (match_dup 0)
16439                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16440               (clobber (reg:CC FLAGS_REG))])])
16442 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
16443 ;; refers to the destination of the load!
16445 (define_peephole2
16446   [(set (match_operand:SI 0 "register_operand")
16447         (match_operand:SI 1 "register_operand"))
16448    (parallel [(set (match_dup 0)
16449                    (match_operator:SI 3 "commutative_operator"
16450                      [(match_dup 0)
16451                       (match_operand:SI 2 "memory_operand")]))
16452               (clobber (reg:CC FLAGS_REG))])]
16453   "REGNO (operands[0]) != REGNO (operands[1])
16454    && GENERAL_REGNO_P (REGNO (operands[0]))
16455    && GENERAL_REGNO_P (REGNO (operands[1]))"
16456   [(set (match_dup 0) (match_dup 4))
16457    (parallel [(set (match_dup 0)
16458                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16459               (clobber (reg:CC FLAGS_REG))])]
16460   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16462 (define_peephole2
16463   [(set (match_operand 0 "register_operand")
16464         (match_operand 1 "register_operand"))
16465    (set (match_dup 0)
16466                    (match_operator 3 "commutative_operator"
16467                      [(match_dup 0)
16468                       (match_operand 2 "memory_operand")]))]
16469   "REGNO (operands[0]) != REGNO (operands[1])
16470    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
16471        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16472   [(set (match_dup 0) (match_dup 2))
16473    (set (match_dup 0)
16474         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16476 ; Don't do logical operations with memory outputs
16478 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16479 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
16480 ; the same decoder scheduling characteristics as the original.
16482 (define_peephole2
16483   [(match_scratch:SI 2 "r")
16484    (parallel [(set (match_operand:SI 0 "memory_operand")
16485                    (match_operator:SI 3 "arith_or_logical_operator"
16486                      [(match_dup 0)
16487                       (match_operand:SI 1 "nonmemory_operand")]))
16488               (clobber (reg:CC FLAGS_REG))])]
16489   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16490    /* Do not split stack checking probes.  */
16491    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16492   [(set (match_dup 2) (match_dup 0))
16493    (parallel [(set (match_dup 2)
16494                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16495               (clobber (reg:CC FLAGS_REG))])
16496    (set (match_dup 0) (match_dup 2))])
16498 (define_peephole2
16499   [(match_scratch:SI 2 "r")
16500    (parallel [(set (match_operand:SI 0 "memory_operand")
16501                    (match_operator:SI 3 "arith_or_logical_operator"
16502                      [(match_operand:SI 1 "nonmemory_operand")
16503                       (match_dup 0)]))
16504               (clobber (reg:CC FLAGS_REG))])]
16505   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16506    /* Do not split stack checking probes.  */
16507    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16508   [(set (match_dup 2) (match_dup 0))
16509    (parallel [(set (match_dup 2)
16510                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16511               (clobber (reg:CC FLAGS_REG))])
16512    (set (match_dup 0) (match_dup 2))])
16514 ;; Attempt to use arith or logical operations with memory outputs with
16515 ;; setting of flags.
16516 (define_peephole2
16517   [(set (match_operand:SWI 0 "register_operand")
16518         (match_operand:SWI 1 "memory_operand"))
16519    (parallel [(set (match_dup 0)
16520                    (match_operator:SWI 3 "plusminuslogic_operator"
16521                      [(match_dup 0)
16522                       (match_operand:SWI 2 "<nonmemory_operand>")]))
16523               (clobber (reg:CC FLAGS_REG))])
16524    (set (match_dup 1) (match_dup 0))
16525    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16526   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16527    && peep2_reg_dead_p (4, operands[0])
16528    && !reg_overlap_mentioned_p (operands[0], operands[1])
16529    && (<MODE>mode != QImode
16530        || immediate_operand (operands[2], QImode)
16531        || q_regs_operand (operands[2], QImode))
16532    && ix86_match_ccmode (peep2_next_insn (3),
16533                          (GET_CODE (operands[3]) == PLUS
16534                           || GET_CODE (operands[3]) == MINUS)
16535                          ? CCGOCmode : CCNOmode)"
16536   [(parallel [(set (match_dup 4) (match_dup 5))
16537               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
16538                                                   (match_dup 2)]))])]
16540   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16541   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16542                                 copy_rtx (operands[1]),
16543                                 copy_rtx (operands[2]));
16544   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16545                                  operands[5], const0_rtx);
16548 (define_peephole2
16549   [(parallel [(set (match_operand:SWI 0 "register_operand")
16550                    (match_operator:SWI 2 "plusminuslogic_operator"
16551                      [(match_dup 0)
16552                       (match_operand:SWI 1 "memory_operand")]))
16553               (clobber (reg:CC FLAGS_REG))])
16554    (set (match_dup 1) (match_dup 0))
16555    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16556   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16557    && GET_CODE (operands[2]) != MINUS
16558    && peep2_reg_dead_p (3, operands[0])
16559    && !reg_overlap_mentioned_p (operands[0], operands[1])
16560    && ix86_match_ccmode (peep2_next_insn (2),
16561                          GET_CODE (operands[2]) == PLUS
16562                          ? CCGOCmode : CCNOmode)"
16563   [(parallel [(set (match_dup 3) (match_dup 4))
16564               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
16565                                                   (match_dup 0)]))])]
16567   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
16568   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
16569                                 copy_rtx (operands[1]),
16570                                 copy_rtx (operands[0]));
16571   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
16572                                  operands[4], const0_rtx);
16575 (define_peephole2
16576   [(set (match_operand:SWI12 0 "register_operand")
16577         (match_operand:SWI12 1 "memory_operand"))
16578    (parallel [(set (match_operand:SI 4 "register_operand")
16579                    (match_operator:SI 3 "plusminuslogic_operator"
16580                      [(match_dup 4)
16581                       (match_operand:SI 2 "nonmemory_operand")]))
16582               (clobber (reg:CC FLAGS_REG))])
16583    (set (match_dup 1) (match_dup 0))
16584    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16585   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16586    && REG_P (operands[0]) && REG_P (operands[4])
16587    && REGNO (operands[0]) == REGNO (operands[4])
16588    && peep2_reg_dead_p (4, operands[0])
16589    && (<MODE>mode != QImode
16590        || immediate_operand (operands[2], SImode)
16591        || q_regs_operand (operands[2], SImode))
16592    && !reg_overlap_mentioned_p (operands[0], operands[1])
16593    && ix86_match_ccmode (peep2_next_insn (3),
16594                          (GET_CODE (operands[3]) == PLUS
16595                           || GET_CODE (operands[3]) == MINUS)
16596                          ? CCGOCmode : CCNOmode)"
16597   [(parallel [(set (match_dup 4) (match_dup 5))
16598               (set (match_dup 1) (match_dup 6))])]
16600   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
16601   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16602   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16603                                 copy_rtx (operands[1]), operands[2]);
16604   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16605                                  operands[5], const0_rtx);
16606   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16607                                 copy_rtx (operands[1]),
16608                                 copy_rtx (operands[2]));
16611 ;; Attempt to always use XOR for zeroing registers.
16612 (define_peephole2
16613   [(set (match_operand 0 "register_operand")
16614         (match_operand 1 "const0_operand"))]
16615   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16616    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16617    && GENERAL_REG_P (operands[0])
16618    && peep2_regno_dead_p (0, FLAGS_REG)"
16619   [(parallel [(set (match_dup 0) (const_int 0))
16620               (clobber (reg:CC FLAGS_REG))])]
16621   "operands[0] = gen_lowpart (word_mode, operands[0]);")
16623 (define_peephole2
16624   [(set (strict_low_part (match_operand 0 "register_operand"))
16625         (const_int 0))]
16626   "(GET_MODE (operands[0]) == QImode
16627     || GET_MODE (operands[0]) == HImode)
16628    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16629    && peep2_regno_dead_p (0, FLAGS_REG)"
16630   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16631               (clobber (reg:CC FLAGS_REG))])])
16633 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16634 (define_peephole2
16635   [(set (match_operand:SWI248 0 "register_operand")
16636         (const_int -1))]
16637   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16638    && peep2_regno_dead_p (0, FLAGS_REG)"
16639   [(parallel [(set (match_dup 0) (const_int -1))
16640               (clobber (reg:CC FLAGS_REG))])]
16642   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16643     operands[0] = gen_lowpart (SImode, operands[0]);
16646 ;; Attempt to convert simple lea to add/shift.
16647 ;; These can be created by move expanders.
16648 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
16649 ;; relevant lea instructions were already split.
16651 (define_peephole2
16652   [(set (match_operand:SWI48 0 "register_operand")
16653         (plus:SWI48 (match_dup 0)
16654                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
16655   "!TARGET_OPT_AGU
16656    && peep2_regno_dead_p (0, FLAGS_REG)"
16657   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16658               (clobber (reg:CC FLAGS_REG))])])
16660 (define_peephole2
16661   [(set (match_operand:SWI48 0 "register_operand")
16662         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
16663                     (match_dup 0)))]
16664   "!TARGET_OPT_AGU
16665    && peep2_regno_dead_p (0, FLAGS_REG)"
16666   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16667               (clobber (reg:CC FLAGS_REG))])])
16669 (define_peephole2
16670   [(set (match_operand:DI 0 "register_operand")
16671         (zero_extend:DI
16672           (plus:SI (match_operand:SI 1 "register_operand")
16673                    (match_operand:SI 2 "nonmemory_operand"))))]
16674   "TARGET_64BIT && !TARGET_OPT_AGU
16675    && REGNO (operands[0]) == REGNO (operands[1])
16676    && peep2_regno_dead_p (0, FLAGS_REG)"
16677   [(parallel [(set (match_dup 0)
16678                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
16679               (clobber (reg:CC FLAGS_REG))])])
16681 (define_peephole2
16682   [(set (match_operand:DI 0 "register_operand")
16683         (zero_extend:DI
16684           (plus:SI (match_operand:SI 1 "nonmemory_operand")
16685                    (match_operand:SI 2 "register_operand"))))]
16686   "TARGET_64BIT && !TARGET_OPT_AGU
16687    && REGNO (operands[0]) == REGNO (operands[2])
16688    && peep2_regno_dead_p (0, FLAGS_REG)"
16689   [(parallel [(set (match_dup 0)
16690                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
16691               (clobber (reg:CC FLAGS_REG))])])
16693 (define_peephole2
16694   [(set (match_operand:SWI48 0 "register_operand")
16695         (mult:SWI48 (match_dup 0)
16696                     (match_operand:SWI48 1 "const_int_operand")))]
16697   "exact_log2 (INTVAL (operands[1])) >= 0
16698    && peep2_regno_dead_p (0, FLAGS_REG)"
16699   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
16700               (clobber (reg:CC FLAGS_REG))])]
16701   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16703 (define_peephole2
16704   [(set (match_operand:DI 0 "register_operand")
16705         (zero_extend:DI
16706           (mult:SI (match_operand:SI 1 "register_operand")
16707                    (match_operand:SI 2 "const_int_operand"))))]
16708   "TARGET_64BIT
16709    && exact_log2 (INTVAL (operands[2])) >= 0
16710    && REGNO (operands[0]) == REGNO (operands[1])
16711    && peep2_regno_dead_p (0, FLAGS_REG)"
16712   [(parallel [(set (match_dup 0)
16713                    (zero_extend (ashift:SI (match_dup 1) (match_dup 2))))
16714               (clobber (reg:CC FLAGS_REG))])]
16715   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16717 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
16718 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16719 ;; On many CPUs it is also faster, since special hardware to avoid esp
16720 ;; dependencies is present.
16722 ;; While some of these conversions may be done using splitters, we use
16723 ;; peepholes in order to allow combine_stack_adjustments pass to see
16724 ;; nonobfuscated RTL.
16726 ;; Convert prologue esp subtractions to push.
16727 ;; We need register to push.  In order to keep verify_flow_info happy we have
16728 ;; two choices
16729 ;; - use scratch and clobber it in order to avoid dependencies
16730 ;; - use already live register
16731 ;; We can't use the second way right now, since there is no reliable way how to
16732 ;; verify that given register is live.  First choice will also most likely in
16733 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
16734 ;; call clobbered registers are dead.  We may want to use base pointer as an
16735 ;; alternative when no register is available later.
16737 (define_peephole2
16738   [(match_scratch:W 1 "r")
16739    (parallel [(set (reg:P SP_REG)
16740                    (plus:P (reg:P SP_REG)
16741                            (match_operand:P 0 "const_int_operand")))
16742               (clobber (reg:CC FLAGS_REG))
16743               (clobber (mem:BLK (scratch)))])]
16744   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16745    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
16746   [(clobber (match_dup 1))
16747    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16748               (clobber (mem:BLK (scratch)))])])
16750 (define_peephole2
16751   [(match_scratch:W 1 "r")
16752    (parallel [(set (reg:P SP_REG)
16753                    (plus:P (reg:P SP_REG)
16754                            (match_operand:P 0 "const_int_operand")))
16755               (clobber (reg:CC FLAGS_REG))
16756               (clobber (mem:BLK (scratch)))])]
16757   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16758    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
16759   [(clobber (match_dup 1))
16760    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16761    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16762               (clobber (mem:BLK (scratch)))])])
16764 ;; Convert esp subtractions to push.
16765 (define_peephole2
16766   [(match_scratch:W 1 "r")
16767    (parallel [(set (reg:P SP_REG)
16768                    (plus:P (reg:P SP_REG)
16769                            (match_operand:P 0 "const_int_operand")))
16770               (clobber (reg:CC FLAGS_REG))])]
16771   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16772    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
16773   [(clobber (match_dup 1))
16774    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16776 (define_peephole2
16777   [(match_scratch:W 1 "r")
16778    (parallel [(set (reg:P SP_REG)
16779                    (plus:P (reg:P SP_REG)
16780                            (match_operand:P 0 "const_int_operand")))
16781               (clobber (reg:CC FLAGS_REG))])]
16782   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16783    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
16784   [(clobber (match_dup 1))
16785    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16786    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16788 ;; Convert epilogue deallocator to pop.
16789 (define_peephole2
16790   [(match_scratch:W 1 "r")
16791    (parallel [(set (reg:P SP_REG)
16792                    (plus:P (reg:P SP_REG)
16793                            (match_operand:P 0 "const_int_operand")))
16794               (clobber (reg:CC FLAGS_REG))
16795               (clobber (mem:BLK (scratch)))])]
16796   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
16797    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
16798   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16799               (clobber (mem:BLK (scratch)))])])
16801 ;; Two pops case is tricky, since pop causes dependency
16802 ;; on destination register.  We use two registers if available.
16803 (define_peephole2
16804   [(match_scratch:W 1 "r")
16805    (match_scratch:W 2 "r")
16806    (parallel [(set (reg:P SP_REG)
16807                    (plus:P (reg:P SP_REG)
16808                            (match_operand:P 0 "const_int_operand")))
16809               (clobber (reg:CC FLAGS_REG))
16810               (clobber (mem:BLK (scratch)))])]
16811   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
16812    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
16813   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16814               (clobber (mem:BLK (scratch)))])
16815    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
16817 (define_peephole2
16818   [(match_scratch:W 1 "r")
16819    (parallel [(set (reg:P SP_REG)
16820                    (plus:P (reg:P SP_REG)
16821                            (match_operand:P 0 "const_int_operand")))
16822               (clobber (reg:CC FLAGS_REG))
16823               (clobber (mem:BLK (scratch)))])]
16824   "optimize_insn_for_size_p ()
16825    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
16826   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16827               (clobber (mem:BLK (scratch)))])
16828    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
16830 ;; Convert esp additions to pop.
16831 (define_peephole2
16832   [(match_scratch:W 1 "r")
16833    (parallel [(set (reg:P SP_REG)
16834                    (plus:P (reg:P SP_REG)
16835                            (match_operand:P 0 "const_int_operand")))
16836               (clobber (reg:CC FLAGS_REG))])]
16837   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
16838   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
16840 ;; Two pops case is tricky, since pop causes dependency
16841 ;; on destination register.  We use two registers if available.
16842 (define_peephole2
16843   [(match_scratch:W 1 "r")
16844    (match_scratch:W 2 "r")
16845    (parallel [(set (reg:P SP_REG)
16846                    (plus:P (reg:P SP_REG)
16847                            (match_operand:P 0 "const_int_operand")))
16848               (clobber (reg:CC FLAGS_REG))])]
16849   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
16850   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16851    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
16853 (define_peephole2
16854   [(match_scratch:W 1 "r")
16855    (parallel [(set (reg:P SP_REG)
16856                    (plus:P (reg:P SP_REG)
16857                            (match_operand:P 0 "const_int_operand")))
16858               (clobber (reg:CC FLAGS_REG))])]
16859   "optimize_insn_for_size_p ()
16860    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
16861   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16862    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
16864 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
16865 ;; required and register dies.  Similarly for 128 to -128.
16866 (define_peephole2
16867   [(set (match_operand 0 "flags_reg_operand")
16868         (match_operator 1 "compare_operator"
16869           [(match_operand 2 "register_operand")
16870            (match_operand 3 "const_int_operand")]))]
16871   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
16872      && incdec_operand (operands[3], GET_MODE (operands[3])))
16873     || (!TARGET_FUSE_CMP_AND_BRANCH
16874         && INTVAL (operands[3]) == 128))
16875    && ix86_match_ccmode (insn, CCGCmode)
16876    && peep2_reg_dead_p (1, operands[2])"
16877   [(parallel [(set (match_dup 0)
16878                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
16879               (clobber (match_dup 2))])])
16881 ;; Convert imul by three, five and nine into lea
16882 (define_peephole2
16883   [(parallel
16884     [(set (match_operand:SWI48 0 "register_operand")
16885           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
16886                       (match_operand:SWI48 2 "const359_operand")))
16887      (clobber (reg:CC FLAGS_REG))])]
16888   "!TARGET_PARTIAL_REG_STALL
16889    || <MODE>mode == SImode
16890    || optimize_function_for_size_p (cfun)"
16891   [(set (match_dup 0)
16892         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
16893                     (match_dup 1)))]
16894   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
16896 (define_peephole2
16897   [(parallel
16898     [(set (match_operand:SWI48 0 "register_operand")
16899           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
16900                       (match_operand:SWI48 2 "const359_operand")))
16901      (clobber (reg:CC FLAGS_REG))])]
16902   "optimize_insn_for_speed_p ()
16903    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
16904   [(set (match_dup 0) (match_dup 1))
16905    (set (match_dup 0)
16906         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
16907                     (match_dup 0)))]
16908   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
16910 ;; imul $32bit_imm, mem, reg is vector decoded, while
16911 ;; imul $32bit_imm, reg, reg is direct decoded.
16912 (define_peephole2
16913   [(match_scratch:SWI48 3 "r")
16914    (parallel [(set (match_operand:SWI48 0 "register_operand")
16915                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
16916                                (match_operand:SWI48 2 "immediate_operand")))
16917               (clobber (reg:CC FLAGS_REG))])]
16918   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
16919    && !satisfies_constraint_K (operands[2])"
16920   [(set (match_dup 3) (match_dup 1))
16921    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
16922               (clobber (reg:CC FLAGS_REG))])])
16924 (define_peephole2
16925   [(match_scratch:SI 3 "r")
16926    (parallel [(set (match_operand:DI 0 "register_operand")
16927                    (zero_extend:DI
16928                      (mult:SI (match_operand:SI 1 "memory_operand")
16929                               (match_operand:SI 2 "immediate_operand"))))
16930               (clobber (reg:CC FLAGS_REG))])]
16931   "TARGET_64BIT
16932    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
16933    && !satisfies_constraint_K (operands[2])"
16934   [(set (match_dup 3) (match_dup 1))
16935    (parallel [(set (match_dup 0)
16936                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
16937               (clobber (reg:CC FLAGS_REG))])])
16939 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
16940 ;; Convert it into imul reg, reg
16941 ;; It would be better to force assembler to encode instruction using long
16942 ;; immediate, but there is apparently no way to do so.
16943 (define_peephole2
16944   [(parallel [(set (match_operand:SWI248 0 "register_operand")
16945                    (mult:SWI248
16946                     (match_operand:SWI248 1 "nonimmediate_operand")
16947                     (match_operand:SWI248 2 "const_int_operand")))
16948               (clobber (reg:CC FLAGS_REG))])
16949    (match_scratch:SWI248 3 "r")]
16950   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
16951    && satisfies_constraint_K (operands[2])"
16952   [(set (match_dup 3) (match_dup 2))
16953    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
16954               (clobber (reg:CC FLAGS_REG))])]
16956   if (!rtx_equal_p (operands[0], operands[1]))
16957     emit_move_insn (operands[0], operands[1]);
16960 ;; After splitting up read-modify operations, array accesses with memory
16961 ;; operands might end up in form:
16962 ;;  sall    $2, %eax
16963 ;;  movl    4(%esp), %edx
16964 ;;  addl    %edx, %eax
16965 ;; instead of pre-splitting:
16966 ;;  sall    $2, %eax
16967 ;;  addl    4(%esp), %eax
16968 ;; Turn it into:
16969 ;;  movl    4(%esp), %edx
16970 ;;  leal    (%edx,%eax,4), %eax
16972 (define_peephole2
16973   [(match_scratch:W 5 "r")
16974    (parallel [(set (match_operand 0 "register_operand")
16975                    (ashift (match_operand 1 "register_operand")
16976                            (match_operand 2 "const_int_operand")))
16977                (clobber (reg:CC FLAGS_REG))])
16978    (parallel [(set (match_operand 3 "register_operand")
16979                    (plus (match_dup 0)
16980                          (match_operand 4 "x86_64_general_operand")))
16981                    (clobber (reg:CC FLAGS_REG))])]
16982   "IN_RANGE (INTVAL (operands[2]), 1, 3)
16983    /* Validate MODE for lea.  */
16984    && ((!TARGET_PARTIAL_REG_STALL
16985         && (GET_MODE (operands[0]) == QImode
16986             || GET_MODE (operands[0]) == HImode))
16987        || GET_MODE (operands[0]) == SImode
16988        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
16989    && (rtx_equal_p (operands[0], operands[3])
16990        || peep2_reg_dead_p (2, operands[0]))
16991    /* We reorder load and the shift.  */
16992    && !reg_overlap_mentioned_p (operands[0], operands[4])"
16993   [(set (match_dup 5) (match_dup 4))
16994    (set (match_dup 0) (match_dup 1))]
16996   enum machine_mode op1mode = GET_MODE (operands[1]);
16997   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
16998   int scale = 1 << INTVAL (operands[2]);
16999   rtx index = gen_lowpart (word_mode, operands[1]);
17000   rtx base = gen_lowpart (word_mode, operands[5]);
17001   rtx dest = gen_lowpart (mode, operands[3]);
17003   operands[1] = gen_rtx_PLUS (word_mode, base,
17004                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17005   operands[5] = base;
17006   if (mode != word_mode)
17007     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17008   if (op1mode != word_mode)
17009     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17010   operands[0] = dest;
17013 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17014 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17015 ;; caught for use by garbage collectors and the like.  Using an insn that
17016 ;; maps to SIGILL makes it more likely the program will rightfully die.
17017 ;; Keeping with tradition, "6" is in honor of #UD.
17018 (define_insn "trap"
17019   [(trap_if (const_int 1) (const_int 6))]
17020   ""
17021   { return ASM_SHORT "0x0b0f"; }
17022   [(set_attr "length" "2")])
17024 (define_expand "prefetch"
17025   [(prefetch (match_operand 0 "address_operand")
17026              (match_operand:SI 1 "const_int_operand")
17027              (match_operand:SI 2 "const_int_operand"))]
17028   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17030   int rw = INTVAL (operands[1]);
17031   int locality = INTVAL (operands[2]);
17033   gcc_assert (rw == 0 || rw == 1);
17034   gcc_assert (IN_RANGE (locality, 0, 3));
17036   if (TARGET_PRFCHW && rw)
17037     operands[2] = GEN_INT (3);
17038   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17039      supported by SSE counterpart or the SSE prefetch is not available
17040      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17041      of locality.  */
17042   else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17043     operands[2] = GEN_INT (3);
17044   else
17045     operands[1] = const0_rtx;
17048 (define_insn "*prefetch_sse"
17049   [(prefetch (match_operand 0 "address_operand" "p")
17050              (const_int 0)
17051              (match_operand:SI 1 "const_int_operand"))]
17052   "TARGET_PREFETCH_SSE"
17054   static const char * const patterns[4] = {
17055    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17056   };
17058   int locality = INTVAL (operands[1]);
17059   gcc_assert (IN_RANGE (locality, 0, 3));
17061   return patterns[locality];
17063   [(set_attr "type" "sse")
17064    (set_attr "atom_sse_attr" "prefetch")
17065    (set (attr "length_address")
17066         (symbol_ref "memory_address_length (operands[0], false)"))
17067    (set_attr "memory" "none")])
17069 (define_insn "*prefetch_3dnow"
17070   [(prefetch (match_operand 0 "address_operand" "p")
17071              (match_operand:SI 1 "const_int_operand" "n")
17072              (const_int 3))]
17073   "TARGET_3DNOW || TARGET_PRFCHW"
17075   if (INTVAL (operands[1]) == 0)
17076     return "prefetch\t%a0";
17077   else
17078     return "prefetchw\t%a0";
17080   [(set_attr "type" "mmx")
17081    (set (attr "length_address")
17082         (symbol_ref "memory_address_length (operands[0], false)"))
17083    (set_attr "memory" "none")])
17085 (define_expand "stack_protect_set"
17086   [(match_operand 0 "memory_operand")
17087    (match_operand 1 "memory_operand")]
17088   "TARGET_SSP_TLS_GUARD"
17090   rtx (*insn)(rtx, rtx);
17092 #ifdef TARGET_THREAD_SSP_OFFSET
17093   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17094   insn = (TARGET_LP64
17095           ? gen_stack_tls_protect_set_di
17096           : gen_stack_tls_protect_set_si);
17097 #else
17098   insn = (TARGET_LP64
17099           ? gen_stack_protect_set_di
17100           : gen_stack_protect_set_si);
17101 #endif
17103   emit_insn (insn (operands[0], operands[1]));
17104   DONE;
17107 (define_insn "stack_protect_set_<mode>"
17108   [(set (match_operand:PTR 0 "memory_operand" "=m")
17109         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17110                     UNSPEC_SP_SET))
17111    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17112    (clobber (reg:CC FLAGS_REG))]
17113   "TARGET_SSP_TLS_GUARD"
17114   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17115   [(set_attr "type" "multi")])
17117 (define_insn "stack_tls_protect_set_<mode>"
17118   [(set (match_operand:PTR 0 "memory_operand" "=m")
17119         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17120                     UNSPEC_SP_TLS_SET))
17121    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17122    (clobber (reg:CC FLAGS_REG))]
17123   ""
17124   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17125   [(set_attr "type" "multi")])
17127 (define_expand "stack_protect_test"
17128   [(match_operand 0 "memory_operand")
17129    (match_operand 1 "memory_operand")
17130    (match_operand 2)]
17131   "TARGET_SSP_TLS_GUARD"
17133   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17135   rtx (*insn)(rtx, rtx, rtx);
17137 #ifdef TARGET_THREAD_SSP_OFFSET
17138   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17139   insn = (TARGET_LP64
17140           ? gen_stack_tls_protect_test_di
17141           : gen_stack_tls_protect_test_si);
17142 #else
17143   insn = (TARGET_LP64
17144           ? gen_stack_protect_test_di
17145           : gen_stack_protect_test_si);
17146 #endif
17148   emit_insn (insn (flags, operands[0], operands[1]));
17150   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17151                                   flags, const0_rtx, operands[2]));
17152   DONE;
17155 (define_insn "stack_protect_test_<mode>"
17156   [(set (match_operand:CCZ 0 "flags_reg_operand")
17157         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17158                      (match_operand:PTR 2 "memory_operand" "m")]
17159                     UNSPEC_SP_TEST))
17160    (clobber (match_scratch:PTR 3 "=&r"))]
17161   "TARGET_SSP_TLS_GUARD"
17162   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17163   [(set_attr "type" "multi")])
17165 (define_insn "stack_tls_protect_test_<mode>"
17166   [(set (match_operand:CCZ 0 "flags_reg_operand")
17167         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17168                      (match_operand:PTR 2 "const_int_operand" "i")]
17169                     UNSPEC_SP_TLS_TEST))
17170    (clobber (match_scratch:PTR 3 "=r"))]
17171   ""
17172   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17173   [(set_attr "type" "multi")])
17175 (define_insn "sse4_2_crc32<mode>"
17176   [(set (match_operand:SI 0 "register_operand" "=r")
17177         (unspec:SI
17178           [(match_operand:SI 1 "register_operand" "0")
17179            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17180           UNSPEC_CRC32))]
17181   "TARGET_SSE4_2 || TARGET_CRC32"
17182   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17183   [(set_attr "type" "sselog1")
17184    (set_attr "prefix_rep" "1")
17185    (set_attr "prefix_extra" "1")
17186    (set (attr "prefix_data16")
17187      (if_then_else (match_operand:HI 2)
17188        (const_string "1")
17189        (const_string "*")))
17190    (set (attr "prefix_rex")
17191      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17192        (const_string "1")
17193        (const_string "*")))
17194    (set_attr "mode" "SI")])
17196 (define_insn "sse4_2_crc32di"
17197   [(set (match_operand:DI 0 "register_operand" "=r")
17198         (unspec:DI
17199           [(match_operand:DI 1 "register_operand" "0")
17200            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17201           UNSPEC_CRC32))]
17202   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17203   "crc32{q}\t{%2, %0|%0, %2}"
17204   [(set_attr "type" "sselog1")
17205    (set_attr "prefix_rep" "1")
17206    (set_attr "prefix_extra" "1")
17207    (set_attr "mode" "DI")])
17209 (define_insn "rdpmc"
17210   [(set (match_operand:DI 0 "register_operand" "=A")
17211         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17212                             UNSPECV_RDPMC))]
17213   "!TARGET_64BIT"
17214   "rdpmc"
17215   [(set_attr "type" "other")
17216    (set_attr "length" "2")])
17218 (define_insn "rdpmc_rex64"
17219   [(set (match_operand:DI 0 "register_operand" "=a")
17220         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17221                             UNSPECV_RDPMC))
17222    (set (match_operand:DI 1 "register_operand" "=d")
17223         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
17224   "TARGET_64BIT"
17225   "rdpmc"
17226   [(set_attr "type" "other")
17227    (set_attr "length" "2")])
17229 (define_insn "rdtsc"
17230   [(set (match_operand:DI 0 "register_operand" "=A")
17231         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17232   "!TARGET_64BIT"
17233   "rdtsc"
17234   [(set_attr "type" "other")
17235    (set_attr "length" "2")])
17237 (define_insn "rdtsc_rex64"
17238   [(set (match_operand:DI 0 "register_operand" "=a")
17239         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17240    (set (match_operand:DI 1 "register_operand" "=d")
17241         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17242   "TARGET_64BIT"
17243   "rdtsc"
17244   [(set_attr "type" "other")
17245    (set_attr "length" "2")])
17247 (define_insn "rdtscp"
17248   [(set (match_operand:DI 0 "register_operand" "=A")
17249         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17250    (set (match_operand:SI 1 "register_operand" "=c")
17251         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17252   "!TARGET_64BIT"
17253   "rdtscp"
17254   [(set_attr "type" "other")
17255    (set_attr "length" "3")])
17257 (define_insn "rdtscp_rex64"
17258   [(set (match_operand:DI 0 "register_operand" "=a")
17259         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17260    (set (match_operand:DI 1 "register_operand" "=d")
17261         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17262    (set (match_operand:SI 2 "register_operand" "=c")
17263         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17264   "TARGET_64BIT"
17265   "rdtscp"
17266   [(set_attr "type" "other")
17267    (set_attr "length" "3")])
17269 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17271 ;; FXSR, XSAVE and XSAVEOPT instructions
17273 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17275 (define_insn "fxsave"
17276   [(set (match_operand:BLK 0 "memory_operand" "=m")
17277         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
17278   "TARGET_FXSR"
17279   "fxsave\t%0"
17280   [(set_attr "type" "other")
17281    (set_attr "memory" "store")
17282    (set (attr "length")
17283         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17285 (define_insn "fxsave64"
17286   [(set (match_operand:BLK 0 "memory_operand" "=m")
17287         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
17288   "TARGET_64BIT && TARGET_FXSR"
17289   "fxsave64\t%0"
17290   [(set_attr "type" "other")
17291    (set_attr "memory" "store")
17292    (set (attr "length")
17293         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17295 (define_insn "fxrstor"
17296   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17297                     UNSPECV_FXRSTOR)]
17298   "TARGET_FXSR"
17299   "fxrstor\t%0"
17300   [(set_attr "type" "other")
17301    (set_attr "memory" "load")
17302    (set (attr "length")
17303         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17305 (define_insn "fxrstor64"
17306   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17307                     UNSPECV_FXRSTOR64)]
17308   "TARGET_64BIT && TARGET_FXSR"
17309   "fxrstor64\t%0"
17310   [(set_attr "type" "other")
17311    (set_attr "memory" "load")
17312    (set (attr "length")
17313         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17315 (define_int_iterator ANY_XSAVE
17316         [UNSPECV_XSAVE
17317          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")])
17319 (define_int_iterator ANY_XSAVE64
17320         [UNSPECV_XSAVE64
17321          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")])
17323 (define_int_attr xsave
17324         [(UNSPECV_XSAVE "xsave")
17325          (UNSPECV_XSAVE64 "xsave64")
17326          (UNSPECV_XSAVEOPT "xsaveopt")
17327          (UNSPECV_XSAVEOPT64 "xsaveopt64")])
17329 (define_insn "<xsave>"
17330   [(set (match_operand:BLK 0 "memory_operand" "=m")
17331         (unspec_volatile:BLK
17332          [(match_operand:DI 1 "register_operand" "A")]
17333          ANY_XSAVE))]
17334   "!TARGET_64BIT && TARGET_XSAVE"
17335   "<xsave>\t%0"
17336   [(set_attr "type" "other")
17337    (set_attr "memory" "store")
17338    (set (attr "length")
17339         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17341 (define_insn "<xsave>_rex64"
17342   [(set (match_operand:BLK 0 "memory_operand" "=m")
17343         (unspec_volatile:BLK
17344          [(match_operand:SI 1 "register_operand" "a")
17345           (match_operand:SI 2 "register_operand" "d")]
17346          ANY_XSAVE))]
17347   "TARGET_64BIT && TARGET_XSAVE"
17348   "<xsave>\t%0"
17349   [(set_attr "type" "other")
17350    (set_attr "memory" "store")
17351    (set (attr "length")
17352         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17354 (define_insn "<xsave>"
17355   [(set (match_operand:BLK 0 "memory_operand" "=m")
17356         (unspec_volatile:BLK
17357          [(match_operand:SI 1 "register_operand" "a")
17358           (match_operand:SI 2 "register_operand" "d")]
17359          ANY_XSAVE64))]
17360   "TARGET_64BIT && TARGET_XSAVE"
17361   "<xsave>\t%0"
17362   [(set_attr "type" "other")
17363    (set_attr "memory" "store")
17364    (set (attr "length")
17365         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17367 (define_insn "xrstor"
17368    [(unspec_volatile:BLK
17369      [(match_operand:BLK 0 "memory_operand" "m")
17370       (match_operand:DI 1 "register_operand" "A")]
17371      UNSPECV_XRSTOR)]
17372   "!TARGET_64BIT && TARGET_XSAVE"
17373   "xrstor\t%0"
17374   [(set_attr "type" "other")
17375    (set_attr "memory" "load")
17376    (set (attr "length")
17377         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17379 (define_insn "xrstor_rex64"
17380    [(unspec_volatile:BLK
17381      [(match_operand:BLK 0 "memory_operand" "m")
17382       (match_operand:SI 1 "register_operand" "a")
17383       (match_operand:SI 2 "register_operand" "d")]
17384      UNSPECV_XRSTOR)]
17385   "TARGET_64BIT && TARGET_XSAVE"
17386   "xrstor\t%0"
17387   [(set_attr "type" "other")
17388    (set_attr "memory" "load")
17389    (set (attr "length")
17390         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17392 (define_insn "xrstor64"
17393    [(unspec_volatile:BLK
17394      [(match_operand:BLK 0 "memory_operand" "m")
17395       (match_operand:SI 1 "register_operand" "a")
17396       (match_operand:SI 2 "register_operand" "d")]
17397      UNSPECV_XRSTOR64)]
17398   "TARGET_64BIT && TARGET_XSAVE"
17399   "xrstor64\t%0"
17400   [(set_attr "type" "other")
17401    (set_attr "memory" "load")
17402    (set (attr "length")
17403         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17405 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17407 ;; LWP instructions
17409 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17411 (define_expand "lwp_llwpcb"
17412   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17413                     UNSPECV_LLWP_INTRINSIC)]
17414   "TARGET_LWP")
17416 (define_insn "*lwp_llwpcb<mode>1"
17417   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17418                     UNSPECV_LLWP_INTRINSIC)]
17419   "TARGET_LWP"
17420   "llwpcb\t%0"
17421   [(set_attr "type" "lwp")
17422    (set_attr "mode" "<MODE>")
17423    (set_attr "length" "5")])
17425 (define_expand "lwp_slwpcb"
17426   [(set (match_operand 0 "register_operand" "=r")
17427         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17428   "TARGET_LWP"
17430   rtx (*insn)(rtx);
17432   insn = (Pmode == DImode
17433           ? gen_lwp_slwpcbdi
17434           : gen_lwp_slwpcbsi);
17436   emit_insn (insn (operands[0]));
17437   DONE;
17440 (define_insn "lwp_slwpcb<mode>"
17441   [(set (match_operand:P 0 "register_operand" "=r")
17442         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17443   "TARGET_LWP"
17444   "slwpcb\t%0"
17445   [(set_attr "type" "lwp")
17446    (set_attr "mode" "<MODE>")
17447    (set_attr "length" "5")])
17449 (define_expand "lwp_lwpval<mode>3"
17450   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17451                      (match_operand:SI 2 "nonimmediate_operand" "rm")
17452                      (match_operand:SI 3 "const_int_operand" "i")]
17453                     UNSPECV_LWPVAL_INTRINSIC)]
17454   "TARGET_LWP"
17455   ;; Avoid unused variable warning.
17456   "(void) operands[0];")
17458 (define_insn "*lwp_lwpval<mode>3_1"
17459   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17460                      (match_operand:SI 1 "nonimmediate_operand" "rm")
17461                      (match_operand:SI 2 "const_int_operand" "i")]
17462                     UNSPECV_LWPVAL_INTRINSIC)]
17463   "TARGET_LWP"
17464   "lwpval\t{%2, %1, %0|%0, %1, %2}"
17465   [(set_attr "type" "lwp")
17466    (set_attr "mode" "<MODE>")
17467    (set (attr "length")
17468         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17470 (define_expand "lwp_lwpins<mode>3"
17471   [(set (reg:CCC FLAGS_REG)
17472         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17473                               (match_operand:SI 2 "nonimmediate_operand" "rm")
17474                               (match_operand:SI 3 "const_int_operand" "i")]
17475                              UNSPECV_LWPINS_INTRINSIC))
17476    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17477         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17478   "TARGET_LWP")
17480 (define_insn "*lwp_lwpins<mode>3_1"
17481   [(set (reg:CCC FLAGS_REG)
17482         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17483                               (match_operand:SI 1 "nonimmediate_operand" "rm")
17484                               (match_operand:SI 2 "const_int_operand" "i")]
17485                              UNSPECV_LWPINS_INTRINSIC))]
17486   "TARGET_LWP"
17487   "lwpins\t{%2, %1, %0|%0, %1, %2}"
17488   [(set_attr "type" "lwp")
17489    (set_attr "mode" "<MODE>")
17490    (set (attr "length")
17491         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17493 (define_int_iterator RDFSGSBASE
17494         [UNSPECV_RDFSBASE
17495          UNSPECV_RDGSBASE])
17497 (define_int_iterator WRFSGSBASE
17498         [UNSPECV_WRFSBASE
17499          UNSPECV_WRGSBASE])
17501 (define_int_attr fsgs
17502         [(UNSPECV_RDFSBASE "fs")
17503          (UNSPECV_RDGSBASE "gs")
17504          (UNSPECV_WRFSBASE "fs")
17505          (UNSPECV_WRGSBASE "gs")])
17507 (define_insn "rd<fsgs>base<mode>"
17508   [(set (match_operand:SWI48 0 "register_operand" "=r")
17509         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
17510   "TARGET_64BIT && TARGET_FSGSBASE"
17511   "rd<fsgs>base\t%0"
17512   [(set_attr "type" "other")
17513    (set_attr "prefix_extra" "2")])
17515 (define_insn "wr<fsgs>base<mode>"
17516   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17517                     WRFSGSBASE)]
17518   "TARGET_64BIT && TARGET_FSGSBASE"
17519   "wr<fsgs>base\t%0"
17520   [(set_attr "type" "other")
17521    (set_attr "prefix_extra" "2")])
17523 (define_insn "rdrand<mode>_1"
17524   [(set (match_operand:SWI248 0 "register_operand" "=r")
17525         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
17526    (set (reg:CCC FLAGS_REG)
17527         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
17528   "TARGET_RDRND"
17529   "rdrand\t%0"
17530   [(set_attr "type" "other")
17531    (set_attr "prefix_extra" "1")])
17533 (define_insn "rdseed<mode>_1"
17534   [(set (match_operand:SWI248 0 "register_operand" "=r")
17535         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
17536    (set (reg:CCC FLAGS_REG)
17537         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
17538   "TARGET_RDSEED"
17539   "rdseed\t%0"
17540   [(set_attr "type" "other")
17541    (set_attr "prefix_extra" "1")])
17543 (define_expand "pause"
17544   [(set (match_dup 0)
17545         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17546   ""
17548   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17549   MEM_VOLATILE_P (operands[0]) = 1;
17552 ;; Use "rep; nop", instead of "pause", to support older assemblers.
17553 ;; They have the same encoding.
17554 (define_insn "*pause"
17555   [(set (match_operand:BLK 0)
17556         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17557   ""
17558   "rep%; nop"
17559   [(set_attr "length" "2")
17560    (set_attr "memory" "unknown")])
17562 (define_expand "xbegin"
17563   [(set (match_operand:SI 0 "register_operand")
17564         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
17565   "TARGET_RTM"
17567   rtx label = gen_label_rtx ();
17569   /* xbegin is emitted as jump_insn, so reload won't be able
17570      to reload its operand.  Force the value into AX hard register.  */
17571   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
17572   emit_move_insn (ax_reg, constm1_rtx);
17574   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
17576   emit_label (label);
17577   LABEL_NUSES (label) = 1;
17579   emit_move_insn (operands[0], ax_reg);
17581   DONE;
17584 (define_insn "xbegin_1"
17585   [(set (pc)
17586         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
17587                           (const_int 0))
17588                       (label_ref (match_operand 1))
17589                       (pc)))
17590    (set (match_operand:SI 0 "register_operand" "+a")
17591         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
17592   "TARGET_RTM"
17593   "xbegin\t%l1"
17594   [(set_attr "type" "other")
17595    (set_attr "length" "6")])
17597 (define_insn "xend"
17598   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
17599   "TARGET_RTM"
17600   "xend"
17601   [(set_attr "type" "other")
17602    (set_attr "length" "3")])
17604 (define_insn "xabort"
17605   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
17606                     UNSPECV_XABORT)]
17607   "TARGET_RTM"
17608   "xabort\t%0"
17609   [(set_attr "type" "other")
17610    (set_attr "length" "3")])
17612 (define_expand "xtest"
17613   [(set (match_operand:QI 0 "register_operand")
17614         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
17615   "TARGET_RTM"
17617   emit_insn (gen_xtest_1 ());
17619   ix86_expand_setcc (operands[0], NE,
17620                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
17621   DONE;
17624 (define_insn "xtest_1"
17625   [(set (reg:CCZ FLAGS_REG)
17626         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
17627   "TARGET_RTM"
17628   "xtest"
17629   [(set_attr "type" "other")
17630    (set_attr "length" "3")])
17632 (include "mmx.md")
17633 (include "sse.md")
17634 (include "sync.md")