Merge from branches/gcc-4_8-branch up to rev 207411.
[official-gcc.git] / gcc-4_8-branch / gcc / config / i386 / i386.md
blob5f1921c106cd4690e757423ff09925bc3ec1f5f4
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
226   UNSPECV_NLGR
229 ;; Constants to represent rounding modes in the ROUND instruction
230 (define_constants
231   [(ROUND_FLOOR                 0x1)
232    (ROUND_CEIL                  0x2)
233    (ROUND_TRUNC                 0x3)
234    (ROUND_MXCSR                 0x4)
235    (ROUND_NO_EXC                0x8)
236   ])
238 ;; Constants to represent pcomtrue/pcomfalse variants
239 (define_constants
240   [(PCOM_FALSE                  0)
241    (PCOM_TRUE                   1)
242    (COM_FALSE_S                 2)
243    (COM_FALSE_P                 3)
244    (COM_TRUE_S                  4)
245    (COM_TRUE_P                  5)
246   ])
248 ;; Constants used in the XOP pperm instruction
249 (define_constants
250   [(PPERM_SRC                   0x00)   /* copy source */
251    (PPERM_INVERT                0x20)   /* invert source */
252    (PPERM_REVERSE               0x40)   /* bit reverse source */
253    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
254    (PPERM_ZERO                  0x80)   /* all 0's */
255    (PPERM_ONES                  0xa0)   /* all 1's */
256    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
257    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
258    (PPERM_SRC1                  0x00)   /* use first source byte */
259    (PPERM_SRC2                  0x10)   /* use second source byte */
260    ])
262 ;; Registers by name.
263 (define_constants
264   [(AX_REG                       0)
265    (DX_REG                       1)
266    (CX_REG                       2)
267    (BX_REG                       3)
268    (SI_REG                       4)
269    (DI_REG                       5)
270    (BP_REG                       6)
271    (SP_REG                       7)
272    (ST0_REG                      8)
273    (ST1_REG                      9)
274    (ST2_REG                     10)
275    (ST3_REG                     11)
276    (ST4_REG                     12)
277    (ST5_REG                     13)
278    (ST6_REG                     14)
279    (ST7_REG                     15)
280    (FLAGS_REG                   17)
281    (FPSR_REG                    18)
282    (FPCR_REG                    19)
283    (XMM0_REG                    21)
284    (XMM1_REG                    22)
285    (XMM2_REG                    23)
286    (XMM3_REG                    24)
287    (XMM4_REG                    25)
288    (XMM5_REG                    26)
289    (XMM6_REG                    27)
290    (XMM7_REG                    28)
291    (MM0_REG                     29)
292    (MM1_REG                     30)
293    (MM2_REG                     31)
294    (MM3_REG                     32)
295    (MM4_REG                     33)
296    (MM5_REG                     34)
297    (MM6_REG                     35)
298    (MM7_REG                     36)
299    (R8_REG                      37)
300    (R9_REG                      38)
301    (R10_REG                     39)
302    (R11_REG                     40)
303    (R12_REG                     41)
304    (R13_REG                     42)
305    (R14_REG                     43)
306    (R15_REG                     44)
307    (XMM8_REG                    45)
308    (XMM9_REG                    46)
309    (XMM10_REG                   47)
310    (XMM11_REG                   48)
311    (XMM12_REG                   49)
312    (XMM13_REG                   50)
313    (XMM14_REG                   51)
314    (XMM15_REG                   52)
315   ])
317 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
318 ;; from i386.c.
320 ;; In C guard expressions, put expressions which may be compile-time
321 ;; constants first.  This allows for better optimization.  For
322 ;; example, write "TARGET_64BIT && reload_completed", not
323 ;; "reload_completed && TARGET_64BIT".
326 ;; Processor type.
327 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
328                     atom,generic64,amdfam10,bdver1,bdver2,bdver3,btver1,btver2"
329   (const (symbol_ref "ix86_schedule")))
331 ;; A basic instruction type.  Refinements due to arguments to be
332 ;; provided in other attributes.
333 (define_attr "type"
334   "other,multi,
335    alu,alu1,negnot,imov,imovx,lea,
336    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
337    icmp,test,ibr,setcc,icmov,
338    push,pop,call,callv,leave,
339    str,bitmanip,
340    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
341    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
342    sse,ssemov,sseadd,sseadd1,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
343    sseshuf,sseshuf1,ssediv,sseins,ssemuladd,sse4arg,lwp,
344    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
345   (const_string "other"))
347 ;; Main data type used by the insn
348 (define_attr "mode"
349   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
350   (const_string "unknown"))
352 ;; The CPU unit operations uses.
353 (define_attr "unit" "integer,i387,sse,mmx,unknown"
354   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
355            (const_string "i387")
356          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
357                           sse,ssemov,sseadd,sseadd1,ssemul,ssecmp,ssecomi,ssecvt,
358                           sseshuf,sseshuf1,ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
359            (const_string "sse")
360          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
361            (const_string "mmx")
362          (eq_attr "type" "other")
363            (const_string "unknown")]
364          (const_string "integer")))
366 ;; The minimum required alignment of vector mode memory operands of the SSE
367 ;; (non-VEX/EVEX) instruction in bits, if it is different from
368 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0.  If an instruction has
369 ;; multiple alternatives, this should be conservative maximum of those minimum
370 ;; required alignments.
371 (define_attr "ssememalign" "" (const_int 0))
373 ;; The (bounding maximum) length of an instruction immediate.
374 (define_attr "length_immediate" ""
375   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
376                           bitmanip,imulx")
377            (const_int 0)
378          (eq_attr "unit" "i387,sse,mmx")
379            (const_int 0)
380          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
381                           rotate,rotatex,rotate1,imul,icmp,push,pop")
382            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
383          (eq_attr "type" "imov,test")
384            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
385          (eq_attr "type" "call")
386            (if_then_else (match_operand 0 "constant_call_address_operand")
387              (const_int 4)
388              (const_int 0))
389          (eq_attr "type" "callv")
390            (if_then_else (match_operand 1 "constant_call_address_operand")
391              (const_int 4)
392              (const_int 0))
393          ;; We don't know the size before shorten_branches.  Expect
394          ;; the instruction to fit for better scheduling.
395          (eq_attr "type" "ibr")
396            (const_int 1)
397          ]
398          (symbol_ref "/* Update immediate_length and other attributes! */
399                       gcc_unreachable (),1")))
401 ;; The (bounding maximum) length of an instruction address.
402 (define_attr "length_address" ""
403   (cond [(eq_attr "type" "str,other,multi,fxch")
404            (const_int 0)
405          (and (eq_attr "type" "call")
406               (match_operand 0 "constant_call_address_operand"))
407              (const_int 0)
408          (and (eq_attr "type" "callv")
409               (match_operand 1 "constant_call_address_operand"))
410              (const_int 0)
411          ]
412          (symbol_ref "ix86_attr_length_address_default (insn)")))
414 ;; Set when length prefix is used.
415 (define_attr "prefix_data16" ""
416   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
417            (const_int 0)
418          (eq_attr "mode" "HI")
419            (const_int 1)
420          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
421            (const_int 1)
422         ]
423         (const_int 0)))
425 ;; Set when string REP prefix is used.
426 (define_attr "prefix_rep" ""
427   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
428            (const_int 0)
429          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
430            (const_int 1)
431         ]
432         (const_int 0)))
434 ;; Set when 0f opcode prefix is used.
435 (define_attr "prefix_0f" ""
436   (if_then_else
437     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
438          (eq_attr "unit" "sse,mmx"))
439     (const_int 1)
440     (const_int 0)))
442 ;; Set when REX opcode prefix is used.
443 (define_attr "prefix_rex" ""
444   (cond [(not (match_test "TARGET_64BIT"))
445            (const_int 0)
446          (and (eq_attr "mode" "DI")
447               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
448                    (eq_attr "unit" "!mmx")))
449            (const_int 1)
450          (and (eq_attr "mode" "QI")
451               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
452            (const_int 1)
453          (match_test "x86_extended_reg_mentioned_p (insn)")
454            (const_int 1)
455          (and (eq_attr "type" "imovx")
456               (match_operand:QI 1 "ext_QIreg_operand"))
457            (const_int 1)
458         ]
459         (const_int 0)))
461 ;; There are also additional prefixes in 3DNOW, SSSE3.
462 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
463 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
464 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
465 (define_attr "prefix_extra" ""
466   (cond [(eq_attr "type" "ssemuladd,sse4arg")
467            (const_int 2)
468          (eq_attr "type" "sseiadd1,ssecvt1")
469            (const_int 1)
470         ]
471         (const_int 0)))
473 ;; Prefix used: original, VEX or maybe VEX.
474 (define_attr "prefix" "orig,vex,maybe_vex"
475   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
476     (const_string "vex")
477     (const_string "orig")))
479 ;; VEX W bit is used.
480 (define_attr "prefix_vex_w" "" (const_int 0))
482 ;; The length of VEX prefix
483 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
484 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
485 ;; still prefix_0f 1, with prefix_extra 1.
486 (define_attr "length_vex" ""
487   (if_then_else (and (eq_attr "prefix_0f" "1")
488                      (eq_attr "prefix_extra" "0"))
489     (if_then_else (eq_attr "prefix_vex_w" "1")
490       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
491       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
492     (if_then_else (eq_attr "prefix_vex_w" "1")
493       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
494       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
496 ;; Set when modrm byte is used.
497 (define_attr "modrm" ""
498   (cond [(eq_attr "type" "str,leave")
499            (const_int 0)
500          (eq_attr "unit" "i387")
501            (const_int 0)
502          (and (eq_attr "type" "incdec")
503               (and (not (match_test "TARGET_64BIT"))
504                    (ior (match_operand:SI 1 "register_operand")
505                         (match_operand:HI 1 "register_operand"))))
506            (const_int 0)
507          (and (eq_attr "type" "push")
508               (not (match_operand 1 "memory_operand")))
509            (const_int 0)
510          (and (eq_attr "type" "pop")
511               (not (match_operand 0 "memory_operand")))
512            (const_int 0)
513          (and (eq_attr "type" "imov")
514               (and (not (eq_attr "mode" "DI"))
515                    (ior (and (match_operand 0 "register_operand")
516                              (match_operand 1 "immediate_operand"))
517                         (ior (and (match_operand 0 "ax_reg_operand")
518                                   (match_operand 1 "memory_displacement_only_operand"))
519                              (and (match_operand 0 "memory_displacement_only_operand")
520                                   (match_operand 1 "ax_reg_operand"))))))
521            (const_int 0)
522          (and (eq_attr "type" "call")
523               (match_operand 0 "constant_call_address_operand"))
524              (const_int 0)
525          (and (eq_attr "type" "callv")
526               (match_operand 1 "constant_call_address_operand"))
527              (const_int 0)
528          (and (eq_attr "type" "alu,alu1,icmp,test")
529               (match_operand 0 "ax_reg_operand"))
530              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
531          ]
532          (const_int 1)))
534 ;; The (bounding maximum) length of an instruction in bytes.
535 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
536 ;; Later we may want to split them and compute proper length as for
537 ;; other insns.
538 (define_attr "length" ""
539   (cond [(eq_attr "type" "other,multi,fistp,frndint")
540            (const_int 16)
541          (eq_attr "type" "fcmp")
542            (const_int 4)
543          (eq_attr "unit" "i387")
544            (plus (const_int 2)
545                  (plus (attr "prefix_data16")
546                        (attr "length_address")))
547          (ior (eq_attr "prefix" "vex")
548               (and (eq_attr "prefix" "maybe_vex")
549                    (match_test "TARGET_AVX")))
550            (plus (attr "length_vex")
551                  (plus (attr "length_immediate")
552                        (plus (attr "modrm")
553                              (attr "length_address"))))]
554          (plus (plus (attr "modrm")
555                      (plus (attr "prefix_0f")
556                            (plus (attr "prefix_rex")
557                                  (plus (attr "prefix_extra")
558                                        (const_int 1)))))
559                (plus (attr "prefix_rep")
560                      (plus (attr "prefix_data16")
561                            (plus (attr "length_immediate")
562                                  (attr "length_address")))))))
564 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
565 ;; `store' if there is a simple memory reference therein, or `unknown'
566 ;; if the instruction is complex.
568 (define_attr "memory" "none,load,store,both,unknown"
569   (cond [(eq_attr "type" "other,multi,str,lwp")
570            (const_string "unknown")
571          (eq_attr "type" "lea,fcmov,fpspc")
572            (const_string "none")
573          (eq_attr "type" "fistp,leave")
574            (const_string "both")
575          (eq_attr "type" "frndint")
576            (const_string "load")
577          (eq_attr "type" "push")
578            (if_then_else (match_operand 1 "memory_operand")
579              (const_string "both")
580              (const_string "store"))
581          (eq_attr "type" "pop")
582            (if_then_else (match_operand 0 "memory_operand")
583              (const_string "both")
584              (const_string "load"))
585          (eq_attr "type" "setcc")
586            (if_then_else (match_operand 0 "memory_operand")
587              (const_string "store")
588              (const_string "none"))
589          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
590            (if_then_else (ior (match_operand 0 "memory_operand")
591                               (match_operand 1 "memory_operand"))
592              (const_string "load")
593              (const_string "none"))
594          (eq_attr "type" "ibr")
595            (if_then_else (match_operand 0 "memory_operand")
596              (const_string "load")
597              (const_string "none"))
598          (eq_attr "type" "call")
599            (if_then_else (match_operand 0 "constant_call_address_operand")
600              (const_string "none")
601              (const_string "load"))
602          (eq_attr "type" "callv")
603            (if_then_else (match_operand 1 "constant_call_address_operand")
604              (const_string "none")
605              (const_string "load"))
606          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
607               (match_operand 1 "memory_operand"))
608            (const_string "both")
609          (and (match_operand 0 "memory_operand")
610               (match_operand 1 "memory_operand"))
611            (const_string "both")
612          (match_operand 0 "memory_operand")
613            (const_string "store")
614          (match_operand 1 "memory_operand")
615            (const_string "load")
616          (and (eq_attr "type"
617                  "!alu1,negnot,ishift1,
618                    imov,imovx,icmp,test,bitmanip,
619                    fmov,fcmp,fsgn,
620                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
621                    sseshuf1,sseadd1,sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
622               (match_operand 2 "memory_operand"))
623            (const_string "load")
624          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
625               (match_operand 3 "memory_operand"))
626            (const_string "load")
627         ]
628         (const_string "none")))
630 ;; Indicates if an instruction has both an immediate and a displacement.
632 (define_attr "imm_disp" "false,true,unknown"
633   (cond [(eq_attr "type" "other,multi")
634            (const_string "unknown")
635          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
636               (and (match_operand 0 "memory_displacement_operand")
637                    (match_operand 1 "immediate_operand")))
638            (const_string "true")
639          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
640               (and (match_operand 0 "memory_displacement_operand")
641                    (match_operand 2 "immediate_operand")))
642            (const_string "true")
643         ]
644         (const_string "false")))
646 ;; Indicates if an FP operation has an integer source.
648 (define_attr "fp_int_src" "false,true"
649   (const_string "false"))
651 ;; Defines rounding mode of an FP operation.
653 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
654   (const_string "any"))
656 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
657 (define_attr "use_carry" "0,1" (const_string "0"))
659 ;; Define attribute to indicate unaligned ssemov insns
660 (define_attr "movu" "0,1" (const_string "0"))
662 ;; Used to control the "enabled" attribute on a per-instruction basis.
663 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,
664                     avx2,noavx2,bmi2,fma4,fma"
665   (const_string "base"))
667 (define_attr "enabled" ""
668   (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
669          (eq_attr "isa" "sse2_noavx")
670            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
671          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
672          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
673          (eq_attr "isa" "sse4_noavx")
674            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
675          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
676          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
677          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
678          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
679          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
680          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
681          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
682         ]
683         (const_int 1)))
685 ;; Describe a user's asm statement.
686 (define_asm_attributes
687   [(set_attr "length" "128")
688    (set_attr "type" "multi")])
690 (define_code_iterator plusminus [plus minus])
692 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
694 ;; Base name for define_insn
695 (define_code_attr plusminus_insn
696   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
697    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
699 ;; Base name for insn mnemonic.
700 (define_code_attr plusminus_mnemonic
701   [(plus "add") (ss_plus "adds") (us_plus "addus")
702    (minus "sub") (ss_minus "subs") (us_minus "subus")])
703 (define_code_attr plusminus_carry_mnemonic
704   [(plus "adc") (minus "sbb")])
706 ;; Mark commutative operators as such in constraints.
707 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
708                         (minus "") (ss_minus "") (us_minus "")])
710 ;; Mapping of max and min
711 (define_code_iterator maxmin [smax smin umax umin])
713 ;; Mapping of signed max and min
714 (define_code_iterator smaxmin [smax smin])
716 ;; Mapping of unsigned max and min
717 (define_code_iterator umaxmin [umax umin])
719 ;; Base name for integer and FP insn mnemonic
720 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
721                               (umax "maxu") (umin "minu")])
722 (define_code_attr maxmin_float [(smax "max") (smin "min")])
724 ;; Mapping of logic operators
725 (define_code_iterator any_logic [and ior xor])
726 (define_code_iterator any_or [ior xor])
728 ;; Base name for insn mnemonic.
729 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
731 ;; Mapping of logic-shift operators
732 (define_code_iterator any_lshift [ashift lshiftrt])
734 ;; Mapping of shift-right operators
735 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
737 ;; Mapping of all shift operators
738 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
740 ;; Base name for define_insn
741 (define_code_attr shift_insn
742   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
744 ;; Base name for insn mnemonic.
745 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
746 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
748 ;; Mapping of rotate operators
749 (define_code_iterator any_rotate [rotate rotatert])
751 ;; Base name for define_insn
752 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
754 ;; Base name for insn mnemonic.
755 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
757 ;; Mapping of abs neg operators
758 (define_code_iterator absneg [abs neg])
760 ;; Base name for x87 insn mnemonic.
761 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
763 ;; Used in signed and unsigned widening multiplications.
764 (define_code_iterator any_extend [sign_extend zero_extend])
766 ;; Prefix for insn menmonic.
767 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
769 ;; Prefix for define_insn
770 (define_code_attr u [(sign_extend "") (zero_extend "u")])
771 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
772 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
774 ;; All integer modes.
775 (define_mode_iterator SWI1248x [QI HI SI DI])
777 ;; All integer modes without QImode.
778 (define_mode_iterator SWI248x [HI SI DI])
780 ;; All integer modes without QImode and HImode.
781 (define_mode_iterator SWI48x [SI DI])
783 ;; All integer modes without SImode and DImode.
784 (define_mode_iterator SWI12 [QI HI])
786 ;; All integer modes without DImode.
787 (define_mode_iterator SWI124 [QI HI SI])
789 ;; All integer modes without QImode and DImode.
790 (define_mode_iterator SWI24 [HI SI])
792 ;; Single word integer modes.
793 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
795 ;; Single word integer modes without QImode.
796 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
798 ;; Single word integer modes without QImode and HImode.
799 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
801 ;; All math-dependant single and double word integer modes.
802 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
803                              (HI "TARGET_HIMODE_MATH")
804                              SI DI (TI "TARGET_64BIT")])
806 ;; Math-dependant single word integer modes.
807 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
808                             (HI "TARGET_HIMODE_MATH")
809                             SI (DI "TARGET_64BIT")])
811 ;; Math-dependant integer modes without DImode.
812 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
813                                (HI "TARGET_HIMODE_MATH")
814                                SI])
816 ;; Math-dependant single word integer modes without QImode.
817 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
818                                SI (DI "TARGET_64BIT")])
820 ;; Double word integer modes.
821 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
822                            (TI "TARGET_64BIT")])
824 ;; Double word integer modes as mode attribute.
825 (define_mode_attr DWI [(SI "DI") (DI "TI")])
826 (define_mode_attr dwi [(SI "di") (DI "ti")])
828 ;; Half mode for double word integer modes.
829 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
830                             (DI "TARGET_64BIT")])
832 ;; Instruction suffix for integer modes.
833 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
835 ;; Pointer size prefix for integer modes (Intel asm dialect)
836 (define_mode_attr iptrsize [(QI "BYTE")
837                             (HI "WORD")
838                             (SI "DWORD")
839                             (DI "QWORD")])
841 ;; Register class for integer modes.
842 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
844 ;; Immediate operand constraint for integer modes.
845 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
847 ;; General operand constraint for word modes.
848 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
850 ;; Immediate operand constraint for double integer modes.
851 (define_mode_attr di [(SI "nF") (DI "e")])
853 ;; Immediate operand constraint for shifts.
854 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
856 ;; General operand predicate for integer modes.
857 (define_mode_attr general_operand
858         [(QI "general_operand")
859          (HI "general_operand")
860          (SI "x86_64_general_operand")
861          (DI "x86_64_general_operand")
862          (TI "x86_64_general_operand")])
864 ;; General sign/zero extend operand predicate for integer modes.
865 (define_mode_attr general_szext_operand
866         [(QI "general_operand")
867          (HI "general_operand")
868          (SI "x86_64_szext_general_operand")
869          (DI "x86_64_szext_general_operand")])
871 ;; Immediate operand predicate for integer modes.
872 (define_mode_attr immediate_operand
873         [(QI "immediate_operand")
874          (HI "immediate_operand")
875          (SI "x86_64_immediate_operand")
876          (DI "x86_64_immediate_operand")])
878 ;; Nonmemory operand predicate for integer modes.
879 (define_mode_attr nonmemory_operand
880         [(QI "nonmemory_operand")
881          (HI "nonmemory_operand")
882          (SI "x86_64_nonmemory_operand")
883          (DI "x86_64_nonmemory_operand")])
885 ;; Operand predicate for shifts.
886 (define_mode_attr shift_operand
887         [(QI "nonimmediate_operand")
888          (HI "nonimmediate_operand")
889          (SI "nonimmediate_operand")
890          (DI "shiftdi_operand")
891          (TI "register_operand")])
893 ;; Operand predicate for shift argument.
894 (define_mode_attr shift_immediate_operand
895         [(QI "const_1_to_31_operand")
896          (HI "const_1_to_31_operand")
897          (SI "const_1_to_31_operand")
898          (DI "const_1_to_63_operand")])
900 ;; Input operand predicate for arithmetic left shifts.
901 (define_mode_attr ashl_input_operand
902         [(QI "nonimmediate_operand")
903          (HI "nonimmediate_operand")
904          (SI "nonimmediate_operand")
905          (DI "ashldi_input_operand")
906          (TI "reg_or_pm1_operand")])
908 ;; SSE and x87 SFmode and DFmode floating point modes
909 (define_mode_iterator MODEF [SF DF])
911 ;; All x87 floating point modes
912 (define_mode_iterator X87MODEF [SF DF XF])
914 ;; SSE instruction suffix for various modes
915 (define_mode_attr ssemodesuffix
916   [(SF "ss") (DF "sd")
917    (V8SF "ps") (V4DF "pd")
918    (V4SF "ps") (V2DF "pd")
919    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
920    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
922 ;; SSE vector suffix for floating point modes
923 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
925 ;; SSE vector mode corresponding to a scalar mode
926 (define_mode_attr ssevecmode
927   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
929 ;; Instruction suffix for REX 64bit operators.
930 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
932 ;; This mode iterator allows :P to be used for patterns that operate on
933 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
934 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
936 ;; This mode iterator allows :W to be used for patterns that operate on
937 ;; word_mode sized quantities.
938 (define_mode_iterator W
939   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
941 ;; This mode iterator allows :PTR to be used for patterns that operate on
942 ;; ptr_mode sized quantities.
943 (define_mode_iterator PTR
944   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
946 ;; Scheduling descriptions
948 (include "pentium.md")
949 (include "ppro.md")
950 (include "k6.md")
951 (include "athlon.md")
952 (include "bdver1.md")
953 (include "bdver3.md")
954 (include "btver2.md")
955 (include "geode.md")
956 (include "atom.md")
957 (include "core2.md")
960 ;; Operand and operator predicates and constraints
962 (include "predicates.md")
963 (include "constraints.md")
966 ;; Compare and branch/compare and store instructions.
968 (define_expand "cbranch<mode>4"
969   [(set (reg:CC FLAGS_REG)
970         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
971                     (match_operand:SDWIM 2 "<general_operand>")))
972    (set (pc) (if_then_else
973                (match_operator 0 "ordered_comparison_operator"
974                 [(reg:CC FLAGS_REG) (const_int 0)])
975                (label_ref (match_operand 3))
976                (pc)))]
977   ""
979   if (MEM_P (operands[1]) && MEM_P (operands[2]))
980     operands[1] = force_reg (<MODE>mode, operands[1]);
981   ix86_expand_branch (GET_CODE (operands[0]),
982                       operands[1], operands[2], operands[3]);
983   DONE;
986 (define_expand "cstore<mode>4"
987   [(set (reg:CC FLAGS_REG)
988         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
989                     (match_operand:SWIM 3 "<general_operand>")))
990    (set (match_operand:QI 0 "register_operand")
991         (match_operator 1 "ordered_comparison_operator"
992           [(reg:CC FLAGS_REG) (const_int 0)]))]
993   ""
995   if (MEM_P (operands[2]) && MEM_P (operands[3]))
996     operands[2] = force_reg (<MODE>mode, operands[2]);
997   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
998                      operands[2], operands[3]);
999   DONE;
1002 (define_expand "cmp<mode>_1"
1003   [(set (reg:CC FLAGS_REG)
1004         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1005                     (match_operand:SWI48 1 "<general_operand>")))])
1007 (define_insn "*cmp<mode>_ccno_1"
1008   [(set (reg FLAGS_REG)
1009         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1010                  (match_operand:SWI 1 "const0_operand")))]
1011   "ix86_match_ccmode (insn, CCNOmode)"
1012   "@
1013    test{<imodesuffix>}\t%0, %0
1014    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1015   [(set_attr "type" "test,icmp")
1016    (set_attr "length_immediate" "0,1")
1017    (set_attr "mode" "<MODE>")])
1019 (define_insn "*cmp<mode>_1"
1020   [(set (reg FLAGS_REG)
1021         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1022                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1023   "ix86_match_ccmode (insn, CCmode)"
1024   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1025   [(set_attr "type" "icmp")
1026    (set_attr "mode" "<MODE>")])
1028 (define_insn "*cmp<mode>_minus_1"
1029   [(set (reg FLAGS_REG)
1030         (compare
1031           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1032                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1033           (const_int 0)))]
1034   "ix86_match_ccmode (insn, CCGOCmode)"
1035   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1036   [(set_attr "type" "icmp")
1037    (set_attr "mode" "<MODE>")])
1039 (define_insn "*cmpqi_ext_1"
1040   [(set (reg FLAGS_REG)
1041         (compare
1042           (match_operand:QI 0 "general_operand" "Qm")
1043           (subreg:QI
1044             (zero_extract:SI
1045               (match_operand 1 "ext_register_operand" "Q")
1046               (const_int 8)
1047               (const_int 8)) 0)))]
1048   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1049   "cmp{b}\t{%h1, %0|%0, %h1}"
1050   [(set_attr "type" "icmp")
1051    (set_attr "mode" "QI")])
1053 (define_insn "*cmpqi_ext_1_rex64"
1054   [(set (reg FLAGS_REG)
1055         (compare
1056           (match_operand:QI 0 "register_operand" "Q")
1057           (subreg:QI
1058             (zero_extract:SI
1059               (match_operand 1 "ext_register_operand" "Q")
1060               (const_int 8)
1061               (const_int 8)) 0)))]
1062   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1063   "cmp{b}\t{%h1, %0|%0, %h1}"
1064   [(set_attr "type" "icmp")
1065    (set_attr "mode" "QI")])
1067 (define_insn "*cmpqi_ext_2"
1068   [(set (reg FLAGS_REG)
1069         (compare
1070           (subreg:QI
1071             (zero_extract:SI
1072               (match_operand 0 "ext_register_operand" "Q")
1073               (const_int 8)
1074               (const_int 8)) 0)
1075           (match_operand:QI 1 "const0_operand")))]
1076   "ix86_match_ccmode (insn, CCNOmode)"
1077   "test{b}\t%h0, %h0"
1078   [(set_attr "type" "test")
1079    (set_attr "length_immediate" "0")
1080    (set_attr "mode" "QI")])
1082 (define_expand "cmpqi_ext_3"
1083   [(set (reg:CC FLAGS_REG)
1084         (compare:CC
1085           (subreg:QI
1086             (zero_extract:SI
1087               (match_operand 0 "ext_register_operand")
1088               (const_int 8)
1089               (const_int 8)) 0)
1090           (match_operand:QI 1 "immediate_operand")))])
1092 (define_insn "*cmpqi_ext_3_insn"
1093   [(set (reg FLAGS_REG)
1094         (compare
1095           (subreg:QI
1096             (zero_extract:SI
1097               (match_operand 0 "ext_register_operand" "Q")
1098               (const_int 8)
1099               (const_int 8)) 0)
1100           (match_operand:QI 1 "general_operand" "Qmn")))]
1101   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1102   "cmp{b}\t{%1, %h0|%h0, %1}"
1103   [(set_attr "type" "icmp")
1104    (set_attr "modrm" "1")
1105    (set_attr "mode" "QI")])
1107 (define_insn "*cmpqi_ext_3_insn_rex64"
1108   [(set (reg FLAGS_REG)
1109         (compare
1110           (subreg:QI
1111             (zero_extract:SI
1112               (match_operand 0 "ext_register_operand" "Q")
1113               (const_int 8)
1114               (const_int 8)) 0)
1115           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1116   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1117   "cmp{b}\t{%1, %h0|%h0, %1}"
1118   [(set_attr "type" "icmp")
1119    (set_attr "modrm" "1")
1120    (set_attr "mode" "QI")])
1122 (define_insn "*cmpqi_ext_4"
1123   [(set (reg FLAGS_REG)
1124         (compare
1125           (subreg:QI
1126             (zero_extract:SI
1127               (match_operand 0 "ext_register_operand" "Q")
1128               (const_int 8)
1129               (const_int 8)) 0)
1130           (subreg:QI
1131             (zero_extract:SI
1132               (match_operand 1 "ext_register_operand" "Q")
1133               (const_int 8)
1134               (const_int 8)) 0)))]
1135   "ix86_match_ccmode (insn, CCmode)"
1136   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1137   [(set_attr "type" "icmp")
1138    (set_attr "mode" "QI")])
1140 ;; These implement float point compares.
1141 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1142 ;; which would allow mix and match FP modes on the compares.  Which is what
1143 ;; the old patterns did, but with many more of them.
1145 (define_expand "cbranchxf4"
1146   [(set (reg:CC FLAGS_REG)
1147         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1148                     (match_operand:XF 2 "nonmemory_operand")))
1149    (set (pc) (if_then_else
1150               (match_operator 0 "ix86_fp_comparison_operator"
1151                [(reg:CC FLAGS_REG)
1152                 (const_int 0)])
1153               (label_ref (match_operand 3))
1154               (pc)))]
1155   "TARGET_80387"
1157   ix86_expand_branch (GET_CODE (operands[0]),
1158                       operands[1], operands[2], operands[3]);
1159   DONE;
1162 (define_expand "cstorexf4"
1163   [(set (reg:CC FLAGS_REG)
1164         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1165                     (match_operand:XF 3 "nonmemory_operand")))
1166    (set (match_operand:QI 0 "register_operand")
1167               (match_operator 1 "ix86_fp_comparison_operator"
1168                [(reg:CC FLAGS_REG)
1169                 (const_int 0)]))]
1170   "TARGET_80387"
1172   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1173                      operands[2], operands[3]);
1174   DONE;
1177 (define_expand "cbranch<mode>4"
1178   [(set (reg:CC FLAGS_REG)
1179         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1180                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1181    (set (pc) (if_then_else
1182               (match_operator 0 "ix86_fp_comparison_operator"
1183                [(reg:CC FLAGS_REG)
1184                 (const_int 0)])
1185               (label_ref (match_operand 3))
1186               (pc)))]
1187   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1189   ix86_expand_branch (GET_CODE (operands[0]),
1190                       operands[1], operands[2], operands[3]);
1191   DONE;
1194 (define_expand "cstore<mode>4"
1195   [(set (reg:CC FLAGS_REG)
1196         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1197                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1198    (set (match_operand:QI 0 "register_operand")
1199               (match_operator 1 "ix86_fp_comparison_operator"
1200                [(reg:CC FLAGS_REG)
1201                 (const_int 0)]))]
1202   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1204   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1205                      operands[2], operands[3]);
1206   DONE;
1209 (define_expand "cbranchcc4"
1210   [(set (pc) (if_then_else
1211               (match_operator 0 "comparison_operator"
1212                [(match_operand 1 "flags_reg_operand")
1213                 (match_operand 2 "const0_operand")])
1214               (label_ref (match_operand 3))
1215               (pc)))]
1216   ""
1218   ix86_expand_branch (GET_CODE (operands[0]),
1219                       operands[1], operands[2], operands[3]);
1220   DONE;
1223 (define_expand "cstorecc4"
1224   [(set (match_operand:QI 0 "register_operand")
1225               (match_operator 1 "comparison_operator"
1226                [(match_operand 2 "flags_reg_operand")
1227                 (match_operand 3 "const0_operand")]))]
1228   ""
1230   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1231                      operands[2], operands[3]);
1232   DONE;
1236 ;; FP compares, step 1:
1237 ;; Set the FP condition codes.
1239 ;; CCFPmode     compare with exceptions
1240 ;; CCFPUmode    compare with no exceptions
1242 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1243 ;; used to manage the reg stack popping would not be preserved.
1245 (define_insn "*cmp<mode>_0_i387"
1246   [(set (match_operand:HI 0 "register_operand" "=a")
1247         (unspec:HI
1248           [(compare:CCFP
1249              (match_operand:X87MODEF 1 "register_operand" "f")
1250              (match_operand:X87MODEF 2 "const0_operand"))]
1251         UNSPEC_FNSTSW))]
1252   "TARGET_80387"
1253   "* return output_fp_compare (insn, operands, false, false);"
1254   [(set_attr "type" "multi")
1255    (set_attr "unit" "i387")
1256    (set_attr "mode" "<MODE>")])
1258 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1259   [(set (reg:CCFP FLAGS_REG)
1260         (compare:CCFP
1261           (match_operand:X87MODEF 1 "register_operand" "f")
1262           (match_operand:X87MODEF 2 "const0_operand")))
1263    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1264   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1265   "#"
1266   "&& reload_completed"
1267   [(set (match_dup 0)
1268         (unspec:HI
1269           [(compare:CCFP (match_dup 1)(match_dup 2))]
1270         UNSPEC_FNSTSW))
1271    (set (reg:CC FLAGS_REG)
1272         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1273   ""
1274   [(set_attr "type" "multi")
1275    (set_attr "unit" "i387")
1276    (set_attr "mode" "<MODE>")])
1278 (define_insn "*cmpxf_i387"
1279   [(set (match_operand:HI 0 "register_operand" "=a")
1280         (unspec:HI
1281           [(compare:CCFP
1282              (match_operand:XF 1 "register_operand" "f")
1283              (match_operand:XF 2 "register_operand" "f"))]
1284           UNSPEC_FNSTSW))]
1285   "TARGET_80387"
1286   "* return output_fp_compare (insn, operands, false, false);"
1287   [(set_attr "type" "multi")
1288    (set_attr "unit" "i387")
1289    (set_attr "mode" "XF")])
1291 (define_insn_and_split "*cmpxf_cc_i387"
1292   [(set (reg:CCFP FLAGS_REG)
1293         (compare:CCFP
1294           (match_operand:XF 1 "register_operand" "f")
1295           (match_operand:XF 2 "register_operand" "f")))
1296    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1297   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1298   "#"
1299   "&& reload_completed"
1300   [(set (match_dup 0)
1301         (unspec:HI
1302           [(compare:CCFP (match_dup 1)(match_dup 2))]
1303         UNSPEC_FNSTSW))
1304    (set (reg:CC FLAGS_REG)
1305         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1306   ""
1307   [(set_attr "type" "multi")
1308    (set_attr "unit" "i387")
1309    (set_attr "mode" "XF")])
1311 (define_insn "*cmp<mode>_i387"
1312   [(set (match_operand:HI 0 "register_operand" "=a")
1313         (unspec:HI
1314           [(compare:CCFP
1315              (match_operand:MODEF 1 "register_operand" "f")
1316              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1317           UNSPEC_FNSTSW))]
1318   "TARGET_80387"
1319   "* return output_fp_compare (insn, operands, false, false);"
1320   [(set_attr "type" "multi")
1321    (set_attr "unit" "i387")
1322    (set_attr "mode" "<MODE>")])
1324 (define_insn_and_split "*cmp<mode>_cc_i387"
1325   [(set (reg:CCFP FLAGS_REG)
1326         (compare:CCFP
1327           (match_operand:MODEF 1 "register_operand" "f")
1328           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1329    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1330   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1331   "#"
1332   "&& reload_completed"
1333   [(set (match_dup 0)
1334         (unspec:HI
1335           [(compare:CCFP (match_dup 1)(match_dup 2))]
1336         UNSPEC_FNSTSW))
1337    (set (reg:CC FLAGS_REG)
1338         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1339   ""
1340   [(set_attr "type" "multi")
1341    (set_attr "unit" "i387")
1342    (set_attr "mode" "<MODE>")])
1344 (define_insn "*cmpu<mode>_i387"
1345   [(set (match_operand:HI 0 "register_operand" "=a")
1346         (unspec:HI
1347           [(compare:CCFPU
1348              (match_operand:X87MODEF 1 "register_operand" "f")
1349              (match_operand:X87MODEF 2 "register_operand" "f"))]
1350           UNSPEC_FNSTSW))]
1351   "TARGET_80387"
1352   "* return output_fp_compare (insn, operands, false, true);"
1353   [(set_attr "type" "multi")
1354    (set_attr "unit" "i387")
1355    (set_attr "mode" "<MODE>")])
1357 (define_insn_and_split "*cmpu<mode>_cc_i387"
1358   [(set (reg:CCFPU FLAGS_REG)
1359         (compare:CCFPU
1360           (match_operand:X87MODEF 1 "register_operand" "f")
1361           (match_operand:X87MODEF 2 "register_operand" "f")))
1362    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1363   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1364   "#"
1365   "&& reload_completed"
1366   [(set (match_dup 0)
1367         (unspec:HI
1368           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1369         UNSPEC_FNSTSW))
1370    (set (reg:CC FLAGS_REG)
1371         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1372   ""
1373   [(set_attr "type" "multi")
1374    (set_attr "unit" "i387")
1375    (set_attr "mode" "<MODE>")])
1377 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1378   [(set (match_operand:HI 0 "register_operand" "=a")
1379         (unspec:HI
1380           [(compare:CCFP
1381              (match_operand:X87MODEF 1 "register_operand" "f")
1382              (match_operator:X87MODEF 3 "float_operator"
1383                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1384           UNSPEC_FNSTSW))]
1385   "TARGET_80387
1386    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1387        || optimize_function_for_size_p (cfun))"
1388   "* return output_fp_compare (insn, operands, false, false);"
1389   [(set_attr "type" "multi")
1390    (set_attr "unit" "i387")
1391    (set_attr "fp_int_src" "true")
1392    (set_attr "mode" "<SWI24:MODE>")])
1394 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1395   [(set (reg:CCFP FLAGS_REG)
1396         (compare:CCFP
1397           (match_operand:X87MODEF 1 "register_operand" "f")
1398           (match_operator:X87MODEF 3 "float_operator"
1399             [(match_operand:SWI24 2 "memory_operand" "m")])))
1400    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1401   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1402    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1403        || optimize_function_for_size_p (cfun))"
1404   "#"
1405   "&& reload_completed"
1406   [(set (match_dup 0)
1407         (unspec:HI
1408           [(compare:CCFP
1409              (match_dup 1)
1410              (match_op_dup 3 [(match_dup 2)]))]
1411         UNSPEC_FNSTSW))
1412    (set (reg:CC FLAGS_REG)
1413         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1414   ""
1415   [(set_attr "type" "multi")
1416    (set_attr "unit" "i387")
1417    (set_attr "fp_int_src" "true")
1418    (set_attr "mode" "<SWI24:MODE>")])
1420 ;; FP compares, step 2
1421 ;; Move the fpsw to ax.
1423 (define_insn "x86_fnstsw_1"
1424   [(set (match_operand:HI 0 "register_operand" "=a")
1425         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1426   "TARGET_80387"
1427   "fnstsw\t%0"
1428   [(set (attr "length")
1429         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1430    (set_attr "mode" "SI")
1431    (set_attr "unit" "i387")])
1433 ;; FP compares, step 3
1434 ;; Get ax into flags, general case.
1436 (define_insn "x86_sahf_1"
1437   [(set (reg:CC FLAGS_REG)
1438         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1439                    UNSPEC_SAHF))]
1440   "TARGET_SAHF"
1442 #ifndef HAVE_AS_IX86_SAHF
1443   if (TARGET_64BIT)
1444     return ASM_BYTE "0x9e";
1445   else
1446 #endif
1447   return "sahf";
1449   [(set_attr "length" "1")
1450    (set_attr "athlon_decode" "vector")
1451    (set_attr "amdfam10_decode" "direct")
1452    (set_attr "bdver1_decode" "direct")
1453    (set_attr "mode" "SI")])
1455 ;; Pentium Pro can do steps 1 through 3 in one go.
1456 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1457 ;; (these i387 instructions set flags directly)
1459 (define_mode_iterator FPCMP [CCFP CCFPU])
1460 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1462 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1463   [(set (reg:FPCMP FLAGS_REG)
1464         (compare:FPCMP
1465           (match_operand:MODEF 0 "register_operand" "f,x")
1466           (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1467   "TARGET_MIX_SSE_I387
1468    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1469   "* return output_fp_compare (insn, operands, true,
1470                                <FPCMP:MODE>mode == CCFPUmode);"
1471   [(set_attr "type" "fcmp,ssecomi")
1472    (set_attr "prefix" "orig,maybe_vex")
1473    (set_attr "mode" "<MODEF:MODE>")
1474    (set (attr "prefix_rep")
1475         (if_then_else (eq_attr "type" "ssecomi")
1476                       (const_string "0")
1477                       (const_string "*")))
1478    (set (attr "prefix_data16")
1479         (cond [(eq_attr "type" "fcmp")
1480                  (const_string "*")
1481                (eq_attr "mode" "DF")
1482                  (const_string "1")
1483               ]
1484               (const_string "0")))
1485    (set_attr "athlon_decode" "vector")
1486    (set_attr "amdfam10_decode" "direct")
1487    (set_attr "bdver1_decode" "double")])
1489 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1490   [(set (reg:FPCMP FLAGS_REG)
1491         (compare:FPCMP
1492           (match_operand:MODEF 0 "register_operand" "x")
1493           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1494   "TARGET_SSE_MATH
1495    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1496   "* return output_fp_compare (insn, operands, true,
1497                                <FPCMP:MODE>mode == CCFPUmode);"
1498   [(set_attr "type" "ssecomi")
1499    (set_attr "prefix" "maybe_vex")
1500    (set_attr "mode" "<MODEF:MODE>")
1501    (set_attr "prefix_rep" "0")
1502    (set (attr "prefix_data16")
1503         (if_then_else (eq_attr "mode" "DF")
1504                       (const_string "1")
1505                       (const_string "0")))
1506    (set_attr "athlon_decode" "vector")
1507    (set_attr "amdfam10_decode" "direct")
1508    (set_attr "bdver1_decode" "double")])
1510 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1511   [(set (reg:FPCMP FLAGS_REG)
1512         (compare:FPCMP
1513           (match_operand:X87MODEF 0 "register_operand" "f")
1514           (match_operand:X87MODEF 1 "register_operand" "f")))]
1515   "TARGET_80387 && TARGET_CMOVE
1516    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1517   "* return output_fp_compare (insn, operands, true,
1518                                <FPCMP:MODE>mode == CCFPUmode);"
1519   [(set_attr "type" "fcmp")
1520    (set_attr "mode" "<X87MODEF:MODE>")
1521    (set_attr "athlon_decode" "vector")
1522    (set_attr "amdfam10_decode" "direct")
1523    (set_attr "bdver1_decode" "double")])
1525 ;; Push/pop instructions.
1527 (define_insn "*push<mode>2"
1528   [(set (match_operand:DWI 0 "push_operand" "=<")
1529         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1530   ""
1531   "#"
1532   [(set_attr "type" "multi")
1533    (set_attr "mode" "<MODE>")])
1535 (define_split
1536   [(set (match_operand:TI 0 "push_operand")
1537         (match_operand:TI 1 "general_operand"))]
1538   "TARGET_64BIT && reload_completed
1539    && !SSE_REG_P (operands[1])"
1540   [(const_int 0)]
1541   "ix86_split_long_move (operands); DONE;")
1543 (define_insn "*pushdi2_rex64"
1544   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1545         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1546   "TARGET_64BIT"
1547   "@
1548    push{q}\t%1
1549    #"
1550   [(set_attr "type" "push,multi")
1551    (set_attr "mode" "DI")])
1553 ;; Convert impossible pushes of immediate to existing instructions.
1554 ;; First try to get scratch register and go through it.  In case this
1555 ;; fails, push sign extended lower part first and then overwrite
1556 ;; upper part by 32bit move.
1557 (define_peephole2
1558   [(match_scratch:DI 2 "r")
1559    (set (match_operand:DI 0 "push_operand")
1560         (match_operand:DI 1 "immediate_operand"))]
1561   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1562    && !x86_64_immediate_operand (operands[1], DImode)"
1563   [(set (match_dup 2) (match_dup 1))
1564    (set (match_dup 0) (match_dup 2))])
1566 ;; We need to define this as both peepholer and splitter for case
1567 ;; peephole2 pass is not run.
1568 ;; "&& 1" is needed to keep it from matching the previous pattern.
1569 (define_peephole2
1570   [(set (match_operand:DI 0 "push_operand")
1571         (match_operand:DI 1 "immediate_operand"))]
1572   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1573    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1574   [(set (match_dup 0) (match_dup 1))
1575    (set (match_dup 2) (match_dup 3))]
1577   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1579   operands[1] = gen_lowpart (DImode, operands[2]);
1580   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1581                                                    GEN_INT (4)));
1584 (define_split
1585   [(set (match_operand:DI 0 "push_operand")
1586         (match_operand:DI 1 "immediate_operand"))]
1587   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1588                     ? epilogue_completed : reload_completed)
1589    && !symbolic_operand (operands[1], DImode)
1590    && !x86_64_immediate_operand (operands[1], DImode)"
1591   [(set (match_dup 0) (match_dup 1))
1592    (set (match_dup 2) (match_dup 3))]
1594   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1596   operands[1] = gen_lowpart (DImode, operands[2]);
1597   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1598                                                    GEN_INT (4)));
1601 (define_split
1602   [(set (match_operand:DI 0 "push_operand")
1603         (match_operand:DI 1 "general_operand"))]
1604   "!TARGET_64BIT && reload_completed
1605    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1606   [(const_int 0)]
1607   "ix86_split_long_move (operands); DONE;")
1609 (define_insn "*pushsi2"
1610   [(set (match_operand:SI 0 "push_operand" "=<")
1611         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1612   "!TARGET_64BIT"
1613   "push{l}\t%1"
1614   [(set_attr "type" "push")
1615    (set_attr "mode" "SI")])
1617 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1618 ;; "push a byte/word".  But actually we use pushl, which has the effect
1619 ;; of rounding the amount pushed up to a word.
1621 ;; For TARGET_64BIT we always round up to 8 bytes.
1622 (define_insn "*push<mode>2_rex64"
1623   [(set (match_operand:SWI124 0 "push_operand" "=X")
1624         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1625   "TARGET_64BIT"
1626   "push{q}\t%q1"
1627   [(set_attr "type" "push")
1628    (set_attr "mode" "DI")])
1630 (define_insn "*push<mode>2"
1631   [(set (match_operand:SWI12 0 "push_operand" "=X")
1632         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1633   "!TARGET_64BIT"
1634   "push{l}\t%k1"
1635   [(set_attr "type" "push")
1636    (set_attr "mode" "SI")])
1638 (define_insn "*push<mode>2_prologue"
1639   [(set (match_operand:W 0 "push_operand" "=<")
1640         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1641    (clobber (mem:BLK (scratch)))]
1642   ""
1643   "push{<imodesuffix>}\t%1"
1644   [(set_attr "type" "push")
1645    (set_attr "mode" "<MODE>")])
1647 (define_insn "*pop<mode>1"
1648   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1649         (match_operand:W 1 "pop_operand" ">"))]
1650   ""
1651   "pop{<imodesuffix>}\t%0"
1652   [(set_attr "type" "pop")
1653    (set_attr "mode" "<MODE>")])
1655 (define_insn "*pop<mode>1_epilogue"
1656   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1657         (match_operand:W 1 "pop_operand" ">"))
1658    (clobber (mem:BLK (scratch)))]
1659   ""
1660   "pop{<imodesuffix>}\t%0"
1661   [(set_attr "type" "pop")
1662    (set_attr "mode" "<MODE>")])
1664 ;; Move instructions.
1666 (define_expand "movoi"
1667   [(set (match_operand:OI 0 "nonimmediate_operand")
1668         (match_operand:OI 1 "general_operand"))]
1669   "TARGET_AVX"
1670   "ix86_expand_move (OImode, operands); DONE;")
1672 (define_expand "movti"
1673   [(set (match_operand:TI 0 "nonimmediate_operand")
1674         (match_operand:TI 1 "nonimmediate_operand"))]
1675   "TARGET_64BIT || TARGET_SSE"
1677   if (TARGET_64BIT)
1678     ix86_expand_move (TImode, operands);
1679   else if (push_operand (operands[0], TImode))
1680     ix86_expand_push (TImode, operands[1]);
1681   else
1682     ix86_expand_vector_move (TImode, operands);
1683   DONE;
1686 ;; This expands to what emit_move_complex would generate if we didn't
1687 ;; have a movti pattern.  Having this avoids problems with reload on
1688 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1689 ;; to have around all the time.
1690 (define_expand "movcdi"
1691   [(set (match_operand:CDI 0 "nonimmediate_operand")
1692         (match_operand:CDI 1 "general_operand"))]
1693   ""
1695   if (push_operand (operands[0], CDImode))
1696     emit_move_complex_push (CDImode, operands[0], operands[1]);
1697   else
1698     emit_move_complex_parts (operands[0], operands[1]);
1699   DONE;
1702 (define_expand "mov<mode>"
1703   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1704         (match_operand:SWI1248x 1 "general_operand"))]
1705   ""
1706   "ix86_expand_move (<MODE>mode, operands); DONE;")
1708 (define_insn "*mov<mode>_xor"
1709   [(set (match_operand:SWI48 0 "register_operand" "=r")
1710         (match_operand:SWI48 1 "const0_operand"))
1711    (clobber (reg:CC FLAGS_REG))]
1712   "reload_completed"
1713   "xor{l}\t%k0, %k0"
1714   [(set_attr "type" "alu1")
1715    (set_attr "mode" "SI")
1716    (set_attr "length_immediate" "0")])
1718 (define_insn "*mov<mode>_or"
1719   [(set (match_operand:SWI48 0 "register_operand" "=r")
1720         (match_operand:SWI48 1 "const_int_operand"))
1721    (clobber (reg:CC FLAGS_REG))]
1722   "reload_completed
1723    && operands[1] == constm1_rtx"
1724   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1725   [(set_attr "type" "alu1")
1726    (set_attr "mode" "<MODE>")
1727    (set_attr "length_immediate" "1")])
1729 (define_insn "*movoi_internal_avx"
1730   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1731         (match_operand:OI 1 "vector_move_operand"  "C ,xm,x"))]
1732   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1734   switch (which_alternative)
1735     {
1736     case 0:
1737       return standard_sse_constant_opcode (insn, operands[1]);
1738     case 1:
1739     case 2:
1740       if (misaligned_operand (operands[0], OImode)
1741           || misaligned_operand (operands[1], OImode))
1742         {
1743           if (get_attr_mode (insn) == MODE_V8SF)
1744             return "vmovups\t{%1, %0|%0, %1}";
1745           else
1746             return "vmovdqu\t{%1, %0|%0, %1}";
1747         }
1748       else
1749         {
1750           if (get_attr_mode (insn) == MODE_V8SF)
1751             return "vmovaps\t{%1, %0|%0, %1}";
1752           else
1753             return "vmovdqa\t{%1, %0|%0, %1}";
1754         }
1755     default:
1756       gcc_unreachable ();
1757     }
1759   [(set_attr "type" "sselog1,ssemov,ssemov")
1760    (set_attr "prefix" "vex")
1761    (set (attr "mode")
1762         (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1763                  (const_string "V8SF")
1764                (and (eq_attr "alternative" "2")
1765                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1766                  (const_string "V8SF")
1767               ]
1768               (const_string "OI")))])
1770 (define_insn "*movti_internal_rex64"
1771   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1772         (match_operand:TI 1 "general_operand"      "riFo,re,C,xm,x"))]
1773   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1775   switch (which_alternative)
1776     {
1777     case 0:
1778     case 1:
1779       return "#";
1780     case 2:
1781       return standard_sse_constant_opcode (insn, operands[1]);
1782     case 3:
1783     case 4:
1784       /* TDmode values are passed as TImode on the stack.  Moving them
1785          to stack may result in unaligned memory access.  */
1786       if (misaligned_operand (operands[0], TImode)
1787           || misaligned_operand (operands[1], TImode))
1788         {
1789           if (get_attr_mode (insn) == MODE_V4SF)
1790             return "%vmovups\t{%1, %0|%0, %1}";
1791           else
1792             return "%vmovdqu\t{%1, %0|%0, %1}";
1793         }
1794       else
1795         {
1796           if (get_attr_mode (insn) == MODE_V4SF)
1797             return "%vmovaps\t{%1, %0|%0, %1}";
1798           else
1799             return "%vmovdqa\t{%1, %0|%0, %1}";
1800         }
1801     default:
1802       gcc_unreachable ();
1803     }
1805   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1806    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1807    (set (attr "mode")
1808         (cond [(eq_attr "alternative" "0,1")
1809                  (const_string "DI")
1810                (not (match_test "TARGET_SSE2"))
1811                  (const_string "V4SF")
1812                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1813                  (const_string "V4SF")
1814                (and (eq_attr "alternative" "4")
1815                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1816                  (const_string "V4SF")
1817                (match_test "TARGET_AVX")
1818                  (const_string "TI")
1819                (match_test "optimize_function_for_size_p (cfun)")
1820                  (const_string "V4SF")
1821                ]
1822                (const_string "TI")))])
1824 (define_split
1825   [(set (match_operand:TI 0 "nonimmediate_operand")
1826         (match_operand:TI 1 "general_operand"))]
1827   "reload_completed
1828    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1829   [(const_int 0)]
1830   "ix86_split_long_move (operands); DONE;")
1832 (define_insn "*movti_internal_sse"
1833   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x ,m")
1834         (match_operand:TI 1 "vector_move_operand"  "C ,xm,x"))]
1835   "TARGET_SSE && !TARGET_64BIT
1836    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1838   switch (which_alternative)
1839     {
1840     case 0:
1841       return standard_sse_constant_opcode (insn, operands[1]);
1842     case 1:
1843     case 2:
1844       /* TDmode values are passed as TImode on the stack.  Moving them
1845          to stack may result in unaligned memory access.  */
1846       if (misaligned_operand (operands[0], TImode)
1847           || misaligned_operand (operands[1], TImode))
1848         {
1849           if (get_attr_mode (insn) == MODE_V4SF)
1850             return "%vmovups\t{%1, %0|%0, %1}";
1851           else
1852             return "%vmovdqu\t{%1, %0|%0, %1}";
1853         }
1854       else
1855         {
1856           if (get_attr_mode (insn) == MODE_V4SF)
1857             return "%vmovaps\t{%1, %0|%0, %1}";
1858           else
1859             return "%vmovdqa\t{%1, %0|%0, %1}";
1860         }
1861     default:
1862       gcc_unreachable ();
1863     }
1865   [(set_attr "type" "sselog1,ssemov,ssemov")
1866    (set_attr "prefix" "maybe_vex")
1867    (set (attr "mode")
1868         (cond [(not (match_test "TARGET_SSE2"))
1869                  (const_string "V4SF")
1870                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1871                  (const_string "V4SF")
1872                (and (eq_attr "alternative" "2")
1873                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1874                  (const_string "V4SF")
1875                (match_test "TARGET_AVX")
1876                  (const_string "TI")
1877                (match_test "optimize_function_for_size_p (cfun)")
1878                  (const_string "V4SF")
1879               ]
1880               (const_string "TI")))])
1882 (define_insn "*movdi_internal_rex64"
1883   [(set (match_operand:DI 0 "nonimmediate_operand"
1884           "=r,r  ,r,m ,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1885         (match_operand:DI 1 "general_operand"
1886           "Z ,rem,i,re,C ,*y ,m  ,*Ym,r   ,C ,*x,*x,m ,*Yi,r   ,*Ym,*x"))]
1887   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1889   switch (get_attr_type (insn))
1890     {
1891     case TYPE_SSECVT:
1892       if (SSE_REG_P (operands[0]))
1893         return "movq2dq\t{%1, %0|%0, %1}";
1894       else
1895         return "movdq2q\t{%1, %0|%0, %1}";
1897     case TYPE_SSEMOV:
1898       if (get_attr_mode (insn) == MODE_V4SF)
1899         return "%vmovaps\t{%1, %0|%0, %1}";
1900       else if (get_attr_mode (insn) == MODE_TI)
1901         return "%vmovdqa\t{%1, %0|%0, %1}";
1903       /* Handle broken assemblers that require movd instead of movq.  */
1904       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1905         return "%vmovd\t{%1, %0|%0, %1}";
1906       else
1907         return "%vmovq\t{%1, %0|%0, %1}";
1909     case TYPE_MMXMOV:
1910       /* Handle broken assemblers that require movd instead of movq.  */
1911       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1912         return "movd\t{%1, %0|%0, %1}";
1913       else
1914         return "movq\t{%1, %0|%0, %1}";
1916     case TYPE_SSELOG1:
1917       return standard_sse_constant_opcode (insn, operands[1]);
1919     case TYPE_MMX:
1920       return "pxor\t%0, %0";
1922     case TYPE_LEA:
1923       return "lea{q}\t{%E1, %0|%0, %E1}";
1925     default:
1926       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1927       if (get_attr_mode (insn) == MODE_SI)
1928         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1929       else if (which_alternative == 2)
1930         return "movabs{q}\t{%1, %0|%0, %1}";
1931       else if (ix86_use_lea_for_mov (insn, operands))
1932         return "lea{q}\t{%E1, %0|%0, %E1}";
1933       else
1934         return "mov{q}\t{%1, %0|%0, %1}";
1935     }
1937   [(set (attr "type")
1938      (cond [(eq_attr "alternative" "4")
1939               (const_string "mmx")
1940             (eq_attr "alternative" "5,6,7,8")
1941               (const_string "mmxmov")
1942             (eq_attr "alternative" "9")
1943               (const_string "sselog1")
1944             (eq_attr "alternative" "10,11,12,13,14")
1945               (const_string "ssemov")
1946             (eq_attr "alternative" "15,16")
1947               (const_string "ssecvt")
1948             (match_operand 1 "pic_32bit_operand")
1949               (const_string "lea")
1950            ]
1951            (const_string "imov")))
1952    (set (attr "modrm")
1953      (if_then_else
1954        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1955          (const_string "0")
1956          (const_string "*")))
1957    (set (attr "length_immediate")
1958      (if_then_else
1959        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1960          (const_string "8")
1961          (const_string "*")))
1962    (set (attr "prefix_rex")
1963      (if_then_else (eq_attr "alternative" "7,8")
1964        (const_string "1")
1965        (const_string "*")))
1966    (set (attr "prefix_data16")
1967      (if_then_else (eq_attr "alternative" "10")
1968        (const_string "1")
1969        (const_string "*")))
1970    (set (attr "prefix")
1971      (if_then_else (eq_attr "alternative" "9,10,11,12,13,14")
1972        (const_string "maybe_vex")
1973        (const_string "orig")))
1974    (set (attr "mode")
1975         (cond [(eq_attr "alternative" "0")
1976                   (const_string "SI")
1977                (eq_attr "alternative" "9,11")
1978                   (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1979                            (const_string "V4SF")
1980                          (match_test "TARGET_AVX")
1981                            (const_string "TI")
1982                          (match_test "optimize_function_for_size_p (cfun)")
1983                            (const_string "V4SF")
1984                         ]
1985                         (const_string "TI"))
1986               ]
1987               (const_string "DI")))])
1989 ;; Reload patterns to support multi-word load/store
1990 ;; with non-offsetable address.
1991 (define_expand "reload_noff_store"
1992   [(parallel [(match_operand 0 "memory_operand" "=m")
1993               (match_operand 1 "register_operand" "r")
1994               (match_operand:DI 2 "register_operand" "=&r")])]
1995   "TARGET_64BIT"
1997   rtx mem = operands[0];
1998   rtx addr = XEXP (mem, 0);
2000   emit_move_insn (operands[2], addr);
2001   mem = replace_equiv_address_nv (mem, operands[2]);
2003   emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2004   DONE;
2007 (define_expand "reload_noff_load"
2008   [(parallel [(match_operand 0 "register_operand" "=r")
2009               (match_operand 1 "memory_operand" "m")
2010               (match_operand:DI 2 "register_operand" "=r")])]
2011   "TARGET_64BIT"
2013   rtx mem = operands[1];
2014   rtx addr = XEXP (mem, 0);
2016   emit_move_insn (operands[2], addr);
2017   mem = replace_equiv_address_nv (mem, operands[2]);
2019   emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2020   DONE;
2023 (define_insn "*movdi_internal"
2024   [(set (match_operand:DI 0 "nonimmediate_operand"
2025           "=r  ,o  ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2026         (match_operand:DI 1 "general_operand"
2027           "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2028   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2030   switch (get_attr_type (insn))
2031     {
2032     case TYPE_SSECVT:
2033       if (SSE_REG_P (operands[0]))
2034         return "movq2dq\t{%1, %0|%0, %1}";
2035       else
2036         return "movdq2q\t{%1, %0|%0, %1}";
2038     case TYPE_SSEMOV:
2039       switch (get_attr_mode (insn))
2040         {
2041         case MODE_TI:
2042           return "%vmovdqa\t{%1, %0|%0, %1}";
2043         case MODE_DI:
2044            return "%vmovq\t{%1, %0|%0, %1}";
2045         case MODE_V4SF:
2046           return "%vmovaps\t{%1, %0|%0, %1}";
2047         case MODE_V2SF:
2048           return "movlps\t{%1, %0|%0, %1}";
2049         default:
2050           gcc_unreachable ();
2051         }
2053     case TYPE_MMXMOV:
2054       return "movq\t{%1, %0|%0, %1}";
2056     case TYPE_SSELOG1:
2057       return standard_sse_constant_opcode (insn, operands[1]);
2059     case TYPE_MMX:
2060       return "pxor\t%0, %0";
2062     case TYPE_MULTI:
2063       return "#";
2065     default:
2066       gcc_unreachable ();
2067     }
2069   [(set (attr "isa")
2070      (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2071               (const_string "sse2")
2072             (eq_attr "alternative" "9,10,11,12")
2073               (const_string "noavx")
2074            ]
2075            (const_string "*")))
2076    (set (attr "type")
2077      (cond [(eq_attr "alternative" "0,1")
2078               (const_string "multi")
2079             (eq_attr "alternative" "2")
2080               (const_string "mmx")
2081             (eq_attr "alternative" "3,4")
2082               (const_string "mmxmov")
2083             (eq_attr "alternative" "5,9")
2084               (const_string "sselog1")
2085             (eq_attr "alternative" "13,14")
2086               (const_string "ssecvt")
2087            ]
2088            (const_string "ssemov")))
2089    (set (attr "prefix")
2090      (if_then_else (eq_attr "alternative" "5,6,7,8")
2091        (const_string "maybe_vex")
2092        (const_string "orig")))
2093    (set (attr "mode")
2094         (cond [(eq_attr "alternative" "9,11")
2095                   (const_string "V4SF")
2096                (eq_attr "alternative" "10,12")
2097                   (const_string "V2SF")
2098                (eq_attr "alternative" "5,7")
2099                   (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2100                            (const_string "V4SF")
2101                          (match_test "TARGET_AVX")
2102                            (const_string "TI")
2103                          (match_test "optimize_function_for_size_p (cfun)")
2104                            (const_string "V4SF")
2105                         ]
2106                         (const_string "TI"))
2107               ]
2108               (const_string "DI")))])
2110 (define_split
2111   [(set (match_operand:DI 0 "nonimmediate_operand")
2112         (match_operand:DI 1 "general_operand"))]
2113   "!TARGET_64BIT && reload_completed
2114    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2115    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2116   [(const_int 0)]
2117   "ix86_split_long_move (operands); DONE;")
2119 (define_insn "*movsi_internal"
2120   [(set (match_operand:SI 0 "nonimmediate_operand"
2121                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2122         (match_operand:SI 1 "general_operand"
2123                         "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m"))]
2124   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2126   switch (get_attr_type (insn))
2127     {
2128     case TYPE_SSELOG1:
2129       return standard_sse_constant_opcode (insn, operands[1]);
2131     case TYPE_SSEMOV:
2132       switch (get_attr_mode (insn))
2133         {
2134         case MODE_TI:
2135           return "%vmovdqa\t{%1, %0|%0, %1}";
2136         case MODE_V4SF:
2137           return "%vmovaps\t{%1, %0|%0, %1}";
2138         case MODE_SI:
2139           return "%vmovd\t{%1, %0|%0, %1}";
2140         case MODE_SF:
2141           return "%vmovss\t{%1, %0|%0, %1}";
2142         default:
2143           gcc_unreachable ();
2144         }
2146     case TYPE_MMX:
2147       return "pxor\t%0, %0";
2149     case TYPE_MMXMOV:
2150       if (get_attr_mode (insn) == MODE_DI)
2151         return "movq\t{%1, %0|%0, %1}";
2152       return "movd\t{%1, %0|%0, %1}";
2154     case TYPE_LEA:
2155       return "lea{l}\t{%E1, %0|%0, %E1}";
2157     default:
2158       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2159       if (ix86_use_lea_for_mov (insn, operands))
2160         return "lea{l}\t{%E1, %0|%0, %E1}";
2161       else
2162         return "mov{l}\t{%1, %0|%0, %1}";
2163     }
2165   [(set (attr "type")
2166      (cond [(eq_attr "alternative" "2")
2167               (const_string "mmx")
2168             (eq_attr "alternative" "3,4,5")
2169               (const_string "mmxmov")
2170             (eq_attr "alternative" "6")
2171               (const_string "sselog1")
2172             (eq_attr "alternative" "7,8,9,10,11")
2173               (const_string "ssemov")
2174             (match_operand 1 "pic_32bit_operand")
2175               (const_string "lea")
2176            ]
2177            (const_string "imov")))
2178    (set (attr "prefix")
2179      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2180        (const_string "orig")
2181        (const_string "maybe_vex")))
2182    (set (attr "prefix_data16")
2183      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2184        (const_string "1")
2185        (const_string "*")))
2186    (set (attr "mode")
2187      (cond [(eq_attr "alternative" "2,3")
2188               (const_string "DI")
2189             (eq_attr "alternative" "6,7")
2190               (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2191                        (const_string "V4SF")
2192                      (match_test "TARGET_AVX")
2193                        (const_string "TI")
2194                      (ior (not (match_test "TARGET_SSE2"))
2195                           (match_test "optimize_function_for_size_p (cfun)"))
2196                        (const_string "V4SF")
2197                     ]
2198                     (const_string "TI"))
2199             (and (eq_attr "alternative" "8,9,10,11")
2200                  (not (match_test "TARGET_SSE2")))
2201               (const_string "SF")
2202            ]
2203            (const_string "SI")))])
2205 (define_insn "*movhi_internal"
2206   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m")
2207         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn"))]
2208   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2210   switch (get_attr_type (insn))
2211     {
2212     case TYPE_IMOVX:
2213       /* movzwl is faster than movw on p2 due to partial word stalls,
2214          though not as fast as an aligned movl.  */
2215       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2216     default:
2217       if (get_attr_mode (insn) == MODE_SI)
2218         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2219       else
2220         return "mov{w}\t{%1, %0|%0, %1}";
2221     }
2223   [(set (attr "type")
2224      (cond [(match_test "optimize_function_for_size_p (cfun)")
2225               (const_string "imov")
2226             (and (eq_attr "alternative" "0")
2227                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2228                       (not (match_test "TARGET_HIMODE_MATH"))))
2229               (const_string "imov")
2230             (and (eq_attr "alternative" "1,2")
2231                  (match_operand:HI 1 "aligned_operand"))
2232               (const_string "imov")
2233             (and (match_test "TARGET_MOVX")
2234                  (eq_attr "alternative" "0,2"))
2235               (const_string "imovx")
2236            ]
2237            (const_string "imov")))
2238     (set (attr "mode")
2239       (cond [(eq_attr "type" "imovx")
2240                (const_string "SI")
2241              (and (eq_attr "alternative" "1,2")
2242                   (match_operand:HI 1 "aligned_operand"))
2243                (const_string "SI")
2244              (and (eq_attr "alternative" "0")
2245                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2246                        (not (match_test "TARGET_HIMODE_MATH"))))
2247                (const_string "SI")
2248             ]
2249             (const_string "HI")))])
2251 ;; Situation is quite tricky about when to choose full sized (SImode) move
2252 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2253 ;; partial register dependency machines (such as AMD Athlon), where QImode
2254 ;; moves issue extra dependency and for partial register stalls machines
2255 ;; that don't use QImode patterns (and QImode move cause stall on the next
2256 ;; instruction).
2258 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2259 ;; register stall machines with, where we use QImode instructions, since
2260 ;; partial register stall can be caused there.  Then we use movzx.
2261 (define_insn "*movqi_internal"
2262   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2263         (match_operand:QI 1 "general_operand"      "q ,qn,qm,q,rn,qm,qn"))]
2264   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2266   switch (get_attr_type (insn))
2267     {
2268     case TYPE_IMOVX:
2269       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2270       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2271     default:
2272       if (get_attr_mode (insn) == MODE_SI)
2273         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2274       else
2275         return "mov{b}\t{%1, %0|%0, %1}";
2276     }
2278   [(set (attr "type")
2279      (cond [(and (eq_attr "alternative" "5")
2280                  (not (match_operand:QI 1 "aligned_operand")))
2281               (const_string "imovx")
2282             (match_test "optimize_function_for_size_p (cfun)")
2283               (const_string "imov")
2284             (and (eq_attr "alternative" "3")
2285                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2286                       (not (match_test "TARGET_QIMODE_MATH"))))
2287               (const_string "imov")
2288             (eq_attr "alternative" "3,5")
2289               (const_string "imovx")
2290             (and (match_test "TARGET_MOVX")
2291                  (eq_attr "alternative" "2"))
2292               (const_string "imovx")
2293            ]
2294            (const_string "imov")))
2295    (set (attr "mode")
2296       (cond [(eq_attr "alternative" "3,4,5")
2297                (const_string "SI")
2298              (eq_attr "alternative" "6")
2299                (const_string "QI")
2300              (eq_attr "type" "imovx")
2301                (const_string "SI")
2302              (and (eq_attr "type" "imov")
2303                   (and (eq_attr "alternative" "0,1")
2304                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2305                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2306                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2307                (const_string "SI")
2308              ;; Avoid partial register stalls when not using QImode arithmetic
2309              (and (eq_attr "type" "imov")
2310                   (and (eq_attr "alternative" "0,1")
2311                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2312                             (not (match_test "TARGET_QIMODE_MATH")))))
2313                (const_string "SI")
2314            ]
2315            (const_string "QI")))])
2317 ;; Stores and loads of ax to arbitrary constant address.
2318 ;; We fake an second form of instruction to force reload to load address
2319 ;; into register when rax is not available
2320 (define_insn "*movabs<mode>_1"
2321   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2322         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2323   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2324   "@
2325    movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2326    mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2327   [(set_attr "type" "imov")
2328    (set_attr "modrm" "0,*")
2329    (set_attr "length_address" "8,0")
2330    (set_attr "length_immediate" "0,*")
2331    (set_attr "memory" "store")
2332    (set_attr "mode" "<MODE>")])
2334 (define_insn "*movabs<mode>_2"
2335   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2336         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2337   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2338   "@
2339    movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2340    mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2341   [(set_attr "type" "imov")
2342    (set_attr "modrm" "0,*")
2343    (set_attr "length_address" "8,0")
2344    (set_attr "length_immediate" "0")
2345    (set_attr "memory" "load")
2346    (set_attr "mode" "<MODE>")])
2348 (define_insn "swap<mode>"
2349   [(set (match_operand:SWI48 0 "register_operand" "+r")
2350         (match_operand:SWI48 1 "register_operand" "+r"))
2351    (set (match_dup 1)
2352         (match_dup 0))]
2353   ""
2354   "xchg{<imodesuffix>}\t%1, %0"
2355   [(set_attr "type" "imov")
2356    (set_attr "mode" "<MODE>")
2357    (set_attr "pent_pair" "np")
2358    (set_attr "athlon_decode" "vector")
2359    (set_attr "amdfam10_decode" "double")
2360    (set_attr "bdver1_decode" "double")])
2362 (define_insn "*swap<mode>_1"
2363   [(set (match_operand:SWI12 0 "register_operand" "+r")
2364         (match_operand:SWI12 1 "register_operand" "+r"))
2365    (set (match_dup 1)
2366         (match_dup 0))]
2367   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2368   "xchg{l}\t%k1, %k0"
2369   [(set_attr "type" "imov")
2370    (set_attr "mode" "SI")
2371    (set_attr "pent_pair" "np")
2372    (set_attr "athlon_decode" "vector")
2373    (set_attr "amdfam10_decode" "double")
2374    (set_attr "bdver1_decode" "double")])
2376 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2377 ;; is disabled for AMDFAM10
2378 (define_insn "*swap<mode>_2"
2379   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2380         (match_operand:SWI12 1 "register_operand" "+<r>"))
2381    (set (match_dup 1)
2382         (match_dup 0))]
2383   "TARGET_PARTIAL_REG_STALL"
2384   "xchg{<imodesuffix>}\t%1, %0"
2385   [(set_attr "type" "imov")
2386    (set_attr "mode" "<MODE>")
2387    (set_attr "pent_pair" "np")
2388    (set_attr "athlon_decode" "vector")])
2390 (define_expand "movstrict<mode>"
2391   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2392         (match_operand:SWI12 1 "general_operand"))]
2393   ""
2395   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2396     FAIL;
2397   if (GET_CODE (operands[0]) == SUBREG
2398       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2399     FAIL;
2400   /* Don't generate memory->memory moves, go through a register */
2401   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2402     operands[1] = force_reg (<MODE>mode, operands[1]);
2405 (define_insn "*movstrict<mode>_1"
2406   [(set (strict_low_part
2407           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2408         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2409   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2410    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2411   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2412   [(set_attr "type" "imov")
2413    (set_attr "mode" "<MODE>")])
2415 (define_insn "*movstrict<mode>_xor"
2416   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2417         (match_operand:SWI12 1 "const0_operand"))
2418    (clobber (reg:CC FLAGS_REG))]
2419   "reload_completed"
2420   "xor{<imodesuffix>}\t%0, %0"
2421   [(set_attr "type" "alu1")
2422    (set_attr "mode" "<MODE>")
2423    (set_attr "length_immediate" "0")])
2425 (define_insn "*mov<mode>_extv_1"
2426   [(set (match_operand:SWI24 0 "register_operand" "=R")
2427         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2428                             (const_int 8)
2429                             (const_int 8)))]
2430   ""
2431   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2432   [(set_attr "type" "imovx")
2433    (set_attr "mode" "SI")])
2435 (define_insn "*movqi_extv_1_rex64"
2436   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2437         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2438                          (const_int 8)
2439                          (const_int 8)))]
2440   "TARGET_64BIT"
2442   switch (get_attr_type (insn))
2443     {
2444     case TYPE_IMOVX:
2445       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2446     default:
2447       return "mov{b}\t{%h1, %0|%0, %h1}";
2448     }
2450   [(set (attr "type")
2451      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2452                         (match_test "TARGET_MOVX"))
2453         (const_string "imovx")
2454         (const_string "imov")))
2455    (set (attr "mode")
2456      (if_then_else (eq_attr "type" "imovx")
2457         (const_string "SI")
2458         (const_string "QI")))])
2460 (define_insn "*movqi_extv_1"
2461   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2462         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2463                          (const_int 8)
2464                          (const_int 8)))]
2465   "!TARGET_64BIT"
2467   switch (get_attr_type (insn))
2468     {
2469     case TYPE_IMOVX:
2470       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2471     default:
2472       return "mov{b}\t{%h1, %0|%0, %h1}";
2473     }
2475   [(set (attr "type")
2476      (if_then_else (and (match_operand:QI 0 "register_operand")
2477                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2478                              (match_test "TARGET_MOVX")))
2479         (const_string "imovx")
2480         (const_string "imov")))
2481    (set (attr "mode")
2482      (if_then_else (eq_attr "type" "imovx")
2483         (const_string "SI")
2484         (const_string "QI")))])
2486 (define_insn "*mov<mode>_extzv_1"
2487   [(set (match_operand:SWI48 0 "register_operand" "=R")
2488         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2489                             (const_int 8)
2490                             (const_int 8)))]
2491   ""
2492   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2493   [(set_attr "type" "imovx")
2494    (set_attr "mode" "SI")])
2496 (define_insn "*movqi_extzv_2_rex64"
2497   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2498         (subreg:QI
2499           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2500                            (const_int 8)
2501                            (const_int 8)) 0))]
2502   "TARGET_64BIT"
2504   switch (get_attr_type (insn))
2505     {
2506     case TYPE_IMOVX:
2507       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2508     default:
2509       return "mov{b}\t{%h1, %0|%0, %h1}";
2510     }
2512   [(set (attr "type")
2513      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2514                         (match_test "TARGET_MOVX"))
2515         (const_string "imovx")
2516         (const_string "imov")))
2517    (set (attr "mode")
2518      (if_then_else (eq_attr "type" "imovx")
2519         (const_string "SI")
2520         (const_string "QI")))])
2522 (define_insn "*movqi_extzv_2"
2523   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2524         (subreg:QI
2525           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2526                            (const_int 8)
2527                            (const_int 8)) 0))]
2528   "!TARGET_64BIT"
2530   switch (get_attr_type (insn))
2531     {
2532     case TYPE_IMOVX:
2533       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2534     default:
2535       return "mov{b}\t{%h1, %0|%0, %h1}";
2536     }
2538   [(set (attr "type")
2539      (if_then_else (and (match_operand:QI 0 "register_operand")
2540                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2541                              (match_test "TARGET_MOVX")))
2542         (const_string "imovx")
2543         (const_string "imov")))
2544    (set (attr "mode")
2545      (if_then_else (eq_attr "type" "imovx")
2546         (const_string "SI")
2547         (const_string "QI")))])
2549 (define_expand "mov<mode>_insv_1"
2550   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand")
2551                             (const_int 8)
2552                             (const_int 8))
2553         (match_operand:SWI48 1 "nonmemory_operand"))])
2555 (define_insn "*mov<mode>_insv_1_rex64"
2556   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2557                              (const_int 8)
2558                              (const_int 8))
2559         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2560   "TARGET_64BIT"
2562   if (CONST_INT_P (operands[1]))
2563     operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2564   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2566   [(set_attr "type" "imov")
2567    (set_attr "mode" "QI")])
2569 (define_insn "*movsi_insv_1"
2570   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2571                          (const_int 8)
2572                          (const_int 8))
2573         (match_operand:SI 1 "general_operand" "Qmn"))]
2574   "!TARGET_64BIT"
2576   if (CONST_INT_P (operands[1]))
2577     operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0);
2578   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2580   [(set_attr "type" "imov")
2581    (set_attr "mode" "QI")])
2583 (define_insn "*movqi_insv_2"
2584   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2585                          (const_int 8)
2586                          (const_int 8))
2587         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2588                      (const_int 8)))]
2589   ""
2590   "mov{b}\t{%h1, %h0|%h0, %h1}"
2591   [(set_attr "type" "imov")
2592    (set_attr "mode" "QI")])
2594 ;; Floating point push instructions.
2596 (define_insn "*pushtf"
2597   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2598         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2599   "TARGET_SSE"
2601   /* This insn should be already split before reg-stack.  */
2602   gcc_unreachable ();
2604   [(set_attr "type" "multi")
2605    (set_attr "unit" "sse,*,*")
2606    (set_attr "mode" "TF,SI,SI")])
2608 ;; %%% Kill this when call knows how to work this out.
2609 (define_split
2610   [(set (match_operand:TF 0 "push_operand")
2611         (match_operand:TF 1 "sse_reg_operand"))]
2612   "TARGET_SSE && reload_completed"
2613   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2614    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2616 (define_insn "*pushxf"
2617   [(set (match_operand:XF 0 "push_operand" "=<,<")
2618         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2619   "optimize_function_for_speed_p (cfun)"
2621   /* This insn should be already split before reg-stack.  */
2622   gcc_unreachable ();
2624   [(set_attr "type" "multi")
2625    (set_attr "unit" "i387,*")
2626    (set_attr "mode" "XF,SI")])
2628 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2629 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2630 ;; Pushing using integer instructions is longer except for constants
2631 ;; and direct memory references (assuming that any given constant is pushed
2632 ;; only once, but this ought to be handled elsewhere).
2634 (define_insn "*pushxf_nointeger"
2635   [(set (match_operand:XF 0 "push_operand" "=<,<")
2636         (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2637   "optimize_function_for_size_p (cfun)"
2639   /* This insn should be already split before reg-stack.  */
2640   gcc_unreachable ();
2642   [(set_attr "type" "multi")
2643    (set_attr "unit" "i387,*")
2644    (set_attr "mode" "XF,SI")])
2646 ;; %%% Kill this when call knows how to work this out.
2647 (define_split
2648   [(set (match_operand:XF 0 "push_operand")
2649         (match_operand:XF 1 "fp_register_operand"))]
2650   "reload_completed"
2651   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2652    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2653   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2655 (define_insn "*pushdf_rex64"
2656   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2657         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2658   "TARGET_64BIT"
2660   /* This insn should be already split before reg-stack.  */
2661   gcc_unreachable ();
2663   [(set_attr "type" "multi")
2664    (set_attr "unit" "i387,*,*")
2665    (set_attr "mode" "DF,DI,DF")])
2667 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2668 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2669 ;; On the average, pushdf using integers can be still shorter.
2671 (define_insn "*pushdf"
2672   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2673         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2674   "!TARGET_64BIT"
2676   /* This insn should be already split before reg-stack.  */
2677   gcc_unreachable ();
2679   [(set_attr "isa" "*,*,sse2")
2680    (set_attr "type" "multi")
2681    (set_attr "unit" "i387,*,*")
2682    (set_attr "mode" "DF,DI,DF")])
2684 ;; %%% Kill this when call knows how to work this out.
2685 (define_split
2686   [(set (match_operand:DF 0 "push_operand")
2687         (match_operand:DF 1 "any_fp_register_operand"))]
2688   "reload_completed"
2689   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2690    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2692 (define_insn "*pushsf_rex64"
2693   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2694         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2695   "TARGET_64BIT"
2697   /* Anything else should be already split before reg-stack.  */
2698   gcc_assert (which_alternative == 1);
2699   return "push{q}\t%q1";
2701   [(set_attr "type" "multi,push,multi")
2702    (set_attr "unit" "i387,*,*")
2703    (set_attr "mode" "SF,DI,SF")])
2705 (define_insn "*pushsf"
2706   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2707         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2708   "!TARGET_64BIT"
2710   /* Anything else should be already split before reg-stack.  */
2711   gcc_assert (which_alternative == 1);
2712   return "push{l}\t%1";
2714   [(set_attr "type" "multi,push,multi")
2715    (set_attr "unit" "i387,*,*")
2716    (set_attr "mode" "SF,SI,SF")])
2718 ;; %%% Kill this when call knows how to work this out.
2719 (define_split
2720   [(set (match_operand:SF 0 "push_operand")
2721         (match_operand:SF 1 "any_fp_register_operand"))]
2722   "reload_completed"
2723   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2724    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2726   rtx op = XEXP (operands[0], 0);
2727   if (GET_CODE (op) == PRE_DEC)
2728     {
2729       gcc_assert (!TARGET_64BIT);
2730       op = GEN_INT (-4);
2731     }
2732   else
2733     {
2734       op = XEXP (XEXP (op, 1), 1);
2735       gcc_assert (CONST_INT_P (op));
2736     }
2737   operands[2] = op;
2740 (define_split
2741   [(set (match_operand:SF 0 "push_operand")
2742         (match_operand:SF 1 "memory_operand"))]
2743   "reload_completed
2744    && (operands[2] = find_constant_src (insn))"
2745   [(set (match_dup 0) (match_dup 2))])
2747 (define_split
2748   [(set (match_operand 0 "push_operand")
2749         (match_operand 1 "general_operand"))]
2750   "reload_completed
2751    && (GET_MODE (operands[0]) == TFmode
2752        || GET_MODE (operands[0]) == XFmode
2753        || GET_MODE (operands[0]) == DFmode)
2754    && !ANY_FP_REG_P (operands[1])"
2755   [(const_int 0)]
2756   "ix86_split_long_move (operands); DONE;")
2758 ;; Floating point move instructions.
2760 (define_expand "movtf"
2761   [(set (match_operand:TF 0 "nonimmediate_operand")
2762         (match_operand:TF 1 "nonimmediate_operand"))]
2763   "TARGET_64BIT || TARGET_SSE"
2765   ix86_expand_move (TFmode, operands);
2766   DONE;
2769 (define_expand "mov<mode>"
2770   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2771         (match_operand:X87MODEF 1 "general_operand"))]
2772   ""
2773   "ix86_expand_move (<MODE>mode, operands); DONE;")
2775 (define_insn "*movtf_internal_rex64"
2776   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2777         (match_operand:TF 1 "general_operand"      "C ,xm,x,*roF,*rC"))]
2778   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2779    && (!can_create_pseudo_p ()
2780        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2781        || GET_CODE (operands[1]) != CONST_DOUBLE
2782        || (optimize_function_for_size_p (cfun)
2783            && standard_sse_constant_p (operands[1])
2784            && !memory_operand (operands[0], TFmode))
2785        || (!TARGET_MEMORY_MISMATCH_STALL
2786            && memory_operand (operands[0], TFmode)))"
2788   switch (which_alternative)
2789     {
2790     case 0:
2791       return standard_sse_constant_opcode (insn, operands[1]);
2792     case 1:
2793     case 2:
2794       /* Handle misaligned load/store since we
2795          don't have movmisaligntf pattern. */
2796       if (misaligned_operand (operands[0], TFmode)
2797           || misaligned_operand (operands[1], TFmode))
2798         {
2799           if (get_attr_mode (insn) == MODE_V4SF)
2800             return "%vmovups\t{%1, %0|%0, %1}";
2801           else
2802             return "%vmovdqu\t{%1, %0|%0, %1}";
2803         }
2804       else
2805         {
2806           if (get_attr_mode (insn) == MODE_V4SF)
2807             return "%vmovaps\t{%1, %0|%0, %1}";
2808           else
2809             return "%vmovdqa\t{%1, %0|%0, %1}";
2810         }
2812     case 3:
2813     case 4:
2814         return "#";
2816     default:
2817       gcc_unreachable ();
2818     }
2820   [(set_attr "type" "sselog1,ssemov,ssemov,*,*")
2821    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2822    (set (attr "mode")
2823         (cond [(eq_attr "alternative" "3,4")
2824                  (const_string "DI")
2825                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2826                  (const_string "V4SF")
2827                (and (eq_attr "alternative" "2")
2828                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2829                  (const_string "V4SF")
2830                (match_test "TARGET_AVX")
2831                  (const_string "TI")
2832                (ior (not (match_test "TARGET_SSE2"))
2833                     (match_test "optimize_function_for_size_p (cfun)"))
2834                  (const_string "V4SF")
2835                ]
2836                (const_string "TI")))])
2838 (define_insn "*movtf_internal_sse"
2839   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m")
2840         (match_operand:TF 1 "general_operand"      "C ,xm,x"))]
2841   "TARGET_SSE && !TARGET_64BIT
2842    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2843    && (!can_create_pseudo_p ()
2844        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2845        || GET_CODE (operands[1]) != CONST_DOUBLE
2846        || (optimize_function_for_size_p (cfun)
2847            && standard_sse_constant_p (operands[1])
2848            && !memory_operand (operands[0], TFmode))
2849        || (!TARGET_MEMORY_MISMATCH_STALL
2850            && memory_operand (operands[0], TFmode)))"
2852   switch (which_alternative)
2853     {
2854     case 0:
2855       return standard_sse_constant_opcode (insn, operands[1]);
2856     case 1:
2857     case 2:
2858       /* Handle misaligned load/store since we
2859          don't have movmisaligntf pattern. */
2860       if (misaligned_operand (operands[0], TFmode)
2861           || misaligned_operand (operands[1], TFmode))
2862         {
2863           if (get_attr_mode (insn) == MODE_V4SF)
2864             return "%vmovups\t{%1, %0|%0, %1}";
2865           else
2866             return "%vmovdqu\t{%1, %0|%0, %1}";
2867         }
2868       else
2869         {
2870           if (get_attr_mode (insn) == MODE_V4SF)
2871             return "%vmovaps\t{%1, %0|%0, %1}";
2872           else
2873             return "%vmovdqa\t{%1, %0|%0, %1}";
2874         }
2875     default:
2876       gcc_unreachable ();
2877     }
2879   [(set_attr "type" "sselog1,ssemov,ssemov")
2880    (set_attr "prefix" "maybe_vex")
2881    (set (attr "mode")
2882         (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2883                  (const_string "V4SF")
2884                (and (eq_attr "alternative" "2")
2885                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2886                  (const_string "V4SF")
2887                (match_test "TARGET_AVX")
2888                  (const_string "TI")
2889                (ior (not (match_test "TARGET_SSE2"))
2890                     (match_test "optimize_function_for_size_p (cfun)"))
2891                  (const_string "V4SF")
2892                ]
2893                (const_string "TI")))])
2895 (define_insn "*movxf_internal_rex64"
2896   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2897         (match_operand:XF 1 "general_operand"      "fm,f,G,Yx*roF,Yx*rC"))]
2898   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2899    && (!can_create_pseudo_p ()
2900        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2901        || GET_CODE (operands[1]) != CONST_DOUBLE
2902        || (optimize_function_for_size_p (cfun)
2903            && standard_80387_constant_p (operands[1]) > 0
2904            && !memory_operand (operands[0], XFmode))
2905        || (!TARGET_MEMORY_MISMATCH_STALL
2906            && memory_operand (operands[0], XFmode)))"
2908   switch (which_alternative)
2909     {
2910     case 0:
2911     case 1:
2912       return output_387_reg_move (insn, operands);
2914     case 2:
2915       return standard_80387_constant_opcode (operands[1]);
2917     case 3:
2918     case 4:
2919       return "#";
2921     default:
2922       gcc_unreachable ();
2923     }
2925   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2926    (set_attr "mode" "XF,XF,XF,SI,SI")])
2928 ;; Possible store forwarding (partial memory) stall in alternative 4.
2929 (define_insn "*movxf_internal"
2930   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2931         (match_operand:XF 1 "general_operand"      "fm,f,G,Yx*roF,Yx*rF"))]
2932   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2933    && (!can_create_pseudo_p ()
2934        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2935        || GET_CODE (operands[1]) != CONST_DOUBLE
2936        || (optimize_function_for_size_p (cfun)
2937            && standard_80387_constant_p (operands[1]) > 0
2938            && !memory_operand (operands[0], XFmode))
2939        || (!TARGET_MEMORY_MISMATCH_STALL
2940            && memory_operand (operands[0], XFmode)))"
2942   switch (which_alternative)
2943     {
2944     case 0:
2945     case 1:
2946       return output_387_reg_move (insn, operands);
2948     case 2:
2949       return standard_80387_constant_opcode (operands[1]);
2951     case 3:
2952     case 4:
2953       return "#";
2955     default:
2956       gcc_unreachable ();
2957     }
2959   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2960    (set_attr "mode" "XF,XF,XF,SI,SI")])
2962 (define_insn "*movdf_internal_rex64"
2963   [(set (match_operand:DF 0 "nonimmediate_operand"
2964                 "=Yf*f,m   ,Yf*f,?r,?m,?r,?r,x,x,x,m,Yi,r")
2965         (match_operand:DF 1 "general_operand"
2966                 "Yf*fm,Yf*f,G   ,rm,rC,C ,F ,C,x,m,x,r ,Yi"))]
2967   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2968    && (!can_create_pseudo_p ()
2969        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2970        || GET_CODE (operands[1]) != CONST_DOUBLE
2971        || (optimize_function_for_size_p (cfun)
2972            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2973                 && standard_80387_constant_p (operands[1]) > 0)
2974                || (TARGET_SSE2 && TARGET_SSE_MATH
2975                    && standard_sse_constant_p (operands[1]))))
2976        || memory_operand (operands[0], DFmode))"
2978   switch (which_alternative)
2979     {
2980     case 0:
2981     case 1:
2982       return output_387_reg_move (insn, operands);
2984     case 2:
2985       return standard_80387_constant_opcode (operands[1]);
2987     case 3:
2988     case 4:
2989       return "mov{q}\t{%1, %0|%0, %1}";
2991     case 5:
2992       return "mov{l}\t{%1, %k0|%k0, %1}";
2994     case 6:
2995       return "movabs{q}\t{%1, %0|%0, %1}";
2997     case 7:
2998       return standard_sse_constant_opcode (insn, operands[1]);
3000     case 8:
3001     case 9:
3002     case 10:
3003       switch (get_attr_mode (insn))
3004         {
3005         case MODE_V2DF:
3006           return "%vmovapd\t{%1, %0|%0, %1}";
3007         case MODE_V4SF:
3008           return "%vmovaps\t{%1, %0|%0, %1}";
3010         case MODE_DI:
3011           return "%vmovq\t{%1, %0|%0, %1}";
3012         case MODE_DF:
3013           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3014             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3015           return "%vmovsd\t{%1, %0|%0, %1}";
3016         case MODE_V1DF:
3017           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3018         case MODE_V2SF:
3019           return "%vmovlps\t{%1, %d0|%d0, %1}";
3020         default:
3021           gcc_unreachable ();
3022         }
3024     case 11:
3025     case 12:
3026       /* Handle broken assemblers that require movd instead of movq.  */
3027       return "%vmovd\t{%1, %0|%0, %1}";
3029     default:
3030       gcc_unreachable();
3031     }
3033   [(set (attr "type")
3034         (cond [(eq_attr "alternative" "0,1,2")
3035                  (const_string "fmov")
3036                (eq_attr "alternative" "3,4,5,6")
3037                  (const_string "imov")
3038                (eq_attr "alternative" "7")
3039                  (const_string "sselog1")
3040               ]
3041               (const_string "ssemov")))
3042    (set (attr "modrm")
3043      (if_then_else
3044        (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
3045          (const_string "0")
3046          (const_string "*")))
3047    (set (attr "length_immediate")
3048      (if_then_else
3049        (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
3050          (const_string "8")
3051          (const_string "*")))
3052    (set (attr "prefix")
3053      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3054        (const_string "orig")
3055        (const_string "maybe_vex")))
3056    (set (attr "prefix_data16")
3057      (if_then_else (eq_attr "mode" "V1DF")
3058        (const_string "1")
3059        (const_string "*")))
3060    (set (attr "mode")
3061         (cond [(eq_attr "alternative" "0,1,2")
3062                  (const_string "DF")
3063                (eq_attr "alternative" "3,4,6,11,12")
3064                  (const_string "DI")
3065                (eq_attr "alternative" "5")
3066                  (const_string "SI")
3068                /* xorps is one byte shorter for !TARGET_AVX.  */
3069                (eq_attr "alternative" "7")
3070                  (cond [(match_test "TARGET_AVX")
3071                           (const_string "V2DF")
3072                         (match_test "optimize_function_for_size_p (cfun)")
3073                           (const_string "V4SF")
3074                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3075                           (const_string "TI")
3076                        ]
3077                        (const_string "V2DF"))
3079                /* For architectures resolving dependencies on
3080                   whole SSE registers use APD move to break dependency
3081                   chains, otherwise use short move to avoid extra work.
3083                   movaps encodes one byte shorter for !TARGET_AVX.  */
3084                (eq_attr "alternative" "8")
3085                  (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3086                           (const_string "V4SF")
3087                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3088                           (const_string "V2DF")
3089                         (match_test "TARGET_AVX")
3090                           (const_string "DF")
3091                         (match_test "optimize_function_for_size_p (cfun)")
3092                           (const_string "V4SF")
3093                    ]
3094                    (const_string "DF"))
3095                /* For architectures resolving dependencies on register
3096                   parts we may avoid extra work to zero out upper part
3097                   of register.  */
3098                (eq_attr "alternative" "9")
3099                  (if_then_else
3100                    (match_test "TARGET_SSE_SPLIT_REGS")
3101                    (const_string "V1DF")
3102                    (const_string "DF"))
3103               ]
3104               (const_string "DF")))])
3106 ;; Possible store forwarding (partial memory) stall in alternative 4.
3107 (define_insn "*movdf_internal"
3108   [(set (match_operand:DF 0 "nonimmediate_operand"
3109                 "=Yf*f,m   ,Yf*f,?Yd*r ,!o   ,x,x,x,m,*x,*x,*x,m")
3110         (match_operand:DF 1 "general_operand"
3111                 "Yf*fm,Yf*f,G   ,Yd*roF,Yd*rF,C,x,m,x,C ,*x,m ,*x"))]
3112   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3113    && (!can_create_pseudo_p ()
3114        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3115        || GET_CODE (operands[1]) != CONST_DOUBLE
3116        || (optimize_function_for_size_p (cfun)
3117            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3118                 && standard_80387_constant_p (operands[1]) > 0)
3119                || (TARGET_SSE2 && TARGET_SSE_MATH
3120                    && standard_sse_constant_p (operands[1])))
3121            && !memory_operand (operands[0], DFmode))
3122        || (!TARGET_MEMORY_MISMATCH_STALL
3123            && memory_operand (operands[0], DFmode)))"
3125   switch (which_alternative)
3126     {
3127     case 0:
3128     case 1:
3129       return output_387_reg_move (insn, operands);
3131     case 2:
3132       return standard_80387_constant_opcode (operands[1]);
3134     case 3:
3135     case 4:
3136       return "#";
3138     case 5:
3139     case 9:
3140       return standard_sse_constant_opcode (insn, operands[1]);
3142     case 6:
3143     case 7:
3144     case 8:
3145     case 10:
3146     case 11:
3147     case 12:
3148       switch (get_attr_mode (insn))
3149         {
3150         case MODE_V2DF:
3151           return "%vmovapd\t{%1, %0|%0, %1}";
3152         case MODE_V4SF:
3153           return "%vmovaps\t{%1, %0|%0, %1}";
3155         case MODE_DI:
3156           return "%vmovq\t{%1, %0|%0, %1}";
3157         case MODE_DF:
3158           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3159             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3160           return "%vmovsd\t{%1, %0|%0, %1}";
3161         case MODE_V1DF:
3162           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3163         case MODE_V2SF:
3164           return "%vmovlps\t{%1, %d0|%d0, %1}";
3165         default:
3166           gcc_unreachable ();
3167         }
3169     default:
3170       gcc_unreachable ();
3171     }
3173   [(set (attr "isa")
3174      (if_then_else (eq_attr "alternative" "5,6,7,8")
3175        (const_string "sse2")
3176        (const_string "*")))
3177    (set (attr "type")
3178         (cond [(eq_attr "alternative" "0,1,2")
3179                  (const_string "fmov")
3180                (eq_attr "alternative" "3,4")
3181                  (const_string "multi")
3182                (eq_attr "alternative" "5,9")
3183                  (const_string "sselog1")
3184               ]
3185               (const_string "ssemov")))
3186    (set (attr "prefix")
3187      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3188        (const_string "orig")
3189        (const_string "maybe_vex")))
3190    (set (attr "prefix_data16")
3191      (if_then_else (eq_attr "mode" "V1DF")
3192        (const_string "1")
3193        (const_string "*")))
3194    (set (attr "mode")
3195         (cond [(eq_attr "alternative" "0,1,2")
3196                  (const_string "DF")
3197                (eq_attr "alternative" "3,4")
3198                  (const_string "SI")
3200                /* For SSE1, we have many fewer alternatives.  */
3201                (not (match_test "TARGET_SSE2"))
3202                  (if_then_else
3203                    (eq_attr "alternative" "5,6,9,10")
3204                    (const_string "V4SF")
3205                    (const_string "V2SF"))
3207                /* xorps is one byte shorter for !TARGET_AVX.  */
3208                (eq_attr "alternative" "5,9")
3209                  (cond [(match_test "TARGET_AVX")
3210                           (const_string "V2DF")
3211                         (match_test "optimize_function_for_size_p (cfun)")
3212                           (const_string "V4SF")
3213                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3214                           (const_string "TI")
3215                        ]
3216                        (const_string "V2DF"))
3218                /* For architectures resolving dependencies on
3219                   whole SSE registers use APD move to break dependency
3220                   chains, otherwise use short move to avoid extra work.
3222                   movaps encodes one byte shorter for !TARGET_AVX.  */
3223                (eq_attr "alternative" "6,10")
3224                  (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3225                           (const_string "V4SF")
3226                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3227                           (const_string "V2DF")
3228                         (match_test "TARGET_AVX")
3229                           (const_string "DF")
3230                         (match_test "optimize_function_for_size_p (cfun)")
3231                           (const_string "V4SF")
3232                    ]
3233                    (const_string "DF"))
3235                /* For architectures resolving dependencies on register
3236                   parts we may avoid extra work to zero out upper part
3237                   of register.  */
3238                (eq_attr "alternative" "7,11")
3239                  (if_then_else
3240                    (match_test "TARGET_SSE_SPLIT_REGS")
3241                    (const_string "V1DF")
3242                    (const_string "DF"))
3243               ]
3244               (const_string "DF")))])
3246 (define_insn "*movsf_internal"
3247   [(set (match_operand:SF 0 "nonimmediate_operand"
3248           "=Yf*f,m   ,Yf*f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3249         (match_operand:SF 1 "general_operand"
3250           "Yf*fm,Yf*f,G   ,rmF,rF,C,x,m,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3251   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3252    && (!can_create_pseudo_p ()
3253        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3254        || GET_CODE (operands[1]) != CONST_DOUBLE
3255        || (optimize_function_for_size_p (cfun)
3256            && ((!TARGET_SSE_MATH
3257                 && standard_80387_constant_p (operands[1]) > 0)
3258                || (TARGET_SSE_MATH
3259                    && standard_sse_constant_p (operands[1]))))
3260        || memory_operand (operands[0], SFmode))"
3262   switch (which_alternative)
3263     {
3264     case 0:
3265     case 1:
3266       return output_387_reg_move (insn, operands);
3268     case 2:
3269       return standard_80387_constant_opcode (operands[1]);
3271     case 3:
3272     case 4:
3273       return "mov{l}\t{%1, %0|%0, %1}";
3275     case 5:
3276       return standard_sse_constant_opcode (insn, operands[1]);
3278     case 6:
3279       if (get_attr_mode (insn) == MODE_V4SF)
3280         return "%vmovaps\t{%1, %0|%0, %1}";
3281       if (TARGET_AVX)
3282         return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3284     case 7:
3285     case 8:
3286       return "%vmovss\t{%1, %0|%0, %1}";
3288     case 9:
3289     case 10:
3290     case 14:
3291     case 15:
3292       return "movd\t{%1, %0|%0, %1}";
3294     case 11:
3295       return "movq\t{%1, %0|%0, %1}";
3297     case 12:
3298     case 13:
3299       return "%vmovd\t{%1, %0|%0, %1}";
3301     default:
3302       gcc_unreachable ();
3303     }
3305   [(set (attr "type")
3306         (cond [(eq_attr "alternative" "0,1,2")
3307                  (const_string "fmov")
3308                (eq_attr "alternative" "3,4")
3309                  (const_string "imov")
3310                (eq_attr "alternative" "5")
3311                  (const_string "sselog1")
3312                (eq_attr "alternative" "9,10,11,14,15")
3313                  (const_string "mmxmov")
3314               ]
3315               (const_string "ssemov")))
3316    (set (attr "prefix")
3317      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3318        (const_string "maybe_vex")
3319        (const_string "orig")))
3320    (set (attr "mode")
3321         (cond [(eq_attr "alternative" "3,4,9,10")
3322                  (const_string "SI")
3323                (eq_attr "alternative" "5")
3324                  (cond [(match_test "TARGET_AVX")
3325                           (const_string "V4SF")
3326                         (ior (not (match_test "TARGET_SSE2"))
3327                              (match_test "optimize_function_for_size_p (cfun)"))
3328                           (const_string "V4SF")
3329                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3330                           (const_string "TI")
3331                        ]
3332                        (const_string "V4SF"))
3334                /* For architectures resolving dependencies on
3335                   whole SSE registers use APS move to break dependency
3336                   chains, otherwise use short move to avoid extra work.
3338                   Do the same for architectures resolving dependencies on
3339                   the parts.  While in DF mode it is better to always handle
3340                   just register parts, the SF mode is different due to lack
3341                   of instructions to load just part of the register.  It is
3342                   better to maintain the whole registers in single format
3343                   to avoid problems on using packed logical operations.  */
3344                (eq_attr "alternative" "6")
3345                  (if_then_else
3346                    (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3347                         (match_test "TARGET_SSE_SPLIT_REGS"))
3348                    (const_string "V4SF")
3349                    (const_string "SF"))
3350                (eq_attr "alternative" "11")
3351                  (const_string "DI")]
3352                (const_string "SF")))])
3354 (define_split
3355   [(set (match_operand 0 "any_fp_register_operand")
3356         (match_operand 1 "memory_operand"))]
3357   "reload_completed
3358    && (GET_MODE (operands[0]) == TFmode
3359        || GET_MODE (operands[0]) == XFmode
3360        || GET_MODE (operands[0]) == DFmode
3361        || GET_MODE (operands[0]) == SFmode)
3362    && (operands[2] = find_constant_src (insn))"
3363   [(set (match_dup 0) (match_dup 2))]
3365   rtx c = operands[2];
3366   int r = REGNO (operands[0]);
3368   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3369       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3370     FAIL;
3373 (define_split
3374   [(set (match_operand 0 "any_fp_register_operand")
3375         (float_extend (match_operand 1 "memory_operand")))]
3376   "reload_completed
3377    && (GET_MODE (operands[0]) == TFmode
3378        || GET_MODE (operands[0]) == XFmode
3379        || GET_MODE (operands[0]) == DFmode)
3380    && (operands[2] = find_constant_src (insn))"
3381   [(set (match_dup 0) (match_dup 2))]
3383   rtx c = operands[2];
3384   int r = REGNO (operands[0]);
3386   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3387       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3388     FAIL;
3391 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3392 (define_split
3393   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3394         (match_operand:X87MODEF 1 "immediate_operand"))]
3395   "reload_completed
3396    && (standard_80387_constant_p (operands[1]) == 8
3397        || standard_80387_constant_p (operands[1]) == 9)"
3398   [(set (match_dup 0)(match_dup 1))
3399    (set (match_dup 0)
3400         (neg:X87MODEF (match_dup 0)))]
3402   REAL_VALUE_TYPE r;
3404   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3405   if (real_isnegzero (&r))
3406     operands[1] = CONST0_RTX (<MODE>mode);
3407   else
3408     operands[1] = CONST1_RTX (<MODE>mode);
3411 (define_split
3412   [(set (match_operand 0 "nonimmediate_operand")
3413         (match_operand 1 "general_operand"))]
3414   "reload_completed
3415    && (GET_MODE (operands[0]) == TFmode
3416        || GET_MODE (operands[0]) == XFmode
3417        || GET_MODE (operands[0]) == DFmode)
3418    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3419   [(const_int 0)]
3420   "ix86_split_long_move (operands); DONE;")
3422 (define_insn "swapxf"
3423   [(set (match_operand:XF 0 "register_operand" "+f")
3424         (match_operand:XF 1 "register_operand" "+f"))
3425    (set (match_dup 1)
3426         (match_dup 0))]
3427   "TARGET_80387"
3429   if (STACK_TOP_P (operands[0]))
3430     return "fxch\t%1";
3431   else
3432     return "fxch\t%0";
3434   [(set_attr "type" "fxch")
3435    (set_attr "mode" "XF")])
3437 (define_insn "*swap<mode>"
3438   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3439         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3440    (set (match_dup 1)
3441         (match_dup 0))]
3442   "TARGET_80387 || reload_completed"
3444   if (STACK_TOP_P (operands[0]))
3445     return "fxch\t%1";
3446   else
3447     return "fxch\t%0";
3449   [(set_attr "type" "fxch")
3450    (set_attr "mode" "<MODE>")])
3452 ;; Zero extension instructions
3454 (define_expand "zero_extendsidi2"
3455   [(set (match_operand:DI 0 "nonimmediate_operand")
3456         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3458 (define_insn "*zero_extendsidi2_rex64"
3459   [(set (match_operand:DI 0 "nonimmediate_operand"
3460                         "=r  ,o,?*Ym,?!*y,?*Yi,?*x")
3461         (zero_extend:DI
3462          (match_operand:SI 1 "x86_64_zext_general_operand"
3463                         "rmWz,0,r   ,m   ,r   ,m")))]
3464   "TARGET_64BIT"
3466   switch (get_attr_type (insn))
3467     {
3468     case TYPE_IMOVX:
3469       if (ix86_use_lea_for_mov (insn, operands))
3470         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3471       else
3472         return "mov{l}\t{%1, %k0|%k0, %1}";
3474     case TYPE_MULTI:
3475       return "#";
3477     case TYPE_MMXMOV:
3478       return "movd\t{%1, %0|%0, %1}";
3480     case TYPE_SSEMOV:
3481       return "%vmovd\t{%1, %0|%0, %1}";
3483     default:
3484       gcc_unreachable ();
3485     }
3487   [(set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3488    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3489    (set_attr "prefix_0f" "0,*,*,*,*,*")
3490    (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3492 (define_insn "*zero_extendsidi2"
3493   [(set (match_operand:DI 0 "nonimmediate_operand"
3494                         "=ro,?r,?o,?*Ym,?!*y,?*Yi,?*x")
3495         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3496                         "0  ,rm,r ,r   ,m   ,r   ,m")))]
3497   "!TARGET_64BIT"
3498   "@
3499    #
3500    #
3501    #
3502    movd\t{%1, %0|%0, %1}
3503    movd\t{%1, %0|%0, %1}
3504    %vmovd\t{%1, %0|%0, %1}
3505    %vmovd\t{%1, %0|%0, %1}"
3506   [(set_attr "isa" "*,*,*,*,*,*,sse2")
3507    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3508    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3509    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3511 (define_split
3512   [(set (match_operand:DI 0 "memory_operand")
3513         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3514   "reload_completed"
3515   [(set (match_dup 4) (const_int 0))]
3516   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3518 (define_split
3519   [(set (match_operand:DI 0 "register_operand")
3520         (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3521   "!TARGET_64BIT && reload_completed
3522    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3523    && true_regnum (operands[0]) == true_regnum (operands[1])"
3524   [(set (match_dup 4) (const_int 0))]
3525   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3527 (define_split
3528   [(set (match_operand:DI 0 "nonimmediate_operand")
3529         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3530   "!TARGET_64BIT && reload_completed
3531    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3532    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3533   [(set (match_dup 3) (match_dup 1))
3534    (set (match_dup 4) (const_int 0))]
3535   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3537 (define_insn "zero_extend<mode>di2"
3538   [(set (match_operand:DI 0 "register_operand" "=r")
3539         (zero_extend:DI
3540          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3541   "TARGET_64BIT"
3542   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3543   [(set_attr "type" "imovx")
3544    (set_attr "mode" "SI")])
3546 (define_expand "zero_extend<mode>si2"
3547   [(set (match_operand:SI 0 "register_operand")
3548         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3549   ""
3551   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3552     {
3553       operands[1] = force_reg (<MODE>mode, operands[1]);
3554       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3555       DONE;
3556     }
3559 (define_insn_and_split "zero_extend<mode>si2_and"
3560   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3561         (zero_extend:SI
3562           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3563    (clobber (reg:CC FLAGS_REG))]
3564   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3565   "#"
3566   "&& reload_completed"
3567   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3568               (clobber (reg:CC FLAGS_REG))])]
3570   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3571     {
3572       ix86_expand_clear (operands[0]);
3574       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3575       emit_insn (gen_movstrict<mode>
3576                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3577       DONE;
3578     }
3580   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3582   [(set_attr "type" "alu1")
3583    (set_attr "mode" "SI")])
3585 (define_insn "*zero_extend<mode>si2"
3586   [(set (match_operand:SI 0 "register_operand" "=r")
3587         (zero_extend:SI
3588           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3589   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3590   "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3591   [(set_attr "type" "imovx")
3592    (set_attr "mode" "SI")])
3594 (define_expand "zero_extendqihi2"
3595   [(set (match_operand:HI 0 "register_operand")
3596         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3597   ""
3599   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3600     {
3601       operands[1] = force_reg (QImode, operands[1]);
3602       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3603       DONE;
3604     }
3607 (define_insn_and_split "zero_extendqihi2_and"
3608   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3609         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3610    (clobber (reg:CC FLAGS_REG))]
3611   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3612   "#"
3613   "&& reload_completed"
3614   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3615               (clobber (reg:CC FLAGS_REG))])]
3617   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3618     {
3619       ix86_expand_clear (operands[0]);
3621       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3622       emit_insn (gen_movstrictqi
3623                   (gen_lowpart (QImode, operands[0]), operands[1]));
3624       DONE;
3625     }
3627   operands[0] = gen_lowpart (SImode, operands[0]);
3629   [(set_attr "type" "alu1")
3630    (set_attr "mode" "SI")])
3632 ; zero extend to SImode to avoid partial register stalls
3633 (define_insn "*zero_extendqihi2"
3634   [(set (match_operand:HI 0 "register_operand" "=r")
3635         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3636   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3637   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3638   [(set_attr "type" "imovx")
3639    (set_attr "mode" "SI")])
3641 ;; Sign extension instructions
3643 (define_expand "extendsidi2"
3644   [(set (match_operand:DI 0 "register_operand")
3645         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3646   ""
3648   if (!TARGET_64BIT)
3649     {
3650       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3651       DONE;
3652     }
3655 (define_insn "*extendsidi2_rex64"
3656   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3657         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3658   "TARGET_64BIT"
3659   "@
3660    {cltq|cdqe}
3661    movs{lq|x}\t{%1, %0|%0, %1}"
3662   [(set_attr "type" "imovx")
3663    (set_attr "mode" "DI")
3664    (set_attr "prefix_0f" "0")
3665    (set_attr "modrm" "0,1")])
3667 (define_insn "extendsidi2_1"
3668   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3669         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3670    (clobber (reg:CC FLAGS_REG))
3671    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3672   "!TARGET_64BIT"
3673   "#")
3675 ;; Split the memory case.  If the source register doesn't die, it will stay
3676 ;; this way, if it does die, following peephole2s take care of it.
3677 (define_split
3678   [(set (match_operand:DI 0 "memory_operand")
3679         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3680    (clobber (reg:CC FLAGS_REG))
3681    (clobber (match_operand:SI 2 "register_operand"))]
3682   "reload_completed"
3683   [(const_int 0)]
3685   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3687   emit_move_insn (operands[3], operands[1]);
3689   /* Generate a cltd if possible and doing so it profitable.  */
3690   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3691       && true_regnum (operands[1]) == AX_REG
3692       && true_regnum (operands[2]) == DX_REG)
3693     {
3694       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3695     }
3696   else
3697     {
3698       emit_move_insn (operands[2], operands[1]);
3699       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3700     }
3701   emit_move_insn (operands[4], operands[2]);
3702   DONE;
3705 ;; Peepholes for the case where the source register does die, after
3706 ;; being split with the above splitter.
3707 (define_peephole2
3708   [(set (match_operand:SI 0 "memory_operand")
3709         (match_operand:SI 1 "register_operand"))
3710    (set (match_operand:SI 2 "register_operand") (match_dup 1))
3711    (parallel [(set (match_dup 2)
3712                    (ashiftrt:SI (match_dup 2) (const_int 31)))
3713                (clobber (reg:CC FLAGS_REG))])
3714    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3715   "REGNO (operands[1]) != REGNO (operands[2])
3716    && peep2_reg_dead_p (2, operands[1])
3717    && peep2_reg_dead_p (4, operands[2])
3718    && !reg_mentioned_p (operands[2], operands[3])"
3719   [(set (match_dup 0) (match_dup 1))
3720    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3721               (clobber (reg:CC FLAGS_REG))])
3722    (set (match_dup 3) (match_dup 1))])
3724 (define_peephole2
3725   [(set (match_operand:SI 0 "memory_operand")
3726         (match_operand:SI 1 "register_operand"))
3727    (parallel [(set (match_operand:SI 2 "register_operand")
3728                    (ashiftrt:SI (match_dup 1) (const_int 31)))
3729                (clobber (reg:CC FLAGS_REG))])
3730    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3731   "/* cltd is shorter than sarl $31, %eax */
3732    !optimize_function_for_size_p (cfun)
3733    && true_regnum (operands[1]) == AX_REG
3734    && true_regnum (operands[2]) == DX_REG
3735    && peep2_reg_dead_p (2, operands[1])
3736    && peep2_reg_dead_p (3, operands[2])
3737    && !reg_mentioned_p (operands[2], operands[3])"
3738   [(set (match_dup 0) (match_dup 1))
3739    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3740               (clobber (reg:CC FLAGS_REG))])
3741    (set (match_dup 3) (match_dup 1))])
3743 ;; Extend to register case.  Optimize case where source and destination
3744 ;; registers match and cases where we can use cltd.
3745 (define_split
3746   [(set (match_operand:DI 0 "register_operand")
3747         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3748    (clobber (reg:CC FLAGS_REG))
3749    (clobber (match_scratch:SI 2))]
3750   "reload_completed"
3751   [(const_int 0)]
3753   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3755   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3756     emit_move_insn (operands[3], operands[1]);
3758   /* Generate a cltd if possible and doing so it profitable.  */
3759   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3760       && true_regnum (operands[3]) == AX_REG
3761       && true_regnum (operands[4]) == DX_REG)
3762     {
3763       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3764       DONE;
3765     }
3767   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3768     emit_move_insn (operands[4], operands[1]);
3770   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3771   DONE;
3774 (define_insn "extend<mode>di2"
3775   [(set (match_operand:DI 0 "register_operand" "=r")
3776         (sign_extend:DI
3777          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3778   "TARGET_64BIT"
3779   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3780   [(set_attr "type" "imovx")
3781    (set_attr "mode" "DI")])
3783 (define_insn "extendhisi2"
3784   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3785         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3786   ""
3788   switch (get_attr_prefix_0f (insn))
3789     {
3790     case 0:
3791       return "{cwtl|cwde}";
3792     default:
3793       return "movs{wl|x}\t{%1, %0|%0, %1}";
3794     }
3796   [(set_attr "type" "imovx")
3797    (set_attr "mode" "SI")
3798    (set (attr "prefix_0f")
3799      ;; movsx is short decodable while cwtl is vector decoded.
3800      (if_then_else (and (eq_attr "cpu" "!k6")
3801                         (eq_attr "alternative" "0"))
3802         (const_string "0")
3803         (const_string "1")))
3804    (set (attr "modrm")
3805      (if_then_else (eq_attr "prefix_0f" "0")
3806         (const_string "0")
3807         (const_string "1")))])
3809 (define_insn "*extendhisi2_zext"
3810   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3811         (zero_extend:DI
3812          (sign_extend:SI
3813           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3814   "TARGET_64BIT"
3816   switch (get_attr_prefix_0f (insn))
3817     {
3818     case 0:
3819       return "{cwtl|cwde}";
3820     default:
3821       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3822     }
3824   [(set_attr "type" "imovx")
3825    (set_attr "mode" "SI")
3826    (set (attr "prefix_0f")
3827      ;; movsx is short decodable while cwtl is vector decoded.
3828      (if_then_else (and (eq_attr "cpu" "!k6")
3829                         (eq_attr "alternative" "0"))
3830         (const_string "0")
3831         (const_string "1")))
3832    (set (attr "modrm")
3833      (if_then_else (eq_attr "prefix_0f" "0")
3834         (const_string "0")
3835         (const_string "1")))])
3837 (define_insn "extendqisi2"
3838   [(set (match_operand:SI 0 "register_operand" "=r")
3839         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3840   ""
3841   "movs{bl|x}\t{%1, %0|%0, %1}"
3842    [(set_attr "type" "imovx")
3843     (set_attr "mode" "SI")])
3845 (define_insn "*extendqisi2_zext"
3846   [(set (match_operand:DI 0 "register_operand" "=r")
3847         (zero_extend:DI
3848           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3849   "TARGET_64BIT"
3850   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3851    [(set_attr "type" "imovx")
3852     (set_attr "mode" "SI")])
3854 (define_insn "extendqihi2"
3855   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3856         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3857   ""
3859   switch (get_attr_prefix_0f (insn))
3860     {
3861     case 0:
3862       return "{cbtw|cbw}";
3863     default:
3864       return "movs{bw|x}\t{%1, %0|%0, %1}";
3865     }
3867   [(set_attr "type" "imovx")
3868    (set_attr "mode" "HI")
3869    (set (attr "prefix_0f")
3870      ;; movsx is short decodable while cwtl is vector decoded.
3871      (if_then_else (and (eq_attr "cpu" "!k6")
3872                         (eq_attr "alternative" "0"))
3873         (const_string "0")
3874         (const_string "1")))
3875    (set (attr "modrm")
3876      (if_then_else (eq_attr "prefix_0f" "0")
3877         (const_string "0")
3878         (const_string "1")))])
3880 ;; Conversions between float and double.
3882 ;; These are all no-ops in the model used for the 80387.
3883 ;; So just emit moves.
3885 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3886 (define_split
3887   [(set (match_operand:DF 0 "push_operand")
3888         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3889   "reload_completed"
3890   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3891    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3893 (define_split
3894   [(set (match_operand:XF 0 "push_operand")
3895         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3896   "reload_completed"
3897   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3898    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3899   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3901 (define_expand "extendsfdf2"
3902   [(set (match_operand:DF 0 "nonimmediate_operand")
3903         (float_extend:DF (match_operand:SF 1 "general_operand")))]
3904   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3906   /* ??? Needed for compress_float_constant since all fp constants
3907      are TARGET_LEGITIMATE_CONSTANT_P.  */
3908   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3909     {
3910       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3911           && standard_80387_constant_p (operands[1]) > 0)
3912         {
3913           operands[1] = simplify_const_unary_operation
3914             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3915           emit_move_insn_1 (operands[0], operands[1]);
3916           DONE;
3917         }
3918       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3919     }
3922 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3923    cvtss2sd:
3924       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3925       cvtps2pd xmm2,xmm1
3926    We do the conversion post reload to avoid producing of 128bit spills
3927    that might lead to ICE on 32bit target.  The sequence unlikely combine
3928    anyway.  */
3929 (define_split
3930   [(set (match_operand:DF 0 "register_operand")
3931         (float_extend:DF
3932           (match_operand:SF 1 "nonimmediate_operand")))]
3933   "TARGET_USE_VECTOR_FP_CONVERTS
3934    && optimize_insn_for_speed_p ()
3935    && reload_completed && SSE_REG_P (operands[0])"
3936    [(set (match_dup 2)
3937          (float_extend:V2DF
3938            (vec_select:V2SF
3939              (match_dup 3)
3940              (parallel [(const_int 0) (const_int 1)]))))]
3942   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3943   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3944   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3945      Try to avoid move when unpacking can be done in source.  */
3946   if (REG_P (operands[1]))
3947     {
3948       /* If it is unsafe to overwrite upper half of source, we need
3949          to move to destination and unpack there.  */
3950       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3951            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3952           && true_regnum (operands[0]) != true_regnum (operands[1]))
3953         {
3954           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3955           emit_move_insn (tmp, operands[1]);
3956         }
3957       else
3958         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3959       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3960                                              operands[3]));
3961     }
3962   else
3963     emit_insn (gen_vec_setv4sf_0 (operands[3],
3964                                   CONST0_RTX (V4SFmode), operands[1]));
3967 (define_insn "*extendsfdf2_mixed"
3968   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3969         (float_extend:DF
3970           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3971   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3973   switch (which_alternative)
3974     {
3975     case 0:
3976     case 1:
3977       return output_387_reg_move (insn, operands);
3979     case 2:
3980       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3982     default:
3983       gcc_unreachable ();
3984     }
3986   [(set_attr "type" "fmov,fmov,ssecvt")
3987    (set_attr "prefix" "orig,orig,maybe_vex")
3988    (set_attr "mode" "SF,XF,DF")])
3990 (define_insn "*extendsfdf2_sse"
3991   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3992         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3993   "TARGET_SSE2 && TARGET_SSE_MATH"
3994   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3995   [(set_attr "type" "ssecvt")
3996    (set_attr "prefix" "maybe_vex")
3997    (set_attr "mode" "DF")])
3999 (define_insn "*extendsfdf2_i387"
4000   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4001         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4002   "TARGET_80387"
4003   "* return output_387_reg_move (insn, operands);"
4004   [(set_attr "type" "fmov")
4005    (set_attr "mode" "SF,XF")])
4007 (define_expand "extend<mode>xf2"
4008   [(set (match_operand:XF 0 "nonimmediate_operand")
4009         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4010   "TARGET_80387"
4012   /* ??? Needed for compress_float_constant since all fp constants
4013      are TARGET_LEGITIMATE_CONSTANT_P.  */
4014   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4015     {
4016       if (standard_80387_constant_p (operands[1]) > 0)
4017         {
4018           operands[1] = simplify_const_unary_operation
4019             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4020           emit_move_insn_1 (operands[0], operands[1]);
4021           DONE;
4022         }
4023       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4024     }
4027 (define_insn "*extend<mode>xf2_i387"
4028   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4029         (float_extend:XF
4030           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4031   "TARGET_80387"
4032   "* return output_387_reg_move (insn, operands);"
4033   [(set_attr "type" "fmov")
4034    (set_attr "mode" "<MODE>,XF")])
4036 ;; %%% This seems bad bad news.
4037 ;; This cannot output into an f-reg because there is no way to be sure
4038 ;; of truncating in that case.  Otherwise this is just like a simple move
4039 ;; insn.  So we pretend we can output to a reg in order to get better
4040 ;; register preferencing, but we really use a stack slot.
4042 ;; Conversion from DFmode to SFmode.
4044 (define_expand "truncdfsf2"
4045   [(set (match_operand:SF 0 "nonimmediate_operand")
4046         (float_truncate:SF
4047           (match_operand:DF 1 "nonimmediate_operand")))]
4048   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4050   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4051     ;
4052   else if (flag_unsafe_math_optimizations)
4053     ;
4054   else
4055     {
4056       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4057       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4058       DONE;
4059     }
4062 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4063    cvtsd2ss:
4064       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4065       cvtpd2ps xmm2,xmm1
4066    We do the conversion post reload to avoid producing of 128bit spills
4067    that might lead to ICE on 32bit target.  The sequence unlikely combine
4068    anyway.  */
4069 (define_split
4070   [(set (match_operand:SF 0 "register_operand")
4071         (float_truncate:SF
4072           (match_operand:DF 1 "nonimmediate_operand")))]
4073   "TARGET_USE_VECTOR_FP_CONVERTS
4074    && optimize_insn_for_speed_p ()
4075    && reload_completed && SSE_REG_P (operands[0])"
4076    [(set (match_dup 2)
4077          (vec_concat:V4SF
4078            (float_truncate:V2SF
4079              (match_dup 4))
4080            (match_dup 3)))]
4082   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4083   operands[3] = CONST0_RTX (V2SFmode);
4084   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4085   /* Use movsd for loading from memory, unpcklpd for registers.
4086      Try to avoid move when unpacking can be done in source, or SSE3
4087      movddup is available.  */
4088   if (REG_P (operands[1]))
4089     {
4090       if (!TARGET_SSE3
4091           && true_regnum (operands[0]) != true_regnum (operands[1])
4092           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4093               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4094         {
4095           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4096           emit_move_insn (tmp, operands[1]);
4097           operands[1] = tmp;
4098         }
4099       else if (!TARGET_SSE3)
4100         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4101       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4102     }
4103   else
4104     emit_insn (gen_sse2_loadlpd (operands[4],
4105                                  CONST0_RTX (V2DFmode), operands[1]));
4108 (define_expand "truncdfsf2_with_temp"
4109   [(parallel [(set (match_operand:SF 0)
4110                    (float_truncate:SF (match_operand:DF 1)))
4111               (clobber (match_operand:SF 2))])])
4113 (define_insn "*truncdfsf_fast_mixed"
4114   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4115         (float_truncate:SF
4116           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4117   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4119   switch (which_alternative)
4120     {
4121     case 0:
4122       return output_387_reg_move (insn, operands);
4123     case 1:
4124       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4125     default:
4126       gcc_unreachable ();
4127     }
4129   [(set_attr "type" "fmov,ssecvt")
4130    (set_attr "prefix" "orig,maybe_vex")
4131    (set_attr "mode" "SF")])
4133 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4134 ;; because nothing we do here is unsafe.
4135 (define_insn "*truncdfsf_fast_sse"
4136   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4137         (float_truncate:SF
4138           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4139   "TARGET_SSE2 && TARGET_SSE_MATH"
4140   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4141   [(set_attr "type" "ssecvt")
4142    (set_attr "prefix" "maybe_vex")
4143    (set_attr "mode" "SF")])
4145 (define_insn "*truncdfsf_fast_i387"
4146   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4147         (float_truncate:SF
4148           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4149   "TARGET_80387 && flag_unsafe_math_optimizations"
4150   "* return output_387_reg_move (insn, operands);"
4151   [(set_attr "type" "fmov")
4152    (set_attr "mode" "SF")])
4154 (define_insn "*truncdfsf_mixed"
4155   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4156         (float_truncate:SF
4157           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4158    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4159   "TARGET_MIX_SSE_I387"
4161   switch (which_alternative)
4162     {
4163     case 0:
4164       return output_387_reg_move (insn, operands);
4165     case 1:
4166       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4168     default:
4169       return "#";
4170     }
4172   [(set_attr "isa" "*,sse2,*,*,*")
4173    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4174    (set_attr "unit" "*,*,i387,i387,i387")
4175    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4176    (set_attr "mode" "SF")])
4178 (define_insn "*truncdfsf_i387"
4179   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4180         (float_truncate:SF
4181           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4182    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4183   "TARGET_80387"
4185   switch (which_alternative)
4186     {
4187     case 0:
4188       return output_387_reg_move (insn, operands);
4190     default:
4191       return "#";
4192     }
4194   [(set_attr "type" "fmov,multi,multi,multi")
4195    (set_attr "unit" "*,i387,i387,i387")
4196    (set_attr "mode" "SF")])
4198 (define_insn "*truncdfsf2_i387_1"
4199   [(set (match_operand:SF 0 "memory_operand" "=m")
4200         (float_truncate:SF
4201           (match_operand:DF 1 "register_operand" "f")))]
4202   "TARGET_80387
4203    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4204    && !TARGET_MIX_SSE_I387"
4205   "* return output_387_reg_move (insn, operands);"
4206   [(set_attr "type" "fmov")
4207    (set_attr "mode" "SF")])
4209 (define_split
4210   [(set (match_operand:SF 0 "register_operand")
4211         (float_truncate:SF
4212          (match_operand:DF 1 "fp_register_operand")))
4213    (clobber (match_operand 2))]
4214   "reload_completed"
4215   [(set (match_dup 2) (match_dup 1))
4216    (set (match_dup 0) (match_dup 2))]
4217   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4219 ;; Conversion from XFmode to {SF,DF}mode
4221 (define_expand "truncxf<mode>2"
4222   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4223                    (float_truncate:MODEF
4224                      (match_operand:XF 1 "register_operand")))
4225               (clobber (match_dup 2))])]
4226   "TARGET_80387"
4228   if (flag_unsafe_math_optimizations)
4229     {
4230       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4231       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4232       if (reg != operands[0])
4233         emit_move_insn (operands[0], reg);
4234       DONE;
4235     }
4236   else
4237     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4240 (define_insn "*truncxfsf2_mixed"
4241   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4242         (float_truncate:SF
4243           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4244    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4245   "TARGET_80387"
4247   gcc_assert (!which_alternative);
4248   return output_387_reg_move (insn, operands);
4250   [(set_attr "type" "fmov,multi,multi,multi")
4251    (set_attr "unit" "*,i387,i387,i387")
4252    (set_attr "mode" "SF")])
4254 (define_insn "*truncxfdf2_mixed"
4255   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4256         (float_truncate:DF
4257           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4258    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4259   "TARGET_80387"
4261   gcc_assert (!which_alternative);
4262   return output_387_reg_move (insn, operands);
4264   [(set_attr "isa" "*,*,sse2,*")
4265    (set_attr "type" "fmov,multi,multi,multi")
4266    (set_attr "unit" "*,i387,i387,i387")
4267    (set_attr "mode" "DF")])
4269 (define_insn "truncxf<mode>2_i387_noop"
4270   [(set (match_operand:MODEF 0 "register_operand" "=f")
4271         (float_truncate:MODEF
4272           (match_operand:XF 1 "register_operand" "f")))]
4273   "TARGET_80387 && flag_unsafe_math_optimizations"
4274   "* return output_387_reg_move (insn, operands);"
4275   [(set_attr "type" "fmov")
4276    (set_attr "mode" "<MODE>")])
4278 (define_insn "*truncxf<mode>2_i387"
4279   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4280         (float_truncate:MODEF
4281           (match_operand:XF 1 "register_operand" "f")))]
4282   "TARGET_80387"
4283   "* return output_387_reg_move (insn, operands);"
4284   [(set_attr "type" "fmov")
4285    (set_attr "mode" "<MODE>")])
4287 (define_split
4288   [(set (match_operand:MODEF 0 "register_operand")
4289         (float_truncate:MODEF
4290           (match_operand:XF 1 "register_operand")))
4291    (clobber (match_operand:MODEF 2 "memory_operand"))]
4292   "TARGET_80387 && reload_completed"
4293   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4294    (set (match_dup 0) (match_dup 2))])
4296 (define_split
4297   [(set (match_operand:MODEF 0 "memory_operand")
4298         (float_truncate:MODEF
4299           (match_operand:XF 1 "register_operand")))
4300    (clobber (match_operand:MODEF 2 "memory_operand"))]
4301   "TARGET_80387"
4302   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4304 ;; Signed conversion to DImode.
4306 (define_expand "fix_truncxfdi2"
4307   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4308                    (fix:DI (match_operand:XF 1 "register_operand")))
4309               (clobber (reg:CC FLAGS_REG))])]
4310   "TARGET_80387"
4312   if (TARGET_FISTTP)
4313    {
4314      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4315      DONE;
4316    }
4319 (define_expand "fix_trunc<mode>di2"
4320   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4321                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4322               (clobber (reg:CC FLAGS_REG))])]
4323   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4325   if (TARGET_FISTTP
4326       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4327    {
4328      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4329      DONE;
4330    }
4331   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4332    {
4333      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4334      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4335      if (out != operands[0])
4336         emit_move_insn (operands[0], out);
4337      DONE;
4338    }
4341 ;; Signed conversion to SImode.
4343 (define_expand "fix_truncxfsi2"
4344   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4345                    (fix:SI (match_operand:XF 1 "register_operand")))
4346               (clobber (reg:CC FLAGS_REG))])]
4347   "TARGET_80387"
4349   if (TARGET_FISTTP)
4350    {
4351      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4352      DONE;
4353    }
4356 (define_expand "fix_trunc<mode>si2"
4357   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4358                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4359               (clobber (reg:CC FLAGS_REG))])]
4360   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4362   if (TARGET_FISTTP
4363       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4364    {
4365      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4366      DONE;
4367    }
4368   if (SSE_FLOAT_MODE_P (<MODE>mode))
4369    {
4370      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4371      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4372      if (out != operands[0])
4373         emit_move_insn (operands[0], out);
4374      DONE;
4375    }
4378 ;; Signed conversion to HImode.
4380 (define_expand "fix_trunc<mode>hi2"
4381   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4382                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4383               (clobber (reg:CC FLAGS_REG))])]
4384   "TARGET_80387
4385    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4387   if (TARGET_FISTTP)
4388    {
4389      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4390      DONE;
4391    }
4394 ;; Unsigned conversion to SImode.
4396 (define_expand "fixuns_trunc<mode>si2"
4397   [(parallel
4398     [(set (match_operand:SI 0 "register_operand")
4399           (unsigned_fix:SI
4400             (match_operand:MODEF 1 "nonimmediate_operand")))
4401      (use (match_dup 2))
4402      (clobber (match_scratch:<ssevecmode> 3))
4403      (clobber (match_scratch:<ssevecmode> 4))])]
4404   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4406   enum machine_mode mode = <MODE>mode;
4407   enum machine_mode vecmode = <ssevecmode>mode;
4408   REAL_VALUE_TYPE TWO31r;
4409   rtx two31;
4411   if (optimize_insn_for_size_p ())
4412     FAIL;
4414   real_ldexp (&TWO31r, &dconst1, 31);
4415   two31 = const_double_from_real_value (TWO31r, mode);
4416   two31 = ix86_build_const_vector (vecmode, true, two31);
4417   operands[2] = force_reg (vecmode, two31);
4420 (define_insn_and_split "*fixuns_trunc<mode>_1"
4421   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4422         (unsigned_fix:SI
4423           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4424    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4425    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4426    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4427   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4428    && optimize_function_for_speed_p (cfun)"
4429   "#"
4430   "&& reload_completed"
4431   [(const_int 0)]
4433   ix86_split_convert_uns_si_sse (operands);
4434   DONE;
4437 ;; Unsigned conversion to HImode.
4438 ;; Without these patterns, we'll try the unsigned SI conversion which
4439 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4441 (define_expand "fixuns_trunc<mode>hi2"
4442   [(set (match_dup 2)
4443         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4444    (set (match_operand:HI 0 "nonimmediate_operand")
4445         (subreg:HI (match_dup 2) 0))]
4446   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4447   "operands[2] = gen_reg_rtx (SImode);")
4449 ;; When SSE is available, it is always faster to use it!
4450 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4451   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4452         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4453   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4454    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4455   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4456   [(set_attr "type" "sseicvt")
4457    (set_attr "prefix" "maybe_vex")
4458    (set (attr "prefix_rex")
4459         (if_then_else
4460           (match_test "<SWI48:MODE>mode == DImode")
4461           (const_string "1")
4462           (const_string "*")))
4463    (set_attr "mode" "<MODEF:MODE>")
4464    (set_attr "athlon_decode" "double,vector")
4465    (set_attr "amdfam10_decode" "double,double")
4466    (set_attr "bdver1_decode" "double,double")])
4468 ;; Avoid vector decoded forms of the instruction.
4469 (define_peephole2
4470   [(match_scratch:MODEF 2 "x")
4471    (set (match_operand:SWI48 0 "register_operand")
4472         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4473   "TARGET_AVOID_VECTOR_DECODE
4474    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4475    && optimize_insn_for_speed_p ()"
4476   [(set (match_dup 2) (match_dup 1))
4477    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4479 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4480   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4481         (fix:SWI248x (match_operand 1 "register_operand")))]
4482   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4483    && TARGET_FISTTP
4484    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4485          && (TARGET_64BIT || <MODE>mode != DImode))
4486         && TARGET_SSE_MATH)
4487    && can_create_pseudo_p ()"
4488   "#"
4489   "&& 1"
4490   [(const_int 0)]
4492   if (memory_operand (operands[0], VOIDmode))
4493     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4494   else
4495     {
4496       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4497       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4498                                                             operands[1],
4499                                                             operands[2]));
4500     }
4501   DONE;
4503   [(set_attr "type" "fisttp")
4504    (set_attr "mode" "<MODE>")])
4506 (define_insn "fix_trunc<mode>_i387_fisttp"
4507   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4508         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4509    (clobber (match_scratch:XF 2 "=&1f"))]
4510   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4511    && TARGET_FISTTP
4512    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4513          && (TARGET_64BIT || <MODE>mode != DImode))
4514         && TARGET_SSE_MATH)"
4515   "* return output_fix_trunc (insn, operands, true);"
4516   [(set_attr "type" "fisttp")
4517    (set_attr "mode" "<MODE>")])
4519 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4520   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4521         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4522    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4523    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4524   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4525    && TARGET_FISTTP
4526    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4527         && (TARGET_64BIT || <MODE>mode != DImode))
4528         && TARGET_SSE_MATH)"
4529   "#"
4530   [(set_attr "type" "fisttp")
4531    (set_attr "mode" "<MODE>")])
4533 (define_split
4534   [(set (match_operand:SWI248x 0 "register_operand")
4535         (fix:SWI248x (match_operand 1 "register_operand")))
4536    (clobber (match_operand:SWI248x 2 "memory_operand"))
4537    (clobber (match_scratch 3))]
4538   "reload_completed"
4539   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4540               (clobber (match_dup 3))])
4541    (set (match_dup 0) (match_dup 2))])
4543 (define_split
4544   [(set (match_operand:SWI248x 0 "memory_operand")
4545         (fix:SWI248x (match_operand 1 "register_operand")))
4546    (clobber (match_operand:SWI248x 2 "memory_operand"))
4547    (clobber (match_scratch 3))]
4548   "reload_completed"
4549   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4550               (clobber (match_dup 3))])])
4552 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4553 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4554 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4555 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4556 ;; function in i386.c.
4557 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4558   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4559         (fix:SWI248x (match_operand 1 "register_operand")))
4560    (clobber (reg:CC FLAGS_REG))]
4561   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4562    && !TARGET_FISTTP
4563    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4564          && (TARGET_64BIT || <MODE>mode != DImode))
4565    && can_create_pseudo_p ()"
4566   "#"
4567   "&& 1"
4568   [(const_int 0)]
4570   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4572   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4573   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4574   if (memory_operand (operands[0], VOIDmode))
4575     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4576                                          operands[2], operands[3]));
4577   else
4578     {
4579       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4580       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4581                                                      operands[2], operands[3],
4582                                                      operands[4]));
4583     }
4584   DONE;
4586   [(set_attr "type" "fistp")
4587    (set_attr "i387_cw" "trunc")
4588    (set_attr "mode" "<MODE>")])
4590 (define_insn "fix_truncdi_i387"
4591   [(set (match_operand:DI 0 "memory_operand" "=m")
4592         (fix:DI (match_operand 1 "register_operand" "f")))
4593    (use (match_operand:HI 2 "memory_operand" "m"))
4594    (use (match_operand:HI 3 "memory_operand" "m"))
4595    (clobber (match_scratch:XF 4 "=&1f"))]
4596   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4597    && !TARGET_FISTTP
4598    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4599   "* return output_fix_trunc (insn, operands, false);"
4600   [(set_attr "type" "fistp")
4601    (set_attr "i387_cw" "trunc")
4602    (set_attr "mode" "DI")])
4604 (define_insn "fix_truncdi_i387_with_temp"
4605   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4606         (fix:DI (match_operand 1 "register_operand" "f,f")))
4607    (use (match_operand:HI 2 "memory_operand" "m,m"))
4608    (use (match_operand:HI 3 "memory_operand" "m,m"))
4609    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4610    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4611   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4612    && !TARGET_FISTTP
4613    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4614   "#"
4615   [(set_attr "type" "fistp")
4616    (set_attr "i387_cw" "trunc")
4617    (set_attr "mode" "DI")])
4619 (define_split
4620   [(set (match_operand:DI 0 "register_operand")
4621         (fix:DI (match_operand 1 "register_operand")))
4622    (use (match_operand:HI 2 "memory_operand"))
4623    (use (match_operand:HI 3 "memory_operand"))
4624    (clobber (match_operand:DI 4 "memory_operand"))
4625    (clobber (match_scratch 5))]
4626   "reload_completed"
4627   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4628               (use (match_dup 2))
4629               (use (match_dup 3))
4630               (clobber (match_dup 5))])
4631    (set (match_dup 0) (match_dup 4))])
4633 (define_split
4634   [(set (match_operand:DI 0 "memory_operand")
4635         (fix:DI (match_operand 1 "register_operand")))
4636    (use (match_operand:HI 2 "memory_operand"))
4637    (use (match_operand:HI 3 "memory_operand"))
4638    (clobber (match_operand:DI 4 "memory_operand"))
4639    (clobber (match_scratch 5))]
4640   "reload_completed"
4641   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4642               (use (match_dup 2))
4643               (use (match_dup 3))
4644               (clobber (match_dup 5))])])
4646 (define_insn "fix_trunc<mode>_i387"
4647   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4648         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4649    (use (match_operand:HI 2 "memory_operand" "m"))
4650    (use (match_operand:HI 3 "memory_operand" "m"))]
4651   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4652    && !TARGET_FISTTP
4653    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4654   "* return output_fix_trunc (insn, operands, false);"
4655   [(set_attr "type" "fistp")
4656    (set_attr "i387_cw" "trunc")
4657    (set_attr "mode" "<MODE>")])
4659 (define_insn "fix_trunc<mode>_i387_with_temp"
4660   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4661         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4662    (use (match_operand:HI 2 "memory_operand" "m,m"))
4663    (use (match_operand:HI 3 "memory_operand" "m,m"))
4664    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4665   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4666    && !TARGET_FISTTP
4667    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4668   "#"
4669   [(set_attr "type" "fistp")
4670    (set_attr "i387_cw" "trunc")
4671    (set_attr "mode" "<MODE>")])
4673 (define_split
4674   [(set (match_operand:SWI24 0 "register_operand")
4675         (fix:SWI24 (match_operand 1 "register_operand")))
4676    (use (match_operand:HI 2 "memory_operand"))
4677    (use (match_operand:HI 3 "memory_operand"))
4678    (clobber (match_operand:SWI24 4 "memory_operand"))]
4679   "reload_completed"
4680   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4681               (use (match_dup 2))
4682               (use (match_dup 3))])
4683    (set (match_dup 0) (match_dup 4))])
4685 (define_split
4686   [(set (match_operand:SWI24 0 "memory_operand")
4687         (fix:SWI24 (match_operand 1 "register_operand")))
4688    (use (match_operand:HI 2 "memory_operand"))
4689    (use (match_operand:HI 3 "memory_operand"))
4690    (clobber (match_operand:SWI24 4 "memory_operand"))]
4691   "reload_completed"
4692   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4693               (use (match_dup 2))
4694               (use (match_dup 3))])])
4696 (define_insn "x86_fnstcw_1"
4697   [(set (match_operand:HI 0 "memory_operand" "=m")
4698         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4699   "TARGET_80387"
4700   "fnstcw\t%0"
4701   [(set (attr "length")
4702         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4703    (set_attr "mode" "HI")
4704    (set_attr "unit" "i387")
4705    (set_attr "bdver1_decode" "vector")])
4707 (define_insn "x86_fldcw_1"
4708   [(set (reg:HI FPCR_REG)
4709         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4710   "TARGET_80387"
4711   "fldcw\t%0"
4712   [(set (attr "length")
4713         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4714    (set_attr "mode" "HI")
4715    (set_attr "unit" "i387")
4716    (set_attr "athlon_decode" "vector")
4717    (set_attr "amdfam10_decode" "vector")
4718    (set_attr "bdver1_decode" "vector")])
4720 ;; Conversion between fixed point and floating point.
4722 ;; Even though we only accept memory inputs, the backend _really_
4723 ;; wants to be able to do this between registers.
4725 (define_expand "floathi<mode>2"
4726   [(set (match_operand:X87MODEF 0 "register_operand")
4727         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4728   "TARGET_80387
4729    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4730        || TARGET_MIX_SSE_I387)")
4732 ;; Pre-reload splitter to add memory clobber to the pattern.
4733 (define_insn_and_split "*floathi<mode>2_1"
4734   [(set (match_operand:X87MODEF 0 "register_operand")
4735         (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4736   "TARGET_80387
4737    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4738        || TARGET_MIX_SSE_I387)
4739    && can_create_pseudo_p ()"
4740   "#"
4741   "&& 1"
4742   [(parallel [(set (match_dup 0)
4743               (float:X87MODEF (match_dup 1)))
4744    (clobber (match_dup 2))])]
4745   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4747 (define_insn "*floathi<mode>2_i387_with_temp"
4748   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4749         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4750   (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4751   "TARGET_80387
4752    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4753        || TARGET_MIX_SSE_I387)"
4754   "#"
4755   [(set_attr "type" "fmov,multi")
4756    (set_attr "mode" "<MODE>")
4757    (set_attr "unit" "*,i387")
4758    (set_attr "fp_int_src" "true")])
4760 (define_insn "*floathi<mode>2_i387"
4761   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4762         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4763   "TARGET_80387
4764    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4765        || TARGET_MIX_SSE_I387)"
4766   "fild%Z1\t%1"
4767   [(set_attr "type" "fmov")
4768    (set_attr "mode" "<MODE>")
4769    (set_attr "fp_int_src" "true")])
4771 (define_split
4772   [(set (match_operand:X87MODEF 0 "register_operand")
4773         (float:X87MODEF (match_operand:HI 1 "register_operand")))
4774    (clobber (match_operand:HI 2 "memory_operand"))]
4775   "TARGET_80387
4776    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4777        || TARGET_MIX_SSE_I387)
4778    && reload_completed"
4779   [(set (match_dup 2) (match_dup 1))
4780    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4782 (define_split
4783   [(set (match_operand:X87MODEF 0 "register_operand")
4784         (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4785    (clobber (match_operand:HI 2 "memory_operand"))]
4786    "TARGET_80387
4787     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4788         || TARGET_MIX_SSE_I387)
4789     && reload_completed"
4790   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4792 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4793   [(set (match_operand:X87MODEF 0 "register_operand")
4794         (float:X87MODEF
4795           (match_operand:SWI48x 1 "nonimmediate_operand")))]
4796   "TARGET_80387
4797    || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4798        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4800   if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4801         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4802       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4803     {
4804       rtx reg = gen_reg_rtx (XFmode);
4805       rtx (*insn)(rtx, rtx);
4807       emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4809       if (<X87MODEF:MODE>mode == SFmode)
4810         insn = gen_truncxfsf2;
4811       else if (<X87MODEF:MODE>mode == DFmode)
4812         insn = gen_truncxfdf2;
4813       else
4814         gcc_unreachable ();
4816       emit_insn (insn (operands[0], reg));
4817       DONE;
4818     }
4821 ;; Pre-reload splitter to add memory clobber to the pattern.
4822 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4823   [(set (match_operand:X87MODEF 0 "register_operand")
4824         (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4825   "((TARGET_80387
4826      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4827      && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4828            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4829          || TARGET_MIX_SSE_I387))
4830     || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4831         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4832         && ((<SWI48x:MODE>mode == SImode
4833              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4834              && optimize_function_for_speed_p (cfun)
4835              && flag_trapping_math)
4836             || !(TARGET_INTER_UNIT_CONVERSIONS
4837                  || optimize_function_for_size_p (cfun)))))
4838    && can_create_pseudo_p ()"
4839   "#"
4840   "&& 1"
4841   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4842               (clobber (match_dup 2))])]
4844   operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4846   /* Avoid store forwarding (partial memory) stall penalty
4847      by passing DImode value through XMM registers.  */
4848   if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4849       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4850       && optimize_function_for_speed_p (cfun))
4851     {
4852       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4853                                                             operands[1],
4854                                                             operands[2]));
4855       DONE;
4856     }
4859 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4860   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4861         (float:MODEF
4862           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4863    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4864   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4865    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4866   "#"
4867   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4868    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4869    (set_attr "unit" "*,i387,*,*,*")
4870    (set_attr "athlon_decode" "*,*,double,direct,double")
4871    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4872    (set_attr "bdver1_decode" "*,*,double,direct,double")
4873    (set_attr "fp_int_src" "true")])
4875 (define_insn "*floatsi<mode>2_vector_mixed"
4876   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4877         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4878   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4879    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4880   "@
4881    fild%Z1\t%1
4882    #"
4883   [(set_attr "type" "fmov,sseicvt")
4884    (set_attr "mode" "<MODE>,<ssevecmode>")
4885    (set_attr "unit" "i387,*")
4886    (set_attr "athlon_decode" "*,direct")
4887    (set_attr "amdfam10_decode" "*,double")
4888    (set_attr "bdver1_decode" "*,direct")
4889    (set_attr "fp_int_src" "true")])
4891 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_with_temp"
4892   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4893         (float:MODEF
4894           (match_operand:SWI48 1 "nonimmediate_operand" "m,?r,r,m")))
4895    (clobber (match_operand:SWI48 2 "memory_operand" "=X,m,m,X"))]
4896   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4897   "#"
4898   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4899    (set_attr "mode" "<MODEF:MODE>")
4900    (set_attr "unit" "*,i387,*,*")
4901    (set_attr "athlon_decode" "*,*,double,direct")
4902    (set_attr "amdfam10_decode" "*,*,vector,double")
4903    (set_attr "bdver1_decode" "*,*,double,direct")
4904    (set_attr "fp_int_src" "true")])
4906 (define_split
4907   [(set (match_operand:MODEF 0 "register_operand")
4908         (float:MODEF (match_operand:SWI48 1 "register_operand")))
4909    (clobber (match_operand:SWI48 2 "memory_operand"))]
4910   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4911    && TARGET_INTER_UNIT_CONVERSIONS
4912    && reload_completed
4913    && (SSE_REG_P (operands[0])
4914        || (GET_CODE (operands[0]) == SUBREG
4915            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4916   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4918 (define_split
4919   [(set (match_operand:MODEF 0 "register_operand")
4920         (float:MODEF (match_operand:SWI48 1 "register_operand")))
4921    (clobber (match_operand:SWI48 2 "memory_operand"))]
4922   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4923    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4924    && reload_completed
4925    && (SSE_REG_P (operands[0])
4926        || (GET_CODE (operands[0]) == SUBREG
4927            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4928   [(set (match_dup 2) (match_dup 1))
4929    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4931 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_interunit"
4932   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4933         (float:MODEF
4934           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4935   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4936    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4937   "@
4938    fild%Z1\t%1
4939    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4940    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4941   [(set_attr "type" "fmov,sseicvt,sseicvt")
4942    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4943    (set_attr "mode" "<MODEF:MODE>")
4944    (set (attr "prefix_rex")
4945      (if_then_else
4946        (and (eq_attr "prefix" "maybe_vex")
4947             (match_test "<SWI48:MODE>mode == DImode"))
4948        (const_string "1")
4949        (const_string "*")))
4950    (set_attr "unit" "i387,*,*")
4951    (set_attr "athlon_decode" "*,double,direct")
4952    (set_attr "amdfam10_decode" "*,vector,double")
4953    (set_attr "bdver1_decode" "*,double,direct")
4954    (set_attr "fp_int_src" "true")])
4956 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_nointerunit"
4957   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4958         (float:MODEF
4959           (match_operand:SWI48 1 "memory_operand" "m,m")))]
4960   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4961    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4962   "@
4963    fild%Z1\t%1
4964    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4965   [(set_attr "type" "fmov,sseicvt")
4966    (set_attr "prefix" "orig,maybe_vex")
4967    (set_attr "mode" "<MODEF:MODE>")
4968    (set (attr "prefix_rex")
4969      (if_then_else
4970        (and (eq_attr "prefix" "maybe_vex")
4971             (match_test "<SWI48:MODE>mode == DImode"))
4972        (const_string "1")
4973        (const_string "*")))
4974    (set_attr "athlon_decode" "*,direct")
4975    (set_attr "amdfam10_decode" "*,double")
4976    (set_attr "bdver1_decode" "*,direct")
4977    (set_attr "fp_int_src" "true")])
4979 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4980   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4981         (float:MODEF
4982           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4983    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4984   "TARGET_SSE2 && TARGET_SSE_MATH
4985    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4986   "#"
4987   [(set_attr "type" "sseicvt")
4988    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4989    (set_attr "athlon_decode" "double,direct,double")
4990    (set_attr "amdfam10_decode" "vector,double,double")
4991    (set_attr "bdver1_decode" "double,direct,double")
4992    (set_attr "fp_int_src" "true")])
4994 (define_insn "*floatsi<mode>2_vector_sse"
4995   [(set (match_operand:MODEF 0 "register_operand" "=x")
4996         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4997   "TARGET_SSE2 && TARGET_SSE_MATH
4998    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4999   "#"
5000   [(set_attr "type" "sseicvt")
5001    (set_attr "mode" "<MODE>")
5002    (set_attr "athlon_decode" "direct")
5003    (set_attr "amdfam10_decode" "double")
5004    (set_attr "bdver1_decode" "direct")
5005    (set_attr "fp_int_src" "true")])
5007 (define_split
5008   [(set (match_operand:MODEF 0 "register_operand")
5009         (float:MODEF (match_operand:SI 1 "register_operand")))
5010    (clobber (match_operand:SI 2 "memory_operand"))]
5011   "TARGET_SSE2 && TARGET_SSE_MATH
5012    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5013    && reload_completed
5014    && (SSE_REG_P (operands[0])
5015        || (GET_CODE (operands[0]) == SUBREG
5016            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5017   [(const_int 0)]
5019   rtx op1 = operands[1];
5021   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5022                                      <MODE>mode, 0);
5023   if (GET_CODE (op1) == SUBREG)
5024     op1 = SUBREG_REG (op1);
5026   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5027     {
5028       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5029       emit_insn (gen_sse2_loadld (operands[4],
5030                                   CONST0_RTX (V4SImode), operands[1]));
5031     }
5032   /* We can ignore possible trapping value in the
5033      high part of SSE register for non-trapping math. */
5034   else if (SSE_REG_P (op1) && !flag_trapping_math)
5035     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5036   else
5037     {
5038       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5039       emit_move_insn (operands[2], operands[1]);
5040       emit_insn (gen_sse2_loadld (operands[4],
5041                                   CONST0_RTX (V4SImode), operands[2]));
5042     }
5043   if (<ssevecmode>mode == V4SFmode)
5044     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5045   else
5046     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5047   DONE;
5050 (define_split
5051   [(set (match_operand:MODEF 0 "register_operand")
5052         (float:MODEF (match_operand:SI 1 "memory_operand")))
5053    (clobber (match_operand:SI 2 "memory_operand"))]
5054   "TARGET_SSE2 && TARGET_SSE_MATH
5055    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5056    && reload_completed
5057    && (SSE_REG_P (operands[0])
5058        || (GET_CODE (operands[0]) == SUBREG
5059            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5060   [(const_int 0)]
5062   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5063                                      <MODE>mode, 0);
5064   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5066   emit_insn (gen_sse2_loadld (operands[4],
5067                               CONST0_RTX (V4SImode), operands[1]));
5068   if (<ssevecmode>mode == V4SFmode)
5069     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5070   else
5071     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5072   DONE;
5075 (define_split
5076   [(set (match_operand:MODEF 0 "register_operand")
5077         (float:MODEF (match_operand:SI 1 "register_operand")))]
5078   "TARGET_SSE2 && TARGET_SSE_MATH
5079    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5080    && reload_completed
5081    && (SSE_REG_P (operands[0])
5082        || (GET_CODE (operands[0]) == SUBREG
5083            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5084   [(const_int 0)]
5086   rtx op1 = operands[1];
5088   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5089                                      <MODE>mode, 0);
5090   if (GET_CODE (op1) == SUBREG)
5091     op1 = SUBREG_REG (op1);
5093   if (GENERAL_REG_P (op1))
5094     {
5095       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5096       if (TARGET_INTER_UNIT_MOVES)
5097         emit_insn (gen_sse2_loadld (operands[4],
5098                                     CONST0_RTX (V4SImode), operands[1]));
5099       else
5100         {
5101           operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5102                                               operands[1]);
5103           emit_insn (gen_sse2_loadld (operands[4],
5104                                       CONST0_RTX (V4SImode), operands[5]));
5105           ix86_free_from_memory (GET_MODE (operands[1]));
5106         }
5107     }
5108   /* We can ignore possible trapping value in the
5109      high part of SSE register for non-trapping math. */
5110   else if (SSE_REG_P (op1) && !flag_trapping_math)
5111     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5112   else
5113     gcc_unreachable ();
5114   if (<ssevecmode>mode == V4SFmode)
5115     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5116   else
5117     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5118   DONE;
5121 (define_split
5122   [(set (match_operand:MODEF 0 "register_operand")
5123         (float:MODEF (match_operand:SI 1 "memory_operand")))]
5124   "TARGET_SSE2 && TARGET_SSE_MATH
5125    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5126    && reload_completed
5127    && (SSE_REG_P (operands[0])
5128        || (GET_CODE (operands[0]) == SUBREG
5129            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5130   [(const_int 0)]
5132   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5133                                      <MODE>mode, 0);
5134   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5136   emit_insn (gen_sse2_loadld (operands[4],
5137                               CONST0_RTX (V4SImode), operands[1]));
5138   if (<ssevecmode>mode == V4SFmode)
5139     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5140   else
5141     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5142   DONE;
5145 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_with_temp"
5146   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5147         (float:MODEF
5148           (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))
5149   (clobber (match_operand:SWI48 2 "memory_operand" "=m,X"))]
5150   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5151   "#"
5152   [(set_attr "type" "sseicvt")
5153    (set_attr "mode" "<MODEF:MODE>")
5154    (set_attr "athlon_decode" "double,direct")
5155    (set_attr "amdfam10_decode" "vector,double")
5156    (set_attr "bdver1_decode" "double,direct")
5157    (set_attr "btver2_decode" "double,double")
5158    (set_attr "fp_int_src" "true")])
5160 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_interunit"
5161   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5162         (float:MODEF
5163           (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))]
5164   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5165    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5166   "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5167   [(set_attr "type" "sseicvt")
5168    (set_attr "prefix" "maybe_vex")
5169    (set_attr "mode" "<MODEF:MODE>")
5170    (set (attr "prefix_rex")
5171      (if_then_else
5172        (and (eq_attr "prefix" "maybe_vex")
5173             (match_test "<SWI48:MODE>mode == DImode"))
5174        (const_string "1")
5175        (const_string "*")))
5176    (set_attr "athlon_decode" "double,direct")
5177    (set_attr "amdfam10_decode" "vector,double")
5178    (set_attr "bdver1_decode" "double,direct")
5179    (set_attr "btver2_decode" "double,double")
5180    (set_attr "fp_int_src" "true")])
5182 (define_split
5183   [(set (match_operand:MODEF 0 "register_operand")
5184         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))
5185    (clobber (match_operand:SWI48 2 "memory_operand"))]
5186   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5187    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5188    && reload_completed
5189    && (SSE_REG_P (operands[0])
5190        || (GET_CODE (operands[0]) == SUBREG
5191            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5192   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5194 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_nointerunit"
5195   [(set (match_operand:MODEF 0 "register_operand" "=x")
5196         (float:MODEF
5197           (match_operand:SWI48 1 "memory_operand" "m")))]
5198   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5199    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5200   "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5201   [(set_attr "type" "sseicvt")
5202    (set_attr "prefix" "maybe_vex")
5203    (set_attr "mode" "<MODEF:MODE>")
5204    (set (attr "prefix_rex")
5205      (if_then_else
5206        (and (eq_attr "prefix" "maybe_vex")
5207             (match_test "<SWI48:MODE>mode == DImode"))
5208        (const_string "1")
5209        (const_string "*")))
5210    (set_attr "athlon_decode" "direct")
5211    (set_attr "amdfam10_decode" "double")
5212    (set_attr "bdver1_decode" "direct")
5213    (set_attr "fp_int_src" "true")])
5215 (define_split
5216   [(set (match_operand:MODEF 0 "register_operand")
5217         (float:MODEF (match_operand:SWI48 1 "register_operand")))
5218    (clobber (match_operand:SWI48 2 "memory_operand"))]
5219   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5220    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5221    && reload_completed
5222    && (SSE_REG_P (operands[0])
5223        || (GET_CODE (operands[0]) == SUBREG
5224            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5225   [(set (match_dup 2) (match_dup 1))
5226    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5228 (define_split
5229   [(set (match_operand:MODEF 0 "register_operand")
5230         (float:MODEF (match_operand:SWI48 1 "memory_operand")))
5231    (clobber (match_operand:SWI48 2 "memory_operand"))]
5232   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5233    && reload_completed
5234    && (SSE_REG_P (operands[0])
5235        || (GET_CODE (operands[0]) == SUBREG
5236            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5237   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5239 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5240   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5241         (float:X87MODEF
5242           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5243   (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5244   "TARGET_80387
5245    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5246   "@
5247    fild%Z1\t%1
5248    #"
5249   [(set_attr "type" "fmov,multi")
5250    (set_attr "mode" "<X87MODEF:MODE>")
5251    (set_attr "unit" "*,i387")
5252    (set_attr "fp_int_src" "true")])
5254 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5255   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5256         (float:X87MODEF
5257           (match_operand:SWI48x 1 "memory_operand" "m")))]
5258   "TARGET_80387
5259    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5260   "fild%Z1\t%1"
5261   [(set_attr "type" "fmov")
5262    (set_attr "mode" "<X87MODEF:MODE>")
5263    (set_attr "fp_int_src" "true")])
5265 (define_split
5266   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5267         (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5268    (clobber (match_operand:SWI48x 2 "memory_operand"))]
5269   "TARGET_80387
5270    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5271    && reload_completed"
5272   [(set (match_dup 2) (match_dup 1))
5273    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5275 (define_split
5276   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5277         (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5278    (clobber (match_operand:SWI48x 2 "memory_operand"))]
5279   "TARGET_80387
5280    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5281    && reload_completed"
5282   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5284 ;; Avoid store forwarding (partial memory) stall penalty
5285 ;; by passing DImode value through XMM registers.  */
5287 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5288   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5289         (float:X87MODEF
5290           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5291    (clobber (match_scratch:V4SI 3 "=X,x"))
5292    (clobber (match_scratch:V4SI 4 "=X,x"))
5293    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5294   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5295    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5296    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5297   "#"
5298   [(set_attr "type" "multi")
5299    (set_attr "mode" "<X87MODEF:MODE>")
5300    (set_attr "unit" "i387")
5301    (set_attr "fp_int_src" "true")])
5303 (define_split
5304   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5305         (float:X87MODEF (match_operand:DI 1 "register_operand")))
5306    (clobber (match_scratch:V4SI 3))
5307    (clobber (match_scratch:V4SI 4))
5308    (clobber (match_operand:DI 2 "memory_operand"))]
5309   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5310    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5311    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5312    && reload_completed"
5313   [(set (match_dup 2) (match_dup 3))
5314    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5316   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5317      Assemble the 64-bit DImode value in an xmm register.  */
5318   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5319                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5320   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5321                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5322   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5323                                          operands[4]));
5325   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5328 (define_split
5329   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5330         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5331    (clobber (match_scratch:V4SI 3))
5332    (clobber (match_scratch:V4SI 4))
5333    (clobber (match_operand:DI 2 "memory_operand"))]
5334   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5335    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5336    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5337    && reload_completed"
5338   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5340 ;; Avoid store forwarding (partial memory) stall penalty by extending
5341 ;; SImode value to DImode through XMM register instead of pushing two
5342 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5343 ;; targets benefit from this optimization. Also note that fild
5344 ;; loads from memory only.
5346 (define_insn "*floatunssi<mode>2_1"
5347   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5348         (unsigned_float:X87MODEF
5349           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5350    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5351    (clobber (match_scratch:SI 3 "=X,x"))]
5352   "!TARGET_64BIT
5353    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5354    && TARGET_SSE"
5355   "#"
5356   [(set_attr "type" "multi")
5357    (set_attr "mode" "<MODE>")])
5359 (define_split
5360   [(set (match_operand:X87MODEF 0 "register_operand")
5361         (unsigned_float:X87MODEF
5362           (match_operand:SI 1 "register_operand")))
5363    (clobber (match_operand:DI 2 "memory_operand"))
5364    (clobber (match_scratch:SI 3))]
5365   "!TARGET_64BIT
5366    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5367    && TARGET_SSE
5368    && reload_completed"
5369   [(set (match_dup 2) (match_dup 1))
5370    (set (match_dup 0)
5371         (float:X87MODEF (match_dup 2)))]
5372   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5374 (define_split
5375   [(set (match_operand:X87MODEF 0 "register_operand")
5376         (unsigned_float:X87MODEF
5377           (match_operand:SI 1 "memory_operand")))
5378    (clobber (match_operand:DI 2 "memory_operand"))
5379    (clobber (match_scratch:SI 3))]
5380   "!TARGET_64BIT
5381    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5382    && TARGET_SSE
5383    && reload_completed"
5384   [(set (match_dup 2) (match_dup 3))
5385    (set (match_dup 0)
5386         (float:X87MODEF (match_dup 2)))]
5388   emit_move_insn (operands[3], operands[1]);
5389   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5392 (define_expand "floatunssi<mode>2"
5393   [(parallel
5394      [(set (match_operand:X87MODEF 0 "register_operand")
5395            (unsigned_float:X87MODEF
5396              (match_operand:SI 1 "nonimmediate_operand")))
5397       (clobber (match_dup 2))
5398       (clobber (match_scratch:SI 3))])]
5399   "!TARGET_64BIT
5400    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5401         && TARGET_SSE)
5402        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5404   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5405     {
5406       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5407       DONE;
5408     }
5409   else
5410     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5413 (define_expand "floatunsdisf2"
5414   [(use (match_operand:SF 0 "register_operand"))
5415    (use (match_operand:DI 1 "nonimmediate_operand"))]
5416   "TARGET_64BIT && TARGET_SSE_MATH"
5417   "x86_emit_floatuns (operands); DONE;")
5419 (define_expand "floatunsdidf2"
5420   [(use (match_operand:DF 0 "register_operand"))
5421    (use (match_operand:DI 1 "nonimmediate_operand"))]
5422   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5423    && TARGET_SSE2 && TARGET_SSE_MATH"
5425   if (TARGET_64BIT)
5426     x86_emit_floatuns (operands);
5427   else
5428     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5429   DONE;
5432 ;; Load effective address instructions
5434 (define_insn_and_split "*lea<mode>"
5435   [(set (match_operand:SWI48 0 "register_operand" "=r")
5436         (match_operand:SWI48 1 "lea_address_operand" "p"))]
5437   ""
5439   if (SImode_address_operand (operands[1], VOIDmode))
5440     {
5441       gcc_assert (TARGET_64BIT);
5442       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5443     }
5444   else 
5445     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5447   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5448   [(const_int 0)]
5450   enum machine_mode mode = <MODE>mode;
5451   rtx pat;
5453   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5454      change operands[] array behind our back.  */
5455   pat = PATTERN (curr_insn);
5457   operands[0] = SET_DEST (pat);
5458   operands[1] = SET_SRC (pat);
5460   /* Emit all operations in SImode for zero-extended addresses.  Recall
5461      that x86_64 inheretly zero-extends SImode operations to DImode.  */
5462   if (SImode_address_operand (operands[1], VOIDmode))
5463     mode = SImode;
5465   ix86_split_lea_for_addr (curr_insn, operands, mode);
5467   /* Zero-extend return register to DImode for zero-extended addresses.  */
5468   if (mode != <MODE>mode)
5469     emit_insn (gen_zero_extendsidi2
5470                (operands[0], gen_lowpart (mode, operands[0])));
5472   DONE;
5474   [(set_attr "type" "lea")
5475    (set (attr "mode")
5476      (if_then_else
5477        (match_operand 1 "SImode_address_operand")
5478        (const_string "SI")
5479        (const_string "<MODE>")))])
5481 ;; Add instructions
5483 (define_expand "add<mode>3"
5484   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5485         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5486                     (match_operand:SDWIM 2 "<general_operand>")))]
5487   ""
5488   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5490 (define_insn_and_split "*add<dwi>3_doubleword"
5491   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5492         (plus:<DWI>
5493           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5494           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5495    (clobber (reg:CC FLAGS_REG))]
5496   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5497   "#"
5498   "reload_completed"
5499   [(parallel [(set (reg:CC FLAGS_REG)
5500                    (unspec:CC [(match_dup 1) (match_dup 2)]
5501                               UNSPEC_ADD_CARRY))
5502               (set (match_dup 0)
5503                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5504    (parallel [(set (match_dup 3)
5505                    (plus:DWIH
5506                      (match_dup 4)
5507                      (plus:DWIH
5508                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5509                        (match_dup 5))))
5510               (clobber (reg:CC FLAGS_REG))])]
5511   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5513 (define_insn "*add<mode>3_cc"
5514   [(set (reg:CC FLAGS_REG)
5515         (unspec:CC
5516           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5517            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5518           UNSPEC_ADD_CARRY))
5519    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5520         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5521   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5522   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5523   [(set_attr "type" "alu")
5524    (set_attr "mode" "<MODE>")])
5526 (define_insn "addqi3_cc"
5527   [(set (reg:CC FLAGS_REG)
5528         (unspec:CC
5529           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5530            (match_operand:QI 2 "general_operand" "qn,qm")]
5531           UNSPEC_ADD_CARRY))
5532    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5533         (plus:QI (match_dup 1) (match_dup 2)))]
5534   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5535   "add{b}\t{%2, %0|%0, %2}"
5536   [(set_attr "type" "alu")
5537    (set_attr "mode" "QI")])
5539 (define_insn "*add<mode>_1"
5540   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5541         (plus:SWI48
5542           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5543           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5544    (clobber (reg:CC FLAGS_REG))]
5545   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5547   switch (get_attr_type (insn))
5548     {
5549     case TYPE_LEA:
5550       return "#";
5552     case TYPE_INCDEC:
5553       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5554       if (operands[2] == const1_rtx)
5555         return "inc{<imodesuffix>}\t%0";
5556       else
5557         {
5558           gcc_assert (operands[2] == constm1_rtx);
5559           return "dec{<imodesuffix>}\t%0";
5560         }
5562     default:
5563       /* For most processors, ADD is faster than LEA.  This alternative
5564          was added to use ADD as much as possible.  */
5565       if (which_alternative == 2)
5566         {
5567           rtx tmp;
5568           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5569         }
5570         
5571       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5572       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5573         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5575       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5576     }
5578   [(set (attr "type")
5579      (cond [(eq_attr "alternative" "3")
5580               (const_string "lea")
5581             (match_operand:SWI48 2 "incdec_operand")
5582               (const_string "incdec")
5583            ]
5584            (const_string "alu")))
5585    (set (attr "length_immediate")
5586       (if_then_else
5587         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5588         (const_string "1")
5589         (const_string "*")))
5590    (set_attr "mode" "<MODE>")])
5592 ;; It may seem that nonimmediate operand is proper one for operand 1.
5593 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5594 ;; we take care in ix86_binary_operator_ok to not allow two memory
5595 ;; operands so proper swapping will be done in reload.  This allow
5596 ;; patterns constructed from addsi_1 to match.
5598 (define_insn "addsi_1_zext"
5599   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5600         (zero_extend:DI
5601           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5602                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5603    (clobber (reg:CC FLAGS_REG))]
5604   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5606   switch (get_attr_type (insn))
5607     {
5608     case TYPE_LEA:
5609       return "#";
5611     case TYPE_INCDEC:
5612       if (operands[2] == const1_rtx)
5613         return "inc{l}\t%k0";
5614       else
5615         {
5616           gcc_assert (operands[2] == constm1_rtx);
5617           return "dec{l}\t%k0";
5618         }
5620     default:
5621       /* For most processors, ADD is faster than LEA.  This alternative
5622          was added to use ADD as much as possible.  */
5623       if (which_alternative == 1)
5624         {
5625           rtx tmp;
5626           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5627         }
5629       if (x86_maybe_negate_const_int (&operands[2], SImode))
5630         return "sub{l}\t{%2, %k0|%k0, %2}";
5632       return "add{l}\t{%2, %k0|%k0, %2}";
5633     }
5635   [(set (attr "type")
5636      (cond [(eq_attr "alternative" "2")
5637               (const_string "lea")
5638             (match_operand:SI 2 "incdec_operand")
5639               (const_string "incdec")
5640            ]
5641            (const_string "alu")))
5642    (set (attr "length_immediate")
5643       (if_then_else
5644         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5645         (const_string "1")
5646         (const_string "*")))
5647    (set_attr "mode" "SI")])
5649 (define_insn "*addhi_1"
5650   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5651         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5652                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5653    (clobber (reg:CC FLAGS_REG))]
5654   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5656   switch (get_attr_type (insn))
5657     {
5658     case TYPE_LEA:
5659       return "#";
5661     case TYPE_INCDEC:
5662       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5663       if (operands[2] == const1_rtx)
5664         return "inc{w}\t%0";
5665       else
5666         {
5667           gcc_assert (operands[2] == constm1_rtx);
5668           return "dec{w}\t%0";
5669         }
5671     default:
5672       /* For most processors, ADD is faster than LEA.  This alternative
5673          was added to use ADD as much as possible.  */
5674       if (which_alternative == 2)
5675         {
5676           rtx tmp;
5677           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5678         }
5680       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5681       if (x86_maybe_negate_const_int (&operands[2], HImode))
5682         return "sub{w}\t{%2, %0|%0, %2}";
5684       return "add{w}\t{%2, %0|%0, %2}";
5685     }
5687   [(set (attr "type")
5688      (cond [(eq_attr "alternative" "3")
5689               (const_string "lea")
5690             (match_operand:HI 2 "incdec_operand")
5691               (const_string "incdec")
5692            ]
5693            (const_string "alu")))
5694    (set (attr "length_immediate")
5695       (if_then_else
5696         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5697         (const_string "1")
5698         (const_string "*")))
5699    (set_attr "mode" "HI,HI,HI,SI")])
5701 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5702 (define_insn "*addqi_1"
5703   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5704         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5705                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5706    (clobber (reg:CC FLAGS_REG))]
5707   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5709   bool widen = (which_alternative == 3 || which_alternative == 4);
5711   switch (get_attr_type (insn))
5712     {
5713     case TYPE_LEA:
5714       return "#";
5716     case TYPE_INCDEC:
5717       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5718       if (operands[2] == const1_rtx)
5719         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5720       else
5721         {
5722           gcc_assert (operands[2] == constm1_rtx);
5723           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5724         }
5726     default:
5727       /* For most processors, ADD is faster than LEA.  These alternatives
5728          were added to use ADD as much as possible.  */
5729       if (which_alternative == 2 || which_alternative == 4)
5730         {
5731           rtx tmp;
5732           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5733         }
5735       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5736       if (x86_maybe_negate_const_int (&operands[2], QImode))
5737         {
5738           if (widen)
5739             return "sub{l}\t{%2, %k0|%k0, %2}";
5740           else
5741             return "sub{b}\t{%2, %0|%0, %2}";
5742         }
5743       if (widen)
5744         return "add{l}\t{%k2, %k0|%k0, %k2}";
5745       else
5746         return "add{b}\t{%2, %0|%0, %2}";
5747     }
5749   [(set (attr "type")
5750      (cond [(eq_attr "alternative" "5")
5751               (const_string "lea")
5752             (match_operand:QI 2 "incdec_operand")
5753               (const_string "incdec")
5754            ]
5755            (const_string "alu")))
5756    (set (attr "length_immediate")
5757       (if_then_else
5758         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5759         (const_string "1")
5760         (const_string "*")))
5761    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5763 (define_insn "*addqi_1_slp"
5764   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5765         (plus:QI (match_dup 0)
5766                  (match_operand:QI 1 "general_operand" "qn,qm")))
5767    (clobber (reg:CC FLAGS_REG))]
5768   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5769    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5771   switch (get_attr_type (insn))
5772     {
5773     case TYPE_INCDEC:
5774       if (operands[1] == const1_rtx)
5775         return "inc{b}\t%0";
5776       else
5777         {
5778           gcc_assert (operands[1] == constm1_rtx);
5779           return "dec{b}\t%0";
5780         }
5782     default:
5783       if (x86_maybe_negate_const_int (&operands[1], QImode))
5784         return "sub{b}\t{%1, %0|%0, %1}";
5786       return "add{b}\t{%1, %0|%0, %1}";
5787     }
5789   [(set (attr "type")
5790      (if_then_else (match_operand:QI 1 "incdec_operand")
5791         (const_string "incdec")
5792         (const_string "alu1")))
5793    (set (attr "memory")
5794      (if_then_else (match_operand 1 "memory_operand")
5795         (const_string "load")
5796         (const_string "none")))
5797    (set_attr "mode" "QI")])
5799 ;; Split non destructive adds if we cannot use lea.
5800 (define_split
5801   [(set (match_operand:SWI48 0 "register_operand")
5802         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5803                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5804    (clobber (reg:CC FLAGS_REG))]
5805   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5806   [(set (match_dup 0) (match_dup 1))
5807    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5808               (clobber (reg:CC FLAGS_REG))])])
5810 ;; Convert add to the lea pattern to avoid flags dependency.
5811 (define_split
5812   [(set (match_operand:SWI 0 "register_operand")
5813         (plus:SWI (match_operand:SWI 1 "register_operand")
5814                   (match_operand:SWI 2 "<nonmemory_operand>")))
5815    (clobber (reg:CC FLAGS_REG))]
5816   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5817   [(const_int 0)]
5819   enum machine_mode mode = <MODE>mode;
5820   rtx pat;
5822   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5823     { 
5824       mode = SImode; 
5825       operands[0] = gen_lowpart (mode, operands[0]);
5826       operands[1] = gen_lowpart (mode, operands[1]);
5827       operands[2] = gen_lowpart (mode, operands[2]);
5828     }
5830   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5832   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5833   DONE;
5836 ;; Split non destructive adds if we cannot use lea.
5837 (define_split
5838   [(set (match_operand:DI 0 "register_operand")
5839         (zero_extend:DI
5840           (plus:SI (match_operand:SI 1 "register_operand")
5841                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5842    (clobber (reg:CC FLAGS_REG))]
5843   "TARGET_64BIT
5844    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5845   [(set (match_dup 3) (match_dup 1))
5846    (parallel [(set (match_dup 0)
5847                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5848               (clobber (reg:CC FLAGS_REG))])]
5849   "operands[3] = gen_lowpart (SImode, operands[0]);")
5851 ;; Convert add to the lea pattern to avoid flags dependency.
5852 (define_split
5853   [(set (match_operand:DI 0 "register_operand")
5854         (zero_extend:DI
5855           (plus:SI (match_operand:SI 1 "register_operand")
5856                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5857    (clobber (reg:CC FLAGS_REG))]
5858   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5859   [(set (match_dup 0)
5860         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5862 (define_insn "*add<mode>_2"
5863   [(set (reg FLAGS_REG)
5864         (compare
5865           (plus:SWI
5866             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5867             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5868           (const_int 0)))
5869    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5870         (plus:SWI (match_dup 1) (match_dup 2)))]
5871   "ix86_match_ccmode (insn, CCGOCmode)
5872    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5874   switch (get_attr_type (insn))
5875     {
5876     case TYPE_INCDEC:
5877       if (operands[2] == const1_rtx)
5878         return "inc{<imodesuffix>}\t%0";
5879       else
5880         {
5881           gcc_assert (operands[2] == constm1_rtx);
5882           return "dec{<imodesuffix>}\t%0";
5883         }
5885     default:
5886       if (which_alternative == 2)
5887         {
5888           rtx tmp;
5889           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5890         }
5891         
5892       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5893       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5894         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5896       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5897     }
5899   [(set (attr "type")
5900      (if_then_else (match_operand:SWI 2 "incdec_operand")
5901         (const_string "incdec")
5902         (const_string "alu")))
5903    (set (attr "length_immediate")
5904       (if_then_else
5905         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5906         (const_string "1")
5907         (const_string "*")))
5908    (set_attr "mode" "<MODE>")])
5910 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5911 (define_insn "*addsi_2_zext"
5912   [(set (reg FLAGS_REG)
5913         (compare
5914           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5915                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5916           (const_int 0)))
5917    (set (match_operand:DI 0 "register_operand" "=r,r")
5918         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5919   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5920    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5922   switch (get_attr_type (insn))
5923     {
5924     case TYPE_INCDEC:
5925       if (operands[2] == const1_rtx)
5926         return "inc{l}\t%k0";
5927       else
5928         {
5929           gcc_assert (operands[2] == constm1_rtx);
5930           return "dec{l}\t%k0";
5931         }
5933     default:
5934       if (which_alternative == 1)
5935         {
5936           rtx tmp;
5937           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5938         }
5940       if (x86_maybe_negate_const_int (&operands[2], SImode))
5941         return "sub{l}\t{%2, %k0|%k0, %2}";
5943       return "add{l}\t{%2, %k0|%k0, %2}";
5944     }
5946   [(set (attr "type")
5947      (if_then_else (match_operand:SI 2 "incdec_operand")
5948         (const_string "incdec")
5949         (const_string "alu")))
5950    (set (attr "length_immediate")
5951       (if_then_else
5952         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5953         (const_string "1")
5954         (const_string "*")))
5955    (set_attr "mode" "SI")])
5957 (define_insn "*add<mode>_3"
5958   [(set (reg FLAGS_REG)
5959         (compare
5960           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5961           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5962    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5963   "ix86_match_ccmode (insn, CCZmode)
5964    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5966   switch (get_attr_type (insn))
5967     {
5968     case TYPE_INCDEC:
5969       if (operands[2] == const1_rtx)
5970         return "inc{<imodesuffix>}\t%0";
5971       else
5972         {
5973           gcc_assert (operands[2] == constm1_rtx);
5974           return "dec{<imodesuffix>}\t%0";
5975         }
5977     default:
5978       if (which_alternative == 1)
5979         {
5980           rtx tmp;
5981           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5982         }
5984       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5985       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5986         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5988       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5989     }
5991   [(set (attr "type")
5992      (if_then_else (match_operand:SWI 2 "incdec_operand")
5993         (const_string "incdec")
5994         (const_string "alu")))
5995    (set (attr "length_immediate")
5996       (if_then_else
5997         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5998         (const_string "1")
5999         (const_string "*")))
6000    (set_attr "mode" "<MODE>")])
6002 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6003 (define_insn "*addsi_3_zext"
6004   [(set (reg FLAGS_REG)
6005         (compare
6006           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6007           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6008    (set (match_operand:DI 0 "register_operand" "=r,r")
6009         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6010   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6011    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6013   switch (get_attr_type (insn))
6014     {
6015     case TYPE_INCDEC:
6016       if (operands[2] == const1_rtx)
6017         return "inc{l}\t%k0";
6018       else
6019         {
6020           gcc_assert (operands[2] == constm1_rtx);
6021           return "dec{l}\t%k0";
6022         }
6024     default:
6025       if (which_alternative == 1)
6026         {
6027           rtx tmp;
6028           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6029         }
6031       if (x86_maybe_negate_const_int (&operands[2], SImode))
6032         return "sub{l}\t{%2, %k0|%k0, %2}";
6034       return "add{l}\t{%2, %k0|%k0, %2}";
6035     }
6037   [(set (attr "type")
6038      (if_then_else (match_operand:SI 2 "incdec_operand")
6039         (const_string "incdec")
6040         (const_string "alu")))
6041    (set (attr "length_immediate")
6042       (if_then_else
6043         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6044         (const_string "1")
6045         (const_string "*")))
6046    (set_attr "mode" "SI")])
6048 ; For comparisons against 1, -1 and 128, we may generate better code
6049 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6050 ; is matched then.  We can't accept general immediate, because for
6051 ; case of overflows,  the result is messed up.
6052 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6053 ; only for comparisons not depending on it.
6055 (define_insn "*adddi_4"
6056   [(set (reg FLAGS_REG)
6057         (compare
6058           (match_operand:DI 1 "nonimmediate_operand" "0")
6059           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6060    (clobber (match_scratch:DI 0 "=rm"))]
6061   "TARGET_64BIT
6062    && ix86_match_ccmode (insn, CCGCmode)"
6064   switch (get_attr_type (insn))
6065     {
6066     case TYPE_INCDEC:
6067       if (operands[2] == constm1_rtx)
6068         return "inc{q}\t%0";
6069       else
6070         {
6071           gcc_assert (operands[2] == const1_rtx);
6072           return "dec{q}\t%0";
6073         }
6075     default:
6076       if (x86_maybe_negate_const_int (&operands[2], DImode))
6077         return "add{q}\t{%2, %0|%0, %2}";
6079       return "sub{q}\t{%2, %0|%0, %2}";
6080     }
6082   [(set (attr "type")
6083      (if_then_else (match_operand:DI 2 "incdec_operand")
6084         (const_string "incdec")
6085         (const_string "alu")))
6086    (set (attr "length_immediate")
6087       (if_then_else
6088         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6089         (const_string "1")
6090         (const_string "*")))
6091    (set_attr "mode" "DI")])
6093 ; For comparisons against 1, -1 and 128, we may generate better code
6094 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6095 ; is matched then.  We can't accept general immediate, because for
6096 ; case of overflows,  the result is messed up.
6097 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6098 ; only for comparisons not depending on it.
6100 (define_insn "*add<mode>_4"
6101   [(set (reg FLAGS_REG)
6102         (compare
6103           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6104           (match_operand:SWI124 2 "const_int_operand" "n")))
6105    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6106   "ix86_match_ccmode (insn, CCGCmode)"
6108   switch (get_attr_type (insn))
6109     {
6110     case TYPE_INCDEC:
6111       if (operands[2] == constm1_rtx)
6112         return "inc{<imodesuffix>}\t%0";
6113       else
6114         {
6115           gcc_assert (operands[2] == const1_rtx);
6116           return "dec{<imodesuffix>}\t%0";
6117         }
6119     default:
6120       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6121         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6123       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6124     }
6126   [(set (attr "type")
6127      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6128         (const_string "incdec")
6129         (const_string "alu")))
6130    (set (attr "length_immediate")
6131       (if_then_else
6132         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6133         (const_string "1")
6134         (const_string "*")))
6135    (set_attr "mode" "<MODE>")])
6137 (define_insn "*add<mode>_5"
6138   [(set (reg FLAGS_REG)
6139         (compare
6140           (plus:SWI
6141             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6142             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6143           (const_int 0)))
6144    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6145   "ix86_match_ccmode (insn, CCGOCmode)
6146    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6148   switch (get_attr_type (insn))
6149     {
6150     case TYPE_INCDEC:
6151       if (operands[2] == const1_rtx)
6152         return "inc{<imodesuffix>}\t%0";
6153       else
6154         {
6155           gcc_assert (operands[2] == constm1_rtx);
6156           return "dec{<imodesuffix>}\t%0";
6157         }
6159     default:
6160       if (which_alternative == 1)
6161         {
6162           rtx tmp;
6163           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6164         }
6166       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6167       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6168         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6170       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6171     }
6173   [(set (attr "type")
6174      (if_then_else (match_operand:SWI 2 "incdec_operand")
6175         (const_string "incdec")
6176         (const_string "alu")))
6177    (set (attr "length_immediate")
6178       (if_then_else
6179         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6180         (const_string "1")
6181         (const_string "*")))
6182    (set_attr "mode" "<MODE>")])
6184 (define_insn "*addqi_ext_1_rex64"
6185   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6186                          (const_int 8)
6187                          (const_int 8))
6188         (plus:SI
6189           (zero_extract:SI
6190             (match_operand 1 "ext_register_operand" "0")
6191             (const_int 8)
6192             (const_int 8))
6193           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6194    (clobber (reg:CC FLAGS_REG))]
6195   "TARGET_64BIT"
6197   switch (get_attr_type (insn))
6198     {
6199     case TYPE_INCDEC:
6200       if (operands[2] == const1_rtx)
6201         return "inc{b}\t%h0";
6202       else
6203         {
6204           gcc_assert (operands[2] == constm1_rtx);
6205           return "dec{b}\t%h0";
6206         }
6208     default:
6209       return "add{b}\t{%2, %h0|%h0, %2}";
6210     }
6212   [(set (attr "type")
6213      (if_then_else (match_operand:QI 2 "incdec_operand")
6214         (const_string "incdec")
6215         (const_string "alu")))
6216    (set_attr "modrm" "1")
6217    (set_attr "mode" "QI")])
6219 (define_insn "addqi_ext_1"
6220   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6221                          (const_int 8)
6222                          (const_int 8))
6223         (plus:SI
6224           (zero_extract:SI
6225             (match_operand 1 "ext_register_operand" "0")
6226             (const_int 8)
6227             (const_int 8))
6228           (match_operand:QI 2 "general_operand" "Qmn")))
6229    (clobber (reg:CC FLAGS_REG))]
6230   "!TARGET_64BIT"
6232   switch (get_attr_type (insn))
6233     {
6234     case TYPE_INCDEC:
6235       if (operands[2] == const1_rtx)
6236         return "inc{b}\t%h0";
6237       else
6238         {
6239           gcc_assert (operands[2] == constm1_rtx);
6240           return "dec{b}\t%h0";
6241         }
6243     default:
6244       return "add{b}\t{%2, %h0|%h0, %2}";
6245     }
6247   [(set (attr "type")
6248      (if_then_else (match_operand:QI 2 "incdec_operand")
6249         (const_string "incdec")
6250         (const_string "alu")))
6251    (set_attr "modrm" "1")
6252    (set_attr "mode" "QI")])
6254 (define_insn "*addqi_ext_2"
6255   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6256                          (const_int 8)
6257                          (const_int 8))
6258         (plus:SI
6259           (zero_extract:SI
6260             (match_operand 1 "ext_register_operand" "%0")
6261             (const_int 8)
6262             (const_int 8))
6263           (zero_extract:SI
6264             (match_operand 2 "ext_register_operand" "Q")
6265             (const_int 8)
6266             (const_int 8))))
6267    (clobber (reg:CC FLAGS_REG))]
6268   ""
6269   "add{b}\t{%h2, %h0|%h0, %h2}"
6270   [(set_attr "type" "alu")
6271    (set_attr "mode" "QI")])
6273 ;; The lea patterns for modes less than 32 bits need to be matched by
6274 ;; several insns converted to real lea by splitters.
6276 (define_insn_and_split "*lea_general_1"
6277   [(set (match_operand 0 "register_operand" "=r")
6278         (plus (plus (match_operand 1 "index_register_operand" "l")
6279                     (match_operand 2 "register_operand" "r"))
6280               (match_operand 3 "immediate_operand" "i")))]
6281   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6282    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6283    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6284    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6285    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6286        || GET_MODE (operands[3]) == VOIDmode)"
6287   "#"
6288   "&& reload_completed"
6289   [(const_int 0)]
6291   enum machine_mode mode = SImode;
6292   rtx pat;
6294   operands[0] = gen_lowpart (mode, operands[0]);
6295   operands[1] = gen_lowpart (mode, operands[1]);
6296   operands[2] = gen_lowpart (mode, operands[2]);
6297   operands[3] = gen_lowpart (mode, operands[3]);
6299   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6300                       operands[3]);
6302   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6303   DONE;
6305   [(set_attr "type" "lea")
6306    (set_attr "mode" "SI")])
6308 (define_insn_and_split "*lea_general_2"
6309   [(set (match_operand 0 "register_operand" "=r")
6310         (plus (mult (match_operand 1 "index_register_operand" "l")
6311                     (match_operand 2 "const248_operand" "n"))
6312               (match_operand 3 "nonmemory_operand" "ri")))]
6313   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6314    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6315    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6316    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6317        || GET_MODE (operands[3]) == VOIDmode)"
6318   "#"
6319   "&& reload_completed"
6320   [(const_int 0)]
6322   enum machine_mode mode = SImode;
6323   rtx pat;
6325   operands[0] = gen_lowpart (mode, operands[0]);
6326   operands[1] = gen_lowpart (mode, operands[1]);
6327   operands[3] = gen_lowpart (mode, operands[3]);
6329   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6330                       operands[3]);
6332   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6333   DONE;
6335   [(set_attr "type" "lea")
6336    (set_attr "mode" "SI")])
6338 (define_insn_and_split "*lea_general_3"
6339   [(set (match_operand 0 "register_operand" "=r")
6340         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6341                           (match_operand 2 "const248_operand" "n"))
6342                     (match_operand 3 "register_operand" "r"))
6343               (match_operand 4 "immediate_operand" "i")))]
6344   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6345    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6346    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6347    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6348   "#"
6349   "&& reload_completed"
6350   [(const_int 0)]
6352   enum machine_mode mode = SImode;
6353   rtx pat;
6355   operands[0] = gen_lowpart (mode, operands[0]);
6356   operands[1] = gen_lowpart (mode, operands[1]);
6357   operands[3] = gen_lowpart (mode, operands[3]);
6358   operands[4] = gen_lowpart (mode, operands[4]);
6360   pat = gen_rtx_PLUS (mode,
6361                       gen_rtx_PLUS (mode,
6362                                     gen_rtx_MULT (mode, operands[1],
6363                                                         operands[2]),
6364                                     operands[3]),
6365                       operands[4]);
6367   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6368   DONE;
6370   [(set_attr "type" "lea")
6371    (set_attr "mode" "SI")])
6373 (define_insn_and_split "*lea_general_4"
6374   [(set (match_operand 0 "register_operand" "=r")
6375         (any_or (ashift
6376                   (match_operand 1 "index_register_operand" "l")
6377                   (match_operand 2 "const_int_operand" "n"))
6378                 (match_operand 3 "const_int_operand" "n")))]
6379   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6380       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6381     || GET_MODE (operands[0]) == SImode
6382     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6383    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6384    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6385    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6386        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6387   "#"
6388   "&& reload_completed"
6389   [(const_int 0)]
6391   enum machine_mode mode = GET_MODE (operands[0]);
6392   rtx pat;
6394   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6395     { 
6396       mode = SImode; 
6397       operands[0] = gen_lowpart (mode, operands[0]);
6398       operands[1] = gen_lowpart (mode, operands[1]);
6399     }
6401   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6403   pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6404                        INTVAL (operands[3]));
6406   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6407   DONE;
6409   [(set_attr "type" "lea")
6410    (set (attr "mode")
6411       (if_then_else (match_operand:DI 0)
6412         (const_string "DI")
6413         (const_string "SI")))])
6415 ;; Subtract instructions
6417 (define_expand "sub<mode>3"
6418   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6419         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6420                      (match_operand:SDWIM 2 "<general_operand>")))]
6421   ""
6422   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6424 (define_insn_and_split "*sub<dwi>3_doubleword"
6425   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6426         (minus:<DWI>
6427           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6428           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6429    (clobber (reg:CC FLAGS_REG))]
6430   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6431   "#"
6432   "reload_completed"
6433   [(parallel [(set (reg:CC FLAGS_REG)
6434                    (compare:CC (match_dup 1) (match_dup 2)))
6435               (set (match_dup 0)
6436                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6437    (parallel [(set (match_dup 3)
6438                    (minus:DWIH
6439                      (match_dup 4)
6440                      (plus:DWIH
6441                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6442                        (match_dup 5))))
6443               (clobber (reg:CC FLAGS_REG))])]
6444   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6446 (define_insn "*sub<mode>_1"
6447   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6448         (minus:SWI
6449           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6450           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6451    (clobber (reg:CC FLAGS_REG))]
6452   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6453   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6454   [(set_attr "type" "alu")
6455    (set_attr "mode" "<MODE>")])
6457 (define_insn "*subsi_1_zext"
6458   [(set (match_operand:DI 0 "register_operand" "=r")
6459         (zero_extend:DI
6460           (minus:SI (match_operand:SI 1 "register_operand" "0")
6461                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6462    (clobber (reg:CC FLAGS_REG))]
6463   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6464   "sub{l}\t{%2, %k0|%k0, %2}"
6465   [(set_attr "type" "alu")
6466    (set_attr "mode" "SI")])
6468 (define_insn "*subqi_1_slp"
6469   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6470         (minus:QI (match_dup 0)
6471                   (match_operand:QI 1 "general_operand" "qn,qm")))
6472    (clobber (reg:CC FLAGS_REG))]
6473   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6474    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6475   "sub{b}\t{%1, %0|%0, %1}"
6476   [(set_attr "type" "alu1")
6477    (set_attr "mode" "QI")])
6479 (define_insn "*sub<mode>_2"
6480   [(set (reg FLAGS_REG)
6481         (compare
6482           (minus:SWI
6483             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6484             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6485           (const_int 0)))
6486    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6487         (minus:SWI (match_dup 1) (match_dup 2)))]
6488   "ix86_match_ccmode (insn, CCGOCmode)
6489    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6490   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6491   [(set_attr "type" "alu")
6492    (set_attr "mode" "<MODE>")])
6494 (define_insn "*subsi_2_zext"
6495   [(set (reg FLAGS_REG)
6496         (compare
6497           (minus:SI (match_operand:SI 1 "register_operand" "0")
6498                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6499           (const_int 0)))
6500    (set (match_operand:DI 0 "register_operand" "=r")
6501         (zero_extend:DI
6502           (minus:SI (match_dup 1)
6503                     (match_dup 2))))]
6504   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6505    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6506   "sub{l}\t{%2, %k0|%k0, %2}"
6507   [(set_attr "type" "alu")
6508    (set_attr "mode" "SI")])
6510 (define_insn "*sub<mode>_3"
6511   [(set (reg FLAGS_REG)
6512         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6513                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6514    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6515         (minus:SWI (match_dup 1) (match_dup 2)))]
6516   "ix86_match_ccmode (insn, CCmode)
6517    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6518   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6519   [(set_attr "type" "alu")
6520    (set_attr "mode" "<MODE>")])
6522 (define_insn "*subsi_3_zext"
6523   [(set (reg FLAGS_REG)
6524         (compare (match_operand:SI 1 "register_operand" "0")
6525                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6526    (set (match_operand:DI 0 "register_operand" "=r")
6527         (zero_extend:DI
6528           (minus:SI (match_dup 1)
6529                     (match_dup 2))))]
6530   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6531    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6532   "sub{l}\t{%2, %1|%1, %2}"
6533   [(set_attr "type" "alu")
6534    (set_attr "mode" "SI")])
6536 ;; Add with carry and subtract with borrow
6538 (define_expand "<plusminus_insn><mode>3_carry"
6539   [(parallel
6540     [(set (match_operand:SWI 0 "nonimmediate_operand")
6541           (plusminus:SWI
6542             (match_operand:SWI 1 "nonimmediate_operand")
6543             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6544                        [(match_operand 3 "flags_reg_operand")
6545                         (const_int 0)])
6546                       (match_operand:SWI 2 "<general_operand>"))))
6547      (clobber (reg:CC FLAGS_REG))])]
6548   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6550 (define_insn "*<plusminus_insn><mode>3_carry"
6551   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6552         (plusminus:SWI
6553           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6554           (plus:SWI
6555             (match_operator 3 "ix86_carry_flag_operator"
6556              [(reg FLAGS_REG) (const_int 0)])
6557             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6558    (clobber (reg:CC FLAGS_REG))]
6559   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6560   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6561   [(set_attr "type" "alu")
6562    (set_attr "use_carry" "1")
6563    (set_attr "pent_pair" "pu")
6564    (set_attr "mode" "<MODE>")])
6566 (define_insn "*addsi3_carry_zext"
6567   [(set (match_operand:DI 0 "register_operand" "=r")
6568         (zero_extend:DI
6569           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6570                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6571                              [(reg FLAGS_REG) (const_int 0)])
6572                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6573    (clobber (reg:CC FLAGS_REG))]
6574   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6575   "adc{l}\t{%2, %k0|%k0, %2}"
6576   [(set_attr "type" "alu")
6577    (set_attr "use_carry" "1")
6578    (set_attr "pent_pair" "pu")
6579    (set_attr "mode" "SI")])
6581 (define_insn "*subsi3_carry_zext"
6582   [(set (match_operand:DI 0 "register_operand" "=r")
6583         (zero_extend:DI
6584           (minus:SI (match_operand:SI 1 "register_operand" "0")
6585                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6586                               [(reg FLAGS_REG) (const_int 0)])
6587                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6588    (clobber (reg:CC FLAGS_REG))]
6589   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6590   "sbb{l}\t{%2, %k0|%k0, %2}"
6591   [(set_attr "type" "alu")
6592    (set_attr "pent_pair" "pu")
6593    (set_attr "mode" "SI")])
6595 ;; ADCX instruction
6597 (define_insn "adcx<mode>3"
6598   [(set (reg:CCC FLAGS_REG)
6599         (compare:CCC
6600           (plus:SWI48
6601             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6602             (plus:SWI48
6603               (match_operator 4 "ix86_carry_flag_operator"
6604                [(match_operand 3 "flags_reg_operand") (const_int 0)])
6605               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6606           (const_int 0)))
6607    (set (match_operand:SWI48 0 "register_operand" "=r")
6608         (plus:SWI48 (match_dup 1)
6609                     (plus:SWI48 (match_op_dup 4
6610                                  [(match_dup 3) (const_int 0)])
6611                                 (match_dup 2))))]
6612   "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6613   "adcx\t{%2, %0|%0, %2}"
6614   [(set_attr "type" "alu")
6615    (set_attr "use_carry" "1")
6616    (set_attr "mode" "<MODE>")])
6618 ;; Overflow setting add instructions
6620 (define_insn "*add<mode>3_cconly_overflow"
6621   [(set (reg:CCC FLAGS_REG)
6622         (compare:CCC
6623           (plus:SWI
6624             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6625             (match_operand:SWI 2 "<general_operand>" "<g>"))
6626           (match_dup 1)))
6627    (clobber (match_scratch:SWI 0 "=<r>"))]
6628   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6629   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6630   [(set_attr "type" "alu")
6631    (set_attr "mode" "<MODE>")])
6633 (define_insn "*add<mode>3_cc_overflow"
6634   [(set (reg:CCC FLAGS_REG)
6635         (compare:CCC
6636             (plus:SWI
6637                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6638                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6639             (match_dup 1)))
6640    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6641         (plus:SWI (match_dup 1) (match_dup 2)))]
6642   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6643   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6644   [(set_attr "type" "alu")
6645    (set_attr "mode" "<MODE>")])
6647 (define_insn "*addsi3_zext_cc_overflow"
6648   [(set (reg:CCC FLAGS_REG)
6649         (compare:CCC
6650           (plus:SI
6651             (match_operand:SI 1 "nonimmediate_operand" "%0")
6652             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6653           (match_dup 1)))
6654    (set (match_operand:DI 0 "register_operand" "=r")
6655         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6656   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6657   "add{l}\t{%2, %k0|%k0, %2}"
6658   [(set_attr "type" "alu")
6659    (set_attr "mode" "SI")])
6661 ;; The patterns that match these are at the end of this file.
6663 (define_expand "<plusminus_insn>xf3"
6664   [(set (match_operand:XF 0 "register_operand")
6665         (plusminus:XF
6666           (match_operand:XF 1 "register_operand")
6667           (match_operand:XF 2 "register_operand")))]
6668   "TARGET_80387")
6670 (define_expand "<plusminus_insn><mode>3"
6671   [(set (match_operand:MODEF 0 "register_operand")
6672         (plusminus:MODEF
6673           (match_operand:MODEF 1 "register_operand")
6674           (match_operand:MODEF 2 "nonimmediate_operand")))]
6675   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6676     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6678 ;; Multiply instructions
6680 (define_expand "mul<mode>3"
6681   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6682                    (mult:SWIM248
6683                      (match_operand:SWIM248 1 "register_operand")
6684                      (match_operand:SWIM248 2 "<general_operand>")))
6685               (clobber (reg:CC FLAGS_REG))])])
6687 (define_expand "mulqi3"
6688   [(parallel [(set (match_operand:QI 0 "register_operand")
6689                    (mult:QI
6690                      (match_operand:QI 1 "register_operand")
6691                      (match_operand:QI 2 "nonimmediate_operand")))
6692               (clobber (reg:CC FLAGS_REG))])]
6693   "TARGET_QIMODE_MATH")
6695 ;; On AMDFAM10
6696 ;; IMUL reg32/64, reg32/64, imm8        Direct
6697 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6698 ;; IMUL reg32/64, reg32/64, imm32       Direct
6699 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6700 ;; IMUL reg32/64, reg32/64              Direct
6701 ;; IMUL reg32/64, mem32/64              Direct
6703 ;; On BDVER1, all above IMULs use DirectPath
6705 (define_insn "*mul<mode>3_1"
6706   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6707         (mult:SWI48
6708           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6709           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6710    (clobber (reg:CC FLAGS_REG))]
6711   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6712   "@
6713    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6714    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6715    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6716   [(set_attr "type" "imul")
6717    (set_attr "prefix_0f" "0,0,1")
6718    (set (attr "athlon_decode")
6719         (cond [(eq_attr "cpu" "athlon")
6720                   (const_string "vector")
6721                (eq_attr "alternative" "1")
6722                   (const_string "vector")
6723                (and (eq_attr "alternative" "2")
6724                     (match_operand 1 "memory_operand"))
6725                   (const_string "vector")]
6726               (const_string "direct")))
6727    (set (attr "amdfam10_decode")
6728         (cond [(and (eq_attr "alternative" "0,1")
6729                     (match_operand 1 "memory_operand"))
6730                   (const_string "vector")]
6731               (const_string "direct")))
6732    (set_attr "bdver1_decode" "direct")
6733    (set_attr "mode" "<MODE>")])
6735 (define_insn "*mulsi3_1_zext"
6736   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6737         (zero_extend:DI
6738           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6739                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6740    (clobber (reg:CC FLAGS_REG))]
6741   "TARGET_64BIT
6742    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6743   "@
6744    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6745    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6746    imul{l}\t{%2, %k0|%k0, %2}"
6747   [(set_attr "type" "imul")
6748    (set_attr "prefix_0f" "0,0,1")
6749    (set (attr "athlon_decode")
6750         (cond [(eq_attr "cpu" "athlon")
6751                   (const_string "vector")
6752                (eq_attr "alternative" "1")
6753                   (const_string "vector")
6754                (and (eq_attr "alternative" "2")
6755                     (match_operand 1 "memory_operand"))
6756                   (const_string "vector")]
6757               (const_string "direct")))
6758    (set (attr "amdfam10_decode")
6759         (cond [(and (eq_attr "alternative" "0,1")
6760                     (match_operand 1 "memory_operand"))
6761                   (const_string "vector")]
6762               (const_string "direct")))
6763    (set_attr "bdver1_decode" "direct")
6764    (set_attr "mode" "SI")])
6766 ;; On AMDFAM10
6767 ;; IMUL reg16, reg16, imm8      VectorPath
6768 ;; IMUL reg16, mem16, imm8      VectorPath
6769 ;; IMUL reg16, reg16, imm16     VectorPath
6770 ;; IMUL reg16, mem16, imm16     VectorPath
6771 ;; IMUL reg16, reg16            Direct
6772 ;; IMUL reg16, mem16            Direct
6774 ;; On BDVER1, all HI MULs use DoublePath
6776 (define_insn "*mulhi3_1"
6777   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6778         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6779                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6780    (clobber (reg:CC FLAGS_REG))]
6781   "TARGET_HIMODE_MATH
6782    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6783   "@
6784    imul{w}\t{%2, %1, %0|%0, %1, %2}
6785    imul{w}\t{%2, %1, %0|%0, %1, %2}
6786    imul{w}\t{%2, %0|%0, %2}"
6787   [(set_attr "type" "imul")
6788    (set_attr "prefix_0f" "0,0,1")
6789    (set (attr "athlon_decode")
6790         (cond [(eq_attr "cpu" "athlon")
6791                   (const_string "vector")
6792                (eq_attr "alternative" "1,2")
6793                   (const_string "vector")]
6794               (const_string "direct")))
6795    (set (attr "amdfam10_decode")
6796         (cond [(eq_attr "alternative" "0,1")
6797                   (const_string "vector")]
6798               (const_string "direct")))
6799    (set_attr "bdver1_decode" "double")
6800    (set_attr "mode" "HI")])
6802 ;;On AMDFAM10 and BDVER1
6803 ;; MUL reg8     Direct
6804 ;; MUL mem8     Direct
6806 (define_insn "*mulqi3_1"
6807   [(set (match_operand:QI 0 "register_operand" "=a")
6808         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6809                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6810    (clobber (reg:CC FLAGS_REG))]
6811   "TARGET_QIMODE_MATH
6812    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6813   "mul{b}\t%2"
6814   [(set_attr "type" "imul")
6815    (set_attr "length_immediate" "0")
6816    (set (attr "athlon_decode")
6817      (if_then_else (eq_attr "cpu" "athlon")
6818         (const_string "vector")
6819         (const_string "direct")))
6820    (set_attr "amdfam10_decode" "direct")
6821    (set_attr "bdver1_decode" "direct")
6822    (set_attr "mode" "QI")])
6824 (define_expand "<u>mul<mode><dwi>3"
6825   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6826                    (mult:<DWI>
6827                      (any_extend:<DWI>
6828                        (match_operand:DWIH 1 "nonimmediate_operand"))
6829                      (any_extend:<DWI>
6830                        (match_operand:DWIH 2 "register_operand"))))
6831               (clobber (reg:CC FLAGS_REG))])])
6833 (define_expand "<u>mulqihi3"
6834   [(parallel [(set (match_operand:HI 0 "register_operand")
6835                    (mult:HI
6836                      (any_extend:HI
6837                        (match_operand:QI 1 "nonimmediate_operand"))
6838                      (any_extend:HI
6839                        (match_operand:QI 2 "register_operand"))))
6840               (clobber (reg:CC FLAGS_REG))])]
6841   "TARGET_QIMODE_MATH")
6843 (define_insn "*bmi2_umulditi3_1"
6844   [(set (match_operand:DI 0 "register_operand" "=r")
6845         (mult:DI
6846           (match_operand:DI 2 "nonimmediate_operand" "%d")
6847           (match_operand:DI 3 "nonimmediate_operand" "rm")))
6848    (set (match_operand:DI 1 "register_operand" "=r")
6849         (truncate:DI
6850           (lshiftrt:TI
6851             (mult:TI (zero_extend:TI (match_dup 2))
6852                      (zero_extend:TI (match_dup 3)))
6853             (const_int 64))))]
6854   "TARGET_64BIT && TARGET_BMI2
6855    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6856   "mulx\t{%3, %0, %1|%1, %0, %3}"
6857   [(set_attr "type" "imulx")
6858    (set_attr "prefix" "vex")
6859    (set_attr "mode" "DI")])
6861 (define_insn "*bmi2_umulsidi3_1"
6862   [(set (match_operand:SI 0 "register_operand" "=r")
6863         (mult:SI
6864           (match_operand:SI 2 "nonimmediate_operand" "%d")
6865           (match_operand:SI 3 "nonimmediate_operand" "rm")))
6866    (set (match_operand:SI 1 "register_operand" "=r")
6867         (truncate:SI
6868           (lshiftrt:DI
6869             (mult:DI (zero_extend:DI (match_dup 2))
6870                      (zero_extend:DI (match_dup 3)))
6871             (const_int 32))))]
6872   "!TARGET_64BIT && TARGET_BMI2
6873    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6874   "mulx\t{%3, %0, %1|%1, %0, %3}"
6875   [(set_attr "type" "imulx")
6876    (set_attr "prefix" "vex")
6877    (set_attr "mode" "SI")])
6879 (define_insn "*umul<mode><dwi>3_1"
6880   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6881         (mult:<DWI>
6882           (zero_extend:<DWI>
6883             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6884           (zero_extend:<DWI>
6885             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6886    (clobber (reg:CC FLAGS_REG))]
6887   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6888   "@
6889    #
6890    mul{<imodesuffix>}\t%2"
6891   [(set_attr "isa" "bmi2,*")
6892    (set_attr "type" "imulx,imul")
6893    (set_attr "length_immediate" "*,0")
6894    (set (attr "athlon_decode")
6895         (cond [(eq_attr "alternative" "1")
6896                  (if_then_else (eq_attr "cpu" "athlon")
6897                    (const_string "vector")
6898                    (const_string "double"))]
6899               (const_string "*")))
6900    (set_attr "amdfam10_decode" "*,double")
6901    (set_attr "bdver1_decode" "*,direct")
6902    (set_attr "prefix" "vex,orig")
6903    (set_attr "mode" "<MODE>")])
6905 ;; Convert mul to the mulx pattern to avoid flags dependency.
6906 (define_split
6907  [(set (match_operand:<DWI> 0 "register_operand")
6908        (mult:<DWI>
6909          (zero_extend:<DWI>
6910            (match_operand:DWIH 1 "register_operand"))
6911          (zero_extend:<DWI>
6912            (match_operand:DWIH 2 "nonimmediate_operand"))))
6913   (clobber (reg:CC FLAGS_REG))]
6914  "TARGET_BMI2 && reload_completed
6915   && true_regnum (operands[1]) == DX_REG"
6916   [(parallel [(set (match_dup 3)
6917                    (mult:DWIH (match_dup 1) (match_dup 2)))
6918               (set (match_dup 4)
6919                    (truncate:DWIH
6920                      (lshiftrt:<DWI>
6921                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6922                                    (zero_extend:<DWI> (match_dup 2)))
6923                        (match_dup 5))))])]
6925   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6927   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6930 (define_insn "*mul<mode><dwi>3_1"
6931   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6932         (mult:<DWI>
6933           (sign_extend:<DWI>
6934             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6935           (sign_extend:<DWI>
6936             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6937    (clobber (reg:CC FLAGS_REG))]
6938   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6939   "imul{<imodesuffix>}\t%2"
6940   [(set_attr "type" "imul")
6941    (set_attr "length_immediate" "0")
6942    (set (attr "athlon_decode")
6943      (if_then_else (eq_attr "cpu" "athlon")
6944         (const_string "vector")
6945         (const_string "double")))
6946    (set_attr "amdfam10_decode" "double")
6947    (set_attr "bdver1_decode" "direct")
6948    (set_attr "mode" "<MODE>")])
6950 (define_insn "*<u>mulqihi3_1"
6951   [(set (match_operand:HI 0 "register_operand" "=a")
6952         (mult:HI
6953           (any_extend:HI
6954             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6955           (any_extend:HI
6956             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6957    (clobber (reg:CC FLAGS_REG))]
6958   "TARGET_QIMODE_MATH
6959    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6960   "<sgnprefix>mul{b}\t%2"
6961   [(set_attr "type" "imul")
6962    (set_attr "length_immediate" "0")
6963    (set (attr "athlon_decode")
6964      (if_then_else (eq_attr "cpu" "athlon")
6965         (const_string "vector")
6966         (const_string "direct")))
6967    (set_attr "amdfam10_decode" "direct")
6968    (set_attr "bdver1_decode" "direct")
6969    (set_attr "mode" "QI")])
6971 (define_expand "<s>mul<mode>3_highpart"
6972   [(parallel [(set (match_operand:SWI48 0 "register_operand")
6973                    (truncate:SWI48
6974                      (lshiftrt:<DWI>
6975                        (mult:<DWI>
6976                          (any_extend:<DWI>
6977                            (match_operand:SWI48 1 "nonimmediate_operand"))
6978                          (any_extend:<DWI>
6979                            (match_operand:SWI48 2 "register_operand")))
6980                        (match_dup 4))))
6981               (clobber (match_scratch:SWI48 3))
6982               (clobber (reg:CC FLAGS_REG))])]
6983   ""
6984   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6986 (define_insn "*<s>muldi3_highpart_1"
6987   [(set (match_operand:DI 0 "register_operand" "=d")
6988         (truncate:DI
6989           (lshiftrt:TI
6990             (mult:TI
6991               (any_extend:TI
6992                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6993               (any_extend:TI
6994                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6995             (const_int 64))))
6996    (clobber (match_scratch:DI 3 "=1"))
6997    (clobber (reg:CC FLAGS_REG))]
6998   "TARGET_64BIT
6999    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7000   "<sgnprefix>mul{q}\t%2"
7001   [(set_attr "type" "imul")
7002    (set_attr "length_immediate" "0")
7003    (set (attr "athlon_decode")
7004      (if_then_else (eq_attr "cpu" "athlon")
7005         (const_string "vector")
7006         (const_string "double")))
7007    (set_attr "amdfam10_decode" "double")
7008    (set_attr "bdver1_decode" "direct")
7009    (set_attr "mode" "DI")])
7011 (define_insn "*<s>mulsi3_highpart_1"
7012   [(set (match_operand:SI 0 "register_operand" "=d")
7013         (truncate:SI
7014           (lshiftrt:DI
7015             (mult:DI
7016               (any_extend:DI
7017                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7018               (any_extend:DI
7019                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7020             (const_int 32))))
7021    (clobber (match_scratch:SI 3 "=1"))
7022    (clobber (reg:CC FLAGS_REG))]
7023   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7024   "<sgnprefix>mul{l}\t%2"
7025   [(set_attr "type" "imul")
7026    (set_attr "length_immediate" "0")
7027    (set (attr "athlon_decode")
7028      (if_then_else (eq_attr "cpu" "athlon")
7029         (const_string "vector")
7030         (const_string "double")))
7031    (set_attr "amdfam10_decode" "double")
7032    (set_attr "bdver1_decode" "direct")
7033    (set_attr "mode" "SI")])
7035 (define_insn "*<s>mulsi3_highpart_zext"
7036   [(set (match_operand:DI 0 "register_operand" "=d")
7037         (zero_extend:DI (truncate:SI
7038           (lshiftrt:DI
7039             (mult:DI (any_extend:DI
7040                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7041                      (any_extend:DI
7042                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7043             (const_int 32)))))
7044    (clobber (match_scratch:SI 3 "=1"))
7045    (clobber (reg:CC FLAGS_REG))]
7046   "TARGET_64BIT
7047    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7048   "<sgnprefix>mul{l}\t%2"
7049   [(set_attr "type" "imul")
7050    (set_attr "length_immediate" "0")
7051    (set (attr "athlon_decode")
7052      (if_then_else (eq_attr "cpu" "athlon")
7053         (const_string "vector")
7054         (const_string "double")))
7055    (set_attr "amdfam10_decode" "double")
7056    (set_attr "bdver1_decode" "direct")
7057    (set_attr "mode" "SI")])
7059 ;; The patterns that match these are at the end of this file.
7061 (define_expand "mulxf3"
7062   [(set (match_operand:XF 0 "register_operand")
7063         (mult:XF (match_operand:XF 1 "register_operand")
7064                  (match_operand:XF 2 "register_operand")))]
7065   "TARGET_80387")
7067 (define_expand "mul<mode>3"
7068   [(set (match_operand:MODEF 0 "register_operand")
7069         (mult:MODEF (match_operand:MODEF 1 "register_operand")
7070                     (match_operand:MODEF 2 "nonimmediate_operand")))]
7071   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7072     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7074 ;; Divide instructions
7076 ;; The patterns that match these are at the end of this file.
7078 (define_expand "divxf3"
7079   [(set (match_operand:XF 0 "register_operand")
7080         (div:XF (match_operand:XF 1 "register_operand")
7081                 (match_operand:XF 2 "register_operand")))]
7082   "TARGET_80387")
7084 (define_expand "divdf3"
7085   [(set (match_operand:DF 0 "register_operand")
7086         (div:DF (match_operand:DF 1 "register_operand")
7087                 (match_operand:DF 2 "nonimmediate_operand")))]
7088    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7089     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7091 (define_expand "divsf3"
7092   [(set (match_operand:SF 0 "register_operand")
7093         (div:SF (match_operand:SF 1 "register_operand")
7094                 (match_operand:SF 2 "nonimmediate_operand")))]
7095   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7096     || TARGET_SSE_MATH"
7098   if (TARGET_SSE_MATH
7099       && TARGET_RECIP_DIV
7100       && optimize_insn_for_speed_p ()
7101       && flag_finite_math_only && !flag_trapping_math
7102       && flag_unsafe_math_optimizations)
7103     {
7104       ix86_emit_swdivsf (operands[0], operands[1],
7105                          operands[2], SFmode);
7106       DONE;
7107     }
7110 ;; Divmod instructions.
7112 (define_expand "divmod<mode>4"
7113   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7114                    (div:SWIM248
7115                      (match_operand:SWIM248 1 "register_operand")
7116                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7117               (set (match_operand:SWIM248 3 "register_operand")
7118                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7119               (clobber (reg:CC FLAGS_REG))])])
7121 ;; Split with 8bit unsigned divide:
7122 ;;      if (dividend an divisor are in [0-255])
7123 ;;         use 8bit unsigned integer divide
7124 ;;       else
7125 ;;         use original integer divide
7126 (define_split
7127   [(set (match_operand:SWI48 0 "register_operand")
7128         (div:SWI48 (match_operand:SWI48 2 "register_operand")
7129                     (match_operand:SWI48 3 "nonimmediate_operand")))
7130    (set (match_operand:SWI48 1 "register_operand")
7131         (mod:SWI48 (match_dup 2) (match_dup 3)))
7132    (clobber (reg:CC FLAGS_REG))]
7133   "TARGET_USE_8BIT_IDIV
7134    && TARGET_QIMODE_MATH
7135    && can_create_pseudo_p ()
7136    && !optimize_insn_for_size_p ()"
7137   [(const_int 0)]
7138   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7140 (define_insn_and_split "divmod<mode>4_1"
7141   [(set (match_operand:SWI48 0 "register_operand" "=a")
7142         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7143                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7144    (set (match_operand:SWI48 1 "register_operand" "=&d")
7145         (mod:SWI48 (match_dup 2) (match_dup 3)))
7146    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7147    (clobber (reg:CC FLAGS_REG))]
7148   ""
7149   "#"
7150   "reload_completed"
7151   [(parallel [(set (match_dup 1)
7152                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7153               (clobber (reg:CC FLAGS_REG))])
7154    (parallel [(set (match_dup 0)
7155                    (div:SWI48 (match_dup 2) (match_dup 3)))
7156               (set (match_dup 1)
7157                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7158               (use (match_dup 1))
7159               (clobber (reg:CC FLAGS_REG))])]
7161   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7163   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7164     operands[4] = operands[2];
7165   else
7166     {
7167       /* Avoid use of cltd in favor of a mov+shift.  */
7168       emit_move_insn (operands[1], operands[2]);
7169       operands[4] = operands[1];
7170     }
7172   [(set_attr "type" "multi")
7173    (set_attr "mode" "<MODE>")])
7175 (define_insn_and_split "*divmod<mode>4"
7176   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7177         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7178                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7179    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7180         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7181    (clobber (reg:CC FLAGS_REG))]
7182   ""
7183   "#"
7184   "reload_completed"
7185   [(parallel [(set (match_dup 1)
7186                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7187               (clobber (reg:CC FLAGS_REG))])
7188    (parallel [(set (match_dup 0)
7189                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7190               (set (match_dup 1)
7191                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7192               (use (match_dup 1))
7193               (clobber (reg:CC FLAGS_REG))])]
7195   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7197   if (<MODE>mode != HImode
7198       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7199     operands[4] = operands[2];
7200   else
7201     {
7202       /* Avoid use of cltd in favor of a mov+shift.  */
7203       emit_move_insn (operands[1], operands[2]);
7204       operands[4] = operands[1];
7205     }
7207   [(set_attr "type" "multi")
7208    (set_attr "mode" "<MODE>")])
7210 (define_insn "*divmod<mode>4_noext"
7211   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7212         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7213                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7214    (set (match_operand:SWIM248 1 "register_operand" "=d")
7215         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7216    (use (match_operand:SWIM248 4 "register_operand" "1"))
7217    (clobber (reg:CC FLAGS_REG))]
7218   ""
7219   "idiv{<imodesuffix>}\t%3"
7220   [(set_attr "type" "idiv")
7221    (set_attr "mode" "<MODE>")])
7223 (define_expand "divmodqi4"
7224   [(parallel [(set (match_operand:QI 0 "register_operand")
7225                    (div:QI
7226                      (match_operand:QI 1 "register_operand")
7227                      (match_operand:QI 2 "nonimmediate_operand")))
7228               (set (match_operand:QI 3 "register_operand")
7229                    (mod:QI (match_dup 1) (match_dup 2)))
7230               (clobber (reg:CC FLAGS_REG))])]
7231   "TARGET_QIMODE_MATH"
7233   rtx div, mod, insn;
7234   rtx tmp0, tmp1;
7235   
7236   tmp0 = gen_reg_rtx (HImode);
7237   tmp1 = gen_reg_rtx (HImode);
7239   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7240      in AX.  */
7241   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7242   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7244   /* Extract remainder from AH.  */
7245   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7246   insn = emit_move_insn (operands[3], tmp1);
7248   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7249   set_unique_reg_note (insn, REG_EQUAL, mod);
7251   /* Extract quotient from AL.  */
7252   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7254   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7255   set_unique_reg_note (insn, REG_EQUAL, div);
7257   DONE;
7260 ;; Divide AX by r/m8, with result stored in
7261 ;; AL <- Quotient
7262 ;; AH <- Remainder
7263 ;; Change div/mod to HImode and extend the second argument to HImode
7264 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7265 ;; combine may fail.
7266 (define_insn "divmodhiqi3"
7267   [(set (match_operand:HI 0 "register_operand" "=a")
7268         (ior:HI
7269           (ashift:HI
7270             (zero_extend:HI
7271               (truncate:QI
7272                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7273                         (sign_extend:HI
7274                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7275             (const_int 8))
7276           (zero_extend:HI
7277             (truncate:QI
7278               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7279    (clobber (reg:CC FLAGS_REG))]
7280   "TARGET_QIMODE_MATH"
7281   "idiv{b}\t%2"
7282   [(set_attr "type" "idiv")
7283    (set_attr "mode" "QI")])
7285 (define_expand "udivmod<mode>4"
7286   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7287                    (udiv:SWIM248
7288                      (match_operand:SWIM248 1 "register_operand")
7289                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7290               (set (match_operand:SWIM248 3 "register_operand")
7291                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7292               (clobber (reg:CC FLAGS_REG))])])
7294 ;; Split with 8bit unsigned divide:
7295 ;;      if (dividend an divisor are in [0-255])
7296 ;;         use 8bit unsigned integer divide
7297 ;;       else
7298 ;;         use original integer divide
7299 (define_split
7300   [(set (match_operand:SWI48 0 "register_operand")
7301         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7302                     (match_operand:SWI48 3 "nonimmediate_operand")))
7303    (set (match_operand:SWI48 1 "register_operand")
7304         (umod:SWI48 (match_dup 2) (match_dup 3)))
7305    (clobber (reg:CC FLAGS_REG))]
7306   "TARGET_USE_8BIT_IDIV
7307    && TARGET_QIMODE_MATH
7308    && can_create_pseudo_p ()
7309    && !optimize_insn_for_size_p ()"
7310   [(const_int 0)]
7311   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7313 (define_insn_and_split "udivmod<mode>4_1"
7314   [(set (match_operand:SWI48 0 "register_operand" "=a")
7315         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7316                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7317    (set (match_operand:SWI48 1 "register_operand" "=&d")
7318         (umod:SWI48 (match_dup 2) (match_dup 3)))
7319    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7320    (clobber (reg:CC FLAGS_REG))]
7321   ""
7322   "#"
7323   "reload_completed"
7324   [(set (match_dup 1) (const_int 0))
7325    (parallel [(set (match_dup 0)
7326                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7327               (set (match_dup 1)
7328                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7329               (use (match_dup 1))
7330               (clobber (reg:CC FLAGS_REG))])]
7331   ""
7332   [(set_attr "type" "multi")
7333    (set_attr "mode" "<MODE>")])
7335 (define_insn_and_split "*udivmod<mode>4"
7336   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7337         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7338                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7339    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7340         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7341    (clobber (reg:CC FLAGS_REG))]
7342   ""
7343   "#"
7344   "reload_completed"
7345   [(set (match_dup 1) (const_int 0))
7346    (parallel [(set (match_dup 0)
7347                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7348               (set (match_dup 1)
7349                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7350               (use (match_dup 1))
7351               (clobber (reg:CC FLAGS_REG))])]
7352   ""
7353   [(set_attr "type" "multi")
7354    (set_attr "mode" "<MODE>")])
7356 (define_insn "*udivmod<mode>4_noext"
7357   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7358         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7359                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7360    (set (match_operand:SWIM248 1 "register_operand" "=d")
7361         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7362    (use (match_operand:SWIM248 4 "register_operand" "1"))
7363    (clobber (reg:CC FLAGS_REG))]
7364   ""
7365   "div{<imodesuffix>}\t%3"
7366   [(set_attr "type" "idiv")
7367    (set_attr "mode" "<MODE>")])
7369 (define_expand "udivmodqi4"
7370   [(parallel [(set (match_operand:QI 0 "register_operand")
7371                    (udiv:QI
7372                      (match_operand:QI 1 "register_operand")
7373                      (match_operand:QI 2 "nonimmediate_operand")))
7374               (set (match_operand:QI 3 "register_operand")
7375                    (umod:QI (match_dup 1) (match_dup 2)))
7376               (clobber (reg:CC FLAGS_REG))])]
7377   "TARGET_QIMODE_MATH"
7379   rtx div, mod, insn;
7380   rtx tmp0, tmp1;
7381   
7382   tmp0 = gen_reg_rtx (HImode);
7383   tmp1 = gen_reg_rtx (HImode);
7385   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7386      in AX.  */
7387   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7388   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7390   /* Extract remainder from AH.  */
7391   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7392   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7393   insn = emit_move_insn (operands[3], tmp1);
7395   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7396   set_unique_reg_note (insn, REG_EQUAL, mod);
7398   /* Extract quotient from AL.  */
7399   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7401   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7402   set_unique_reg_note (insn, REG_EQUAL, div);
7404   DONE;
7407 (define_insn "udivmodhiqi3"
7408   [(set (match_operand:HI 0 "register_operand" "=a")
7409         (ior:HI
7410           (ashift:HI
7411             (zero_extend:HI
7412               (truncate:QI
7413                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7414                         (zero_extend:HI
7415                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7416             (const_int 8))
7417           (zero_extend:HI
7418             (truncate:QI
7419               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7420    (clobber (reg:CC FLAGS_REG))]
7421   "TARGET_QIMODE_MATH"
7422   "div{b}\t%2"
7423   [(set_attr "type" "idiv")
7424    (set_attr "mode" "QI")])
7426 ;; We cannot use div/idiv for double division, because it causes
7427 ;; "division by zero" on the overflow and that's not what we expect
7428 ;; from truncate.  Because true (non truncating) double division is
7429 ;; never generated, we can't create this insn anyway.
7431 ;(define_insn ""
7432 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7433 ;       (truncate:SI
7434 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7435 ;                  (zero_extend:DI
7436 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7437 ;   (set (match_operand:SI 3 "register_operand" "=d")
7438 ;       (truncate:SI
7439 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7440 ;   (clobber (reg:CC FLAGS_REG))]
7441 ;  ""
7442 ;  "div{l}\t{%2, %0|%0, %2}"
7443 ;  [(set_attr "type" "idiv")])
7445 ;;- Logical AND instructions
7447 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7448 ;; Note that this excludes ah.
7450 (define_expand "testsi_ccno_1"
7451   [(set (reg:CCNO FLAGS_REG)
7452         (compare:CCNO
7453           (and:SI (match_operand:SI 0 "nonimmediate_operand")
7454                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
7455           (const_int 0)))])
7457 (define_expand "testqi_ccz_1"
7458   [(set (reg:CCZ FLAGS_REG)
7459         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7460                              (match_operand:QI 1 "nonmemory_operand"))
7461                  (const_int 0)))])
7463 (define_expand "testdi_ccno_1"
7464   [(set (reg:CCNO FLAGS_REG)
7465         (compare:CCNO
7466           (and:DI (match_operand:DI 0 "nonimmediate_operand")
7467                   (match_operand:DI 1 "x86_64_szext_general_operand"))
7468           (const_int 0)))]
7469   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7471 (define_insn "*testdi_1"
7472   [(set (reg FLAGS_REG)
7473         (compare
7474          (and:DI
7475           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7476           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7477          (const_int 0)))]
7478   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7479    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7480   "@
7481    test{l}\t{%k1, %k0|%k0, %k1}
7482    test{l}\t{%k1, %k0|%k0, %k1}
7483    test{q}\t{%1, %0|%0, %1}
7484    test{q}\t{%1, %0|%0, %1}
7485    test{q}\t{%1, %0|%0, %1}"
7486   [(set_attr "type" "test")
7487    (set_attr "modrm" "0,1,0,1,1")
7488    (set_attr "mode" "SI,SI,DI,DI,DI")])
7490 (define_insn "*testqi_1_maybe_si"
7491   [(set (reg FLAGS_REG)
7492         (compare
7493           (and:QI
7494             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7495             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7496           (const_int 0)))]
7497    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7498     && ix86_match_ccmode (insn,
7499                          CONST_INT_P (operands[1])
7500                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7502   if (which_alternative == 3)
7503     {
7504       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7505         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7506       return "test{l}\t{%1, %k0|%k0, %1}";
7507     }
7508   return "test{b}\t{%1, %0|%0, %1}";
7510   [(set_attr "type" "test")
7511    (set_attr "modrm" "0,1,1,1")
7512    (set_attr "mode" "QI,QI,QI,SI")
7513    (set_attr "pent_pair" "uv,np,uv,np")])
7515 (define_insn "*test<mode>_1"
7516   [(set (reg FLAGS_REG)
7517         (compare
7518          (and:SWI124
7519           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7520           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7521          (const_int 0)))]
7522   "ix86_match_ccmode (insn, CCNOmode)
7523    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7524   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7525   [(set_attr "type" "test")
7526    (set_attr "modrm" "0,1,1")
7527    (set_attr "mode" "<MODE>")
7528    (set_attr "pent_pair" "uv,np,uv")])
7530 (define_expand "testqi_ext_ccno_0"
7531   [(set (reg:CCNO FLAGS_REG)
7532         (compare:CCNO
7533           (and:SI
7534             (zero_extract:SI
7535               (match_operand 0 "ext_register_operand")
7536               (const_int 8)
7537               (const_int 8))
7538             (match_operand 1 "const_int_operand"))
7539           (const_int 0)))])
7541 (define_insn "*testqi_ext_0"
7542   [(set (reg FLAGS_REG)
7543         (compare
7544           (and:SI
7545             (zero_extract:SI
7546               (match_operand 0 "ext_register_operand" "Q")
7547               (const_int 8)
7548               (const_int 8))
7549             (match_operand 1 "const_int_operand" "n"))
7550           (const_int 0)))]
7551   "ix86_match_ccmode (insn, CCNOmode)"
7552   "test{b}\t{%1, %h0|%h0, %1}"
7553   [(set_attr "type" "test")
7554    (set_attr "mode" "QI")
7555    (set_attr "length_immediate" "1")
7556    (set_attr "modrm" "1")
7557    (set_attr "pent_pair" "np")])
7559 (define_insn "*testqi_ext_1_rex64"
7560   [(set (reg FLAGS_REG)
7561         (compare
7562           (and:SI
7563             (zero_extract:SI
7564               (match_operand 0 "ext_register_operand" "Q")
7565               (const_int 8)
7566               (const_int 8))
7567             (zero_extend:SI
7568               (match_operand:QI 1 "register_operand" "Q")))
7569           (const_int 0)))]
7570   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7571   "test{b}\t{%1, %h0|%h0, %1}"
7572   [(set_attr "type" "test")
7573    (set_attr "mode" "QI")])
7575 (define_insn "*testqi_ext_1"
7576   [(set (reg FLAGS_REG)
7577         (compare
7578           (and:SI
7579             (zero_extract:SI
7580               (match_operand 0 "ext_register_operand" "Q")
7581               (const_int 8)
7582               (const_int 8))
7583             (zero_extend:SI
7584               (match_operand:QI 1 "general_operand" "Qm")))
7585           (const_int 0)))]
7586   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7587   "test{b}\t{%1, %h0|%h0, %1}"
7588   [(set_attr "type" "test")
7589    (set_attr "mode" "QI")])
7591 (define_insn "*testqi_ext_2"
7592   [(set (reg FLAGS_REG)
7593         (compare
7594           (and:SI
7595             (zero_extract:SI
7596               (match_operand 0 "ext_register_operand" "Q")
7597               (const_int 8)
7598               (const_int 8))
7599             (zero_extract:SI
7600               (match_operand 1 "ext_register_operand" "Q")
7601               (const_int 8)
7602               (const_int 8)))
7603           (const_int 0)))]
7604   "ix86_match_ccmode (insn, CCNOmode)"
7605   "test{b}\t{%h1, %h0|%h0, %h1}"
7606   [(set_attr "type" "test")
7607    (set_attr "mode" "QI")])
7609 (define_insn "*testqi_ext_3_rex64"
7610   [(set (reg FLAGS_REG)
7611         (compare (zero_extract:DI
7612                    (match_operand 0 "nonimmediate_operand" "rm")
7613                    (match_operand:DI 1 "const_int_operand")
7614                    (match_operand:DI 2 "const_int_operand"))
7615                  (const_int 0)))]
7616   "TARGET_64BIT
7617    && ix86_match_ccmode (insn, CCNOmode)
7618    && INTVAL (operands[1]) > 0
7619    && INTVAL (operands[2]) >= 0
7620    /* Ensure that resulting mask is zero or sign extended operand.  */
7621    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7622        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7623            && INTVAL (operands[1]) > 32))
7624    && (GET_MODE (operands[0]) == SImode
7625        || GET_MODE (operands[0]) == DImode
7626        || GET_MODE (operands[0]) == HImode
7627        || GET_MODE (operands[0]) == QImode)"
7628   "#")
7630 ;; Combine likes to form bit extractions for some tests.  Humor it.
7631 (define_insn "*testqi_ext_3"
7632   [(set (reg FLAGS_REG)
7633         (compare (zero_extract:SI
7634                    (match_operand 0 "nonimmediate_operand" "rm")
7635                    (match_operand:SI 1 "const_int_operand")
7636                    (match_operand:SI 2 "const_int_operand"))
7637                  (const_int 0)))]
7638   "ix86_match_ccmode (insn, CCNOmode)
7639    && INTVAL (operands[1]) > 0
7640    && INTVAL (operands[2]) >= 0
7641    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7642    && (GET_MODE (operands[0]) == SImode
7643        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7644        || GET_MODE (operands[0]) == HImode
7645        || GET_MODE (operands[0]) == QImode)"
7646   "#")
7648 (define_split
7649   [(set (match_operand 0 "flags_reg_operand")
7650         (match_operator 1 "compare_operator"
7651           [(zero_extract
7652              (match_operand 2 "nonimmediate_operand")
7653              (match_operand 3 "const_int_operand")
7654              (match_operand 4 "const_int_operand"))
7655            (const_int 0)]))]
7656   "ix86_match_ccmode (insn, CCNOmode)"
7657   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7659   rtx val = operands[2];
7660   HOST_WIDE_INT len = INTVAL (operands[3]);
7661   HOST_WIDE_INT pos = INTVAL (operands[4]);
7662   HOST_WIDE_INT mask;
7663   enum machine_mode mode, submode;
7665   mode = GET_MODE (val);
7666   if (MEM_P (val))
7667     {
7668       /* ??? Combine likes to put non-volatile mem extractions in QImode
7669          no matter the size of the test.  So find a mode that works.  */
7670       if (! MEM_VOLATILE_P (val))
7671         {
7672           mode = smallest_mode_for_size (pos + len, MODE_INT);
7673           val = adjust_address (val, mode, 0);
7674         }
7675     }
7676   else if (GET_CODE (val) == SUBREG
7677            && (submode = GET_MODE (SUBREG_REG (val)),
7678                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7679            && pos + len <= GET_MODE_BITSIZE (submode)
7680            && GET_MODE_CLASS (submode) == MODE_INT)
7681     {
7682       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7683       mode = submode;
7684       val = SUBREG_REG (val);
7685     }
7686   else if (mode == HImode && pos + len <= 8)
7687     {
7688       /* Small HImode tests can be converted to QImode.  */
7689       mode = QImode;
7690       val = gen_lowpart (QImode, val);
7691     }
7693   if (len == HOST_BITS_PER_WIDE_INT)
7694     mask = -1;
7695   else
7696     mask = ((HOST_WIDE_INT)1 << len) - 1;
7697   mask <<= pos;
7699   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7702 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7703 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7704 ;; this is relatively important trick.
7705 ;; Do the conversion only post-reload to avoid limiting of the register class
7706 ;; to QI regs.
7707 (define_split
7708   [(set (match_operand 0 "flags_reg_operand")
7709         (match_operator 1 "compare_operator"
7710           [(and (match_operand 2 "register_operand")
7711                 (match_operand 3 "const_int_operand"))
7712            (const_int 0)]))]
7713    "reload_completed
7714     && QI_REG_P (operands[2])
7715     && GET_MODE (operands[2]) != QImode
7716     && ((ix86_match_ccmode (insn, CCZmode)
7717          && !(INTVAL (operands[3]) & ~(255 << 8)))
7718         || (ix86_match_ccmode (insn, CCNOmode)
7719             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7720   [(set (match_dup 0)
7721         (match_op_dup 1
7722           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7723                    (match_dup 3))
7724            (const_int 0)]))]
7726   operands[2] = gen_lowpart (SImode, operands[2]);
7727   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7730 (define_split
7731   [(set (match_operand 0 "flags_reg_operand")
7732         (match_operator 1 "compare_operator"
7733           [(and (match_operand 2 "nonimmediate_operand")
7734                 (match_operand 3 "const_int_operand"))
7735            (const_int 0)]))]
7736    "reload_completed
7737     && GET_MODE (operands[2]) != QImode
7738     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7739     && ((ix86_match_ccmode (insn, CCZmode)
7740          && !(INTVAL (operands[3]) & ~255))
7741         || (ix86_match_ccmode (insn, CCNOmode)
7742             && !(INTVAL (operands[3]) & ~127)))"
7743   [(set (match_dup 0)
7744         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7745                          (const_int 0)]))]
7747   operands[2] = gen_lowpart (QImode, operands[2]);
7748   operands[3] = gen_lowpart (QImode, operands[3]);
7751 ;; %%% This used to optimize known byte-wide and operations to memory,
7752 ;; and sometimes to QImode registers.  If this is considered useful,
7753 ;; it should be done with splitters.
7755 (define_expand "and<mode>3"
7756   [(set (match_operand:SWIM 0 "nonimmediate_operand")
7757         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7758                   (match_operand:SWIM 2 "<general_szext_operand>")))]
7759   ""
7761   enum machine_mode mode = <MODE>mode;
7762   rtx (*insn) (rtx, rtx);
7764   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7765     {
7766       HOST_WIDE_INT ival = INTVAL (operands[2]);
7768       if (ival == (HOST_WIDE_INT) 0xffffffff)
7769         mode = SImode;
7770       else if (ival == 0xffff)
7771         mode = HImode;
7772       else if (ival == 0xff)
7773         mode = QImode;
7774       }
7776   if (mode == <MODE>mode)
7777     {
7778       ix86_expand_binary_operator (AND, <MODE>mode, operands);
7779       DONE;
7780     }
7782   if (<MODE>mode == DImode)
7783     insn = (mode == SImode)
7784            ? gen_zero_extendsidi2
7785            : (mode == HImode)
7786            ? gen_zero_extendhidi2
7787            : gen_zero_extendqidi2;
7788   else if (<MODE>mode == SImode)
7789     insn = (mode == HImode)
7790            ? gen_zero_extendhisi2
7791            : gen_zero_extendqisi2;
7792   else if (<MODE>mode == HImode)
7793     insn = gen_zero_extendqihi2;
7794   else
7795     gcc_unreachable ();
7797   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7798   DONE;
7801 (define_insn "*anddi_1"
7802   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7803         (and:DI
7804          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7805          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7806    (clobber (reg:CC FLAGS_REG))]
7807   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7809   switch (get_attr_type (insn))
7810     {
7811     case TYPE_IMOVX:
7812       return "#";
7814     default:
7815       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7816       if (get_attr_mode (insn) == MODE_SI)
7817         return "and{l}\t{%k2, %k0|%k0, %k2}";
7818       else
7819         return "and{q}\t{%2, %0|%0, %2}";
7820     }
7822   [(set_attr "type" "alu,alu,alu,imovx")
7823    (set_attr "length_immediate" "*,*,*,0")
7824    (set (attr "prefix_rex")
7825      (if_then_else
7826        (and (eq_attr "type" "imovx")
7827             (and (match_test "INTVAL (operands[2]) == 0xff")
7828                  (match_operand 1 "ext_QIreg_operand")))
7829        (const_string "1")
7830        (const_string "*")))
7831    (set_attr "mode" "SI,DI,DI,SI")])
7833 (define_insn "*andsi_1"
7834   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7835         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7836                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7837    (clobber (reg:CC FLAGS_REG))]
7838   "ix86_binary_operator_ok (AND, SImode, operands)"
7840   switch (get_attr_type (insn))
7841     {
7842     case TYPE_IMOVX:
7843       return "#";
7845     default:
7846       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7847       return "and{l}\t{%2, %0|%0, %2}";
7848     }
7850   [(set_attr "type" "alu,alu,imovx")
7851    (set (attr "prefix_rex")
7852      (if_then_else
7853        (and (eq_attr "type" "imovx")
7854             (and (match_test "INTVAL (operands[2]) == 0xff")
7855                  (match_operand 1 "ext_QIreg_operand")))
7856        (const_string "1")
7857        (const_string "*")))
7858    (set_attr "length_immediate" "*,*,0")
7859    (set_attr "mode" "SI")])
7861 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7862 (define_insn "*andsi_1_zext"
7863   [(set (match_operand:DI 0 "register_operand" "=r")
7864         (zero_extend:DI
7865           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7866                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7867    (clobber (reg:CC FLAGS_REG))]
7868   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7869   "and{l}\t{%2, %k0|%k0, %2}"
7870   [(set_attr "type" "alu")
7871    (set_attr "mode" "SI")])
7873 (define_insn "*andhi_1"
7874   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7875         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7876                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7877    (clobber (reg:CC FLAGS_REG))]
7878   "ix86_binary_operator_ok (AND, HImode, operands)"
7880   switch (get_attr_type (insn))
7881     {
7882     case TYPE_IMOVX:
7883       return "#";
7885     default:
7886       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7887       return "and{w}\t{%2, %0|%0, %2}";
7888     }
7890   [(set_attr "type" "alu,alu,imovx")
7891    (set_attr "length_immediate" "*,*,0")
7892    (set (attr "prefix_rex")
7893      (if_then_else
7894        (and (eq_attr "type" "imovx")
7895             (match_operand 1 "ext_QIreg_operand"))
7896        (const_string "1")
7897        (const_string "*")))
7898    (set_attr "mode" "HI,HI,SI")])
7900 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7901 (define_insn "*andqi_1"
7902   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7903         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7904                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7905    (clobber (reg:CC FLAGS_REG))]
7906   "ix86_binary_operator_ok (AND, QImode, operands)"
7907   "@
7908    and{b}\t{%2, %0|%0, %2}
7909    and{b}\t{%2, %0|%0, %2}
7910    and{l}\t{%k2, %k0|%k0, %k2}"
7911   [(set_attr "type" "alu")
7912    (set_attr "mode" "QI,QI,SI")])
7914 (define_insn "*andqi_1_slp"
7915   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7916         (and:QI (match_dup 0)
7917                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7918    (clobber (reg:CC FLAGS_REG))]
7919   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7920    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7921   "and{b}\t{%1, %0|%0, %1}"
7922   [(set_attr "type" "alu1")
7923    (set_attr "mode" "QI")])
7925 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7926 (define_split
7927   [(set (match_operand:DI 0 "register_operand")
7928         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7929                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7930    (clobber (reg:CC FLAGS_REG))]
7931   "TARGET_64BIT"
7932   [(parallel [(set (match_dup 0)
7933                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7934               (clobber (reg:CC FLAGS_REG))])]
7935   "operands[2] = gen_lowpart (SImode, operands[2]);")
7937 (define_split
7938   [(set (match_operand:SWI248 0 "register_operand")
7939         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7940                     (match_operand:SWI248 2 "const_int_operand")))
7941    (clobber (reg:CC FLAGS_REG))]
7942   "reload_completed
7943    && true_regnum (operands[0]) != true_regnum (operands[1])"
7944   [(const_int 0)]
7946   HOST_WIDE_INT ival = INTVAL (operands[2]);
7947   enum machine_mode mode;
7948   rtx (*insn) (rtx, rtx);
7950   if (ival == (HOST_WIDE_INT) 0xffffffff)
7951     mode = SImode;
7952   else if (ival == 0xffff)
7953     mode = HImode;
7954   else
7955     {
7956       gcc_assert (ival == 0xff);
7957       mode = QImode;
7958     }
7960   if (<MODE>mode == DImode)
7961     insn = (mode == SImode)
7962            ? gen_zero_extendsidi2
7963            : (mode == HImode)
7964            ? gen_zero_extendhidi2
7965            : gen_zero_extendqidi2;
7966   else
7967     {
7968       if (<MODE>mode != SImode)
7969         /* Zero extend to SImode to avoid partial register stalls.  */
7970         operands[0] = gen_lowpart (SImode, operands[0]);
7972       insn = (mode == HImode)
7973              ? gen_zero_extendhisi2
7974              : gen_zero_extendqisi2;
7975     }
7976   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7977   DONE;
7980 (define_split
7981   [(set (match_operand 0 "register_operand")
7982         (and (match_dup 0)
7983              (const_int -65536)))
7984    (clobber (reg:CC FLAGS_REG))]
7985   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7986     || optimize_function_for_size_p (cfun)"
7987   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7988   "operands[1] = gen_lowpart (HImode, operands[0]);")
7990 (define_split
7991   [(set (match_operand 0 "ext_register_operand")
7992         (and (match_dup 0)
7993              (const_int -256)))
7994    (clobber (reg:CC FLAGS_REG))]
7995   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7996    && reload_completed"
7997   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7998   "operands[1] = gen_lowpart (QImode, operands[0]);")
8000 (define_split
8001   [(set (match_operand 0 "ext_register_operand")
8002         (and (match_dup 0)
8003              (const_int -65281)))
8004    (clobber (reg:CC FLAGS_REG))]
8005   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8006    && reload_completed"
8007   [(parallel [(set (zero_extract:SI (match_dup 0)
8008                                     (const_int 8)
8009                                     (const_int 8))
8010                    (xor:SI
8011                      (zero_extract:SI (match_dup 0)
8012                                       (const_int 8)
8013                                       (const_int 8))
8014                      (zero_extract:SI (match_dup 0)
8015                                       (const_int 8)
8016                                       (const_int 8))))
8017               (clobber (reg:CC FLAGS_REG))])]
8018   "operands[0] = gen_lowpart (SImode, operands[0]);")
8020 (define_insn "*anddi_2"
8021   [(set (reg FLAGS_REG)
8022         (compare
8023          (and:DI
8024           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8025           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8026          (const_int 0)))
8027    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8028         (and:DI (match_dup 1) (match_dup 2)))]
8029   "TARGET_64BIT
8030    && ix86_match_ccmode
8031         (insn,
8032          /* If we are going to emit andl instead of andq, and the operands[2]
8033             constant might have the SImode sign bit set, make sure the sign
8034             flag isn't tested, because the instruction will set the sign flag
8035             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
8036             conservatively assume it might have bit 31 set.  */
8037          (satisfies_constraint_Z (operands[2])
8038           && (!CONST_INT_P (operands[2])
8039               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8040          ? CCZmode : CCNOmode)
8041    && ix86_binary_operator_ok (AND, DImode, operands)"
8042   "@
8043    and{l}\t{%k2, %k0|%k0, %k2}
8044    and{q}\t{%2, %0|%0, %2}
8045    and{q}\t{%2, %0|%0, %2}"
8046   [(set_attr "type" "alu")
8047    (set_attr "mode" "SI,DI,DI")])
8049 (define_insn "*andqi_2_maybe_si"
8050   [(set (reg FLAGS_REG)
8051         (compare (and:QI
8052                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8053                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8054                  (const_int 0)))
8055    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8056         (and:QI (match_dup 1) (match_dup 2)))]
8057   "ix86_binary_operator_ok (AND, QImode, operands)
8058    && ix86_match_ccmode (insn,
8059                          CONST_INT_P (operands[2])
8060                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8062   if (which_alternative == 2)
8063     {
8064       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8065         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8066       return "and{l}\t{%2, %k0|%k0, %2}";
8067     }
8068   return "and{b}\t{%2, %0|%0, %2}";
8070   [(set_attr "type" "alu")
8071    (set_attr "mode" "QI,QI,SI")])
8073 (define_insn "*and<mode>_2"
8074   [(set (reg FLAGS_REG)
8075         (compare (and:SWI124
8076                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8077                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8078                  (const_int 0)))
8079    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8080         (and:SWI124 (match_dup 1) (match_dup 2)))]
8081   "ix86_match_ccmode (insn, CCNOmode)
8082    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8083   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8084   [(set_attr "type" "alu")
8085    (set_attr "mode" "<MODE>")])
8087 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8088 (define_insn "*andsi_2_zext"
8089   [(set (reg FLAGS_REG)
8090         (compare (and:SI
8091                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8092                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
8093                  (const_int 0)))
8094    (set (match_operand:DI 0 "register_operand" "=r")
8095         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8096   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8097    && ix86_binary_operator_ok (AND, SImode, operands)"
8098   "and{l}\t{%2, %k0|%k0, %2}"
8099   [(set_attr "type" "alu")
8100    (set_attr "mode" "SI")])
8102 (define_insn "*andqi_2_slp"
8103   [(set (reg FLAGS_REG)
8104         (compare (and:QI
8105                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8106                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8107                  (const_int 0)))
8108    (set (strict_low_part (match_dup 0))
8109         (and:QI (match_dup 0) (match_dup 1)))]
8110   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8111    && ix86_match_ccmode (insn, CCNOmode)
8112    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8113   "and{b}\t{%1, %0|%0, %1}"
8114   [(set_attr "type" "alu1")
8115    (set_attr "mode" "QI")])
8117 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8118 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8119 ;; for a QImode operand, which of course failed.
8120 (define_insn "andqi_ext_0"
8121   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8122                          (const_int 8)
8123                          (const_int 8))
8124         (and:SI
8125           (zero_extract:SI
8126             (match_operand 1 "ext_register_operand" "0")
8127             (const_int 8)
8128             (const_int 8))
8129           (match_operand 2 "const_int_operand" "n")))
8130    (clobber (reg:CC FLAGS_REG))]
8131   ""
8132   "and{b}\t{%2, %h0|%h0, %2}"
8133   [(set_attr "type" "alu")
8134    (set_attr "length_immediate" "1")
8135    (set_attr "modrm" "1")
8136    (set_attr "mode" "QI")])
8138 ;; Generated by peephole translating test to and.  This shows up
8139 ;; often in fp comparisons.
8140 (define_insn "*andqi_ext_0_cc"
8141   [(set (reg FLAGS_REG)
8142         (compare
8143           (and:SI
8144             (zero_extract:SI
8145               (match_operand 1 "ext_register_operand" "0")
8146               (const_int 8)
8147               (const_int 8))
8148             (match_operand 2 "const_int_operand" "n"))
8149           (const_int 0)))
8150    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8151                          (const_int 8)
8152                          (const_int 8))
8153         (and:SI
8154           (zero_extract:SI
8155             (match_dup 1)
8156             (const_int 8)
8157             (const_int 8))
8158           (match_dup 2)))]
8159   "ix86_match_ccmode (insn, CCNOmode)"
8160   "and{b}\t{%2, %h0|%h0, %2}"
8161   [(set_attr "type" "alu")
8162    (set_attr "length_immediate" "1")
8163    (set_attr "modrm" "1")
8164    (set_attr "mode" "QI")])
8166 (define_insn "*andqi_ext_1_rex64"
8167   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8168                          (const_int 8)
8169                          (const_int 8))
8170         (and:SI
8171           (zero_extract:SI
8172             (match_operand 1 "ext_register_operand" "0")
8173             (const_int 8)
8174             (const_int 8))
8175           (zero_extend:SI
8176             (match_operand 2 "ext_register_operand" "Q"))))
8177    (clobber (reg:CC FLAGS_REG))]
8178   "TARGET_64BIT"
8179   "and{b}\t{%2, %h0|%h0, %2}"
8180   [(set_attr "type" "alu")
8181    (set_attr "length_immediate" "0")
8182    (set_attr "mode" "QI")])
8184 (define_insn "*andqi_ext_1"
8185   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8186                          (const_int 8)
8187                          (const_int 8))
8188         (and:SI
8189           (zero_extract:SI
8190             (match_operand 1 "ext_register_operand" "0")
8191             (const_int 8)
8192             (const_int 8))
8193           (zero_extend:SI
8194             (match_operand:QI 2 "general_operand" "Qm"))))
8195    (clobber (reg:CC FLAGS_REG))]
8196   "!TARGET_64BIT"
8197   "and{b}\t{%2, %h0|%h0, %2}"
8198   [(set_attr "type" "alu")
8199    (set_attr "length_immediate" "0")
8200    (set_attr "mode" "QI")])
8202 (define_insn "*andqi_ext_2"
8203   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8204                          (const_int 8)
8205                          (const_int 8))
8206         (and:SI
8207           (zero_extract:SI
8208             (match_operand 1 "ext_register_operand" "%0")
8209             (const_int 8)
8210             (const_int 8))
8211           (zero_extract:SI
8212             (match_operand 2 "ext_register_operand" "Q")
8213             (const_int 8)
8214             (const_int 8))))
8215    (clobber (reg:CC FLAGS_REG))]
8216   ""
8217   "and{b}\t{%h2, %h0|%h0, %h2}"
8218   [(set_attr "type" "alu")
8219    (set_attr "length_immediate" "0")
8220    (set_attr "mode" "QI")])
8222 ;; Convert wide AND instructions with immediate operand to shorter QImode
8223 ;; equivalents when possible.
8224 ;; Don't do the splitting with memory operands, since it introduces risk
8225 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8226 ;; for size, but that can (should?) be handled by generic code instead.
8227 (define_split
8228   [(set (match_operand 0 "register_operand")
8229         (and (match_operand 1 "register_operand")
8230              (match_operand 2 "const_int_operand")))
8231    (clobber (reg:CC FLAGS_REG))]
8232    "reload_completed
8233     && QI_REG_P (operands[0])
8234     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8235     && !(~INTVAL (operands[2]) & ~(255 << 8))
8236     && GET_MODE (operands[0]) != QImode"
8237   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8238                    (and:SI (zero_extract:SI (match_dup 1)
8239                                             (const_int 8) (const_int 8))
8240                            (match_dup 2)))
8241               (clobber (reg:CC FLAGS_REG))])]
8243   operands[0] = gen_lowpart (SImode, operands[0]);
8244   operands[1] = gen_lowpart (SImode, operands[1]);
8245   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8248 ;; Since AND can be encoded with sign extended immediate, this is only
8249 ;; profitable when 7th bit is not set.
8250 (define_split
8251   [(set (match_operand 0 "register_operand")
8252         (and (match_operand 1 "general_operand")
8253              (match_operand 2 "const_int_operand")))
8254    (clobber (reg:CC FLAGS_REG))]
8255    "reload_completed
8256     && ANY_QI_REG_P (operands[0])
8257     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8258     && !(~INTVAL (operands[2]) & ~255)
8259     && !(INTVAL (operands[2]) & 128)
8260     && GET_MODE (operands[0]) != QImode"
8261   [(parallel [(set (strict_low_part (match_dup 0))
8262                    (and:QI (match_dup 1)
8263                            (match_dup 2)))
8264               (clobber (reg:CC FLAGS_REG))])]
8266   operands[0] = gen_lowpart (QImode, operands[0]);
8267   operands[1] = gen_lowpart (QImode, operands[1]);
8268   operands[2] = gen_lowpart (QImode, operands[2]);
8271 ;; Logical inclusive and exclusive OR instructions
8273 ;; %%% This used to optimize known byte-wide and operations to memory.
8274 ;; If this is considered useful, it should be done with splitters.
8276 (define_expand "<code><mode>3"
8277   [(set (match_operand:SWIM 0 "nonimmediate_operand")
8278         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8279                      (match_operand:SWIM 2 "<general_operand>")))]
8280   ""
8281   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8283 (define_insn "*<code><mode>_1"
8284   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8285         (any_or:SWI248
8286          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8287          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8288    (clobber (reg:CC FLAGS_REG))]
8289   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8290   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8291   [(set_attr "type" "alu")
8292    (set_attr "mode" "<MODE>")])
8294 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8295 (define_insn "*<code>qi_1"
8296   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8297         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8298                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8299    (clobber (reg:CC FLAGS_REG))]
8300   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8301   "@
8302    <logic>{b}\t{%2, %0|%0, %2}
8303    <logic>{b}\t{%2, %0|%0, %2}
8304    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8305   [(set_attr "type" "alu")
8306    (set_attr "mode" "QI,QI,SI")])
8308 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8309 (define_insn "*<code>si_1_zext"
8310   [(set (match_operand:DI 0 "register_operand" "=r")
8311         (zero_extend:DI
8312          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8313                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8314    (clobber (reg:CC FLAGS_REG))]
8315   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8316   "<logic>{l}\t{%2, %k0|%k0, %2}"
8317   [(set_attr "type" "alu")
8318    (set_attr "mode" "SI")])
8320 (define_insn "*<code>si_1_zext_imm"
8321   [(set (match_operand:DI 0 "register_operand" "=r")
8322         (any_or:DI
8323          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8324          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8325    (clobber (reg:CC FLAGS_REG))]
8326   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8327   "<logic>{l}\t{%2, %k0|%k0, %2}"
8328   [(set_attr "type" "alu")
8329    (set_attr "mode" "SI")])
8331 (define_insn "*<code>qi_1_slp"
8332   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8333         (any_or:QI (match_dup 0)
8334                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8335    (clobber (reg:CC FLAGS_REG))]
8336   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8337    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8338   "<logic>{b}\t{%1, %0|%0, %1}"
8339   [(set_attr "type" "alu1")
8340    (set_attr "mode" "QI")])
8342 (define_insn "*<code><mode>_2"
8343   [(set (reg FLAGS_REG)
8344         (compare (any_or:SWI
8345                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8346                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8347                  (const_int 0)))
8348    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8349         (any_or:SWI (match_dup 1) (match_dup 2)))]
8350   "ix86_match_ccmode (insn, CCNOmode)
8351    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8352   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8353   [(set_attr "type" "alu")
8354    (set_attr "mode" "<MODE>")])
8356 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8357 ;; ??? Special case for immediate operand is missing - it is tricky.
8358 (define_insn "*<code>si_2_zext"
8359   [(set (reg FLAGS_REG)
8360         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8361                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8362                  (const_int 0)))
8363    (set (match_operand:DI 0 "register_operand" "=r")
8364         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8365   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8366    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8367   "<logic>{l}\t{%2, %k0|%k0, %2}"
8368   [(set_attr "type" "alu")
8369    (set_attr "mode" "SI")])
8371 (define_insn "*<code>si_2_zext_imm"
8372   [(set (reg FLAGS_REG)
8373         (compare (any_or:SI
8374                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8375                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8376                  (const_int 0)))
8377    (set (match_operand:DI 0 "register_operand" "=r")
8378         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8379   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8380    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8381   "<logic>{l}\t{%2, %k0|%k0, %2}"
8382   [(set_attr "type" "alu")
8383    (set_attr "mode" "SI")])
8385 (define_insn "*<code>qi_2_slp"
8386   [(set (reg FLAGS_REG)
8387         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8388                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8389                  (const_int 0)))
8390    (set (strict_low_part (match_dup 0))
8391         (any_or:QI (match_dup 0) (match_dup 1)))]
8392   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8393    && ix86_match_ccmode (insn, CCNOmode)
8394    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8395   "<logic>{b}\t{%1, %0|%0, %1}"
8396   [(set_attr "type" "alu1")
8397    (set_attr "mode" "QI")])
8399 (define_insn "*<code><mode>_3"
8400   [(set (reg FLAGS_REG)
8401         (compare (any_or:SWI
8402                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8403                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8404                  (const_int 0)))
8405    (clobber (match_scratch:SWI 0 "=<r>"))]
8406   "ix86_match_ccmode (insn, CCNOmode)
8407    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8408   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8409   [(set_attr "type" "alu")
8410    (set_attr "mode" "<MODE>")])
8412 (define_insn "*<code>qi_ext_0"
8413   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8414                          (const_int 8)
8415                          (const_int 8))
8416         (any_or:SI
8417           (zero_extract:SI
8418             (match_operand 1 "ext_register_operand" "0")
8419             (const_int 8)
8420             (const_int 8))
8421           (match_operand 2 "const_int_operand" "n")))
8422    (clobber (reg:CC FLAGS_REG))]
8423   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8424   "<logic>{b}\t{%2, %h0|%h0, %2}"
8425   [(set_attr "type" "alu")
8426    (set_attr "length_immediate" "1")
8427    (set_attr "modrm" "1")
8428    (set_attr "mode" "QI")])
8430 (define_insn "*<code>qi_ext_1_rex64"
8431   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8432                          (const_int 8)
8433                          (const_int 8))
8434         (any_or:SI
8435           (zero_extract:SI
8436             (match_operand 1 "ext_register_operand" "0")
8437             (const_int 8)
8438             (const_int 8))
8439           (zero_extend:SI
8440             (match_operand 2 "ext_register_operand" "Q"))))
8441    (clobber (reg:CC FLAGS_REG))]
8442   "TARGET_64BIT
8443    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8444   "<logic>{b}\t{%2, %h0|%h0, %2}"
8445   [(set_attr "type" "alu")
8446    (set_attr "length_immediate" "0")
8447    (set_attr "mode" "QI")])
8449 (define_insn "*<code>qi_ext_1"
8450   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8451                          (const_int 8)
8452                          (const_int 8))
8453         (any_or:SI
8454           (zero_extract:SI
8455             (match_operand 1 "ext_register_operand" "0")
8456             (const_int 8)
8457             (const_int 8))
8458           (zero_extend:SI
8459             (match_operand:QI 2 "general_operand" "Qm"))))
8460    (clobber (reg:CC FLAGS_REG))]
8461   "!TARGET_64BIT
8462    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8463   "<logic>{b}\t{%2, %h0|%h0, %2}"
8464   [(set_attr "type" "alu")
8465    (set_attr "length_immediate" "0")
8466    (set_attr "mode" "QI")])
8468 (define_insn "*<code>qi_ext_2"
8469   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8470                          (const_int 8)
8471                          (const_int 8))
8472         (any_or:SI
8473           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8474                            (const_int 8)
8475                            (const_int 8))
8476           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8477                            (const_int 8)
8478                            (const_int 8))))
8479    (clobber (reg:CC FLAGS_REG))]
8480   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8481   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8482   [(set_attr "type" "alu")
8483    (set_attr "length_immediate" "0")
8484    (set_attr "mode" "QI")])
8486 (define_split
8487   [(set (match_operand 0 "register_operand")
8488         (any_or (match_operand 1 "register_operand")
8489                 (match_operand 2 "const_int_operand")))
8490    (clobber (reg:CC FLAGS_REG))]
8491    "reload_completed
8492     && QI_REG_P (operands[0])
8493     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8494     && !(INTVAL (operands[2]) & ~(255 << 8))
8495     && GET_MODE (operands[0]) != QImode"
8496   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8497                    (any_or:SI (zero_extract:SI (match_dup 1)
8498                                                (const_int 8) (const_int 8))
8499                               (match_dup 2)))
8500               (clobber (reg:CC FLAGS_REG))])]
8502   operands[0] = gen_lowpart (SImode, operands[0]);
8503   operands[1] = gen_lowpart (SImode, operands[1]);
8504   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8507 ;; Since OR can be encoded with sign extended immediate, this is only
8508 ;; profitable when 7th bit is set.
8509 (define_split
8510   [(set (match_operand 0 "register_operand")
8511         (any_or (match_operand 1 "general_operand")
8512                 (match_operand 2 "const_int_operand")))
8513    (clobber (reg:CC FLAGS_REG))]
8514    "reload_completed
8515     && ANY_QI_REG_P (operands[0])
8516     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8517     && !(INTVAL (operands[2]) & ~255)
8518     && (INTVAL (operands[2]) & 128)
8519     && GET_MODE (operands[0]) != QImode"
8520   [(parallel [(set (strict_low_part (match_dup 0))
8521                    (any_or:QI (match_dup 1)
8522                               (match_dup 2)))
8523               (clobber (reg:CC FLAGS_REG))])]
8525   operands[0] = gen_lowpart (QImode, operands[0]);
8526   operands[1] = gen_lowpart (QImode, operands[1]);
8527   operands[2] = gen_lowpart (QImode, operands[2]);
8530 (define_expand "xorqi_cc_ext_1"
8531   [(parallel [
8532      (set (reg:CCNO FLAGS_REG)
8533           (compare:CCNO
8534             (xor:SI
8535               (zero_extract:SI
8536                 (match_operand 1 "ext_register_operand")
8537                 (const_int 8)
8538                 (const_int 8))
8539               (match_operand:QI 2 "general_operand"))
8540             (const_int 0)))
8541      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8542                            (const_int 8)
8543                            (const_int 8))
8544           (xor:SI
8545             (zero_extract:SI
8546              (match_dup 1)
8547              (const_int 8)
8548              (const_int 8))
8549             (match_dup 2)))])])
8551 (define_insn "*xorqi_cc_ext_1_rex64"
8552   [(set (reg FLAGS_REG)
8553         (compare
8554           (xor:SI
8555             (zero_extract:SI
8556               (match_operand 1 "ext_register_operand" "0")
8557               (const_int 8)
8558               (const_int 8))
8559             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8560           (const_int 0)))
8561    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8562                          (const_int 8)
8563                          (const_int 8))
8564         (xor:SI
8565           (zero_extract:SI
8566            (match_dup 1)
8567            (const_int 8)
8568            (const_int 8))
8569           (match_dup 2)))]
8570   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8571   "xor{b}\t{%2, %h0|%h0, %2}"
8572   [(set_attr "type" "alu")
8573    (set_attr "modrm" "1")
8574    (set_attr "mode" "QI")])
8576 (define_insn "*xorqi_cc_ext_1"
8577   [(set (reg FLAGS_REG)
8578         (compare
8579           (xor:SI
8580             (zero_extract:SI
8581               (match_operand 1 "ext_register_operand" "0")
8582               (const_int 8)
8583               (const_int 8))
8584             (match_operand:QI 2 "general_operand" "qmn"))
8585           (const_int 0)))
8586    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8587                          (const_int 8)
8588                          (const_int 8))
8589         (xor:SI
8590           (zero_extract:SI
8591            (match_dup 1)
8592            (const_int 8)
8593            (const_int 8))
8594           (match_dup 2)))]
8595   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8596   "xor{b}\t{%2, %h0|%h0, %2}"
8597   [(set_attr "type" "alu")
8598    (set_attr "modrm" "1")
8599    (set_attr "mode" "QI")])
8601 ;; Negation instructions
8603 (define_expand "neg<mode>2"
8604   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8605         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8606   ""
8607   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8609 (define_insn_and_split "*neg<dwi>2_doubleword"
8610   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8611         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8612    (clobber (reg:CC FLAGS_REG))]
8613   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8614   "#"
8615   "reload_completed"
8616   [(parallel
8617     [(set (reg:CCZ FLAGS_REG)
8618           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8619      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8620    (parallel
8621     [(set (match_dup 2)
8622           (plus:DWIH (match_dup 3)
8623                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8624                                 (const_int 0))))
8625      (clobber (reg:CC FLAGS_REG))])
8626    (parallel
8627     [(set (match_dup 2)
8628           (neg:DWIH (match_dup 2)))
8629      (clobber (reg:CC FLAGS_REG))])]
8630   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8632 (define_insn "*neg<mode>2_1"
8633   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8634         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8635    (clobber (reg:CC FLAGS_REG))]
8636   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8637   "neg{<imodesuffix>}\t%0"
8638   [(set_attr "type" "negnot")
8639    (set_attr "mode" "<MODE>")])
8641 ;; Combine is quite creative about this pattern.
8642 (define_insn "*negsi2_1_zext"
8643   [(set (match_operand:DI 0 "register_operand" "=r")
8644         (lshiftrt:DI
8645           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8646                              (const_int 32)))
8647         (const_int 32)))
8648    (clobber (reg:CC FLAGS_REG))]
8649   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8650   "neg{l}\t%k0"
8651   [(set_attr "type" "negnot")
8652    (set_attr "mode" "SI")])
8654 ;; The problem with neg is that it does not perform (compare x 0),
8655 ;; it really performs (compare 0 x), which leaves us with the zero
8656 ;; flag being the only useful item.
8658 (define_insn "*neg<mode>2_cmpz"
8659   [(set (reg:CCZ FLAGS_REG)
8660         (compare:CCZ
8661           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8662                    (const_int 0)))
8663    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8664         (neg:SWI (match_dup 1)))]
8665   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8666   "neg{<imodesuffix>}\t%0"
8667   [(set_attr "type" "negnot")
8668    (set_attr "mode" "<MODE>")])
8670 (define_insn "*negsi2_cmpz_zext"
8671   [(set (reg:CCZ FLAGS_REG)
8672         (compare:CCZ
8673           (lshiftrt:DI
8674             (neg:DI (ashift:DI
8675                       (match_operand:DI 1 "register_operand" "0")
8676                       (const_int 32)))
8677             (const_int 32))
8678           (const_int 0)))
8679    (set (match_operand:DI 0 "register_operand" "=r")
8680         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8681                                         (const_int 32)))
8682                      (const_int 32)))]
8683   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8684   "neg{l}\t%k0"
8685   [(set_attr "type" "negnot")
8686    (set_attr "mode" "SI")])
8688 ;; Changing of sign for FP values is doable using integer unit too.
8690 (define_expand "<code><mode>2"
8691   [(set (match_operand:X87MODEF 0 "register_operand")
8692         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8693   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8694   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8696 (define_insn "*absneg<mode>2_mixed"
8697   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8698         (match_operator:MODEF 3 "absneg_operator"
8699           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8700    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8701    (clobber (reg:CC FLAGS_REG))]
8702   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8703   "#")
8705 (define_insn "*absneg<mode>2_sse"
8706   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8707         (match_operator:MODEF 3 "absneg_operator"
8708           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8709    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8710    (clobber (reg:CC FLAGS_REG))]
8711   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8712   "#")
8714 (define_insn "*absneg<mode>2_i387"
8715   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8716         (match_operator:X87MODEF 3 "absneg_operator"
8717           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8718    (use (match_operand 2))
8719    (clobber (reg:CC FLAGS_REG))]
8720   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8721   "#")
8723 (define_expand "<code>tf2"
8724   [(set (match_operand:TF 0 "register_operand")
8725         (absneg:TF (match_operand:TF 1 "register_operand")))]
8726   "TARGET_SSE"
8727   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8729 (define_insn "*absnegtf2_sse"
8730   [(set (match_operand:TF 0 "register_operand" "=x,x")
8731         (match_operator:TF 3 "absneg_operator"
8732           [(match_operand:TF 1 "register_operand" "0,x")]))
8733    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8734    (clobber (reg:CC FLAGS_REG))]
8735   "TARGET_SSE"
8736   "#")
8738 ;; Splitters for fp abs and neg.
8740 (define_split
8741   [(set (match_operand 0 "fp_register_operand")
8742         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8743    (use (match_operand 2))
8744    (clobber (reg:CC FLAGS_REG))]
8745   "reload_completed"
8746   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8748 (define_split
8749   [(set (match_operand 0 "register_operand")
8750         (match_operator 3 "absneg_operator"
8751           [(match_operand 1 "register_operand")]))
8752    (use (match_operand 2 "nonimmediate_operand"))
8753    (clobber (reg:CC FLAGS_REG))]
8754   "reload_completed && SSE_REG_P (operands[0])"
8755   [(set (match_dup 0) (match_dup 3))]
8757   enum machine_mode mode = GET_MODE (operands[0]);
8758   enum machine_mode vmode = GET_MODE (operands[2]);
8759   rtx tmp;
8761   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8762   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8763   if (operands_match_p (operands[0], operands[2]))
8764     {
8765       tmp = operands[1];
8766       operands[1] = operands[2];
8767       operands[2] = tmp;
8768     }
8769   if (GET_CODE (operands[3]) == ABS)
8770     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8771   else
8772     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8773   operands[3] = tmp;
8776 (define_split
8777   [(set (match_operand:SF 0 "register_operand")
8778         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8779    (use (match_operand:V4SF 2))
8780    (clobber (reg:CC FLAGS_REG))]
8781   "reload_completed"
8782   [(parallel [(set (match_dup 0) (match_dup 1))
8783               (clobber (reg:CC FLAGS_REG))])]
8785   rtx tmp;
8786   operands[0] = gen_lowpart (SImode, operands[0]);
8787   if (GET_CODE (operands[1]) == ABS)
8788     {
8789       tmp = gen_int_mode (0x7fffffff, SImode);
8790       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8791     }
8792   else
8793     {
8794       tmp = gen_int_mode (0x80000000, SImode);
8795       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8796     }
8797   operands[1] = tmp;
8800 (define_split
8801   [(set (match_operand:DF 0 "register_operand")
8802         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8803    (use (match_operand 2))
8804    (clobber (reg:CC FLAGS_REG))]
8805   "reload_completed"
8806   [(parallel [(set (match_dup 0) (match_dup 1))
8807               (clobber (reg:CC FLAGS_REG))])]
8809   rtx tmp;
8810   if (TARGET_64BIT)
8811     {
8812       tmp = gen_lowpart (DImode, operands[0]);
8813       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8814       operands[0] = tmp;
8816       if (GET_CODE (operands[1]) == ABS)
8817         tmp = const0_rtx;
8818       else
8819         tmp = gen_rtx_NOT (DImode, tmp);
8820     }
8821   else
8822     {
8823       operands[0] = gen_highpart (SImode, operands[0]);
8824       if (GET_CODE (operands[1]) == ABS)
8825         {
8826           tmp = gen_int_mode (0x7fffffff, SImode);
8827           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8828         }
8829       else
8830         {
8831           tmp = gen_int_mode (0x80000000, SImode);
8832           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8833         }
8834     }
8835   operands[1] = tmp;
8838 (define_split
8839   [(set (match_operand:XF 0 "register_operand")
8840         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8841    (use (match_operand 2))
8842    (clobber (reg:CC FLAGS_REG))]
8843   "reload_completed"
8844   [(parallel [(set (match_dup 0) (match_dup 1))
8845               (clobber (reg:CC FLAGS_REG))])]
8847   rtx tmp;
8848   operands[0] = gen_rtx_REG (SImode,
8849                              true_regnum (operands[0])
8850                              + (TARGET_64BIT ? 1 : 2));
8851   if (GET_CODE (operands[1]) == ABS)
8852     {
8853       tmp = GEN_INT (0x7fff);
8854       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8855     }
8856   else
8857     {
8858       tmp = GEN_INT (0x8000);
8859       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8860     }
8861   operands[1] = tmp;
8864 ;; Conditionalize these after reload. If they match before reload, we
8865 ;; lose the clobber and ability to use integer instructions.
8867 (define_insn "*<code><mode>2_1"
8868   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8869         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8870   "TARGET_80387
8871    && (reload_completed
8872        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8873   "f<absneg_mnemonic>"
8874   [(set_attr "type" "fsgn")
8875    (set_attr "mode" "<MODE>")])
8877 (define_insn "*<code>extendsfdf2"
8878   [(set (match_operand:DF 0 "register_operand" "=f")
8879         (absneg:DF (float_extend:DF
8880                      (match_operand:SF 1 "register_operand" "0"))))]
8881   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8882   "f<absneg_mnemonic>"
8883   [(set_attr "type" "fsgn")
8884    (set_attr "mode" "DF")])
8886 (define_insn "*<code>extendsfxf2"
8887   [(set (match_operand:XF 0 "register_operand" "=f")
8888         (absneg:XF (float_extend:XF
8889                      (match_operand:SF 1 "register_operand" "0"))))]
8890   "TARGET_80387"
8891   "f<absneg_mnemonic>"
8892   [(set_attr "type" "fsgn")
8893    (set_attr "mode" "XF")])
8895 (define_insn "*<code>extenddfxf2"
8896   [(set (match_operand:XF 0 "register_operand" "=f")
8897         (absneg:XF (float_extend:XF
8898                      (match_operand:DF 1 "register_operand" "0"))))]
8899   "TARGET_80387"
8900   "f<absneg_mnemonic>"
8901   [(set_attr "type" "fsgn")
8902    (set_attr "mode" "XF")])
8904 ;; Copysign instructions
8906 (define_mode_iterator CSGNMODE [SF DF TF])
8907 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8909 (define_expand "copysign<mode>3"
8910   [(match_operand:CSGNMODE 0 "register_operand")
8911    (match_operand:CSGNMODE 1 "nonmemory_operand")
8912    (match_operand:CSGNMODE 2 "register_operand")]
8913   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8914    || (TARGET_SSE && (<MODE>mode == TFmode))"
8915   "ix86_expand_copysign (operands); DONE;")
8917 (define_insn_and_split "copysign<mode>3_const"
8918   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8919         (unspec:CSGNMODE
8920           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8921            (match_operand:CSGNMODE 2 "register_operand" "0")
8922            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8923           UNSPEC_COPYSIGN))]
8924   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8925    || (TARGET_SSE && (<MODE>mode == TFmode))"
8926   "#"
8927   "&& reload_completed"
8928   [(const_int 0)]
8929   "ix86_split_copysign_const (operands); DONE;")
8931 (define_insn "copysign<mode>3_var"
8932   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8933         (unspec:CSGNMODE
8934           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8935            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8936            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8937            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8938           UNSPEC_COPYSIGN))
8939    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8940   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8941    || (TARGET_SSE && (<MODE>mode == TFmode))"
8942   "#")
8944 (define_split
8945   [(set (match_operand:CSGNMODE 0 "register_operand")
8946         (unspec:CSGNMODE
8947           [(match_operand:CSGNMODE 2 "register_operand")
8948            (match_operand:CSGNMODE 3 "register_operand")
8949            (match_operand:<CSGNVMODE> 4)
8950            (match_operand:<CSGNVMODE> 5)]
8951           UNSPEC_COPYSIGN))
8952    (clobber (match_scratch:<CSGNVMODE> 1))]
8953   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8954     || (TARGET_SSE && (<MODE>mode == TFmode)))
8955    && reload_completed"
8956   [(const_int 0)]
8957   "ix86_split_copysign_var (operands); DONE;")
8959 ;; One complement instructions
8961 (define_expand "one_cmpl<mode>2"
8962   [(set (match_operand:SWIM 0 "nonimmediate_operand")
8963         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8964   ""
8965   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8967 (define_insn "*one_cmpl<mode>2_1"
8968   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8969         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8970   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8971   "not{<imodesuffix>}\t%0"
8972   [(set_attr "type" "negnot")
8973    (set_attr "mode" "<MODE>")])
8975 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8976 (define_insn "*one_cmplqi2_1"
8977   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8978         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8979   "ix86_unary_operator_ok (NOT, QImode, operands)"
8980   "@
8981    not{b}\t%0
8982    not{l}\t%k0"
8983   [(set_attr "type" "negnot")
8984    (set_attr "mode" "QI,SI")])
8986 ;; ??? Currently never generated - xor is used instead.
8987 (define_insn "*one_cmplsi2_1_zext"
8988   [(set (match_operand:DI 0 "register_operand" "=r")
8989         (zero_extend:DI
8990           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8991   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8992   "not{l}\t%k0"
8993   [(set_attr "type" "negnot")
8994    (set_attr "mode" "SI")])
8996 (define_insn "*one_cmpl<mode>2_2"
8997   [(set (reg FLAGS_REG)
8998         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8999                  (const_int 0)))
9000    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9001         (not:SWI (match_dup 1)))]
9002   "ix86_match_ccmode (insn, CCNOmode)
9003    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9004   "#"
9005   [(set_attr "type" "alu1")
9006    (set_attr "mode" "<MODE>")])
9008 (define_split
9009   [(set (match_operand 0 "flags_reg_operand")
9010         (match_operator 2 "compare_operator"
9011           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9012            (const_int 0)]))
9013    (set (match_operand:SWI 1 "nonimmediate_operand")
9014         (not:SWI (match_dup 3)))]
9015   "ix86_match_ccmode (insn, CCNOmode)"
9016   [(parallel [(set (match_dup 0)
9017                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9018                                     (const_int 0)]))
9019               (set (match_dup 1)
9020                    (xor:SWI (match_dup 3) (const_int -1)))])])
9022 ;; ??? Currently never generated - xor is used instead.
9023 (define_insn "*one_cmplsi2_2_zext"
9024   [(set (reg FLAGS_REG)
9025         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9026                  (const_int 0)))
9027    (set (match_operand:DI 0 "register_operand" "=r")
9028         (zero_extend:DI (not:SI (match_dup 1))))]
9029   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9030    && ix86_unary_operator_ok (NOT, SImode, operands)"
9031   "#"
9032   [(set_attr "type" "alu1")
9033    (set_attr "mode" "SI")])
9035 (define_split
9036   [(set (match_operand 0 "flags_reg_operand")
9037         (match_operator 2 "compare_operator"
9038           [(not:SI (match_operand:SI 3 "register_operand"))
9039            (const_int 0)]))
9040    (set (match_operand:DI 1 "register_operand")
9041         (zero_extend:DI (not:SI (match_dup 3))))]
9042   "ix86_match_ccmode (insn, CCNOmode)"
9043   [(parallel [(set (match_dup 0)
9044                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9045                                     (const_int 0)]))
9046               (set (match_dup 1)
9047                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9049 ;; Shift instructions
9051 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9052 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9053 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9054 ;; from the assembler input.
9056 ;; This instruction shifts the target reg/mem as usual, but instead of
9057 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9058 ;; is a left shift double, bits are taken from the high order bits of
9059 ;; reg, else if the insn is a shift right double, bits are taken from the
9060 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9061 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9063 ;; Since sh[lr]d does not change the `reg' operand, that is done
9064 ;; separately, making all shifts emit pairs of shift double and normal
9065 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9066 ;; support a 63 bit shift, each shift where the count is in a reg expands
9067 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9069 ;; If the shift count is a constant, we need never emit more than one
9070 ;; shift pair, instead using moves and sign extension for counts greater
9071 ;; than 31.
9073 (define_expand "ashl<mode>3"
9074   [(set (match_operand:SDWIM 0 "<shift_operand>")
9075         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9076                       (match_operand:QI 2 "nonmemory_operand")))]
9077   ""
9078   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9080 (define_insn "*ashl<mode>3_doubleword"
9081   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9082         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9083                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9084    (clobber (reg:CC FLAGS_REG))]
9085   ""
9086   "#"
9087   [(set_attr "type" "multi")])
9089 (define_split
9090   [(set (match_operand:DWI 0 "register_operand")
9091         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9092                     (match_operand:QI 2 "nonmemory_operand")))
9093    (clobber (reg:CC FLAGS_REG))]
9094   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9095   [(const_int 0)]
9096   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9098 ;; By default we don't ask for a scratch register, because when DWImode
9099 ;; values are manipulated, registers are already at a premium.  But if
9100 ;; we have one handy, we won't turn it away.
9102 (define_peephole2
9103   [(match_scratch:DWIH 3 "r")
9104    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9105                    (ashift:<DWI>
9106                      (match_operand:<DWI> 1 "nonmemory_operand")
9107                      (match_operand:QI 2 "nonmemory_operand")))
9108               (clobber (reg:CC FLAGS_REG))])
9109    (match_dup 3)]
9110   "TARGET_CMOVE"
9111   [(const_int 0)]
9112   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9114 (define_insn "x86_64_shld"
9115   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9116         (ior:DI (ashift:DI (match_dup 0)
9117                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9118                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9119                   (minus:QI (const_int 64) (match_dup 2)))))
9120    (clobber (reg:CC FLAGS_REG))]
9121   "TARGET_64BIT"
9122   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9123   [(set_attr "type" "ishift")
9124    (set_attr "prefix_0f" "1")
9125    (set_attr "mode" "DI")
9126    (set_attr "athlon_decode" "vector")
9127    (set_attr "amdfam10_decode" "vector")
9128    (set_attr "bdver1_decode" "vector")])
9130 (define_insn "x86_shld"
9131   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9132         (ior:SI (ashift:SI (match_dup 0)
9133                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9134                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9135                   (minus:QI (const_int 32) (match_dup 2)))))
9136    (clobber (reg:CC FLAGS_REG))]
9137   ""
9138   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9139   [(set_attr "type" "ishift")
9140    (set_attr "prefix_0f" "1")
9141    (set_attr "mode" "SI")
9142    (set_attr "pent_pair" "np")
9143    (set_attr "athlon_decode" "vector")
9144    (set_attr "amdfam10_decode" "vector")
9145    (set_attr "bdver1_decode" "vector")])
9147 (define_expand "x86_shift<mode>_adj_1"
9148   [(set (reg:CCZ FLAGS_REG)
9149         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9150                              (match_dup 4))
9151                      (const_int 0)))
9152    (set (match_operand:SWI48 0 "register_operand")
9153         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9154                             (match_operand:SWI48 1 "register_operand")
9155                             (match_dup 0)))
9156    (set (match_dup 1)
9157         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9158                             (match_operand:SWI48 3 "register_operand")
9159                             (match_dup 1)))]
9160   "TARGET_CMOVE"
9161   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9163 (define_expand "x86_shift<mode>_adj_2"
9164   [(use (match_operand:SWI48 0 "register_operand"))
9165    (use (match_operand:SWI48 1 "register_operand"))
9166    (use (match_operand:QI 2 "register_operand"))]
9167   ""
9169   rtx label = gen_label_rtx ();
9170   rtx tmp;
9172   emit_insn (gen_testqi_ccz_1 (operands[2],
9173                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9175   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9176   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9177   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9178                               gen_rtx_LABEL_REF (VOIDmode, label),
9179                               pc_rtx);
9180   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9181   JUMP_LABEL (tmp) = label;
9183   emit_move_insn (operands[0], operands[1]);
9184   ix86_expand_clear (operands[1]);
9186   emit_label (label);
9187   LABEL_NUSES (label) = 1;
9189   DONE;
9192 ;; Avoid useless masking of count operand.
9193 (define_insn "*ashl<mode>3_mask"
9194   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9195         (ashift:SWI48
9196           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9197           (subreg:QI
9198             (and:SI
9199               (match_operand:SI 2 "register_operand" "c")
9200               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9201    (clobber (reg:CC FLAGS_REG))]
9202   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9203    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9204       == GET_MODE_BITSIZE (<MODE>mode)-1"
9206   return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9208   [(set_attr "type" "ishift")
9209    (set_attr "mode" "<MODE>")])
9211 (define_insn "*bmi2_ashl<mode>3_1"
9212   [(set (match_operand:SWI48 0 "register_operand" "=r")
9213         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9214                       (match_operand:SWI48 2 "register_operand" "r")))]
9215   "TARGET_BMI2"
9216   "shlx\t{%2, %1, %0|%0, %1, %2}"
9217   [(set_attr "type" "ishiftx")
9218    (set_attr "mode" "<MODE>")])
9220 (define_insn "*ashl<mode>3_1"
9221   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9222         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9223                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9224    (clobber (reg:CC FLAGS_REG))]
9225   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9227   switch (get_attr_type (insn))
9228     {
9229     case TYPE_LEA:
9230     case TYPE_ISHIFTX:
9231       return "#";
9233     case TYPE_ALU:
9234       gcc_assert (operands[2] == const1_rtx);
9235       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9236       return "add{<imodesuffix>}\t%0, %0";
9238     default:
9239       if (operands[2] == const1_rtx
9240           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9241         return "sal{<imodesuffix>}\t%0";
9242       else
9243         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9244     }
9246   [(set_attr "isa" "*,*,bmi2")
9247    (set (attr "type")
9248      (cond [(eq_attr "alternative" "1")
9249               (const_string "lea")
9250             (eq_attr "alternative" "2")
9251               (const_string "ishiftx")
9252             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9253                       (match_operand 0 "register_operand"))
9254                  (match_operand 2 "const1_operand"))
9255               (const_string "alu")
9256            ]
9257            (const_string "ishift")))
9258    (set (attr "length_immediate")
9259      (if_then_else
9260        (ior (eq_attr "type" "alu")
9261             (and (eq_attr "type" "ishift")
9262                  (and (match_operand 2 "const1_operand")
9263                       (ior (match_test "TARGET_SHIFT1")
9264                            (match_test "optimize_function_for_size_p (cfun)")))))
9265        (const_string "0")
9266        (const_string "*")))
9267    (set_attr "mode" "<MODE>")])
9269 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9270 (define_split
9271   [(set (match_operand:SWI48 0 "register_operand")
9272         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9273                       (match_operand:QI 2 "register_operand")))
9274    (clobber (reg:CC FLAGS_REG))]
9275   "TARGET_BMI2 && reload_completed"
9276   [(set (match_dup 0)
9277         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9278   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9280 (define_insn "*bmi2_ashlsi3_1_zext"
9281   [(set (match_operand:DI 0 "register_operand" "=r")
9282         (zero_extend:DI
9283           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9284                      (match_operand:SI 2 "register_operand" "r"))))]
9285   "TARGET_64BIT && TARGET_BMI2"
9286   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9287   [(set_attr "type" "ishiftx")
9288    (set_attr "mode" "SI")])
9290 (define_insn "*ashlsi3_1_zext"
9291   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9292         (zero_extend:DI
9293           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9294                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9295    (clobber (reg:CC FLAGS_REG))]
9296   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9298   switch (get_attr_type (insn))
9299     {
9300     case TYPE_LEA:
9301     case TYPE_ISHIFTX:
9302       return "#";
9304     case TYPE_ALU:
9305       gcc_assert (operands[2] == const1_rtx);
9306       return "add{l}\t%k0, %k0";
9308     default:
9309       if (operands[2] == const1_rtx
9310           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9311         return "sal{l}\t%k0";
9312       else
9313         return "sal{l}\t{%2, %k0|%k0, %2}";
9314     }
9316   [(set_attr "isa" "*,*,bmi2")
9317    (set (attr "type")
9318      (cond [(eq_attr "alternative" "1")
9319               (const_string "lea")
9320             (eq_attr "alternative" "2")
9321               (const_string "ishiftx")
9322             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9323                  (match_operand 2 "const1_operand"))
9324               (const_string "alu")
9325            ]
9326            (const_string "ishift")))
9327    (set (attr "length_immediate")
9328      (if_then_else
9329        (ior (eq_attr "type" "alu")
9330             (and (eq_attr "type" "ishift")
9331                  (and (match_operand 2 "const1_operand")
9332                       (ior (match_test "TARGET_SHIFT1")
9333                            (match_test "optimize_function_for_size_p (cfun)")))))
9334        (const_string "0")
9335        (const_string "*")))
9336    (set_attr "mode" "SI")])
9338 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9339 (define_split
9340   [(set (match_operand:DI 0 "register_operand")
9341         (zero_extend:DI
9342           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9343                      (match_operand:QI 2 "register_operand"))))
9344    (clobber (reg:CC FLAGS_REG))]
9345   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9346   [(set (match_dup 0)
9347         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9348   "operands[2] = gen_lowpart (SImode, operands[2]);")
9350 (define_insn "*ashlhi3_1"
9351   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9352         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9353                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9354    (clobber (reg:CC FLAGS_REG))]
9355   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9357   switch (get_attr_type (insn))
9358     {
9359     case TYPE_LEA:
9360       return "#";
9362     case TYPE_ALU:
9363       gcc_assert (operands[2] == const1_rtx);
9364       return "add{w}\t%0, %0";
9366     default:
9367       if (operands[2] == const1_rtx
9368           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9369         return "sal{w}\t%0";
9370       else
9371         return "sal{w}\t{%2, %0|%0, %2}";
9372     }
9374   [(set (attr "type")
9375      (cond [(eq_attr "alternative" "1")
9376               (const_string "lea")
9377             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9378                       (match_operand 0 "register_operand"))
9379                  (match_operand 2 "const1_operand"))
9380               (const_string "alu")
9381            ]
9382            (const_string "ishift")))
9383    (set (attr "length_immediate")
9384      (if_then_else
9385        (ior (eq_attr "type" "alu")
9386             (and (eq_attr "type" "ishift")
9387                  (and (match_operand 2 "const1_operand")
9388                       (ior (match_test "TARGET_SHIFT1")
9389                            (match_test "optimize_function_for_size_p (cfun)")))))
9390        (const_string "0")
9391        (const_string "*")))
9392    (set_attr "mode" "HI,SI")])
9394 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9395 (define_insn "*ashlqi3_1"
9396   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9397         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9398                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9399    (clobber (reg:CC FLAGS_REG))]
9400   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9402   switch (get_attr_type (insn))
9403     {
9404     case TYPE_LEA:
9405       return "#";
9407     case TYPE_ALU:
9408       gcc_assert (operands[2] == const1_rtx);
9409       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9410         return "add{l}\t%k0, %k0";
9411       else
9412         return "add{b}\t%0, %0";
9414     default:
9415       if (operands[2] == const1_rtx
9416           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9417         {
9418           if (get_attr_mode (insn) == MODE_SI)
9419             return "sal{l}\t%k0";
9420           else
9421             return "sal{b}\t%0";
9422         }
9423       else
9424         {
9425           if (get_attr_mode (insn) == MODE_SI)
9426             return "sal{l}\t{%2, %k0|%k0, %2}";
9427           else
9428             return "sal{b}\t{%2, %0|%0, %2}";
9429         }
9430     }
9432   [(set (attr "type")
9433      (cond [(eq_attr "alternative" "2")
9434               (const_string "lea")
9435             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9436                       (match_operand 0 "register_operand"))
9437                  (match_operand 2 "const1_operand"))
9438               (const_string "alu")
9439            ]
9440            (const_string "ishift")))
9441    (set (attr "length_immediate")
9442      (if_then_else
9443        (ior (eq_attr "type" "alu")
9444             (and (eq_attr "type" "ishift")
9445                  (and (match_operand 2 "const1_operand")
9446                       (ior (match_test "TARGET_SHIFT1")
9447                            (match_test "optimize_function_for_size_p (cfun)")))))
9448        (const_string "0")
9449        (const_string "*")))
9450    (set_attr "mode" "QI,SI,SI")])
9452 (define_insn "*ashlqi3_1_slp"
9453   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9454         (ashift:QI (match_dup 0)
9455                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9456    (clobber (reg:CC FLAGS_REG))]
9457   "(optimize_function_for_size_p (cfun)
9458     || !TARGET_PARTIAL_FLAG_REG_STALL
9459     || (operands[1] == const1_rtx
9460         && (TARGET_SHIFT1
9461             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9463   switch (get_attr_type (insn))
9464     {
9465     case TYPE_ALU:
9466       gcc_assert (operands[1] == const1_rtx);
9467       return "add{b}\t%0, %0";
9469     default:
9470       if (operands[1] == const1_rtx
9471           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9472         return "sal{b}\t%0";
9473       else
9474         return "sal{b}\t{%1, %0|%0, %1}";
9475     }
9477   [(set (attr "type")
9478      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9479                       (match_operand 0 "register_operand"))
9480                  (match_operand 1 "const1_operand"))
9481               (const_string "alu")
9482            ]
9483            (const_string "ishift1")))
9484    (set (attr "length_immediate")
9485      (if_then_else
9486        (ior (eq_attr "type" "alu")
9487             (and (eq_attr "type" "ishift1")
9488                  (and (match_operand 1 "const1_operand")
9489                       (ior (match_test "TARGET_SHIFT1")
9490                            (match_test "optimize_function_for_size_p (cfun)")))))
9491        (const_string "0")
9492        (const_string "*")))
9493    (set_attr "mode" "QI")])
9495 ;; Convert ashift to the lea pattern to avoid flags dependency.
9496 (define_split
9497   [(set (match_operand 0 "register_operand")
9498         (ashift (match_operand 1 "index_register_operand")
9499                 (match_operand:QI 2 "const_int_operand")))
9500    (clobber (reg:CC FLAGS_REG))]
9501   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9502    && reload_completed
9503    && true_regnum (operands[0]) != true_regnum (operands[1])"
9504   [(const_int 0)]
9506   enum machine_mode mode = GET_MODE (operands[0]);
9507   rtx pat;
9509   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9510     { 
9511       mode = SImode; 
9512       operands[0] = gen_lowpart (mode, operands[0]);
9513       operands[1] = gen_lowpart (mode, operands[1]);
9514     }
9516   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9518   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9520   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9521   DONE;
9524 ;; Convert ashift to the lea pattern to avoid flags dependency.
9525 (define_split
9526   [(set (match_operand:DI 0 "register_operand")
9527         (zero_extend:DI
9528           (ashift:SI (match_operand:SI 1 "index_register_operand")
9529                      (match_operand:QI 2 "const_int_operand"))))
9530    (clobber (reg:CC FLAGS_REG))]
9531   "TARGET_64BIT && reload_completed
9532    && true_regnum (operands[0]) != true_regnum (operands[1])"
9533   [(set (match_dup 0)
9534         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9536   operands[1] = gen_lowpart (SImode, operands[1]);
9537   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9540 ;; This pattern can't accept a variable shift count, since shifts by
9541 ;; zero don't affect the flags.  We assume that shifts by constant
9542 ;; zero are optimized away.
9543 (define_insn "*ashl<mode>3_cmp"
9544   [(set (reg FLAGS_REG)
9545         (compare
9546           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9547                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9548           (const_int 0)))
9549    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9550         (ashift:SWI (match_dup 1) (match_dup 2)))]
9551   "(optimize_function_for_size_p (cfun)
9552     || !TARGET_PARTIAL_FLAG_REG_STALL
9553     || (operands[2] == const1_rtx
9554         && (TARGET_SHIFT1
9555             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9556    && ix86_match_ccmode (insn, CCGOCmode)
9557    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9559   switch (get_attr_type (insn))
9560     {
9561     case TYPE_ALU:
9562       gcc_assert (operands[2] == const1_rtx);
9563       return "add{<imodesuffix>}\t%0, %0";
9565     default:
9566       if (operands[2] == const1_rtx
9567           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9568         return "sal{<imodesuffix>}\t%0";
9569       else
9570         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9571     }
9573   [(set (attr "type")
9574      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9575                       (match_operand 0 "register_operand"))
9576                  (match_operand 2 "const1_operand"))
9577               (const_string "alu")
9578            ]
9579            (const_string "ishift")))
9580    (set (attr "length_immediate")
9581      (if_then_else
9582        (ior (eq_attr "type" "alu")
9583             (and (eq_attr "type" "ishift")
9584                  (and (match_operand 2 "const1_operand")
9585                       (ior (match_test "TARGET_SHIFT1")
9586                            (match_test "optimize_function_for_size_p (cfun)")))))
9587        (const_string "0")
9588        (const_string "*")))
9589    (set_attr "mode" "<MODE>")])
9591 (define_insn "*ashlsi3_cmp_zext"
9592   [(set (reg FLAGS_REG)
9593         (compare
9594           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9595                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9596           (const_int 0)))
9597    (set (match_operand:DI 0 "register_operand" "=r")
9598         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9599   "TARGET_64BIT
9600    && (optimize_function_for_size_p (cfun)
9601        || !TARGET_PARTIAL_FLAG_REG_STALL
9602        || (operands[2] == const1_rtx
9603            && (TARGET_SHIFT1
9604                || TARGET_DOUBLE_WITH_ADD)))
9605    && ix86_match_ccmode (insn, CCGOCmode)
9606    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9608   switch (get_attr_type (insn))
9609     {
9610     case TYPE_ALU:
9611       gcc_assert (operands[2] == const1_rtx);
9612       return "add{l}\t%k0, %k0";
9614     default:
9615       if (operands[2] == const1_rtx
9616           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9617         return "sal{l}\t%k0";
9618       else
9619         return "sal{l}\t{%2, %k0|%k0, %2}";
9620     }
9622   [(set (attr "type")
9623      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9624                  (match_operand 2 "const1_operand"))
9625               (const_string "alu")
9626            ]
9627            (const_string "ishift")))
9628    (set (attr "length_immediate")
9629      (if_then_else
9630        (ior (eq_attr "type" "alu")
9631             (and (eq_attr "type" "ishift")
9632                  (and (match_operand 2 "const1_operand")
9633                       (ior (match_test "TARGET_SHIFT1")
9634                            (match_test "optimize_function_for_size_p (cfun)")))))
9635        (const_string "0")
9636        (const_string "*")))
9637    (set_attr "mode" "SI")])
9639 (define_insn "*ashl<mode>3_cconly"
9640   [(set (reg FLAGS_REG)
9641         (compare
9642           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9643                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9644           (const_int 0)))
9645    (clobber (match_scratch:SWI 0 "=<r>"))]
9646   "(optimize_function_for_size_p (cfun)
9647     || !TARGET_PARTIAL_FLAG_REG_STALL
9648     || (operands[2] == const1_rtx
9649         && (TARGET_SHIFT1
9650             || TARGET_DOUBLE_WITH_ADD)))
9651    && ix86_match_ccmode (insn, CCGOCmode)"
9653   switch (get_attr_type (insn))
9654     {
9655     case TYPE_ALU:
9656       gcc_assert (operands[2] == const1_rtx);
9657       return "add{<imodesuffix>}\t%0, %0";
9659     default:
9660       if (operands[2] == const1_rtx
9661           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9662         return "sal{<imodesuffix>}\t%0";
9663       else
9664         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9665     }
9667   [(set (attr "type")
9668      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9669                       (match_operand 0 "register_operand"))
9670                  (match_operand 2 "const1_operand"))
9671               (const_string "alu")
9672            ]
9673            (const_string "ishift")))
9674    (set (attr "length_immediate")
9675      (if_then_else
9676        (ior (eq_attr "type" "alu")
9677             (and (eq_attr "type" "ishift")
9678                  (and (match_operand 2 "const1_operand")
9679                       (ior (match_test "TARGET_SHIFT1")
9680                            (match_test "optimize_function_for_size_p (cfun)")))))
9681        (const_string "0")
9682        (const_string "*")))
9683    (set_attr "mode" "<MODE>")])
9685 ;; See comment above `ashl<mode>3' about how this works.
9687 (define_expand "<shift_insn><mode>3"
9688   [(set (match_operand:SDWIM 0 "<shift_operand>")
9689         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9690                            (match_operand:QI 2 "nonmemory_operand")))]
9691   ""
9692   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9694 ;; Avoid useless masking of count operand.
9695 (define_insn "*<shift_insn><mode>3_mask"
9696   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9697         (any_shiftrt:SWI48
9698           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9699           (subreg:QI
9700             (and:SI
9701               (match_operand:SI 2 "register_operand" "c")
9702               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9703    (clobber (reg:CC FLAGS_REG))]
9704   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9705    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9706       == GET_MODE_BITSIZE (<MODE>mode)-1"
9708   return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9710   [(set_attr "type" "ishift")
9711    (set_attr "mode" "<MODE>")])
9713 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9714   [(set (match_operand:DWI 0 "register_operand" "=r")
9715         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9716                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9717    (clobber (reg:CC FLAGS_REG))]
9718   ""
9719   "#"
9720   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9721   [(const_int 0)]
9722   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9723   [(set_attr "type" "multi")])
9725 ;; By default we don't ask for a scratch register, because when DWImode
9726 ;; values are manipulated, registers are already at a premium.  But if
9727 ;; we have one handy, we won't turn it away.
9729 (define_peephole2
9730   [(match_scratch:DWIH 3 "r")
9731    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9732                    (any_shiftrt:<DWI>
9733                      (match_operand:<DWI> 1 "register_operand")
9734                      (match_operand:QI 2 "nonmemory_operand")))
9735               (clobber (reg:CC FLAGS_REG))])
9736    (match_dup 3)]
9737   "TARGET_CMOVE"
9738   [(const_int 0)]
9739   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9741 (define_insn "x86_64_shrd"
9742   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9743         (ior:DI (ashiftrt:DI (match_dup 0)
9744                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9745                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9746                   (minus:QI (const_int 64) (match_dup 2)))))
9747    (clobber (reg:CC FLAGS_REG))]
9748   "TARGET_64BIT"
9749   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9750   [(set_attr "type" "ishift")
9751    (set_attr "prefix_0f" "1")
9752    (set_attr "mode" "DI")
9753    (set_attr "athlon_decode" "vector")
9754    (set_attr "amdfam10_decode" "vector")
9755    (set_attr "bdver1_decode" "vector")])
9757 (define_insn "x86_shrd"
9758   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9759         (ior:SI (ashiftrt:SI (match_dup 0)
9760                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9761                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9762                   (minus:QI (const_int 32) (match_dup 2)))))
9763    (clobber (reg:CC FLAGS_REG))]
9764   ""
9765   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9766   [(set_attr "type" "ishift")
9767    (set_attr "prefix_0f" "1")
9768    (set_attr "mode" "SI")
9769    (set_attr "pent_pair" "np")
9770    (set_attr "athlon_decode" "vector")
9771    (set_attr "amdfam10_decode" "vector")
9772    (set_attr "bdver1_decode" "vector")])
9774 (define_insn "ashrdi3_cvt"
9775   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9776         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9777                      (match_operand:QI 2 "const_int_operand")))
9778    (clobber (reg:CC FLAGS_REG))]
9779   "TARGET_64BIT && INTVAL (operands[2]) == 63
9780    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9781    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9782   "@
9783    {cqto|cqo}
9784    sar{q}\t{%2, %0|%0, %2}"
9785   [(set_attr "type" "imovx,ishift")
9786    (set_attr "prefix_0f" "0,*")
9787    (set_attr "length_immediate" "0,*")
9788    (set_attr "modrm" "0,1")
9789    (set_attr "mode" "DI")])
9791 (define_insn "ashrsi3_cvt"
9792   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9793         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9794                      (match_operand:QI 2 "const_int_operand")))
9795    (clobber (reg:CC FLAGS_REG))]
9796   "INTVAL (operands[2]) == 31
9797    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9798    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9799   "@
9800    {cltd|cdq}
9801    sar{l}\t{%2, %0|%0, %2}"
9802   [(set_attr "type" "imovx,ishift")
9803    (set_attr "prefix_0f" "0,*")
9804    (set_attr "length_immediate" "0,*")
9805    (set_attr "modrm" "0,1")
9806    (set_attr "mode" "SI")])
9808 (define_insn "*ashrsi3_cvt_zext"
9809   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9810         (zero_extend:DI
9811           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9812                        (match_operand:QI 2 "const_int_operand"))))
9813    (clobber (reg:CC FLAGS_REG))]
9814   "TARGET_64BIT && INTVAL (operands[2]) == 31
9815    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9816    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9817   "@
9818    {cltd|cdq}
9819    sar{l}\t{%2, %k0|%k0, %2}"
9820   [(set_attr "type" "imovx,ishift")
9821    (set_attr "prefix_0f" "0,*")
9822    (set_attr "length_immediate" "0,*")
9823    (set_attr "modrm" "0,1")
9824    (set_attr "mode" "SI")])
9826 (define_expand "x86_shift<mode>_adj_3"
9827   [(use (match_operand:SWI48 0 "register_operand"))
9828    (use (match_operand:SWI48 1 "register_operand"))
9829    (use (match_operand:QI 2 "register_operand"))]
9830   ""
9832   rtx label = gen_label_rtx ();
9833   rtx tmp;
9835   emit_insn (gen_testqi_ccz_1 (operands[2],
9836                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9838   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9839   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9840   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9841                               gen_rtx_LABEL_REF (VOIDmode, label),
9842                               pc_rtx);
9843   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9844   JUMP_LABEL (tmp) = label;
9846   emit_move_insn (operands[0], operands[1]);
9847   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9848                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9849   emit_label (label);
9850   LABEL_NUSES (label) = 1;
9852   DONE;
9855 (define_insn "*bmi2_<shift_insn><mode>3_1"
9856   [(set (match_operand:SWI48 0 "register_operand" "=r")
9857         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9858                            (match_operand:SWI48 2 "register_operand" "r")))]
9859   "TARGET_BMI2"
9860   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9861   [(set_attr "type" "ishiftx")
9862    (set_attr "mode" "<MODE>")])
9864 (define_insn "*<shift_insn><mode>3_1"
9865   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9866         (any_shiftrt:SWI48
9867           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9868           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9869    (clobber (reg:CC FLAGS_REG))]
9870   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9872   switch (get_attr_type (insn))
9873     {
9874     case TYPE_ISHIFTX:
9875       return "#";
9877     default:
9878       if (operands[2] == const1_rtx
9879           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9880         return "<shift>{<imodesuffix>}\t%0";
9881       else
9882         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9883     }
9885   [(set_attr "isa" "*,bmi2")
9886    (set_attr "type" "ishift,ishiftx")
9887    (set (attr "length_immediate")
9888      (if_then_else
9889        (and (match_operand 2 "const1_operand")
9890             (ior (match_test "TARGET_SHIFT1")
9891                  (match_test "optimize_function_for_size_p (cfun)")))
9892        (const_string "0")
9893        (const_string "*")))
9894    (set_attr "mode" "<MODE>")])
9896 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9897 (define_split
9898   [(set (match_operand:SWI48 0 "register_operand")
9899         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9900                            (match_operand:QI 2 "register_operand")))
9901    (clobber (reg:CC FLAGS_REG))]
9902   "TARGET_BMI2 && reload_completed"
9903   [(set (match_dup 0)
9904         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9905   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9907 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9908   [(set (match_operand:DI 0 "register_operand" "=r")
9909         (zero_extend:DI
9910           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9911                           (match_operand:SI 2 "register_operand" "r"))))]
9912   "TARGET_64BIT && TARGET_BMI2"
9913   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9914   [(set_attr "type" "ishiftx")
9915    (set_attr "mode" "SI")])
9917 (define_insn "*<shift_insn>si3_1_zext"
9918   [(set (match_operand:DI 0 "register_operand" "=r,r")
9919         (zero_extend:DI
9920           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9921                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9922    (clobber (reg:CC FLAGS_REG))]
9923   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9925   switch (get_attr_type (insn))
9926     {
9927     case TYPE_ISHIFTX:
9928       return "#";
9930     default:
9931       if (operands[2] == const1_rtx
9932           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9933         return "<shift>{l}\t%k0";
9934       else
9935         return "<shift>{l}\t{%2, %k0|%k0, %2}";
9936     }
9938   [(set_attr "isa" "*,bmi2")
9939    (set_attr "type" "ishift,ishiftx")
9940    (set (attr "length_immediate")
9941      (if_then_else
9942        (and (match_operand 2 "const1_operand")
9943             (ior (match_test "TARGET_SHIFT1")
9944                  (match_test "optimize_function_for_size_p (cfun)")))
9945        (const_string "0")
9946        (const_string "*")))
9947    (set_attr "mode" "SI")])
9949 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9950 (define_split
9951   [(set (match_operand:DI 0 "register_operand")
9952         (zero_extend:DI
9953           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9954                           (match_operand:QI 2 "register_operand"))))
9955    (clobber (reg:CC FLAGS_REG))]
9956   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9957   [(set (match_dup 0)
9958         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9959   "operands[2] = gen_lowpart (SImode, operands[2]);")
9961 (define_insn "*<shift_insn><mode>3_1"
9962   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9963         (any_shiftrt:SWI12
9964           (match_operand:SWI12 1 "nonimmediate_operand" "0")
9965           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9966    (clobber (reg:CC FLAGS_REG))]
9967   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9969   if (operands[2] == const1_rtx
9970       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9971     return "<shift>{<imodesuffix>}\t%0";
9972   else
9973     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9975   [(set_attr "type" "ishift")
9976    (set (attr "length_immediate")
9977      (if_then_else
9978        (and (match_operand 2 "const1_operand")
9979             (ior (match_test "TARGET_SHIFT1")
9980                  (match_test "optimize_function_for_size_p (cfun)")))
9981        (const_string "0")
9982        (const_string "*")))
9983    (set_attr "mode" "<MODE>")])
9985 (define_insn "*<shift_insn>qi3_1_slp"
9986   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9987         (any_shiftrt:QI (match_dup 0)
9988                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9989    (clobber (reg:CC FLAGS_REG))]
9990   "(optimize_function_for_size_p (cfun)
9991     || !TARGET_PARTIAL_REG_STALL
9992     || (operands[1] == const1_rtx
9993         && TARGET_SHIFT1))"
9995   if (operands[1] == const1_rtx
9996       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9997     return "<shift>{b}\t%0";
9998   else
9999     return "<shift>{b}\t{%1, %0|%0, %1}";
10001   [(set_attr "type" "ishift1")
10002    (set (attr "length_immediate")
10003      (if_then_else
10004        (and (match_operand 1 "const1_operand")
10005             (ior (match_test "TARGET_SHIFT1")
10006                  (match_test "optimize_function_for_size_p (cfun)")))
10007        (const_string "0")
10008        (const_string "*")))
10009    (set_attr "mode" "QI")])
10011 ;; This pattern can't accept a variable shift count, since shifts by
10012 ;; zero don't affect the flags.  We assume that shifts by constant
10013 ;; zero are optimized away.
10014 (define_insn "*<shift_insn><mode>3_cmp"
10015   [(set (reg FLAGS_REG)
10016         (compare
10017           (any_shiftrt:SWI
10018             (match_operand:SWI 1 "nonimmediate_operand" "0")
10019             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10020           (const_int 0)))
10021    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10022         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10023   "(optimize_function_for_size_p (cfun)
10024     || !TARGET_PARTIAL_FLAG_REG_STALL
10025     || (operands[2] == const1_rtx
10026         && TARGET_SHIFT1))
10027    && ix86_match_ccmode (insn, CCGOCmode)
10028    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10030   if (operands[2] == const1_rtx
10031       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10032     return "<shift>{<imodesuffix>}\t%0";
10033   else
10034     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10036   [(set_attr "type" "ishift")
10037    (set (attr "length_immediate")
10038      (if_then_else
10039        (and (match_operand 2 "const1_operand")
10040             (ior (match_test "TARGET_SHIFT1")
10041                  (match_test "optimize_function_for_size_p (cfun)")))
10042        (const_string "0")
10043        (const_string "*")))
10044    (set_attr "mode" "<MODE>")])
10046 (define_insn "*<shift_insn>si3_cmp_zext"
10047   [(set (reg FLAGS_REG)
10048         (compare
10049           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10050                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10051           (const_int 0)))
10052    (set (match_operand:DI 0 "register_operand" "=r")
10053         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10054   "TARGET_64BIT
10055    && (optimize_function_for_size_p (cfun)
10056        || !TARGET_PARTIAL_FLAG_REG_STALL
10057        || (operands[2] == const1_rtx
10058            && TARGET_SHIFT1))
10059    && ix86_match_ccmode (insn, CCGOCmode)
10060    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10062   if (operands[2] == const1_rtx
10063       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10064     return "<shift>{l}\t%k0";
10065   else
10066     return "<shift>{l}\t{%2, %k0|%k0, %2}";
10068   [(set_attr "type" "ishift")
10069    (set (attr "length_immediate")
10070      (if_then_else
10071        (and (match_operand 2 "const1_operand")
10072             (ior (match_test "TARGET_SHIFT1")
10073                  (match_test "optimize_function_for_size_p (cfun)")))
10074        (const_string "0")
10075        (const_string "*")))
10076    (set_attr "mode" "SI")])
10078 (define_insn "*<shift_insn><mode>3_cconly"
10079   [(set (reg FLAGS_REG)
10080         (compare
10081           (any_shiftrt:SWI
10082             (match_operand:SWI 1 "register_operand" "0")
10083             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10084           (const_int 0)))
10085    (clobber (match_scratch:SWI 0 "=<r>"))]
10086   "(optimize_function_for_size_p (cfun)
10087     || !TARGET_PARTIAL_FLAG_REG_STALL
10088     || (operands[2] == const1_rtx
10089         && TARGET_SHIFT1))
10090    && ix86_match_ccmode (insn, CCGOCmode)"
10092   if (operands[2] == const1_rtx
10093       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10094     return "<shift>{<imodesuffix>}\t%0";
10095   else
10096     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10098   [(set_attr "type" "ishift")
10099    (set (attr "length_immediate")
10100      (if_then_else
10101        (and (match_operand 2 "const1_operand")
10102             (ior (match_test "TARGET_SHIFT1")
10103                  (match_test "optimize_function_for_size_p (cfun)")))
10104        (const_string "0")
10105        (const_string "*")))
10106    (set_attr "mode" "<MODE>")])
10108 ;; Rotate instructions
10110 (define_expand "<rotate_insn>ti3"
10111   [(set (match_operand:TI 0 "register_operand")
10112         (any_rotate:TI (match_operand:TI 1 "register_operand")
10113                        (match_operand:QI 2 "nonmemory_operand")))]
10114   "TARGET_64BIT"
10116   if (const_1_to_63_operand (operands[2], VOIDmode))
10117     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10118                 (operands[0], operands[1], operands[2]));
10119   else
10120     FAIL;
10122   DONE;
10125 (define_expand "<rotate_insn>di3"
10126   [(set (match_operand:DI 0 "shiftdi_operand")
10127         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10128                        (match_operand:QI 2 "nonmemory_operand")))]
10129  ""
10131   if (TARGET_64BIT)
10132     ix86_expand_binary_operator (<CODE>, DImode, operands);
10133   else if (const_1_to_31_operand (operands[2], VOIDmode))
10134     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10135                 (operands[0], operands[1], operands[2]));
10136   else
10137     FAIL;
10139   DONE;
10142 (define_expand "<rotate_insn><mode>3"
10143   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10144         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10145                             (match_operand:QI 2 "nonmemory_operand")))]
10146   ""
10147   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10149 ;; Avoid useless masking of count operand.
10150 (define_insn "*<rotate_insn><mode>3_mask"
10151   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10152         (any_rotate:SWI48
10153           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10154           (subreg:QI
10155             (and:SI
10156               (match_operand:SI 2 "register_operand" "c")
10157               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10158    (clobber (reg:CC FLAGS_REG))]
10159   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10160    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10161       == GET_MODE_BITSIZE (<MODE>mode)-1"
10163   return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10165   [(set_attr "type" "rotate")
10166    (set_attr "mode" "<MODE>")])
10168 ;; Implement rotation using two double-precision
10169 ;; shift instructions and a scratch register.
10171 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10172  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10173        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10174                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10175   (clobber (reg:CC FLAGS_REG))
10176   (clobber (match_scratch:DWIH 3 "=&r"))]
10177  ""
10178  "#"
10179  "reload_completed"
10180  [(set (match_dup 3) (match_dup 4))
10181   (parallel
10182    [(set (match_dup 4)
10183          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10184                    (lshiftrt:DWIH (match_dup 5)
10185                                   (minus:QI (match_dup 6) (match_dup 2)))))
10186     (clobber (reg:CC FLAGS_REG))])
10187   (parallel
10188    [(set (match_dup 5)
10189          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10190                    (lshiftrt:DWIH (match_dup 3)
10191                                   (minus:QI (match_dup 6) (match_dup 2)))))
10192     (clobber (reg:CC FLAGS_REG))])]
10194   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10196   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10199 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10200  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10201        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10202                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10203   (clobber (reg:CC FLAGS_REG))
10204   (clobber (match_scratch:DWIH 3 "=&r"))]
10205  ""
10206  "#"
10207  "reload_completed"
10208  [(set (match_dup 3) (match_dup 4))
10209   (parallel
10210    [(set (match_dup 4)
10211          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10212                    (ashift:DWIH (match_dup 5)
10213                                 (minus:QI (match_dup 6) (match_dup 2)))))
10214     (clobber (reg:CC FLAGS_REG))])
10215   (parallel
10216    [(set (match_dup 5)
10217          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10218                    (ashift:DWIH (match_dup 3)
10219                                 (minus:QI (match_dup 6) (match_dup 2)))))
10220     (clobber (reg:CC FLAGS_REG))])]
10222   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10224   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10227 (define_insn "*bmi2_rorx<mode>3_1"
10228   [(set (match_operand:SWI48 0 "register_operand" "=r")
10229         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10230                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10231   "TARGET_BMI2"
10232   "rorx\t{%2, %1, %0|%0, %1, %2}"
10233   [(set_attr "type" "rotatex")
10234    (set_attr "mode" "<MODE>")])
10236 (define_insn "*<rotate_insn><mode>3_1"
10237   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10238         (any_rotate:SWI48
10239           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10240           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10241    (clobber (reg:CC FLAGS_REG))]
10242   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10244   switch (get_attr_type (insn))
10245     {
10246     case TYPE_ROTATEX:
10247       return "#";
10249     default:
10250       if (operands[2] == const1_rtx
10251           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10252         return "<rotate>{<imodesuffix>}\t%0";
10253       else
10254         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10255     }
10257   [(set_attr "isa" "*,bmi2")
10258    (set_attr "type" "rotate,rotatex")
10259    (set (attr "length_immediate")
10260      (if_then_else
10261        (and (eq_attr "type" "rotate")
10262             (and (match_operand 2 "const1_operand")
10263                  (ior (match_test "TARGET_SHIFT1")
10264                       (match_test "optimize_function_for_size_p (cfun)"))))
10265        (const_string "0")
10266        (const_string "*")))
10267    (set_attr "mode" "<MODE>")])
10269 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10270 (define_split
10271   [(set (match_operand:SWI48 0 "register_operand")
10272         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10273                       (match_operand:QI 2 "immediate_operand")))
10274    (clobber (reg:CC FLAGS_REG))]
10275   "TARGET_BMI2 && reload_completed"
10276   [(set (match_dup 0)
10277         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10279   operands[2]
10280     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10283 (define_split
10284   [(set (match_operand:SWI48 0 "register_operand")
10285         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10286                         (match_operand:QI 2 "immediate_operand")))
10287    (clobber (reg:CC FLAGS_REG))]
10288   "TARGET_BMI2 && reload_completed"
10289   [(set (match_dup 0)
10290         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10292 (define_insn "*bmi2_rorxsi3_1_zext"
10293   [(set (match_operand:DI 0 "register_operand" "=r")
10294         (zero_extend:DI
10295           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10296                        (match_operand:QI 2 "immediate_operand" "I"))))]
10297   "TARGET_64BIT && TARGET_BMI2"
10298   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10299   [(set_attr "type" "rotatex")
10300    (set_attr "mode" "SI")])
10302 (define_insn "*<rotate_insn>si3_1_zext"
10303   [(set (match_operand:DI 0 "register_operand" "=r,r")
10304         (zero_extend:DI
10305           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10306                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10307    (clobber (reg:CC FLAGS_REG))]
10308   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10310   switch (get_attr_type (insn))
10311     {
10312     case TYPE_ROTATEX:
10313       return "#";
10315     default:
10316       if (operands[2] == const1_rtx
10317           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10318         return "<rotate>{l}\t%k0";
10319       else
10320         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10321     }
10323   [(set_attr "isa" "*,bmi2")
10324    (set_attr "type" "rotate,rotatex")
10325    (set (attr "length_immediate")
10326      (if_then_else
10327        (and (eq_attr "type" "rotate")
10328             (and (match_operand 2 "const1_operand")
10329                  (ior (match_test "TARGET_SHIFT1")
10330                       (match_test "optimize_function_for_size_p (cfun)"))))
10331        (const_string "0")
10332        (const_string "*")))
10333    (set_attr "mode" "SI")])
10335 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10336 (define_split
10337   [(set (match_operand:DI 0 "register_operand")
10338         (zero_extend:DI
10339           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10340                      (match_operand:QI 2 "immediate_operand"))))
10341    (clobber (reg:CC FLAGS_REG))]
10342   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10343   [(set (match_dup 0)
10344         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10346   operands[2]
10347     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10350 (define_split
10351   [(set (match_operand:DI 0 "register_operand")
10352         (zero_extend:DI
10353           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10354                        (match_operand:QI 2 "immediate_operand"))))
10355    (clobber (reg:CC FLAGS_REG))]
10356   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10357   [(set (match_dup 0)
10358         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10360 (define_insn "*<rotate_insn><mode>3_1"
10361   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10362         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10363                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10364    (clobber (reg:CC FLAGS_REG))]
10365   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10367   if (operands[2] == const1_rtx
10368       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10369     return "<rotate>{<imodesuffix>}\t%0";
10370   else
10371     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10373   [(set_attr "type" "rotate")
10374    (set (attr "length_immediate")
10375      (if_then_else
10376        (and (match_operand 2 "const1_operand")
10377             (ior (match_test "TARGET_SHIFT1")
10378                  (match_test "optimize_function_for_size_p (cfun)")))
10379        (const_string "0")
10380        (const_string "*")))
10381    (set_attr "mode" "<MODE>")])
10383 (define_insn "*<rotate_insn>qi3_1_slp"
10384   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10385         (any_rotate:QI (match_dup 0)
10386                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10387    (clobber (reg:CC FLAGS_REG))]
10388   "(optimize_function_for_size_p (cfun)
10389     || !TARGET_PARTIAL_REG_STALL
10390     || (operands[1] == const1_rtx
10391         && TARGET_SHIFT1))"
10393   if (operands[1] == const1_rtx
10394       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10395     return "<rotate>{b}\t%0";
10396   else
10397     return "<rotate>{b}\t{%1, %0|%0, %1}";
10399   [(set_attr "type" "rotate1")
10400    (set (attr "length_immediate")
10401      (if_then_else
10402        (and (match_operand 1 "const1_operand")
10403             (ior (match_test "TARGET_SHIFT1")
10404                  (match_test "optimize_function_for_size_p (cfun)")))
10405        (const_string "0")
10406        (const_string "*")))
10407    (set_attr "mode" "QI")])
10409 (define_split
10410  [(set (match_operand:HI 0 "register_operand")
10411        (any_rotate:HI (match_dup 0) (const_int 8)))
10412   (clobber (reg:CC FLAGS_REG))]
10413  "reload_completed
10414   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10415  [(parallel [(set (strict_low_part (match_dup 0))
10416                   (bswap:HI (match_dup 0)))
10417              (clobber (reg:CC FLAGS_REG))])])
10419 ;; Bit set / bit test instructions
10421 (define_expand "extv"
10422   [(set (match_operand:SI 0 "register_operand")
10423         (sign_extract:SI (match_operand:SI 1 "register_operand")
10424                          (match_operand:SI 2 "const8_operand")
10425                          (match_operand:SI 3 "const8_operand")))]
10426   ""
10428   /* Handle extractions from %ah et al.  */
10429   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10430     FAIL;
10432   /* From mips.md: extract_bit_field doesn't verify that our source
10433      matches the predicate, so check it again here.  */
10434   if (! ext_register_operand (operands[1], VOIDmode))
10435     FAIL;
10438 (define_expand "extzv"
10439   [(set (match_operand:SI 0 "register_operand")
10440         (zero_extract:SI (match_operand 1 "ext_register_operand")
10441                          (match_operand:SI 2 "const8_operand")
10442                          (match_operand:SI 3 "const8_operand")))]
10443   ""
10445   /* Handle extractions from %ah et al.  */
10446   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10447     FAIL;
10449   /* From mips.md: extract_bit_field doesn't verify that our source
10450      matches the predicate, so check it again here.  */
10451   if (! ext_register_operand (operands[1], VOIDmode))
10452     FAIL;
10455 (define_expand "insv"
10456   [(set (zero_extract (match_operand 0 "register_operand")
10457                       (match_operand 1 "const_int_operand")
10458                       (match_operand 2 "const_int_operand"))
10459         (match_operand 3 "register_operand"))]
10460   ""
10462   rtx (*gen_mov_insv_1) (rtx, rtx);
10464   if (ix86_expand_pinsr (operands))
10465     DONE;
10467   /* Handle insertions to %ah et al.  */
10468   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10469     FAIL;
10471   /* From mips.md: insert_bit_field doesn't verify that our source
10472      matches the predicate, so check it again here.  */
10473   if (! ext_register_operand (operands[0], VOIDmode))
10474     FAIL;
10476   gen_mov_insv_1 = (TARGET_64BIT
10477                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10479   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10480   DONE;
10483 ;; %%% bts, btr, btc, bt.
10484 ;; In general these instructions are *slow* when applied to memory,
10485 ;; since they enforce atomic operation.  When applied to registers,
10486 ;; it depends on the cpu implementation.  They're never faster than
10487 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10488 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10489 ;; within the instruction itself, so operating on bits in the high
10490 ;; 32-bits of a register becomes easier.
10492 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10493 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10494 ;; negdf respectively, so they can never be disabled entirely.
10496 (define_insn "*btsq"
10497   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10498                          (const_int 1)
10499                          (match_operand:DI 1 "const_0_to_63_operand"))
10500         (const_int 1))
10501    (clobber (reg:CC FLAGS_REG))]
10502   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10503   "bts{q}\t{%1, %0|%0, %1}"
10504   [(set_attr "type" "alu1")
10505    (set_attr "prefix_0f" "1")
10506    (set_attr "mode" "DI")])
10508 (define_insn "*btrq"
10509   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10510                          (const_int 1)
10511                          (match_operand:DI 1 "const_0_to_63_operand"))
10512         (const_int 0))
10513    (clobber (reg:CC FLAGS_REG))]
10514   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10515   "btr{q}\t{%1, %0|%0, %1}"
10516   [(set_attr "type" "alu1")
10517    (set_attr "prefix_0f" "1")
10518    (set_attr "mode" "DI")])
10520 (define_insn "*btcq"
10521   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10522                          (const_int 1)
10523                          (match_operand:DI 1 "const_0_to_63_operand"))
10524         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10525    (clobber (reg:CC FLAGS_REG))]
10526   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10527   "btc{q}\t{%1, %0|%0, %1}"
10528   [(set_attr "type" "alu1")
10529    (set_attr "prefix_0f" "1")
10530    (set_attr "mode" "DI")])
10532 ;; Allow Nocona to avoid these instructions if a register is available.
10534 (define_peephole2
10535   [(match_scratch:DI 2 "r")
10536    (parallel [(set (zero_extract:DI
10537                      (match_operand:DI 0 "register_operand")
10538                      (const_int 1)
10539                      (match_operand:DI 1 "const_0_to_63_operand"))
10540                    (const_int 1))
10541               (clobber (reg:CC FLAGS_REG))])]
10542   "TARGET_64BIT && !TARGET_USE_BT"
10543   [(const_int 0)]
10545   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10546   rtx op1;
10548   if (HOST_BITS_PER_WIDE_INT >= 64)
10549     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10550   else if (i < HOST_BITS_PER_WIDE_INT)
10551     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10552   else
10553     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10555   op1 = immed_double_const (lo, hi, DImode);
10556   if (i >= 31)
10557     {
10558       emit_move_insn (operands[2], op1);
10559       op1 = operands[2];
10560     }
10562   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10563   DONE;
10566 (define_peephole2
10567   [(match_scratch:DI 2 "r")
10568    (parallel [(set (zero_extract:DI
10569                      (match_operand:DI 0 "register_operand")
10570                      (const_int 1)
10571                      (match_operand:DI 1 "const_0_to_63_operand"))
10572                    (const_int 0))
10573               (clobber (reg:CC FLAGS_REG))])]
10574   "TARGET_64BIT && !TARGET_USE_BT"
10575   [(const_int 0)]
10577   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10578   rtx op1;
10580   if (HOST_BITS_PER_WIDE_INT >= 64)
10581     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10582   else if (i < HOST_BITS_PER_WIDE_INT)
10583     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10584   else
10585     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10587   op1 = immed_double_const (~lo, ~hi, DImode);
10588   if (i >= 32)
10589     {
10590       emit_move_insn (operands[2], op1);
10591       op1 = operands[2];
10592     }
10594   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10595   DONE;
10598 (define_peephole2
10599   [(match_scratch:DI 2 "r")
10600    (parallel [(set (zero_extract:DI
10601                      (match_operand:DI 0 "register_operand")
10602                      (const_int 1)
10603                      (match_operand:DI 1 "const_0_to_63_operand"))
10604               (not:DI (zero_extract:DI
10605                         (match_dup 0) (const_int 1) (match_dup 1))))
10606               (clobber (reg:CC FLAGS_REG))])]
10607   "TARGET_64BIT && !TARGET_USE_BT"
10608   [(const_int 0)]
10610   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10611   rtx op1;
10613   if (HOST_BITS_PER_WIDE_INT >= 64)
10614     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10615   else if (i < HOST_BITS_PER_WIDE_INT)
10616     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10617   else
10618     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10620   op1 = immed_double_const (lo, hi, DImode);
10621   if (i >= 31)
10622     {
10623       emit_move_insn (operands[2], op1);
10624       op1 = operands[2];
10625     }
10627   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10628   DONE;
10631 (define_insn "*bt<mode>"
10632   [(set (reg:CCC FLAGS_REG)
10633         (compare:CCC
10634           (zero_extract:SWI48
10635             (match_operand:SWI48 0 "register_operand" "r")
10636             (const_int 1)
10637             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10638           (const_int 0)))]
10639   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10640   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10641   [(set_attr "type" "alu1")
10642    (set_attr "prefix_0f" "1")
10643    (set_attr "mode" "<MODE>")])
10645 ;; Store-flag instructions.
10647 ;; For all sCOND expanders, also expand the compare or test insn that
10648 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10650 (define_insn_and_split "*setcc_di_1"
10651   [(set (match_operand:DI 0 "register_operand" "=q")
10652         (match_operator:DI 1 "ix86_comparison_operator"
10653           [(reg FLAGS_REG) (const_int 0)]))]
10654   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10655   "#"
10656   "&& reload_completed"
10657   [(set (match_dup 2) (match_dup 1))
10658    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10660   PUT_MODE (operands[1], QImode);
10661   operands[2] = gen_lowpart (QImode, operands[0]);
10664 (define_insn_and_split "*setcc_si_1_and"
10665   [(set (match_operand:SI 0 "register_operand" "=q")
10666         (match_operator:SI 1 "ix86_comparison_operator"
10667           [(reg FLAGS_REG) (const_int 0)]))
10668    (clobber (reg:CC FLAGS_REG))]
10669   "!TARGET_PARTIAL_REG_STALL
10670    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10671   "#"
10672   "&& reload_completed"
10673   [(set (match_dup 2) (match_dup 1))
10674    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10675               (clobber (reg:CC FLAGS_REG))])]
10677   PUT_MODE (operands[1], QImode);
10678   operands[2] = gen_lowpart (QImode, operands[0]);
10681 (define_insn_and_split "*setcc_si_1_movzbl"
10682   [(set (match_operand:SI 0 "register_operand" "=q")
10683         (match_operator:SI 1 "ix86_comparison_operator"
10684           [(reg FLAGS_REG) (const_int 0)]))]
10685   "!TARGET_PARTIAL_REG_STALL
10686    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10687   "#"
10688   "&& reload_completed"
10689   [(set (match_dup 2) (match_dup 1))
10690    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10692   PUT_MODE (operands[1], QImode);
10693   operands[2] = gen_lowpart (QImode, operands[0]);
10696 (define_insn "*setcc_qi"
10697   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10698         (match_operator:QI 1 "ix86_comparison_operator"
10699           [(reg FLAGS_REG) (const_int 0)]))]
10700   ""
10701   "set%C1\t%0"
10702   [(set_attr "type" "setcc")
10703    (set_attr "mode" "QI")])
10705 (define_insn "*setcc_qi_slp"
10706   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10707         (match_operator:QI 1 "ix86_comparison_operator"
10708           [(reg FLAGS_REG) (const_int 0)]))]
10709   ""
10710   "set%C1\t%0"
10711   [(set_attr "type" "setcc")
10712    (set_attr "mode" "QI")])
10714 ;; In general it is not safe to assume too much about CCmode registers,
10715 ;; so simplify-rtx stops when it sees a second one.  Under certain
10716 ;; conditions this is safe on x86, so help combine not create
10718 ;;      seta    %al
10719 ;;      testb   %al, %al
10720 ;;      sete    %al
10722 (define_split
10723   [(set (match_operand:QI 0 "nonimmediate_operand")
10724         (ne:QI (match_operator 1 "ix86_comparison_operator"
10725                  [(reg FLAGS_REG) (const_int 0)])
10726             (const_int 0)))]
10727   ""
10728   [(set (match_dup 0) (match_dup 1))]
10729   "PUT_MODE (operands[1], QImode);")
10731 (define_split
10732   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10733         (ne:QI (match_operator 1 "ix86_comparison_operator"
10734                  [(reg FLAGS_REG) (const_int 0)])
10735             (const_int 0)))]
10736   ""
10737   [(set (match_dup 0) (match_dup 1))]
10738   "PUT_MODE (operands[1], QImode);")
10740 (define_split
10741   [(set (match_operand:QI 0 "nonimmediate_operand")
10742         (eq:QI (match_operator 1 "ix86_comparison_operator"
10743                  [(reg FLAGS_REG) (const_int 0)])
10744             (const_int 0)))]
10745   ""
10746   [(set (match_dup 0) (match_dup 1))]
10748   rtx new_op1 = copy_rtx (operands[1]);
10749   operands[1] = new_op1;
10750   PUT_MODE (new_op1, QImode);
10751   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10752                                              GET_MODE (XEXP (new_op1, 0))));
10754   /* Make sure that (a) the CCmode we have for the flags is strong
10755      enough for the reversed compare or (b) we have a valid FP compare.  */
10756   if (! ix86_comparison_operator (new_op1, VOIDmode))
10757     FAIL;
10760 (define_split
10761   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10762         (eq:QI (match_operator 1 "ix86_comparison_operator"
10763                  [(reg FLAGS_REG) (const_int 0)])
10764             (const_int 0)))]
10765   ""
10766   [(set (match_dup 0) (match_dup 1))]
10768   rtx new_op1 = copy_rtx (operands[1]);
10769   operands[1] = new_op1;
10770   PUT_MODE (new_op1, QImode);
10771   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10772                                              GET_MODE (XEXP (new_op1, 0))));
10774   /* Make sure that (a) the CCmode we have for the flags is strong
10775      enough for the reversed compare or (b) we have a valid FP compare.  */
10776   if (! ix86_comparison_operator (new_op1, VOIDmode))
10777     FAIL;
10780 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10781 ;; subsequent logical operations are used to imitate conditional moves.
10782 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10783 ;; it directly.
10785 (define_insn "setcc_<mode>_sse"
10786   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10787         (match_operator:MODEF 3 "sse_comparison_operator"
10788           [(match_operand:MODEF 1 "register_operand" "0,x")
10789            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10790   "SSE_FLOAT_MODE_P (<MODE>mode)"
10791   "@
10792    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10793    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10794   [(set_attr "isa" "noavx,avx")
10795    (set_attr "type" "ssecmp")
10796    (set_attr "length_immediate" "1")
10797    (set_attr "prefix" "orig,vex")
10798    (set_attr "mode" "<MODE>")])
10800 ;; Basic conditional jump instructions.
10801 ;; We ignore the overflow flag for signed branch instructions.
10803 (define_insn "*jcc_1"
10804   [(set (pc)
10805         (if_then_else (match_operator 1 "ix86_comparison_operator"
10806                                       [(reg FLAGS_REG) (const_int 0)])
10807                       (label_ref (match_operand 0))
10808                       (pc)))]
10809   ""
10810   "%+j%C1\t%l0"
10811   [(set_attr "type" "ibr")
10812    (set_attr "modrm" "0")
10813    (set (attr "length")
10814            (if_then_else (and (ge (minus (match_dup 0) (pc))
10815                                   (const_int -126))
10816                               (lt (minus (match_dup 0) (pc))
10817                                   (const_int 128)))
10818              (const_int 2)
10819              (const_int 6)))])
10821 (define_insn "*jcc_2"
10822   [(set (pc)
10823         (if_then_else (match_operator 1 "ix86_comparison_operator"
10824                                       [(reg FLAGS_REG) (const_int 0)])
10825                       (pc)
10826                       (label_ref (match_operand 0))))]
10827   ""
10828   "%+j%c1\t%l0"
10829   [(set_attr "type" "ibr")
10830    (set_attr "modrm" "0")
10831    (set (attr "length")
10832            (if_then_else (and (ge (minus (match_dup 0) (pc))
10833                                   (const_int -126))
10834                               (lt (minus (match_dup 0) (pc))
10835                                   (const_int 128)))
10836              (const_int 2)
10837              (const_int 6)))])
10839 ;; In general it is not safe to assume too much about CCmode registers,
10840 ;; so simplify-rtx stops when it sees a second one.  Under certain
10841 ;; conditions this is safe on x86, so help combine not create
10843 ;;      seta    %al
10844 ;;      testb   %al, %al
10845 ;;      je      Lfoo
10847 (define_split
10848   [(set (pc)
10849         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10850                                       [(reg FLAGS_REG) (const_int 0)])
10851                           (const_int 0))
10852                       (label_ref (match_operand 1))
10853                       (pc)))]
10854   ""
10855   [(set (pc)
10856         (if_then_else (match_dup 0)
10857                       (label_ref (match_dup 1))
10858                       (pc)))]
10859   "PUT_MODE (operands[0], VOIDmode);")
10861 (define_split
10862   [(set (pc)
10863         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10864                                       [(reg FLAGS_REG) (const_int 0)])
10865                           (const_int 0))
10866                       (label_ref (match_operand 1))
10867                       (pc)))]
10868   ""
10869   [(set (pc)
10870         (if_then_else (match_dup 0)
10871                       (label_ref (match_dup 1))
10872                       (pc)))]
10874   rtx new_op0 = copy_rtx (operands[0]);
10875   operands[0] = new_op0;
10876   PUT_MODE (new_op0, VOIDmode);
10877   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10878                                              GET_MODE (XEXP (new_op0, 0))));
10880   /* Make sure that (a) the CCmode we have for the flags is strong
10881      enough for the reversed compare or (b) we have a valid FP compare.  */
10882   if (! ix86_comparison_operator (new_op0, VOIDmode))
10883     FAIL;
10886 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10887 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10888 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10889 ;; appropriate modulo of the bit offset value.
10891 (define_insn_and_split "*jcc_bt<mode>"
10892   [(set (pc)
10893         (if_then_else (match_operator 0 "bt_comparison_operator"
10894                         [(zero_extract:SWI48
10895                            (match_operand:SWI48 1 "register_operand" "r")
10896                            (const_int 1)
10897                            (zero_extend:SI
10898                              (match_operand:QI 2 "register_operand" "r")))
10899                          (const_int 0)])
10900                       (label_ref (match_operand 3))
10901                       (pc)))
10902    (clobber (reg:CC FLAGS_REG))]
10903   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10904   "#"
10905   "&& 1"
10906   [(set (reg:CCC FLAGS_REG)
10907         (compare:CCC
10908           (zero_extract:SWI48
10909             (match_dup 1)
10910             (const_int 1)
10911             (match_dup 2))
10912           (const_int 0)))
10913    (set (pc)
10914         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10915                       (label_ref (match_dup 3))
10916                       (pc)))]
10918   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10920   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10923 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10924 ;; also for DImode, this is what combine produces.
10925 (define_insn_and_split "*jcc_bt<mode>_mask"
10926   [(set (pc)
10927         (if_then_else (match_operator 0 "bt_comparison_operator"
10928                         [(zero_extract:SWI48
10929                            (match_operand:SWI48 1 "register_operand" "r")
10930                            (const_int 1)
10931                            (and:SI
10932                              (match_operand:SI 2 "register_operand" "r")
10933                              (match_operand:SI 3 "const_int_operand" "n")))])
10934                       (label_ref (match_operand 4))
10935                       (pc)))
10936    (clobber (reg:CC FLAGS_REG))]
10937   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10938    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10939       == GET_MODE_BITSIZE (<MODE>mode)-1"
10940   "#"
10941   "&& 1"
10942   [(set (reg:CCC FLAGS_REG)
10943         (compare:CCC
10944           (zero_extract:SWI48
10945             (match_dup 1)
10946             (const_int 1)
10947             (match_dup 2))
10948           (const_int 0)))
10949    (set (pc)
10950         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10951                       (label_ref (match_dup 4))
10952                       (pc)))]
10954   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10956   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10959 (define_insn_and_split "*jcc_btsi_1"
10960   [(set (pc)
10961         (if_then_else (match_operator 0 "bt_comparison_operator"
10962                         [(and:SI
10963                            (lshiftrt:SI
10964                              (match_operand:SI 1 "register_operand" "r")
10965                              (match_operand:QI 2 "register_operand" "r"))
10966                            (const_int 1))
10967                          (const_int 0)])
10968                       (label_ref (match_operand 3))
10969                       (pc)))
10970    (clobber (reg:CC FLAGS_REG))]
10971   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10972   "#"
10973   "&& 1"
10974   [(set (reg:CCC FLAGS_REG)
10975         (compare:CCC
10976           (zero_extract:SI
10977             (match_dup 1)
10978             (const_int 1)
10979             (match_dup 2))
10980           (const_int 0)))
10981    (set (pc)
10982         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10983                       (label_ref (match_dup 3))
10984                       (pc)))]
10986   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10988   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10991 ;; avoid useless masking of bit offset operand
10992 (define_insn_and_split "*jcc_btsi_mask_1"
10993   [(set (pc)
10994         (if_then_else
10995           (match_operator 0 "bt_comparison_operator"
10996             [(and:SI
10997                (lshiftrt:SI
10998                  (match_operand:SI 1 "register_operand" "r")
10999                  (subreg:QI
11000                    (and:SI
11001                      (match_operand:SI 2 "register_operand" "r")
11002                      (match_operand:SI 3 "const_int_operand" "n")) 0))
11003                (const_int 1))
11004              (const_int 0)])
11005           (label_ref (match_operand 4))
11006           (pc)))
11007    (clobber (reg:CC FLAGS_REG))]
11008   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11009    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11010   "#"
11011   "&& 1"
11012   [(set (reg:CCC FLAGS_REG)
11013         (compare:CCC
11014           (zero_extract:SI
11015             (match_dup 1)
11016             (const_int 1)
11017             (match_dup 2))
11018           (const_int 0)))
11019    (set (pc)
11020         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11021                       (label_ref (match_dup 4))
11022                       (pc)))]
11023   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11025 ;; Define combination compare-and-branch fp compare instructions to help
11026 ;; combine.
11028 (define_insn "*jcc<mode>_0_i387"
11029   [(set (pc)
11030         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11031                         [(match_operand:X87MODEF 1 "register_operand" "f")
11032                          (match_operand:X87MODEF 2 "const0_operand")])
11033           (label_ref (match_operand 3))
11034           (pc)))
11035    (clobber (reg:CCFP FPSR_REG))
11036    (clobber (reg:CCFP FLAGS_REG))
11037    (clobber (match_scratch:HI 4 "=a"))]
11038   "TARGET_80387 && !TARGET_CMOVE"
11039   "#")
11041 (define_insn "*jcc<mode>_0_r_i387"
11042   [(set (pc)
11043         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11044                         [(match_operand:X87MODEF 1 "register_operand" "f")
11045                          (match_operand:X87MODEF 2 "const0_operand")])
11046           (pc)
11047           (label_ref (match_operand 3))))
11048    (clobber (reg:CCFP FPSR_REG))
11049    (clobber (reg:CCFP FLAGS_REG))
11050    (clobber (match_scratch:HI 4 "=a"))]
11051   "TARGET_80387 && !TARGET_CMOVE"
11052   "#")
11054 (define_insn "*jccxf_i387"
11055   [(set (pc)
11056         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11057                         [(match_operand:XF 1 "register_operand" "f")
11058                          (match_operand:XF 2 "register_operand" "f")])
11059           (label_ref (match_operand 3))
11060           (pc)))
11061    (clobber (reg:CCFP FPSR_REG))
11062    (clobber (reg:CCFP FLAGS_REG))
11063    (clobber (match_scratch:HI 4 "=a"))]
11064   "TARGET_80387 && !TARGET_CMOVE"
11065   "#")
11067 (define_insn "*jccxf_r_i387"
11068   [(set (pc)
11069         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11070                         [(match_operand:XF 1 "register_operand" "f")
11071                          (match_operand:XF 2 "register_operand" "f")])
11072           (pc)
11073           (label_ref (match_operand 3))))
11074    (clobber (reg:CCFP FPSR_REG))
11075    (clobber (reg:CCFP FLAGS_REG))
11076    (clobber (match_scratch:HI 4 "=a"))]
11077   "TARGET_80387 && !TARGET_CMOVE"
11078   "#")
11080 (define_insn "*jcc<mode>_i387"
11081   [(set (pc)
11082         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11083                         [(match_operand:MODEF 1 "register_operand" "f")
11084                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11085           (label_ref (match_operand 3))
11086           (pc)))
11087    (clobber (reg:CCFP FPSR_REG))
11088    (clobber (reg:CCFP FLAGS_REG))
11089    (clobber (match_scratch:HI 4 "=a"))]
11090   "TARGET_80387 && !TARGET_CMOVE"
11091   "#")
11093 (define_insn "*jcc<mode>_r_i387"
11094   [(set (pc)
11095         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11096                         [(match_operand:MODEF 1 "register_operand" "f")
11097                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11098           (pc)
11099           (label_ref (match_operand 3))))
11100    (clobber (reg:CCFP FPSR_REG))
11101    (clobber (reg:CCFP FLAGS_REG))
11102    (clobber (match_scratch:HI 4 "=a"))]
11103   "TARGET_80387 && !TARGET_CMOVE"
11104   "#")
11106 (define_insn "*jccu<mode>_i387"
11107   [(set (pc)
11108         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11109                         [(match_operand:X87MODEF 1 "register_operand" "f")
11110                          (match_operand:X87MODEF 2 "register_operand" "f")])
11111           (label_ref (match_operand 3))
11112           (pc)))
11113    (clobber (reg:CCFP FPSR_REG))
11114    (clobber (reg:CCFP FLAGS_REG))
11115    (clobber (match_scratch:HI 4 "=a"))]
11116   "TARGET_80387 && !TARGET_CMOVE"
11117   "#")
11119 (define_insn "*jccu<mode>_r_i387"
11120   [(set (pc)
11121         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11122                         [(match_operand:X87MODEF 1 "register_operand" "f")
11123                          (match_operand:X87MODEF 2 "register_operand" "f")])
11124           (pc)
11125           (label_ref (match_operand 3))))
11126    (clobber (reg:CCFP FPSR_REG))
11127    (clobber (reg:CCFP FLAGS_REG))
11128    (clobber (match_scratch:HI 4 "=a"))]
11129   "TARGET_80387 && !TARGET_CMOVE"
11130   "#")
11132 (define_split
11133   [(set (pc)
11134         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11135                         [(match_operand:X87MODEF 1 "register_operand")
11136                          (match_operand:X87MODEF 2 "nonimmediate_operand")])
11137           (match_operand 3)
11138           (match_operand 4)))
11139    (clobber (reg:CCFP FPSR_REG))
11140    (clobber (reg:CCFP FLAGS_REG))]
11141   "TARGET_80387 && !TARGET_CMOVE
11142    && reload_completed"
11143   [(const_int 0)]
11145   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11146                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11147   DONE;
11150 (define_split
11151   [(set (pc)
11152         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11153                         [(match_operand:X87MODEF 1 "register_operand")
11154                          (match_operand:X87MODEF 2 "general_operand")])
11155           (match_operand 3)
11156           (match_operand 4)))
11157    (clobber (reg:CCFP FPSR_REG))
11158    (clobber (reg:CCFP FLAGS_REG))
11159    (clobber (match_scratch:HI 5))]
11160   "TARGET_80387 && !TARGET_CMOVE
11161    && reload_completed"
11162   [(const_int 0)]
11164   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11165                         operands[3], operands[4], operands[5], NULL_RTX);
11166   DONE;
11169 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11170 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11171 ;; with a precedence over other operators and is always put in the first
11172 ;; place. Swap condition and operands to match ficom instruction.
11174 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11175   [(set (pc)
11176         (if_then_else
11177           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11178             [(match_operator:X87MODEF 1 "float_operator"
11179               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11180              (match_operand:X87MODEF 3 "register_operand" "f,f")])
11181           (label_ref (match_operand 4))
11182           (pc)))
11183    (clobber (reg:CCFP FPSR_REG))
11184    (clobber (reg:CCFP FLAGS_REG))
11185    (clobber (match_scratch:HI 5 "=a,a"))]
11186   "TARGET_80387 && !TARGET_CMOVE
11187    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11188        || optimize_function_for_size_p (cfun))"
11189   "#")
11191 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11192   [(set (pc)
11193         (if_then_else
11194           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11195             [(match_operator:X87MODEF 1 "float_operator"
11196               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11197              (match_operand:X87MODEF 3 "register_operand" "f,f")])
11198           (pc)
11199           (label_ref (match_operand 4))))
11200    (clobber (reg:CCFP FPSR_REG))
11201    (clobber (reg:CCFP FLAGS_REG))
11202    (clobber (match_scratch:HI 5 "=a,a"))]
11203   "TARGET_80387 && !TARGET_CMOVE
11204    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11205        || optimize_function_for_size_p (cfun))"
11206   "#")
11208 (define_split
11209   [(set (pc)
11210         (if_then_else
11211           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11212             [(match_operator:X87MODEF 1 "float_operator"
11213               [(match_operand:SWI24 2 "memory_operand")])
11214              (match_operand:X87MODEF 3 "register_operand")])
11215           (match_operand 4)
11216           (match_operand 5)))
11217    (clobber (reg:CCFP FPSR_REG))
11218    (clobber (reg:CCFP FLAGS_REG))
11219    (clobber (match_scratch:HI 6))]
11220   "TARGET_80387 && !TARGET_CMOVE
11221    && reload_completed"
11222   [(const_int 0)]
11224   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11225                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11226                         operands[4], operands[5], operands[6], NULL_RTX);
11227   DONE;
11230 ;; %%% Kill this when reload knows how to do it.
11231 (define_split
11232   [(set (pc)
11233         (if_then_else
11234           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11235             [(match_operator:X87MODEF 1 "float_operator"
11236               [(match_operand:SWI24 2 "register_operand")])
11237              (match_operand:X87MODEF 3 "register_operand")])
11238           (match_operand 4)
11239           (match_operand 5)))
11240    (clobber (reg:CCFP FPSR_REG))
11241    (clobber (reg:CCFP FLAGS_REG))
11242    (clobber (match_scratch:HI 6))]
11243   "TARGET_80387 && !TARGET_CMOVE
11244    && reload_completed"
11245   [(const_int 0)]
11247   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11249   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11250                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]),
11251                         operands[4], operands[5], operands[6], operands[2]);
11252   DONE;
11255 ;; Unconditional and other jump instructions
11257 (define_insn "jump"
11258   [(set (pc)
11259         (label_ref (match_operand 0)))]
11260   ""
11261   "jmp\t%l0"
11262   [(set_attr "type" "ibr")
11263    (set (attr "length")
11264            (if_then_else (and (ge (minus (match_dup 0) (pc))
11265                                   (const_int -126))
11266                               (lt (minus (match_dup 0) (pc))
11267                                   (const_int 128)))
11268              (const_int 2)
11269              (const_int 5)))
11270    (set_attr "modrm" "0")])
11272 (define_expand "indirect_jump"
11273   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11274   ""
11276   if (TARGET_X32)
11277     operands[0] = convert_memory_address (word_mode, operands[0]);
11280 (define_insn "*indirect_jump"
11281   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11282   ""
11283   "jmp\t%A0"
11284   [(set_attr "type" "ibr")
11285    (set_attr "length_immediate" "0")])
11287 (define_expand "tablejump"
11288   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11289               (use (label_ref (match_operand 1)))])]
11290   ""
11292   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11293      relative.  Convert the relative address to an absolute address.  */
11294   if (flag_pic)
11295     {
11296       rtx op0, op1;
11297       enum rtx_code code;
11299       /* We can't use @GOTOFF for text labels on VxWorks;
11300          see gotoff_operand.  */
11301       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11302         {
11303           code = PLUS;
11304           op0 = operands[0];
11305           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11306         }
11307       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11308         {
11309           code = PLUS;
11310           op0 = operands[0];
11311           op1 = pic_offset_table_rtx;
11312         }
11313       else
11314         {
11315           code = MINUS;
11316           op0 = pic_offset_table_rtx;
11317           op1 = operands[0];
11318         }
11320       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11321                                          OPTAB_DIRECT);
11322     }
11324   if (TARGET_X32)
11325     operands[0] = convert_memory_address (word_mode, operands[0]);
11328 (define_insn "*tablejump_1"
11329   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11330    (use (label_ref (match_operand 1)))]
11331   ""
11332   "jmp\t%A0"
11333   [(set_attr "type" "ibr")
11334    (set_attr "length_immediate" "0")])
11336 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11338 (define_peephole2
11339   [(set (reg FLAGS_REG) (match_operand 0))
11340    (set (match_operand:QI 1 "register_operand")
11341         (match_operator:QI 2 "ix86_comparison_operator"
11342           [(reg FLAGS_REG) (const_int 0)]))
11343    (set (match_operand 3 "q_regs_operand")
11344         (zero_extend (match_dup 1)))]
11345   "(peep2_reg_dead_p (3, operands[1])
11346     || operands_match_p (operands[1], operands[3]))
11347    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11348   [(set (match_dup 4) (match_dup 0))
11349    (set (strict_low_part (match_dup 5))
11350         (match_dup 2))]
11352   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11353   operands[5] = gen_lowpart (QImode, operands[3]);
11354   ix86_expand_clear (operands[3]);
11357 (define_peephole2
11358   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11359               (match_operand 4)])
11360    (set (match_operand:QI 1 "register_operand")
11361         (match_operator:QI 2 "ix86_comparison_operator"
11362           [(reg FLAGS_REG) (const_int 0)]))
11363    (set (match_operand 3 "q_regs_operand")
11364         (zero_extend (match_dup 1)))]
11365   "(peep2_reg_dead_p (3, operands[1])
11366     || operands_match_p (operands[1], operands[3]))
11367    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11368   [(parallel [(set (match_dup 5) (match_dup 0))
11369               (match_dup 4)])
11370    (set (strict_low_part (match_dup 6))
11371         (match_dup 2))]
11373   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11374   operands[6] = gen_lowpart (QImode, operands[3]);
11375   ix86_expand_clear (operands[3]);
11378 ;; Similar, but match zero extend with andsi3.
11380 (define_peephole2
11381   [(set (reg FLAGS_REG) (match_operand 0))
11382    (set (match_operand:QI 1 "register_operand")
11383         (match_operator:QI 2 "ix86_comparison_operator"
11384           [(reg FLAGS_REG) (const_int 0)]))
11385    (parallel [(set (match_operand:SI 3 "q_regs_operand")
11386                    (and:SI (match_dup 3) (const_int 255)))
11387               (clobber (reg:CC FLAGS_REG))])]
11388   "REGNO (operands[1]) == REGNO (operands[3])
11389    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11390   [(set (match_dup 4) (match_dup 0))
11391    (set (strict_low_part (match_dup 5))
11392         (match_dup 2))]
11394   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11395   operands[5] = gen_lowpart (QImode, operands[3]);
11396   ix86_expand_clear (operands[3]);
11399 (define_peephole2
11400   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11401               (match_operand 4)])
11402    (set (match_operand:QI 1 "register_operand")
11403         (match_operator:QI 2 "ix86_comparison_operator"
11404           [(reg FLAGS_REG) (const_int 0)]))
11405    (parallel [(set (match_operand 3 "q_regs_operand")
11406                    (zero_extend (match_dup 1)))
11407               (clobber (reg:CC FLAGS_REG))])]
11408   "(peep2_reg_dead_p (3, operands[1])
11409     || operands_match_p (operands[1], operands[3]))
11410    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11411   [(parallel [(set (match_dup 5) (match_dup 0))
11412               (match_dup 4)])
11413    (set (strict_low_part (match_dup 6))
11414         (match_dup 2))]
11416   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11417   operands[6] = gen_lowpart (QImode, operands[3]);
11418   ix86_expand_clear (operands[3]);
11421 ;; Call instructions.
11423 ;; The predicates normally associated with named expanders are not properly
11424 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11425 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11427 ;; P6 processors will jump to the address after the decrement when %esp
11428 ;; is used as a call operand, so they will execute return address as a code.
11429 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11431 ;; Register constraint for call instruction.
11432 (define_mode_attr c [(SI "l") (DI "r")])
11434 ;; Call subroutine returning no value.
11436 (define_expand "call"
11437   [(call (match_operand:QI 0)
11438          (match_operand 1))
11439    (use (match_operand 2))]
11440   ""
11442   ix86_expand_call (NULL, operands[0], operands[1],
11443                     operands[2], NULL, false);
11444   DONE;
11447 (define_expand "sibcall"
11448   [(call (match_operand:QI 0)
11449          (match_operand 1))
11450    (use (match_operand 2))]
11451   ""
11453   ix86_expand_call (NULL, operands[0], operands[1],
11454                     operands[2], NULL, true);
11455   DONE;
11458 (define_insn "*call"
11459   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11460          (match_operand 1))]
11461   "!SIBLING_CALL_P (insn)"
11462   "* return ix86_output_call_insn (insn, operands[0]);"
11463   [(set_attr "type" "call")])
11465 (define_insn "*call_rex64_ms_sysv"
11466   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11467          (match_operand 1))
11468    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11469    (clobber (reg:TI XMM6_REG))
11470    (clobber (reg:TI XMM7_REG))
11471    (clobber (reg:TI XMM8_REG))
11472    (clobber (reg:TI XMM9_REG))
11473    (clobber (reg:TI XMM10_REG))
11474    (clobber (reg:TI XMM11_REG))
11475    (clobber (reg:TI XMM12_REG))
11476    (clobber (reg:TI XMM13_REG))
11477    (clobber (reg:TI XMM14_REG))
11478    (clobber (reg:TI XMM15_REG))
11479    (clobber (reg:DI SI_REG))
11480    (clobber (reg:DI DI_REG))]
11481   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11482   "* return ix86_output_call_insn (insn, operands[0]);"
11483   [(set_attr "type" "call")])
11485 (define_insn "*sibcall"
11486   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11487          (match_operand 1))]
11488   "SIBLING_CALL_P (insn)"
11489   "* return ix86_output_call_insn (insn, operands[0]);"
11490   [(set_attr "type" "call")])
11492 (define_expand "call_pop"
11493   [(parallel [(call (match_operand:QI 0)
11494                     (match_operand:SI 1))
11495               (set (reg:SI SP_REG)
11496                    (plus:SI (reg:SI SP_REG)
11497                             (match_operand:SI 3)))])]
11498   "!TARGET_64BIT"
11500   ix86_expand_call (NULL, operands[0], operands[1],
11501                     operands[2], operands[3], false);
11502   DONE;
11505 (define_insn "*call_pop"
11506   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11507          (match_operand 1))
11508    (set (reg:SI SP_REG)
11509         (plus:SI (reg:SI SP_REG)
11510                  (match_operand:SI 2 "immediate_operand" "i")))]
11511   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11512   "* return ix86_output_call_insn (insn, operands[0]);"
11513   [(set_attr "type" "call")])
11515 (define_insn "*sibcall_pop"
11516   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11517          (match_operand 1))
11518    (set (reg:SI SP_REG)
11519         (plus:SI (reg:SI SP_REG)
11520                  (match_operand:SI 2 "immediate_operand" "i")))]
11521   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11522   "* return ix86_output_call_insn (insn, operands[0]);"
11523   [(set_attr "type" "call")])
11525 ;; Call subroutine, returning value in operand 0
11527 (define_expand "call_value"
11528   [(set (match_operand 0)
11529         (call (match_operand:QI 1)
11530               (match_operand 2)))
11531    (use (match_operand 3))]
11532   ""
11534   ix86_expand_call (operands[0], operands[1], operands[2],
11535                     operands[3], NULL, false);
11536   DONE;
11539 (define_expand "sibcall_value"
11540   [(set (match_operand 0)
11541         (call (match_operand:QI 1)
11542               (match_operand 2)))
11543    (use (match_operand 3))]
11544   ""
11546   ix86_expand_call (operands[0], operands[1], operands[2],
11547                     operands[3], NULL, true);
11548   DONE;
11551 (define_insn "*call_value"
11552   [(set (match_operand 0)
11553         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11554               (match_operand 2)))]
11555   "!SIBLING_CALL_P (insn)"
11556   "* return ix86_output_call_insn (insn, operands[1]);"
11557   [(set_attr "type" "callv")])
11559 (define_insn "*sibcall_value"
11560   [(set (match_operand 0)
11561         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11562               (match_operand 2)))]
11563   "SIBLING_CALL_P (insn)"
11564   "* return ix86_output_call_insn (insn, operands[1]);"
11565   [(set_attr "type" "callv")])
11567 (define_insn "*call_value_rex64_ms_sysv"
11568   [(set (match_operand 0)
11569         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11570               (match_operand 2)))
11571    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11572    (clobber (reg:TI XMM6_REG))
11573    (clobber (reg:TI XMM7_REG))
11574    (clobber (reg:TI XMM8_REG))
11575    (clobber (reg:TI XMM9_REG))
11576    (clobber (reg:TI XMM10_REG))
11577    (clobber (reg:TI XMM11_REG))
11578    (clobber (reg:TI XMM12_REG))
11579    (clobber (reg:TI XMM13_REG))
11580    (clobber (reg:TI XMM14_REG))
11581    (clobber (reg:TI XMM15_REG))
11582    (clobber (reg:DI SI_REG))
11583    (clobber (reg:DI DI_REG))]
11584   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11585   "* return ix86_output_call_insn (insn, operands[1]);"
11586   [(set_attr "type" "callv")])
11588 (define_expand "call_value_pop"
11589   [(parallel [(set (match_operand 0)
11590                    (call (match_operand:QI 1)
11591                          (match_operand:SI 2)))
11592               (set (reg:SI SP_REG)
11593                    (plus:SI (reg:SI SP_REG)
11594                             (match_operand:SI 4)))])]
11595   "!TARGET_64BIT"
11597   ix86_expand_call (operands[0], operands[1], operands[2],
11598                     operands[3], operands[4], false);
11599   DONE;
11602 (define_insn "*call_value_pop"
11603   [(set (match_operand 0)
11604         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11605               (match_operand 2)))
11606    (set (reg:SI SP_REG)
11607         (plus:SI (reg:SI SP_REG)
11608                  (match_operand:SI 3 "immediate_operand" "i")))]
11609   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11610   "* return ix86_output_call_insn (insn, operands[1]);"
11611   [(set_attr "type" "callv")])
11613 (define_insn "*sibcall_value_pop"
11614   [(set (match_operand 0)
11615         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11616               (match_operand 2)))
11617    (set (reg:SI SP_REG)
11618         (plus:SI (reg:SI SP_REG)
11619                  (match_operand:SI 3 "immediate_operand" "i")))]
11620   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11621   "* return ix86_output_call_insn (insn, operands[1]);"
11622   [(set_attr "type" "callv")])
11624 ;; Call subroutine returning any type.
11626 (define_expand "untyped_call"
11627   [(parallel [(call (match_operand 0)
11628                     (const_int 0))
11629               (match_operand 1)
11630               (match_operand 2)])]
11631   ""
11633   int i;
11635   /* In order to give reg-stack an easier job in validating two
11636      coprocessor registers as containing a possible return value,
11637      simply pretend the untyped call returns a complex long double
11638      value. 
11640      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11641      and should have the default ABI.  */
11643   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11644                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11645                     operands[0], const0_rtx,
11646                     GEN_INT ((TARGET_64BIT
11647                               ? (ix86_abi == SYSV_ABI
11648                                  ? X86_64_SSE_REGPARM_MAX
11649                                  : X86_64_MS_SSE_REGPARM_MAX)
11650                               : X86_32_SSE_REGPARM_MAX)
11651                              - 1),
11652                     NULL, false);
11654   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11655     {
11656       rtx set = XVECEXP (operands[2], 0, i);
11657       emit_move_insn (SET_DEST (set), SET_SRC (set));
11658     }
11660   /* The optimizer does not know that the call sets the function value
11661      registers we stored in the result block.  We avoid problems by
11662      claiming that all hard registers are used and clobbered at this
11663      point.  */
11664   emit_insn (gen_blockage ());
11666   DONE;
11669 ;; Prologue and epilogue instructions
11671 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11672 ;; all of memory.  This blocks insns from being moved across this point.
11674 (define_insn "blockage"
11675   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11676   ""
11677   ""
11678   [(set_attr "length" "0")])
11680 ;; Do not schedule instructions accessing memory across this point.
11682 (define_expand "memory_blockage"
11683   [(set (match_dup 0)
11684         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11685   ""
11687   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11688   MEM_VOLATILE_P (operands[0]) = 1;
11691 (define_insn "*memory_blockage"
11692   [(set (match_operand:BLK 0)
11693         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11694   ""
11695   ""
11696   [(set_attr "length" "0")])
11698 ;; As USE insns aren't meaningful after reload, this is used instead
11699 ;; to prevent deleting instructions setting registers for PIC code
11700 (define_insn "prologue_use"
11701   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11702   ""
11703   ""
11704   [(set_attr "length" "0")])
11706 ;; Insn emitted into the body of a function to return from a function.
11707 ;; This is only done if the function's epilogue is known to be simple.
11708 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11710 (define_expand "return"
11711   [(simple_return)]
11712   "ix86_can_use_return_insn_p ()"
11714   if (crtl->args.pops_args)
11715     {
11716       rtx popc = GEN_INT (crtl->args.pops_args);
11717       emit_jump_insn (gen_simple_return_pop_internal (popc));
11718       DONE;
11719     }
11722 ;; We need to disable this for TARGET_SEH, as otherwise
11723 ;; shrink-wrapped prologue gets enabled too.  This might exceed
11724 ;; the maximum size of prologue in unwind information.
11726 (define_expand "simple_return"
11727   [(simple_return)]
11728   "!TARGET_SEH"
11730   if (crtl->args.pops_args)
11731     {
11732       rtx popc = GEN_INT (crtl->args.pops_args);
11733       emit_jump_insn (gen_simple_return_pop_internal (popc));
11734       DONE;
11735     }
11738 (define_insn "simple_return_internal"
11739   [(simple_return)]
11740   "reload_completed"
11741   "ret"
11742   [(set_attr "length" "1")
11743    (set_attr "atom_unit" "jeu")
11744    (set_attr "length_immediate" "0")
11745    (set_attr "modrm" "0")])
11747 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11748 ;; instruction Athlon and K8 have.
11750 (define_insn "simple_return_internal_long"
11751   [(simple_return)
11752    (unspec [(const_int 0)] UNSPEC_REP)]
11753   "reload_completed"
11754   "rep%; ret"
11755   [(set_attr "length" "2")
11756    (set_attr "atom_unit" "jeu")
11757    (set_attr "length_immediate" "0")
11758    (set_attr "prefix_rep" "1")
11759    (set_attr "modrm" "0")])
11761 (define_insn "simple_return_pop_internal"
11762   [(simple_return)
11763    (use (match_operand:SI 0 "const_int_operand"))]
11764   "reload_completed"
11765   "ret\t%0"
11766   [(set_attr "length" "3")
11767    (set_attr "atom_unit" "jeu")
11768    (set_attr "length_immediate" "2")
11769    (set_attr "modrm" "0")])
11771 (define_insn "simple_return_indirect_internal"
11772   [(simple_return)
11773    (use (match_operand:SI 0 "register_operand" "r"))]
11774   "reload_completed"
11775   "jmp\t%A0"
11776   [(set_attr "type" "ibr")
11777    (set_attr "length_immediate" "0")])
11779 (define_insn "nop"
11780   [(const_int 0)]
11781   ""
11782   "nop"
11783   [(set_attr "length" "1")
11784    (set_attr "length_immediate" "0")
11785    (set_attr "modrm" "0")])
11787 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11788 (define_insn "nops"
11789   [(unspec_volatile [(match_operand 0 "const_int_operand")]
11790                     UNSPECV_NOPS)]
11791   "reload_completed"
11793   int num = INTVAL (operands[0]);
11795   gcc_assert (IN_RANGE (num, 1, 8));
11797   while (num--)
11798     fputs ("\tnop\n", asm_out_file);
11800   return "";
11802   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11803    (set_attr "length_immediate" "0")
11804    (set_attr "modrm" "0")])
11806 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11807 ;; branch prediction penalty for the third jump in a 16-byte
11808 ;; block on K8.
11810 (define_insn "pad"
11811   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11812   ""
11814 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11815   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11816 #else
11817   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11818      The align insn is used to avoid 3 jump instructions in the row to improve
11819      branch prediction and the benefits hardly outweigh the cost of extra 8
11820      nops on the average inserted by full alignment pseudo operation.  */
11821 #endif
11822   return "";
11824   [(set_attr "length" "16")])
11826 (define_expand "prologue"
11827   [(const_int 0)]
11828   ""
11829   "ix86_expand_prologue (); DONE;")
11831 (define_insn "set_got"
11832   [(set (match_operand:SI 0 "register_operand" "=r")
11833         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11834    (clobber (reg:CC FLAGS_REG))]
11835   "!TARGET_64BIT"
11836   "* return output_set_got (operands[0], NULL_RTX);"
11837   [(set_attr "type" "multi")
11838    (set_attr "length" "12")])
11840 (define_insn "set_got_labelled"
11841   [(set (match_operand:SI 0 "register_operand" "=r")
11842         (unspec:SI [(label_ref (match_operand 1))]
11843          UNSPEC_SET_GOT))
11844    (clobber (reg:CC FLAGS_REG))]
11845   "!TARGET_64BIT"
11846   "* return output_set_got (operands[0], operands[1]);"
11847   [(set_attr "type" "multi")
11848    (set_attr "length" "12")])
11850 (define_insn "set_got_rex64"
11851   [(set (match_operand:DI 0 "register_operand" "=r")
11852         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11853   "TARGET_64BIT"
11854   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11855   [(set_attr "type" "lea")
11856    (set_attr "length_address" "4")
11857    (set_attr "mode" "DI")])
11859 (define_insn "set_rip_rex64"
11860   [(set (match_operand:DI 0 "register_operand" "=r")
11861         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
11862   "TARGET_64BIT"
11863   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11864   [(set_attr "type" "lea")
11865    (set_attr "length_address" "4")
11866    (set_attr "mode" "DI")])
11868 (define_insn "set_got_offset_rex64"
11869   [(set (match_operand:DI 0 "register_operand" "=r")
11870         (unspec:DI
11871           [(label_ref (match_operand 1))]
11872           UNSPEC_SET_GOT_OFFSET))]
11873   "TARGET_LP64"
11874   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11875   [(set_attr "type" "imov")
11876    (set_attr "length_immediate" "0")
11877    (set_attr "length_address" "8")
11878    (set_attr "mode" "DI")])
11880 (define_expand "epilogue"
11881   [(const_int 0)]
11882   ""
11883   "ix86_expand_epilogue (1); DONE;")
11885 (define_expand "sibcall_epilogue"
11886   [(const_int 0)]
11887   ""
11888   "ix86_expand_epilogue (0); DONE;")
11890 (define_expand "eh_return"
11891   [(use (match_operand 0 "register_operand"))]
11892   ""
11894   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11896   /* Tricky bit: we write the address of the handler to which we will
11897      be returning into someone else's stack frame, one word below the
11898      stack address we wish to restore.  */
11899   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11900   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
11901   tmp = gen_rtx_MEM (Pmode, tmp);
11902   emit_move_insn (tmp, ra);
11904   emit_jump_insn (gen_eh_return_internal ());
11905   emit_barrier ();
11906   DONE;
11909 (define_insn_and_split "eh_return_internal"
11910   [(eh_return)]
11911   ""
11912   "#"
11913   "epilogue_completed"
11914   [(const_int 0)]
11915   "ix86_expand_epilogue (2); DONE;")
11917 (define_insn "leave"
11918   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11919    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11920    (clobber (mem:BLK (scratch)))]
11921   "!TARGET_64BIT"
11922   "leave"
11923   [(set_attr "type" "leave")])
11925 (define_insn "leave_rex64"
11926   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11927    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11928    (clobber (mem:BLK (scratch)))]
11929   "TARGET_64BIT"
11930   "leave"
11931   [(set_attr "type" "leave")])
11933 ;; Handle -fsplit-stack.
11935 (define_expand "split_stack_prologue"
11936   [(const_int 0)]
11937   ""
11939   ix86_expand_split_stack_prologue ();
11940   DONE;
11943 ;; In order to support the call/return predictor, we use a return
11944 ;; instruction which the middle-end doesn't see.
11945 (define_insn "split_stack_return"
11946   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
11947                      UNSPECV_SPLIT_STACK_RETURN)]
11948   ""
11950   if (operands[0] == const0_rtx)
11951     return "ret";
11952   else
11953     return "ret\t%0";
11955   [(set_attr "atom_unit" "jeu")
11956    (set_attr "modrm" "0")
11957    (set (attr "length")
11958         (if_then_else (match_operand:SI 0 "const0_operand")
11959                       (const_int 1)
11960                       (const_int 3)))
11961    (set (attr "length_immediate")
11962         (if_then_else (match_operand:SI 0 "const0_operand")
11963                       (const_int 0)
11964                       (const_int 2)))])
11966 ;; If there are operand 0 bytes available on the stack, jump to
11967 ;; operand 1.
11969 (define_expand "split_stack_space_check"
11970   [(set (pc) (if_then_else
11971               (ltu (minus (reg SP_REG)
11972                           (match_operand 0 "register_operand"))
11973                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11974               (label_ref (match_operand 1))
11975               (pc)))]
11976   ""
11978   rtx reg, size, limit;
11980   reg = gen_reg_rtx (Pmode);
11981   size = force_reg (Pmode, operands[0]);
11982   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11983   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11984                           UNSPEC_STACK_CHECK);
11985   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11986   ix86_expand_branch (GEU, reg, limit, operands[1]);
11988   DONE;
11991 ;; Bit manipulation instructions.
11993 (define_expand "ffs<mode>2"
11994   [(set (match_dup 2) (const_int -1))
11995    (parallel [(set (match_dup 3) (match_dup 4))
11996               (set (match_operand:SWI48 0 "register_operand")
11997                    (ctz:SWI48
11998                      (match_operand:SWI48 1 "nonimmediate_operand")))])
11999    (set (match_dup 0) (if_then_else:SWI48
12000                         (eq (match_dup 3) (const_int 0))
12001                         (match_dup 2)
12002                         (match_dup 0)))
12003    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12004               (clobber (reg:CC FLAGS_REG))])]
12005   ""
12007   enum machine_mode flags_mode;
12009   if (<MODE>mode == SImode && !TARGET_CMOVE)
12010     {
12011       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12012       DONE;
12013     }
12015   flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12017   operands[2] = gen_reg_rtx (<MODE>mode);
12018   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12019   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12022 (define_insn_and_split "ffssi2_no_cmove"
12023   [(set (match_operand:SI 0 "register_operand" "=r")
12024         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12025    (clobber (match_scratch:SI 2 "=&q"))
12026    (clobber (reg:CC FLAGS_REG))]
12027   "!TARGET_CMOVE"
12028   "#"
12029   "&& reload_completed"
12030   [(parallel [(set (match_dup 4) (match_dup 5))
12031               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12032    (set (strict_low_part (match_dup 3))
12033         (eq:QI (match_dup 4) (const_int 0)))
12034    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12035               (clobber (reg:CC FLAGS_REG))])
12036    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12037               (clobber (reg:CC FLAGS_REG))])
12038    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12039               (clobber (reg:CC FLAGS_REG))])]
12041   enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12043   operands[3] = gen_lowpart (QImode, operands[2]);
12044   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12045   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12047   ix86_expand_clear (operands[2]);
12050 (define_insn "*tzcnt<mode>_1"
12051   [(set (reg:CCC FLAGS_REG)
12052         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12053                      (const_int 0)))
12054    (set (match_operand:SWI48 0 "register_operand" "=r")
12055         (ctz:SWI48 (match_dup 1)))]
12056   "TARGET_BMI"
12057   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12058   [(set_attr "type" "alu1")
12059    (set_attr "prefix_0f" "1")
12060    (set_attr "prefix_rep" "1")
12061    (set_attr "btver2_decode" "double")
12062    (set_attr "mode" "<MODE>")])
12064 (define_insn "*bsf<mode>_1"
12065   [(set (reg:CCZ FLAGS_REG)
12066         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12067                      (const_int 0)))
12068    (set (match_operand:SWI48 0 "register_operand" "=r")
12069         (ctz:SWI48 (match_dup 1)))]
12070   ""
12071   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12072   [(set_attr "type" "alu1")
12073    (set_attr "prefix_0f" "1")
12074    (set_attr "btver2_decode" "double")
12075    (set_attr "mode" "<MODE>")])
12077 (define_insn "ctz<mode>2"
12078   [(set (match_operand:SWI248 0 "register_operand" "=r")
12079         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12080    (clobber (reg:CC FLAGS_REG))]
12081   ""
12083   if (TARGET_BMI)
12084     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12085   else if (optimize_function_for_size_p (cfun))
12086     ;
12087   else if (TARGET_GENERIC)
12088     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12089     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12091   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12093   [(set_attr "type" "alu1")
12094    (set_attr "prefix_0f" "1")
12095    (set (attr "prefix_rep")
12096      (if_then_else
12097        (ior (match_test "TARGET_BMI")
12098             (and (not (match_test "optimize_function_for_size_p (cfun)"))
12099                  (match_test "TARGET_GENERIC")))
12100        (const_string "1")
12101        (const_string "0")))
12102    (set_attr "mode" "<MODE>")])
12104 (define_expand "clz<mode>2"
12105   [(parallel
12106      [(set (match_operand:SWI248 0 "register_operand")
12107            (minus:SWI248
12108              (match_dup 2)
12109              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12110       (clobber (reg:CC FLAGS_REG))])
12111    (parallel
12112      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12113       (clobber (reg:CC FLAGS_REG))])]
12114   ""
12116   if (TARGET_LZCNT)
12117     {
12118       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12119       DONE;
12120     }
12121   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12124 (define_insn "clz<mode>2_lzcnt"
12125   [(set (match_operand:SWI248 0 "register_operand" "=r")
12126         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12127    (clobber (reg:CC FLAGS_REG))]
12128   "TARGET_LZCNT"
12129   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12130   [(set_attr "prefix_rep" "1")
12131    (set_attr "type" "bitmanip")
12132    (set_attr "mode" "<MODE>")])
12134 ;; BMI instructions.
12135 (define_insn "*bmi_andn_<mode>"
12136   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12137         (and:SWI48
12138           (not:SWI48
12139             (match_operand:SWI48 1 "register_operand" "r,r"))
12140             (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12141    (clobber (reg:CC FLAGS_REG))]
12142   "TARGET_BMI"
12143   "andn\t{%2, %1, %0|%0, %1, %2}"
12144   [(set_attr "type" "bitmanip")
12145    (set_attr "btver2_decode" "direct, double")
12146    (set_attr "mode" "<MODE>")])
12148 (define_insn "bmi_bextr_<mode>"
12149   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12150         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12151                        (match_operand:SWI48 2 "register_operand" "r,r")]
12152                        UNSPEC_BEXTR))
12153    (clobber (reg:CC FLAGS_REG))]
12154   "TARGET_BMI"
12155   "bextr\t{%2, %1, %0|%0, %1, %2}"
12156   [(set_attr "type" "bitmanip")
12157    (set_attr "btver2_decode" "direct, double")
12158    (set_attr "mode" "<MODE>")])
12160 (define_insn "*bmi_blsi_<mode>"
12161   [(set (match_operand:SWI48 0 "register_operand" "=r")
12162         (and:SWI48
12163           (neg:SWI48
12164             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12165           (match_dup 1)))
12166    (clobber (reg:CC FLAGS_REG))]
12167   "TARGET_BMI"
12168   "blsi\t{%1, %0|%0, %1}"
12169   [(set_attr "type" "bitmanip")
12170    (set_attr "btver2_decode" "double")
12171    (set_attr "mode" "<MODE>")])
12173 (define_insn "*bmi_blsmsk_<mode>"
12174   [(set (match_operand:SWI48 0 "register_operand" "=r")
12175         (xor:SWI48
12176           (plus:SWI48
12177             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12178             (const_int -1))
12179           (match_dup 1)))
12180    (clobber (reg:CC FLAGS_REG))]
12181   "TARGET_BMI"
12182   "blsmsk\t{%1, %0|%0, %1}"
12183   [(set_attr "type" "bitmanip")
12184    (set_attr "btver2_decode" "double")
12185    (set_attr "mode" "<MODE>")])
12187 (define_insn "*bmi_blsr_<mode>"
12188   [(set (match_operand:SWI48 0 "register_operand" "=r")
12189         (and:SWI48
12190           (plus:SWI48
12191             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12192             (const_int -1))
12193           (match_dup 1)))
12194    (clobber (reg:CC FLAGS_REG))]
12195    "TARGET_BMI"
12196    "blsr\t{%1, %0|%0, %1}"
12197   [(set_attr "type" "bitmanip")
12198    (set_attr "btver2_decode" "double")
12199    (set_attr "mode" "<MODE>")])
12201 ;; BMI2 instructions.
12202 (define_insn "bmi2_bzhi_<mode>3"
12203   [(set (match_operand:SWI48 0 "register_operand" "=r")
12204         (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12205                                    (match_operand:SWI48 2 "register_operand" "r"))
12206                    (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12207    (clobber (reg:CC FLAGS_REG))]
12208   "TARGET_BMI2"
12209   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12210   [(set_attr "type" "bitmanip")
12211    (set_attr "prefix" "vex")
12212    (set_attr "mode" "<MODE>")])
12214 (define_insn "bmi2_pdep_<mode>3"
12215   [(set (match_operand:SWI48 0 "register_operand" "=r")
12216         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12217                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12218                        UNSPEC_PDEP))]
12219   "TARGET_BMI2"
12220   "pdep\t{%2, %1, %0|%0, %1, %2}"
12221   [(set_attr "type" "bitmanip")
12222    (set_attr "prefix" "vex")
12223    (set_attr "mode" "<MODE>")])
12225 (define_insn "bmi2_pext_<mode>3"
12226   [(set (match_operand:SWI48 0 "register_operand" "=r")
12227         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12228                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12229                        UNSPEC_PEXT))]
12230   "TARGET_BMI2"
12231   "pext\t{%2, %1, %0|%0, %1, %2}"
12232   [(set_attr "type" "bitmanip")
12233    (set_attr "prefix" "vex")
12234    (set_attr "mode" "<MODE>")])
12236 ;; TBM instructions.
12237 (define_insn "tbm_bextri_<mode>"
12238   [(set (match_operand:SWI48 0 "register_operand" "=r")
12239         (zero_extract:SWI48
12240           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12241           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12242           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12243    (clobber (reg:CC FLAGS_REG))]
12244    "TARGET_TBM"
12246   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12247   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12249   [(set_attr "type" "bitmanip")
12250    (set_attr "mode" "<MODE>")])
12252 (define_insn "*tbm_blcfill_<mode>"
12253   [(set (match_operand:SWI48 0 "register_operand" "=r")
12254         (and:SWI48
12255           (plus:SWI48
12256             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12257             (const_int 1))
12258           (match_dup 1)))
12259    (clobber (reg:CC FLAGS_REG))]
12260    "TARGET_TBM"
12261    "blcfill\t{%1, %0|%0, %1}"
12262   [(set_attr "type" "bitmanip")
12263    (set_attr "mode" "<MODE>")])
12265 (define_insn "*tbm_blci_<mode>"
12266   [(set (match_operand:SWI48 0 "register_operand" "=r")
12267         (ior:SWI48
12268           (not:SWI48
12269             (plus:SWI48
12270               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12271               (const_int 1)))
12272           (match_dup 1)))
12273    (clobber (reg:CC FLAGS_REG))]
12274    "TARGET_TBM"
12275    "blci\t{%1, %0|%0, %1}"
12276   [(set_attr "type" "bitmanip")
12277    (set_attr "mode" "<MODE>")])
12279 (define_insn "*tbm_blcic_<mode>"
12280   [(set (match_operand:SWI48 0 "register_operand" "=r")
12281         (and:SWI48
12282           (plus:SWI48
12283             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12284             (const_int 1))
12285           (not:SWI48
12286             (match_dup 1))))
12287    (clobber (reg:CC FLAGS_REG))]
12288    "TARGET_TBM"
12289    "blcic\t{%1, %0|%0, %1}"
12290   [(set_attr "type" "bitmanip")
12291    (set_attr "mode" "<MODE>")])
12293 (define_insn "*tbm_blcmsk_<mode>"
12294   [(set (match_operand:SWI48 0 "register_operand" "=r")
12295         (xor:SWI48
12296           (plus:SWI48
12297             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12298             (const_int 1))
12299           (match_dup 1)))
12300    (clobber (reg:CC FLAGS_REG))]
12301    "TARGET_TBM"
12302    "blcmsk\t{%1, %0|%0, %1}"
12303   [(set_attr "type" "bitmanip")
12304    (set_attr "mode" "<MODE>")])
12306 (define_insn "*tbm_blcs_<mode>"
12307   [(set (match_operand:SWI48 0 "register_operand" "=r")
12308         (ior:SWI48
12309           (plus:SWI48
12310             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12311             (const_int 1))
12312           (match_dup 1)))
12313    (clobber (reg:CC FLAGS_REG))]
12314    "TARGET_TBM"
12315    "blcs\t{%1, %0|%0, %1}"
12316   [(set_attr "type" "bitmanip")
12317    (set_attr "mode" "<MODE>")])
12319 (define_insn "*tbm_blsfill_<mode>"
12320   [(set (match_operand:SWI48 0 "register_operand" "=r")
12321         (ior:SWI48
12322           (plus:SWI48
12323             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12324             (const_int -1))
12325           (match_dup 1)))
12326    (clobber (reg:CC FLAGS_REG))]
12327    "TARGET_TBM"
12328    "blsfill\t{%1, %0|%0, %1}"
12329   [(set_attr "type" "bitmanip")
12330    (set_attr "mode" "<MODE>")])
12332 (define_insn "*tbm_blsic_<mode>"
12333   [(set (match_operand:SWI48 0 "register_operand" "=r")
12334         (ior:SWI48
12335           (plus:SWI48
12336             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12337             (const_int -1))
12338           (not:SWI48
12339             (match_dup 1))))
12340    (clobber (reg:CC FLAGS_REG))]
12341    "TARGET_TBM"
12342    "blsic\t{%1, %0|%0, %1}"
12343   [(set_attr "type" "bitmanip")
12344    (set_attr "mode" "<MODE>")])
12346 (define_insn "*tbm_t1mskc_<mode>"
12347   [(set (match_operand:SWI48 0 "register_operand" "=r")
12348         (ior:SWI48
12349           (plus:SWI48
12350             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12351             (const_int 1))
12352           (not:SWI48
12353             (match_dup 1))))
12354    (clobber (reg:CC FLAGS_REG))]
12355    "TARGET_TBM"
12356    "t1mskc\t{%1, %0|%0, %1}"
12357   [(set_attr "type" "bitmanip")
12358    (set_attr "mode" "<MODE>")])
12360 (define_insn "*tbm_tzmsk_<mode>"
12361   [(set (match_operand:SWI48 0 "register_operand" "=r")
12362         (and:SWI48
12363           (plus:SWI48
12364             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12365             (const_int -1))
12366           (not:SWI48
12367             (match_dup 1))))
12368    (clobber (reg:CC FLAGS_REG))]
12369    "TARGET_TBM"
12370    "tzmsk\t{%1, %0|%0, %1}"
12371   [(set_attr "type" "bitmanip")
12372    (set_attr "mode" "<MODE>")])
12374 (define_insn "bsr_rex64"
12375   [(set (match_operand:DI 0 "register_operand" "=r")
12376         (minus:DI (const_int 63)
12377                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12378    (clobber (reg:CC FLAGS_REG))]
12379   "TARGET_64BIT"
12380   "bsr{q}\t{%1, %0|%0, %1}"
12381   [(set_attr "type" "alu1")
12382    (set_attr "prefix_0f" "1")
12383    (set_attr "mode" "DI")])
12385 (define_insn "bsr"
12386   [(set (match_operand:SI 0 "register_operand" "=r")
12387         (minus:SI (const_int 31)
12388                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12389    (clobber (reg:CC FLAGS_REG))]
12390   ""
12391   "bsr{l}\t{%1, %0|%0, %1}"
12392   [(set_attr "type" "alu1")
12393    (set_attr "prefix_0f" "1")
12394    (set_attr "mode" "SI")])
12396 (define_insn "*bsrhi"
12397   [(set (match_operand:HI 0 "register_operand" "=r")
12398         (minus:HI (const_int 15)
12399                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12400    (clobber (reg:CC FLAGS_REG))]
12401   ""
12402   "bsr{w}\t{%1, %0|%0, %1}"
12403   [(set_attr "type" "alu1")
12404    (set_attr "prefix_0f" "1")
12405    (set_attr "mode" "HI")])
12407 (define_insn "popcount<mode>2"
12408   [(set (match_operand:SWI248 0 "register_operand" "=r")
12409         (popcount:SWI248
12410           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12411    (clobber (reg:CC FLAGS_REG))]
12412   "TARGET_POPCNT"
12414 #if TARGET_MACHO
12415   return "popcnt\t{%1, %0|%0, %1}";
12416 #else
12417   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12418 #endif
12420   [(set_attr "prefix_rep" "1")
12421    (set_attr "type" "bitmanip")
12422    (set_attr "mode" "<MODE>")])
12424 (define_insn "*popcount<mode>2_cmp"
12425   [(set (reg FLAGS_REG)
12426         (compare
12427           (popcount:SWI248
12428             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12429           (const_int 0)))
12430    (set (match_operand:SWI248 0 "register_operand" "=r")
12431         (popcount:SWI248 (match_dup 1)))]
12432   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12434 #if TARGET_MACHO
12435   return "popcnt\t{%1, %0|%0, %1}";
12436 #else
12437   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12438 #endif
12440   [(set_attr "prefix_rep" "1")
12441    (set_attr "type" "bitmanip")
12442    (set_attr "mode" "<MODE>")])
12444 (define_insn "*popcountsi2_cmp_zext"
12445   [(set (reg FLAGS_REG)
12446         (compare
12447           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12448           (const_int 0)))
12449    (set (match_operand:DI 0 "register_operand" "=r")
12450         (zero_extend:DI(popcount:SI (match_dup 1))))]
12451   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12453 #if TARGET_MACHO
12454   return "popcnt\t{%1, %0|%0, %1}";
12455 #else
12456   return "popcnt{l}\t{%1, %0|%0, %1}";
12457 #endif
12459   [(set_attr "prefix_rep" "1")
12460    (set_attr "type" "bitmanip")
12461    (set_attr "mode" "SI")])
12463 (define_expand "bswapdi2"
12464   [(set (match_operand:DI 0 "register_operand")
12465         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12466   "TARGET_64BIT"
12468   if (!TARGET_MOVBE)
12469     operands[1] = force_reg (DImode, operands[1]);
12472 (define_expand "bswapsi2"
12473   [(set (match_operand:SI 0 "register_operand")
12474         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12475   ""
12477   if (TARGET_MOVBE)
12478     ;
12479   else if (TARGET_BSWAP)
12480     operands[1] = force_reg (SImode, operands[1]);
12481   else
12482     {
12483       rtx x = operands[0];
12485       emit_move_insn (x, operands[1]);
12486       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12487       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12488       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12489       DONE;
12490     }
12493 (define_insn "*bswap<mode>2_movbe"
12494   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12495         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12496   "TARGET_MOVBE
12497    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12498   "@
12499     bswap\t%0
12500     movbe\t{%1, %0|%0, %1}
12501     movbe\t{%1, %0|%0, %1}"
12502   [(set_attr "type" "bitmanip,imov,imov")
12503    (set_attr "modrm" "0,1,1")
12504    (set_attr "prefix_0f" "*,1,1")
12505    (set_attr "prefix_extra" "*,1,1")
12506    (set_attr "mode" "<MODE>")])
12508 (define_insn "*bswap<mode>2"
12509   [(set (match_operand:SWI48 0 "register_operand" "=r")
12510         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12511   "TARGET_BSWAP"
12512   "bswap\t%0"
12513   [(set_attr "type" "bitmanip")
12514    (set_attr "modrm" "0")
12515    (set_attr "mode" "<MODE>")])
12517 (define_insn "*bswaphi_lowpart_1"
12518   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12519         (bswap:HI (match_dup 0)))
12520    (clobber (reg:CC FLAGS_REG))]
12521   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12522   "@
12523     xchg{b}\t{%h0, %b0|%b0, %h0}
12524     rol{w}\t{$8, %0|%0, 8}"
12525   [(set_attr "length" "2,4")
12526    (set_attr "mode" "QI,HI")])
12528 (define_insn "bswaphi_lowpart"
12529   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12530         (bswap:HI (match_dup 0)))
12531    (clobber (reg:CC FLAGS_REG))]
12532   ""
12533   "rol{w}\t{$8, %0|%0, 8}"
12534   [(set_attr "length" "4")
12535    (set_attr "mode" "HI")])
12537 (define_expand "paritydi2"
12538   [(set (match_operand:DI 0 "register_operand")
12539         (parity:DI (match_operand:DI 1 "register_operand")))]
12540   "! TARGET_POPCNT"
12542   rtx scratch = gen_reg_rtx (QImode);
12543   rtx cond;
12545   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12546                                 NULL_RTX, operands[1]));
12548   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12549                          gen_rtx_REG (CCmode, FLAGS_REG),
12550                          const0_rtx);
12551   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12553   if (TARGET_64BIT)
12554     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12555   else
12556     {
12557       rtx tmp = gen_reg_rtx (SImode);
12559       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12560       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12561     }
12562   DONE;
12565 (define_expand "paritysi2"
12566   [(set (match_operand:SI 0 "register_operand")
12567         (parity:SI (match_operand:SI 1 "register_operand")))]
12568   "! TARGET_POPCNT"
12570   rtx scratch = gen_reg_rtx (QImode);
12571   rtx cond;
12573   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12575   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12576                          gen_rtx_REG (CCmode, FLAGS_REG),
12577                          const0_rtx);
12578   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12580   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12581   DONE;
12584 (define_insn_and_split "paritydi2_cmp"
12585   [(set (reg:CC FLAGS_REG)
12586         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12587                    UNSPEC_PARITY))
12588    (clobber (match_scratch:DI 0 "=r"))
12589    (clobber (match_scratch:SI 1 "=&r"))
12590    (clobber (match_scratch:HI 2 "=Q"))]
12591   "! TARGET_POPCNT"
12592   "#"
12593   "&& reload_completed"
12594   [(parallel
12595      [(set (match_dup 1)
12596            (xor:SI (match_dup 1) (match_dup 4)))
12597       (clobber (reg:CC FLAGS_REG))])
12598    (parallel
12599      [(set (reg:CC FLAGS_REG)
12600            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12601       (clobber (match_dup 1))
12602       (clobber (match_dup 2))])]
12604   operands[4] = gen_lowpart (SImode, operands[3]);
12606   if (TARGET_64BIT)
12607     {
12608       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12609       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12610     }
12611   else
12612     operands[1] = gen_highpart (SImode, operands[3]);
12615 (define_insn_and_split "paritysi2_cmp"
12616   [(set (reg:CC FLAGS_REG)
12617         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12618                    UNSPEC_PARITY))
12619    (clobber (match_scratch:SI 0 "=r"))
12620    (clobber (match_scratch:HI 1 "=&Q"))]
12621   "! TARGET_POPCNT"
12622   "#"
12623   "&& reload_completed"
12624   [(parallel
12625      [(set (match_dup 1)
12626            (xor:HI (match_dup 1) (match_dup 3)))
12627       (clobber (reg:CC FLAGS_REG))])
12628    (parallel
12629      [(set (reg:CC FLAGS_REG)
12630            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12631       (clobber (match_dup 1))])]
12633   operands[3] = gen_lowpart (HImode, operands[2]);
12635   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12636   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12639 (define_insn "*parityhi2_cmp"
12640   [(set (reg:CC FLAGS_REG)
12641         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12642                    UNSPEC_PARITY))
12643    (clobber (match_scratch:HI 0 "=Q"))]
12644   "! TARGET_POPCNT"
12645   "xor{b}\t{%h0, %b0|%b0, %h0}"
12646   [(set_attr "length" "2")
12647    (set_attr "mode" "HI")])
12650 ;; Thread-local storage patterns for ELF.
12652 ;; Note that these code sequences must appear exactly as shown
12653 ;; in order to allow linker relaxation.
12655 (define_insn "*tls_global_dynamic_32_gnu"
12656   [(set (match_operand:SI 0 "register_operand" "=a")
12657         (unspec:SI
12658          [(match_operand:SI 1 "register_operand" "b")
12659           (match_operand 2 "tls_symbolic_operand")
12660           (match_operand 3 "constant_call_address_operand" "z")]
12661          UNSPEC_TLS_GD))
12662    (clobber (match_scratch:SI 4 "=d"))
12663    (clobber (match_scratch:SI 5 "=c"))
12664    (clobber (reg:CC FLAGS_REG))]
12665   "!TARGET_64BIT && TARGET_GNU_TLS"
12667   output_asm_insn
12668     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12669   if (TARGET_SUN_TLS)
12670 #ifdef HAVE_AS_IX86_TLSGDPLT
12671     return "call\t%a2@tlsgdplt";
12672 #else
12673     return "call\t%p3@plt";
12674 #endif
12675   return "call\t%P3";
12677   [(set_attr "type" "multi")
12678    (set_attr "length" "12")])
12680 (define_expand "tls_global_dynamic_32"
12681   [(parallel
12682     [(set (match_operand:SI 0 "register_operand")
12683           (unspec:SI [(match_operand:SI 2 "register_operand")
12684                       (match_operand 1 "tls_symbolic_operand")
12685                       (match_operand 3 "constant_call_address_operand")]
12686                      UNSPEC_TLS_GD))
12687      (clobber (match_scratch:SI 4))
12688      (clobber (match_scratch:SI 5))
12689      (clobber (reg:CC FLAGS_REG))])])
12691 (define_insn "*tls_global_dynamic_64_<mode>"
12692   [(set (match_operand:P 0 "register_operand" "=a")
12693         (call:P
12694          (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12695          (match_operand 3)))
12696    (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12697              UNSPEC_TLS_GD)]
12698   "TARGET_64BIT"
12700   if (!TARGET_X32)
12701     fputs (ASM_BYTE "0x66\n", asm_out_file);
12702   output_asm_insn
12703     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12704   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12705   fputs ("\trex64\n", asm_out_file);
12706   if (TARGET_SUN_TLS)
12707     return "call\t%p2@plt";
12708   return "call\t%P2";
12710   [(set_attr "type" "multi")
12711    (set (attr "length")
12712         (symbol_ref "TARGET_X32 ? 15 : 16"))])
12714 (define_expand "tls_global_dynamic_64_<mode>"
12715   [(parallel
12716     [(set (match_operand:P 0 "register_operand")
12717           (call:P
12718            (mem:QI (match_operand 2 "constant_call_address_operand"))
12719            (const_int 0)))
12720      (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12721                UNSPEC_TLS_GD)])]
12722   "TARGET_64BIT")
12724 (define_insn "*tls_local_dynamic_base_32_gnu"
12725   [(set (match_operand:SI 0 "register_operand" "=a")
12726         (unspec:SI
12727          [(match_operand:SI 1 "register_operand" "b")
12728           (match_operand 2 "constant_call_address_operand" "z")]
12729          UNSPEC_TLS_LD_BASE))
12730    (clobber (match_scratch:SI 3 "=d"))
12731    (clobber (match_scratch:SI 4 "=c"))
12732    (clobber (reg:CC FLAGS_REG))]
12733   "!TARGET_64BIT && TARGET_GNU_TLS"
12735   output_asm_insn
12736     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12737   if (TARGET_SUN_TLS)
12738 #ifdef HAVE_AS_IX86_TLSLDMPLT
12739     return "call\t%&@tlsldmplt";
12740 #else
12741     return "call\t%p2@plt";
12742 #endif
12743   return "call\t%P2";
12745   [(set_attr "type" "multi")
12746    (set_attr "length" "11")])
12748 (define_expand "tls_local_dynamic_base_32"
12749   [(parallel
12750      [(set (match_operand:SI 0 "register_operand")
12751            (unspec:SI
12752             [(match_operand:SI 1 "register_operand")
12753              (match_operand 2 "constant_call_address_operand")]
12754             UNSPEC_TLS_LD_BASE))
12755       (clobber (match_scratch:SI 3))
12756       (clobber (match_scratch:SI 4))
12757       (clobber (reg:CC FLAGS_REG))])])
12759 (define_insn "*tls_local_dynamic_base_64_<mode>"
12760   [(set (match_operand:P 0 "register_operand" "=a")
12761         (call:P
12762          (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12763          (match_operand 2)))
12764    (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12765   "TARGET_64BIT"
12767   output_asm_insn
12768     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12769   if (TARGET_SUN_TLS)
12770     return "call\t%p1@plt";
12771   return "call\t%P1";
12773   [(set_attr "type" "multi")
12774    (set_attr "length" "12")])
12776 (define_expand "tls_local_dynamic_base_64_<mode>"
12777   [(parallel
12778      [(set (match_operand:P 0 "register_operand")
12779            (call:P
12780             (mem:QI (match_operand 1 "constant_call_address_operand"))
12781             (const_int 0)))
12782       (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12783   "TARGET_64BIT")
12785 ;; Local dynamic of a single variable is a lose.  Show combine how
12786 ;; to convert that back to global dynamic.
12788 (define_insn_and_split "*tls_local_dynamic_32_once"
12789   [(set (match_operand:SI 0 "register_operand" "=a")
12790         (plus:SI
12791          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12792                      (match_operand 2 "constant_call_address_operand" "z")]
12793                     UNSPEC_TLS_LD_BASE)
12794          (const:SI (unspec:SI
12795                     [(match_operand 3 "tls_symbolic_operand")]
12796                     UNSPEC_DTPOFF))))
12797    (clobber (match_scratch:SI 4 "=d"))
12798    (clobber (match_scratch:SI 5 "=c"))
12799    (clobber (reg:CC FLAGS_REG))]
12800   ""
12801   "#"
12802   ""
12803   [(parallel
12804      [(set (match_dup 0)
12805            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12806                       UNSPEC_TLS_GD))
12807       (clobber (match_dup 4))
12808       (clobber (match_dup 5))
12809       (clobber (reg:CC FLAGS_REG))])])
12811 ;; Segment register for the thread base ptr load
12812 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12814 ;; Load and add the thread base pointer from %<tp_seg>:0.
12815 (define_insn "*load_tp_x32"
12816   [(set (match_operand:SI 0 "register_operand" "=r")
12817         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12818   "TARGET_X32"
12819   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12820   [(set_attr "type" "imov")
12821    (set_attr "modrm" "0")
12822    (set_attr "length" "7")
12823    (set_attr "memory" "load")
12824    (set_attr "imm_disp" "false")])
12826 (define_insn "*load_tp_x32_zext"
12827   [(set (match_operand:DI 0 "register_operand" "=r")
12828         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12829   "TARGET_X32"
12830   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12831   [(set_attr "type" "imov")
12832    (set_attr "modrm" "0")
12833    (set_attr "length" "7")
12834    (set_attr "memory" "load")
12835    (set_attr "imm_disp" "false")])
12837 (define_insn "*load_tp_<mode>"
12838   [(set (match_operand:P 0 "register_operand" "=r")
12839         (unspec:P [(const_int 0)] UNSPEC_TP))]
12840   "!TARGET_X32"
12841   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12842   [(set_attr "type" "imov")
12843    (set_attr "modrm" "0")
12844    (set_attr "length" "7")
12845    (set_attr "memory" "load")
12846    (set_attr "imm_disp" "false")])
12848 (define_insn "*add_tp_x32"
12849   [(set (match_operand:SI 0 "register_operand" "=r")
12850         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12851                  (match_operand:SI 1 "register_operand" "0")))
12852    (clobber (reg:CC FLAGS_REG))]
12853   "TARGET_X32"
12854   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12855   [(set_attr "type" "alu")
12856    (set_attr "modrm" "0")
12857    (set_attr "length" "7")
12858    (set_attr "memory" "load")
12859    (set_attr "imm_disp" "false")])
12861 (define_insn "*add_tp_x32_zext"
12862   [(set (match_operand:DI 0 "register_operand" "=r")
12863         (zero_extend:DI
12864           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12865                    (match_operand:SI 1 "register_operand" "0"))))
12866    (clobber (reg:CC FLAGS_REG))]
12867   "TARGET_X32"
12868   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12869   [(set_attr "type" "alu")
12870    (set_attr "modrm" "0")
12871    (set_attr "length" "7")
12872    (set_attr "memory" "load")
12873    (set_attr "imm_disp" "false")])
12875 (define_insn "*add_tp_<mode>"
12876   [(set (match_operand:P 0 "register_operand" "=r")
12877         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12878                 (match_operand:P 1 "register_operand" "0")))
12879    (clobber (reg:CC FLAGS_REG))]
12880   "!TARGET_X32"
12881   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12882   [(set_attr "type" "alu")
12883    (set_attr "modrm" "0")
12884    (set_attr "length" "7")
12885    (set_attr "memory" "load")
12886    (set_attr "imm_disp" "false")])
12888 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12889 ;; %rax as destination of the initial executable code sequence.
12890 (define_insn "tls_initial_exec_64_sun"
12891   [(set (match_operand:DI 0 "register_operand" "=a")
12892         (unspec:DI
12893          [(match_operand 1 "tls_symbolic_operand")]
12894          UNSPEC_TLS_IE_SUN))
12895    (clobber (reg:CC FLAGS_REG))]
12896   "TARGET_64BIT && TARGET_SUN_TLS"
12898   output_asm_insn
12899     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12900   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12902   [(set_attr "type" "multi")])
12904 ;; GNU2 TLS patterns can be split.
12906 (define_expand "tls_dynamic_gnu2_32"
12907   [(set (match_dup 3)
12908         (plus:SI (match_operand:SI 2 "register_operand")
12909                  (const:SI
12910                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
12911                              UNSPEC_TLSDESC))))
12912    (parallel
12913     [(set (match_operand:SI 0 "register_operand")
12914           (unspec:SI [(match_dup 1) (match_dup 3)
12915                       (match_dup 2) (reg:SI SP_REG)]
12916                       UNSPEC_TLSDESC))
12917      (clobber (reg:CC FLAGS_REG))])]
12918   "!TARGET_64BIT && TARGET_GNU2_TLS"
12920   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12921   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12924 (define_insn "*tls_dynamic_gnu2_lea_32"
12925   [(set (match_operand:SI 0 "register_operand" "=r")
12926         (plus:SI (match_operand:SI 1 "register_operand" "b")
12927                  (const:SI
12928                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
12929                               UNSPEC_TLSDESC))))]
12930   "!TARGET_64BIT && TARGET_GNU2_TLS"
12931   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12932   [(set_attr "type" "lea")
12933    (set_attr "mode" "SI")
12934    (set_attr "length" "6")
12935    (set_attr "length_address" "4")])
12937 (define_insn "*tls_dynamic_gnu2_call_32"
12938   [(set (match_operand:SI 0 "register_operand" "=a")
12939         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
12940                     (match_operand:SI 2 "register_operand" "0")
12941                     ;; we have to make sure %ebx still points to the GOT
12942                     (match_operand:SI 3 "register_operand" "b")
12943                     (reg:SI SP_REG)]
12944                    UNSPEC_TLSDESC))
12945    (clobber (reg:CC FLAGS_REG))]
12946   "!TARGET_64BIT && TARGET_GNU2_TLS"
12947   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12948   [(set_attr "type" "call")
12949    (set_attr "length" "2")
12950    (set_attr "length_address" "0")])
12952 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12953   [(set (match_operand:SI 0 "register_operand" "=&a")
12954         (plus:SI
12955          (unspec:SI [(match_operand 3 "tls_modbase_operand")
12956                      (match_operand:SI 4)
12957                      (match_operand:SI 2 "register_operand" "b")
12958                      (reg:SI SP_REG)]
12959                     UNSPEC_TLSDESC)
12960          (const:SI (unspec:SI
12961                     [(match_operand 1 "tls_symbolic_operand")]
12962                     UNSPEC_DTPOFF))))
12963    (clobber (reg:CC FLAGS_REG))]
12964   "!TARGET_64BIT && TARGET_GNU2_TLS"
12965   "#"
12966   ""
12967   [(set (match_dup 0) (match_dup 5))]
12969   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12970   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12973 (define_expand "tls_dynamic_gnu2_64"
12974   [(set (match_dup 2)
12975         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12976                    UNSPEC_TLSDESC))
12977    (parallel
12978     [(set (match_operand:DI 0 "register_operand")
12979           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12980                      UNSPEC_TLSDESC))
12981      (clobber (reg:CC FLAGS_REG))])]
12982   "TARGET_64BIT && TARGET_GNU2_TLS"
12984   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12985   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12988 (define_insn "*tls_dynamic_gnu2_lea_64"
12989   [(set (match_operand:DI 0 "register_operand" "=r")
12990         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12991                    UNSPEC_TLSDESC))]
12992   "TARGET_64BIT && TARGET_GNU2_TLS"
12993   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12994   [(set_attr "type" "lea")
12995    (set_attr "mode" "DI")
12996    (set_attr "length" "7")
12997    (set_attr "length_address" "4")])
12999 (define_insn "*tls_dynamic_gnu2_call_64"
13000   [(set (match_operand:DI 0 "register_operand" "=a")
13001         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13002                     (match_operand:DI 2 "register_operand" "0")
13003                     (reg:DI SP_REG)]
13004                    UNSPEC_TLSDESC))
13005    (clobber (reg:CC FLAGS_REG))]
13006   "TARGET_64BIT && TARGET_GNU2_TLS"
13007   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13008   [(set_attr "type" "call")
13009    (set_attr "length" "2")
13010    (set_attr "length_address" "0")])
13012 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13013   [(set (match_operand:DI 0 "register_operand" "=&a")
13014         (plus:DI
13015          (unspec:DI [(match_operand 2 "tls_modbase_operand")
13016                      (match_operand:DI 3)
13017                      (reg:DI SP_REG)]
13018                     UNSPEC_TLSDESC)
13019          (const:DI (unspec:DI
13020                     [(match_operand 1 "tls_symbolic_operand")]
13021                     UNSPEC_DTPOFF))))
13022    (clobber (reg:CC FLAGS_REG))]
13023   "TARGET_64BIT && TARGET_GNU2_TLS"
13024   "#"
13025   ""
13026   [(set (match_dup 0) (match_dup 4))]
13028   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13029   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13032 ;; These patterns match the binary 387 instructions for addM3, subM3,
13033 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13034 ;; SFmode.  The first is the normal insn, the second the same insn but
13035 ;; with one operand a conversion, and the third the same insn but with
13036 ;; the other operand a conversion.  The conversion may be SFmode or
13037 ;; SImode if the target mode DFmode, but only SImode if the target mode
13038 ;; is SFmode.
13040 ;; Gcc is slightly more smart about handling normal two address instructions
13041 ;; so use special patterns for add and mull.
13043 (define_insn "*fop_<mode>_comm_mixed"
13044   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13045         (match_operator:MODEF 3 "binary_fp_operator"
13046           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13047            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13048   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13049    && COMMUTATIVE_ARITH_P (operands[3])
13050    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13051   "* return output_387_binary_op (insn, operands);"
13052   [(set (attr "type")
13053         (if_then_else (eq_attr "alternative" "1,2")
13054            (if_then_else (match_operand:MODEF 3 "mult_operator")
13055               (const_string "ssemul")
13056               (const_string "sseadd"))
13057            (if_then_else (match_operand:MODEF 3 "mult_operator")
13058               (const_string "fmul")
13059               (const_string "fop"))))
13060    (set_attr "isa" "*,noavx,avx")
13061    (set_attr "prefix" "orig,orig,vex")
13062    (set_attr "mode" "<MODE>")])
13064 (define_insn "*fop_<mode>_comm_sse"
13065   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13066         (match_operator:MODEF 3 "binary_fp_operator"
13067           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13068            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13069   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13070    && COMMUTATIVE_ARITH_P (operands[3])
13071    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13072   "* return output_387_binary_op (insn, operands);"
13073   [(set (attr "type")
13074         (if_then_else (match_operand:MODEF 3 "mult_operator")
13075            (const_string "ssemul")
13076            (const_string "sseadd")))
13077    (set_attr "isa" "noavx,avx")
13078    (set_attr "prefix" "orig,vex")
13079    (set_attr "mode" "<MODE>")])
13081 (define_insn "*fop_<mode>_comm_i387"
13082   [(set (match_operand:MODEF 0 "register_operand" "=f")
13083         (match_operator:MODEF 3 "binary_fp_operator"
13084           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13085            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13086   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13087    && COMMUTATIVE_ARITH_P (operands[3])
13088    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13089   "* return output_387_binary_op (insn, operands);"
13090   [(set (attr "type")
13091         (if_then_else (match_operand:MODEF 3 "mult_operator")
13092            (const_string "fmul")
13093            (const_string "fop")))
13094    (set_attr "mode" "<MODE>")])
13096 (define_insn "*fop_<mode>_1_mixed"
13097   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13098         (match_operator:MODEF 3 "binary_fp_operator"
13099           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13100            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13101   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13102    && !COMMUTATIVE_ARITH_P (operands[3])
13103    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13104   "* return output_387_binary_op (insn, operands);"
13105   [(set (attr "type")
13106         (cond [(and (eq_attr "alternative" "2,3")
13107                     (match_operand:MODEF 3 "mult_operator"))
13108                  (const_string "ssemul")
13109                (and (eq_attr "alternative" "2,3")
13110                     (match_operand:MODEF 3 "div_operator"))
13111                  (const_string "ssediv")
13112                (eq_attr "alternative" "2,3")
13113                  (const_string "sseadd")
13114                (match_operand:MODEF 3 "mult_operator")
13115                  (const_string "fmul")
13116                (match_operand:MODEF 3 "div_operator")
13117                  (const_string "fdiv")
13118               ]
13119               (const_string "fop")))
13120    (set_attr "isa" "*,*,noavx,avx")
13121    (set_attr "prefix" "orig,orig,orig,vex")
13122    (set_attr "mode" "<MODE>")])
13124 (define_insn "*rcpsf2_sse"
13125   [(set (match_operand:SF 0 "register_operand" "=x")
13126         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13127                    UNSPEC_RCP))]
13128   "TARGET_SSE_MATH"
13129   "%vrcpss\t{%1, %d0|%d0, %1}"
13130   [(set_attr "type" "sse")
13131    (set_attr "atom_sse_attr" "rcp")
13132    (set_attr "btver2_sse_attr" "rcp")
13133    (set_attr "prefix" "maybe_vex")
13134    (set_attr "mode" "SF")])
13136 (define_insn "*fop_<mode>_1_sse"
13137   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13138         (match_operator:MODEF 3 "binary_fp_operator"
13139           [(match_operand:MODEF 1 "register_operand" "0,x")
13140            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13141   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13142    && !COMMUTATIVE_ARITH_P (operands[3])"
13143   "* return output_387_binary_op (insn, operands);"
13144   [(set (attr "type")
13145         (cond [(match_operand:MODEF 3 "mult_operator")
13146                  (const_string "ssemul")
13147                (match_operand:MODEF 3 "div_operator")
13148                  (const_string "ssediv")
13149               ]
13150               (const_string "sseadd")))
13151    (set_attr "isa" "noavx,avx")
13152    (set_attr "prefix" "orig,vex")
13153    (set_attr "mode" "<MODE>")])
13155 ;; This pattern is not fully shadowed by the pattern above.
13156 (define_insn "*fop_<mode>_1_i387"
13157   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13158         (match_operator:MODEF 3 "binary_fp_operator"
13159           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13160            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13161   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13162    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13163    && !COMMUTATIVE_ARITH_P (operands[3])
13164    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13165   "* return output_387_binary_op (insn, operands);"
13166   [(set (attr "type")
13167         (cond [(match_operand:MODEF 3 "mult_operator")
13168                  (const_string "fmul")
13169                (match_operand:MODEF 3 "div_operator")
13170                  (const_string "fdiv")
13171               ]
13172               (const_string "fop")))
13173    (set_attr "mode" "<MODE>")])
13175 ;; ??? Add SSE splitters for these!
13176 (define_insn "*fop_<MODEF:mode>_2_i387"
13177   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13178         (match_operator:MODEF 3 "binary_fp_operator"
13179           [(float:MODEF
13180              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13181            (match_operand:MODEF 2 "register_operand" "0,0")]))]
13182   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13183    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13184    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13185   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13186   [(set (attr "type")
13187         (cond [(match_operand:MODEF 3 "mult_operator")
13188                  (const_string "fmul")
13189                (match_operand:MODEF 3 "div_operator")
13190                  (const_string "fdiv")
13191               ]
13192               (const_string "fop")))
13193    (set_attr "fp_int_src" "true")
13194    (set_attr "mode" "<SWI24:MODE>")])
13196 (define_insn "*fop_<MODEF:mode>_3_i387"
13197   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13198         (match_operator:MODEF 3 "binary_fp_operator"
13199           [(match_operand:MODEF 1 "register_operand" "0,0")
13200            (float:MODEF
13201              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13202   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13203    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13204    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13205   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13206   [(set (attr "type")
13207         (cond [(match_operand:MODEF 3 "mult_operator")
13208                  (const_string "fmul")
13209                (match_operand:MODEF 3 "div_operator")
13210                  (const_string "fdiv")
13211               ]
13212               (const_string "fop")))
13213    (set_attr "fp_int_src" "true")
13214    (set_attr "mode" "<MODE>")])
13216 (define_insn "*fop_df_4_i387"
13217   [(set (match_operand:DF 0 "register_operand" "=f,f")
13218         (match_operator:DF 3 "binary_fp_operator"
13219            [(float_extend:DF
13220              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13221             (match_operand:DF 2 "register_operand" "0,f")]))]
13222   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13223    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13224    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13225   "* return output_387_binary_op (insn, operands);"
13226   [(set (attr "type")
13227         (cond [(match_operand:DF 3 "mult_operator")
13228                  (const_string "fmul")
13229                (match_operand:DF 3 "div_operator")
13230                  (const_string "fdiv")
13231               ]
13232               (const_string "fop")))
13233    (set_attr "mode" "SF")])
13235 (define_insn "*fop_df_5_i387"
13236   [(set (match_operand:DF 0 "register_operand" "=f,f")
13237         (match_operator:DF 3 "binary_fp_operator"
13238           [(match_operand:DF 1 "register_operand" "0,f")
13239            (float_extend:DF
13240             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13241   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13242    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13243   "* return output_387_binary_op (insn, operands);"
13244   [(set (attr "type")
13245         (cond [(match_operand:DF 3 "mult_operator")
13246                  (const_string "fmul")
13247                (match_operand:DF 3 "div_operator")
13248                  (const_string "fdiv")
13249               ]
13250               (const_string "fop")))
13251    (set_attr "mode" "SF")])
13253 (define_insn "*fop_df_6_i387"
13254   [(set (match_operand:DF 0 "register_operand" "=f,f")
13255         (match_operator:DF 3 "binary_fp_operator"
13256           [(float_extend:DF
13257             (match_operand:SF 1 "register_operand" "0,f"))
13258            (float_extend:DF
13259             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13260   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13261    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13262   "* return output_387_binary_op (insn, operands);"
13263   [(set (attr "type")
13264         (cond [(match_operand:DF 3 "mult_operator")
13265                  (const_string "fmul")
13266                (match_operand:DF 3 "div_operator")
13267                  (const_string "fdiv")
13268               ]
13269               (const_string "fop")))
13270    (set_attr "mode" "SF")])
13272 (define_insn "*fop_xf_comm_i387"
13273   [(set (match_operand:XF 0 "register_operand" "=f")
13274         (match_operator:XF 3 "binary_fp_operator"
13275                         [(match_operand:XF 1 "register_operand" "%0")
13276                          (match_operand:XF 2 "register_operand" "f")]))]
13277   "TARGET_80387
13278    && COMMUTATIVE_ARITH_P (operands[3])"
13279   "* return output_387_binary_op (insn, operands);"
13280   [(set (attr "type")
13281         (if_then_else (match_operand:XF 3 "mult_operator")
13282            (const_string "fmul")
13283            (const_string "fop")))
13284    (set_attr "mode" "XF")])
13286 (define_insn "*fop_xf_1_i387"
13287   [(set (match_operand:XF 0 "register_operand" "=f,f")
13288         (match_operator:XF 3 "binary_fp_operator"
13289                         [(match_operand:XF 1 "register_operand" "0,f")
13290                          (match_operand:XF 2 "register_operand" "f,0")]))]
13291   "TARGET_80387
13292    && !COMMUTATIVE_ARITH_P (operands[3])"
13293   "* return output_387_binary_op (insn, operands);"
13294   [(set (attr "type")
13295         (cond [(match_operand:XF 3 "mult_operator")
13296                  (const_string "fmul")
13297                (match_operand:XF 3 "div_operator")
13298                  (const_string "fdiv")
13299               ]
13300               (const_string "fop")))
13301    (set_attr "mode" "XF")])
13303 (define_insn "*fop_xf_2_i387"
13304   [(set (match_operand:XF 0 "register_operand" "=f,f")
13305         (match_operator:XF 3 "binary_fp_operator"
13306           [(float:XF
13307              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13308            (match_operand:XF 2 "register_operand" "0,0")]))]
13309   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13310   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13311   [(set (attr "type")
13312         (cond [(match_operand:XF 3 "mult_operator")
13313                  (const_string "fmul")
13314                (match_operand:XF 3 "div_operator")
13315                  (const_string "fdiv")
13316               ]
13317               (const_string "fop")))
13318    (set_attr "fp_int_src" "true")
13319    (set_attr "mode" "<MODE>")])
13321 (define_insn "*fop_xf_3_i387"
13322   [(set (match_operand:XF 0 "register_operand" "=f,f")
13323         (match_operator:XF 3 "binary_fp_operator"
13324           [(match_operand:XF 1 "register_operand" "0,0")
13325            (float:XF
13326              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13327   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13328   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13329   [(set (attr "type")
13330         (cond [(match_operand:XF 3 "mult_operator")
13331                  (const_string "fmul")
13332                (match_operand:XF 3 "div_operator")
13333                  (const_string "fdiv")
13334               ]
13335               (const_string "fop")))
13336    (set_attr "fp_int_src" "true")
13337    (set_attr "mode" "<MODE>")])
13339 (define_insn "*fop_xf_4_i387"
13340   [(set (match_operand:XF 0 "register_operand" "=f,f")
13341         (match_operator:XF 3 "binary_fp_operator"
13342            [(float_extend:XF
13343               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13344             (match_operand:XF 2 "register_operand" "0,f")]))]
13345   "TARGET_80387"
13346   "* return output_387_binary_op (insn, operands);"
13347   [(set (attr "type")
13348         (cond [(match_operand:XF 3 "mult_operator")
13349                  (const_string "fmul")
13350                (match_operand:XF 3 "div_operator")
13351                  (const_string "fdiv")
13352               ]
13353               (const_string "fop")))
13354    (set_attr "mode" "<MODE>")])
13356 (define_insn "*fop_xf_5_i387"
13357   [(set (match_operand:XF 0 "register_operand" "=f,f")
13358         (match_operator:XF 3 "binary_fp_operator"
13359           [(match_operand:XF 1 "register_operand" "0,f")
13360            (float_extend:XF
13361              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13362   "TARGET_80387"
13363   "* return output_387_binary_op (insn, operands);"
13364   [(set (attr "type")
13365         (cond [(match_operand:XF 3 "mult_operator")
13366                  (const_string "fmul")
13367                (match_operand:XF 3 "div_operator")
13368                  (const_string "fdiv")
13369               ]
13370               (const_string "fop")))
13371    (set_attr "mode" "<MODE>")])
13373 (define_insn "*fop_xf_6_i387"
13374   [(set (match_operand:XF 0 "register_operand" "=f,f")
13375         (match_operator:XF 3 "binary_fp_operator"
13376           [(float_extend:XF
13377              (match_operand:MODEF 1 "register_operand" "0,f"))
13378            (float_extend:XF
13379              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13380   "TARGET_80387"
13381   "* return output_387_binary_op (insn, operands);"
13382   [(set (attr "type")
13383         (cond [(match_operand:XF 3 "mult_operator")
13384                  (const_string "fmul")
13385                (match_operand:XF 3 "div_operator")
13386                  (const_string "fdiv")
13387               ]
13388               (const_string "fop")))
13389    (set_attr "mode" "<MODE>")])
13391 (define_split
13392   [(set (match_operand 0 "register_operand")
13393         (match_operator 3 "binary_fp_operator"
13394            [(float (match_operand:SWI24 1 "register_operand"))
13395             (match_operand 2 "register_operand")]))]
13396   "reload_completed
13397    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13398    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13399   [(const_int 0)]
13401   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13402   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13403   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13404                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13405                                           GET_MODE (operands[3]),
13406                                           operands[4],
13407                                           operands[2])));
13408   ix86_free_from_memory (GET_MODE (operands[1]));
13409   DONE;
13412 (define_split
13413   [(set (match_operand 0 "register_operand")
13414         (match_operator 3 "binary_fp_operator"
13415            [(match_operand 1 "register_operand")
13416             (float (match_operand:SWI24 2 "register_operand"))]))]
13417   "reload_completed
13418    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13419    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13420   [(const_int 0)]
13422   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13423   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13424   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13425                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13426                                           GET_MODE (operands[3]),
13427                                           operands[1],
13428                                           operands[4])));
13429   ix86_free_from_memory (GET_MODE (operands[2]));
13430   DONE;
13433 ;; FPU special functions.
13435 ;; This pattern implements a no-op XFmode truncation for
13436 ;; all fancy i386 XFmode math functions.
13438 (define_insn "truncxf<mode>2_i387_noop_unspec"
13439   [(set (match_operand:MODEF 0 "register_operand" "=f")
13440         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13441         UNSPEC_TRUNC_NOOP))]
13442   "TARGET_USE_FANCY_MATH_387"
13443   "* return output_387_reg_move (insn, operands);"
13444   [(set_attr "type" "fmov")
13445    (set_attr "mode" "<MODE>")])
13447 (define_insn "sqrtxf2"
13448   [(set (match_operand:XF 0 "register_operand" "=f")
13449         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13450   "TARGET_USE_FANCY_MATH_387"
13451   "fsqrt"
13452   [(set_attr "type" "fpspc")
13453    (set_attr "mode" "XF")
13454    (set_attr "athlon_decode" "direct")
13455    (set_attr "amdfam10_decode" "direct")
13456    (set_attr "bdver1_decode" "direct")])
13458 (define_insn "sqrt_extend<mode>xf2_i387"
13459   [(set (match_operand:XF 0 "register_operand" "=f")
13460         (sqrt:XF
13461           (float_extend:XF
13462             (match_operand:MODEF 1 "register_operand" "0"))))]
13463   "TARGET_USE_FANCY_MATH_387"
13464   "fsqrt"
13465   [(set_attr "type" "fpspc")
13466    (set_attr "mode" "XF")
13467    (set_attr "athlon_decode" "direct")
13468    (set_attr "amdfam10_decode" "direct")
13469    (set_attr "bdver1_decode" "direct")])
13471 (define_insn "*rsqrtsf2_sse"
13472   [(set (match_operand:SF 0 "register_operand" "=x")
13473         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13474                    UNSPEC_RSQRT))]
13475   "TARGET_SSE_MATH"
13476   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13477   [(set_attr "type" "sse")
13478    (set_attr "atom_sse_attr" "rcp")
13479    (set_attr "btver2_sse_attr" "rcp")
13480    (set_attr "prefix" "maybe_vex")
13481    (set_attr "mode" "SF")])
13483 (define_expand "rsqrtsf2"
13484   [(set (match_operand:SF 0 "register_operand")
13485         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13486                    UNSPEC_RSQRT))]
13487   "TARGET_SSE_MATH"
13489   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13490   DONE;
13493 (define_insn "*sqrt<mode>2_sse"
13494   [(set (match_operand:MODEF 0 "register_operand" "=x")
13495         (sqrt:MODEF
13496           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13497   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13498   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13499   [(set_attr "type" "sse")
13500    (set_attr "atom_sse_attr" "sqrt")
13501    (set_attr "btver2_sse_attr" "sqrt")
13502    (set_attr "prefix" "maybe_vex")
13503    (set_attr "mode" "<MODE>")
13504    (set_attr "athlon_decode" "*")
13505    (set_attr "amdfam10_decode" "*")
13506    (set_attr "bdver1_decode" "*")])
13508 (define_expand "sqrt<mode>2"
13509   [(set (match_operand:MODEF 0 "register_operand")
13510         (sqrt:MODEF
13511           (match_operand:MODEF 1 "nonimmediate_operand")))]
13512   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13513    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13515   if (<MODE>mode == SFmode
13516       && TARGET_SSE_MATH
13517       && TARGET_RECIP_SQRT
13518       && !optimize_function_for_size_p (cfun)
13519       && flag_finite_math_only && !flag_trapping_math
13520       && flag_unsafe_math_optimizations)
13521     {
13522       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13523       DONE;
13524     }
13526   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13527     {
13528       rtx op0 = gen_reg_rtx (XFmode);
13529       rtx op1 = force_reg (<MODE>mode, operands[1]);
13531       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13532       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13533       DONE;
13534    }
13537 (define_insn "fpremxf4_i387"
13538   [(set (match_operand:XF 0 "register_operand" "=f")
13539         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13540                     (match_operand:XF 3 "register_operand" "1")]
13541                    UNSPEC_FPREM_F))
13542    (set (match_operand:XF 1 "register_operand" "=u")
13543         (unspec:XF [(match_dup 2) (match_dup 3)]
13544                    UNSPEC_FPREM_U))
13545    (set (reg:CCFP FPSR_REG)
13546         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13547                      UNSPEC_C2_FLAG))]
13548   "TARGET_USE_FANCY_MATH_387"
13549   "fprem"
13550   [(set_attr "type" "fpspc")
13551    (set_attr "mode" "XF")])
13553 (define_expand "fmodxf3"
13554   [(use (match_operand:XF 0 "register_operand"))
13555    (use (match_operand:XF 1 "general_operand"))
13556    (use (match_operand:XF 2 "general_operand"))]
13557   "TARGET_USE_FANCY_MATH_387"
13559   rtx label = gen_label_rtx ();
13561   rtx op1 = gen_reg_rtx (XFmode);
13562   rtx op2 = gen_reg_rtx (XFmode);
13564   emit_move_insn (op2, operands[2]);
13565   emit_move_insn (op1, operands[1]);
13567   emit_label (label);
13568   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13569   ix86_emit_fp_unordered_jump (label);
13570   LABEL_NUSES (label) = 1;
13572   emit_move_insn (operands[0], op1);
13573   DONE;
13576 (define_expand "fmod<mode>3"
13577   [(use (match_operand:MODEF 0 "register_operand"))
13578    (use (match_operand:MODEF 1 "general_operand"))
13579    (use (match_operand:MODEF 2 "general_operand"))]
13580   "TARGET_USE_FANCY_MATH_387"
13582   rtx (*gen_truncxf) (rtx, rtx);
13584   rtx label = gen_label_rtx ();
13586   rtx op1 = gen_reg_rtx (XFmode);
13587   rtx op2 = gen_reg_rtx (XFmode);
13589   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13590   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13592   emit_label (label);
13593   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13594   ix86_emit_fp_unordered_jump (label);
13595   LABEL_NUSES (label) = 1;
13597   /* Truncate the result properly for strict SSE math.  */
13598   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13599       && !TARGET_MIX_SSE_I387)
13600     gen_truncxf = gen_truncxf<mode>2;
13601   else
13602     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13604   emit_insn (gen_truncxf (operands[0], op1));
13605   DONE;
13608 (define_insn "fprem1xf4_i387"
13609   [(set (match_operand:XF 0 "register_operand" "=f")
13610         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13611                     (match_operand:XF 3 "register_operand" "1")]
13612                    UNSPEC_FPREM1_F))
13613    (set (match_operand:XF 1 "register_operand" "=u")
13614         (unspec:XF [(match_dup 2) (match_dup 3)]
13615                    UNSPEC_FPREM1_U))
13616    (set (reg:CCFP FPSR_REG)
13617         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13618                      UNSPEC_C2_FLAG))]
13619   "TARGET_USE_FANCY_MATH_387"
13620   "fprem1"
13621   [(set_attr "type" "fpspc")
13622    (set_attr "mode" "XF")])
13624 (define_expand "remainderxf3"
13625   [(use (match_operand:XF 0 "register_operand"))
13626    (use (match_operand:XF 1 "general_operand"))
13627    (use (match_operand:XF 2 "general_operand"))]
13628   "TARGET_USE_FANCY_MATH_387"
13630   rtx label = gen_label_rtx ();
13632   rtx op1 = gen_reg_rtx (XFmode);
13633   rtx op2 = gen_reg_rtx (XFmode);
13635   emit_move_insn (op2, operands[2]);
13636   emit_move_insn (op1, operands[1]);
13638   emit_label (label);
13639   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13640   ix86_emit_fp_unordered_jump (label);
13641   LABEL_NUSES (label) = 1;
13643   emit_move_insn (operands[0], op1);
13644   DONE;
13647 (define_expand "remainder<mode>3"
13648   [(use (match_operand:MODEF 0 "register_operand"))
13649    (use (match_operand:MODEF 1 "general_operand"))
13650    (use (match_operand:MODEF 2 "general_operand"))]
13651   "TARGET_USE_FANCY_MATH_387"
13653   rtx (*gen_truncxf) (rtx, rtx);
13655   rtx label = gen_label_rtx ();
13657   rtx op1 = gen_reg_rtx (XFmode);
13658   rtx op2 = gen_reg_rtx (XFmode);
13660   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13661   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13663   emit_label (label);
13665   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13666   ix86_emit_fp_unordered_jump (label);
13667   LABEL_NUSES (label) = 1;
13669   /* Truncate the result properly for strict SSE math.  */
13670   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13671       && !TARGET_MIX_SSE_I387)
13672     gen_truncxf = gen_truncxf<mode>2;
13673   else
13674     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13676   emit_insn (gen_truncxf (operands[0], op1));
13677   DONE;
13680 (define_int_iterator SINCOS
13681         [UNSPEC_SIN
13682          UNSPEC_COS])
13684 (define_int_attr sincos
13685         [(UNSPEC_SIN "sin")
13686          (UNSPEC_COS "cos")])
13688 (define_insn "*<sincos>xf2_i387"
13689   [(set (match_operand:XF 0 "register_operand" "=f")
13690         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13691                    SINCOS))]
13692   "TARGET_USE_FANCY_MATH_387
13693    && flag_unsafe_math_optimizations"
13694   "f<sincos>"
13695   [(set_attr "type" "fpspc")
13696    (set_attr "mode" "XF")])
13698 (define_insn "*<sincos>_extend<mode>xf2_i387"
13699   [(set (match_operand:XF 0 "register_operand" "=f")
13700         (unspec:XF [(float_extend:XF
13701                       (match_operand:MODEF 1 "register_operand" "0"))]
13702                    SINCOS))]
13703   "TARGET_USE_FANCY_MATH_387
13704    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13705        || TARGET_MIX_SSE_I387)
13706    && flag_unsafe_math_optimizations"
13707   "f<sincos>"
13708   [(set_attr "type" "fpspc")
13709    (set_attr "mode" "XF")])
13711 ;; When sincos pattern is defined, sin and cos builtin functions will be
13712 ;; expanded to sincos pattern with one of its outputs left unused.
13713 ;; CSE pass will figure out if two sincos patterns can be combined,
13714 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13715 ;; depending on the unused output.
13717 (define_insn "sincosxf3"
13718   [(set (match_operand:XF 0 "register_operand" "=f")
13719         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13720                    UNSPEC_SINCOS_COS))
13721    (set (match_operand:XF 1 "register_operand" "=u")
13722         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13723   "TARGET_USE_FANCY_MATH_387
13724    && flag_unsafe_math_optimizations"
13725   "fsincos"
13726   [(set_attr "type" "fpspc")
13727    (set_attr "mode" "XF")])
13729 (define_split
13730   [(set (match_operand:XF 0 "register_operand")
13731         (unspec:XF [(match_operand:XF 2 "register_operand")]
13732                    UNSPEC_SINCOS_COS))
13733    (set (match_operand:XF 1 "register_operand")
13734         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13735   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13736    && can_create_pseudo_p ()"
13737   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13739 (define_split
13740   [(set (match_operand:XF 0 "register_operand")
13741         (unspec:XF [(match_operand:XF 2 "register_operand")]
13742                    UNSPEC_SINCOS_COS))
13743    (set (match_operand:XF 1 "register_operand")
13744         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13745   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13746    && can_create_pseudo_p ()"
13747   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13749 (define_insn "sincos_extend<mode>xf3_i387"
13750   [(set (match_operand:XF 0 "register_operand" "=f")
13751         (unspec:XF [(float_extend:XF
13752                       (match_operand:MODEF 2 "register_operand" "0"))]
13753                    UNSPEC_SINCOS_COS))
13754    (set (match_operand:XF 1 "register_operand" "=u")
13755         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13756   "TARGET_USE_FANCY_MATH_387
13757    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13758        || TARGET_MIX_SSE_I387)
13759    && flag_unsafe_math_optimizations"
13760   "fsincos"
13761   [(set_attr "type" "fpspc")
13762    (set_attr "mode" "XF")])
13764 (define_split
13765   [(set (match_operand:XF 0 "register_operand")
13766         (unspec:XF [(float_extend:XF
13767                       (match_operand:MODEF 2 "register_operand"))]
13768                    UNSPEC_SINCOS_COS))
13769    (set (match_operand:XF 1 "register_operand")
13770         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13771   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13772    && can_create_pseudo_p ()"
13773   [(set (match_dup 1)
13774         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13776 (define_split
13777   [(set (match_operand:XF 0 "register_operand")
13778         (unspec:XF [(float_extend:XF
13779                       (match_operand:MODEF 2 "register_operand"))]
13780                    UNSPEC_SINCOS_COS))
13781    (set (match_operand:XF 1 "register_operand")
13782         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13783   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13784    && can_create_pseudo_p ()"
13785   [(set (match_dup 0)
13786         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13788 (define_expand "sincos<mode>3"
13789   [(use (match_operand:MODEF 0 "register_operand"))
13790    (use (match_operand:MODEF 1 "register_operand"))
13791    (use (match_operand:MODEF 2 "register_operand"))]
13792   "TARGET_USE_FANCY_MATH_387
13793    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13794        || TARGET_MIX_SSE_I387)
13795    && flag_unsafe_math_optimizations"
13797   rtx op0 = gen_reg_rtx (XFmode);
13798   rtx op1 = gen_reg_rtx (XFmode);
13800   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13801   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13802   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13803   DONE;
13806 (define_insn "fptanxf4_i387"
13807   [(set (match_operand:XF 0 "register_operand" "=f")
13808         (match_operand:XF 3 "const_double_operand" "F"))
13809    (set (match_operand:XF 1 "register_operand" "=u")
13810         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13811                    UNSPEC_TAN))]
13812   "TARGET_USE_FANCY_MATH_387
13813    && flag_unsafe_math_optimizations
13814    && standard_80387_constant_p (operands[3]) == 2"
13815   "fptan"
13816   [(set_attr "type" "fpspc")
13817    (set_attr "mode" "XF")])
13819 (define_insn "fptan_extend<mode>xf4_i387"
13820   [(set (match_operand:MODEF 0 "register_operand" "=f")
13821         (match_operand:MODEF 3 "const_double_operand" "F"))
13822    (set (match_operand:XF 1 "register_operand" "=u")
13823         (unspec:XF [(float_extend:XF
13824                       (match_operand:MODEF 2 "register_operand" "0"))]
13825                    UNSPEC_TAN))]
13826   "TARGET_USE_FANCY_MATH_387
13827    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13828        || TARGET_MIX_SSE_I387)
13829    && flag_unsafe_math_optimizations
13830    && standard_80387_constant_p (operands[3]) == 2"
13831   "fptan"
13832   [(set_attr "type" "fpspc")
13833    (set_attr "mode" "XF")])
13835 (define_expand "tanxf2"
13836   [(use (match_operand:XF 0 "register_operand"))
13837    (use (match_operand:XF 1 "register_operand"))]
13838   "TARGET_USE_FANCY_MATH_387
13839    && flag_unsafe_math_optimizations"
13841   rtx one = gen_reg_rtx (XFmode);
13842   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13844   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13845   DONE;
13848 (define_expand "tan<mode>2"
13849   [(use (match_operand:MODEF 0 "register_operand"))
13850    (use (match_operand:MODEF 1 "register_operand"))]
13851   "TARGET_USE_FANCY_MATH_387
13852    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13853        || TARGET_MIX_SSE_I387)
13854    && flag_unsafe_math_optimizations"
13856   rtx op0 = gen_reg_rtx (XFmode);
13858   rtx one = gen_reg_rtx (<MODE>mode);
13859   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13861   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13862                                              operands[1], op2));
13863   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13864   DONE;
13867 (define_insn "*fpatanxf3_i387"
13868   [(set (match_operand:XF 0 "register_operand" "=f")
13869         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13870                     (match_operand:XF 2 "register_operand" "u")]
13871                    UNSPEC_FPATAN))
13872    (clobber (match_scratch:XF 3 "=2"))]
13873   "TARGET_USE_FANCY_MATH_387
13874    && flag_unsafe_math_optimizations"
13875   "fpatan"
13876   [(set_attr "type" "fpspc")
13877    (set_attr "mode" "XF")])
13879 (define_insn "fpatan_extend<mode>xf3_i387"
13880   [(set (match_operand:XF 0 "register_operand" "=f")
13881         (unspec:XF [(float_extend:XF
13882                       (match_operand:MODEF 1 "register_operand" "0"))
13883                     (float_extend:XF
13884                       (match_operand:MODEF 2 "register_operand" "u"))]
13885                    UNSPEC_FPATAN))
13886    (clobber (match_scratch:XF 3 "=2"))]
13887   "TARGET_USE_FANCY_MATH_387
13888    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13889        || TARGET_MIX_SSE_I387)
13890    && flag_unsafe_math_optimizations"
13891   "fpatan"
13892   [(set_attr "type" "fpspc")
13893    (set_attr "mode" "XF")])
13895 (define_expand "atan2xf3"
13896   [(parallel [(set (match_operand:XF 0 "register_operand")
13897                    (unspec:XF [(match_operand:XF 2 "register_operand")
13898                                (match_operand:XF 1 "register_operand")]
13899                               UNSPEC_FPATAN))
13900               (clobber (match_scratch:XF 3))])]
13901   "TARGET_USE_FANCY_MATH_387
13902    && flag_unsafe_math_optimizations")
13904 (define_expand "atan2<mode>3"
13905   [(use (match_operand:MODEF 0 "register_operand"))
13906    (use (match_operand:MODEF 1 "register_operand"))
13907    (use (match_operand:MODEF 2 "register_operand"))]
13908   "TARGET_USE_FANCY_MATH_387
13909    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13910        || TARGET_MIX_SSE_I387)
13911    && flag_unsafe_math_optimizations"
13913   rtx op0 = gen_reg_rtx (XFmode);
13915   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13916   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13917   DONE;
13920 (define_expand "atanxf2"
13921   [(parallel [(set (match_operand:XF 0 "register_operand")
13922                    (unspec:XF [(match_dup 2)
13923                                (match_operand:XF 1 "register_operand")]
13924                               UNSPEC_FPATAN))
13925               (clobber (match_scratch:XF 3))])]
13926   "TARGET_USE_FANCY_MATH_387
13927    && flag_unsafe_math_optimizations"
13929   operands[2] = gen_reg_rtx (XFmode);
13930   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13933 (define_expand "atan<mode>2"
13934   [(use (match_operand:MODEF 0 "register_operand"))
13935    (use (match_operand:MODEF 1 "register_operand"))]
13936   "TARGET_USE_FANCY_MATH_387
13937    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13938        || TARGET_MIX_SSE_I387)
13939    && flag_unsafe_math_optimizations"
13941   rtx op0 = gen_reg_rtx (XFmode);
13943   rtx op2 = gen_reg_rtx (<MODE>mode);
13944   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13946   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13947   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13948   DONE;
13951 (define_expand "asinxf2"
13952   [(set (match_dup 2)
13953         (mult:XF (match_operand:XF 1 "register_operand")
13954                  (match_dup 1)))
13955    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13956    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13957    (parallel [(set (match_operand:XF 0 "register_operand")
13958                    (unspec:XF [(match_dup 5) (match_dup 1)]
13959                               UNSPEC_FPATAN))
13960               (clobber (match_scratch:XF 6))])]
13961   "TARGET_USE_FANCY_MATH_387
13962    && flag_unsafe_math_optimizations"
13964   int i;
13966   if (optimize_insn_for_size_p ())
13967     FAIL;
13969   for (i = 2; i < 6; i++)
13970     operands[i] = gen_reg_rtx (XFmode);
13972   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13975 (define_expand "asin<mode>2"
13976   [(use (match_operand:MODEF 0 "register_operand"))
13977    (use (match_operand:MODEF 1 "general_operand"))]
13978  "TARGET_USE_FANCY_MATH_387
13979    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13980        || TARGET_MIX_SSE_I387)
13981    && flag_unsafe_math_optimizations"
13983   rtx op0 = gen_reg_rtx (XFmode);
13984   rtx op1 = gen_reg_rtx (XFmode);
13986   if (optimize_insn_for_size_p ())
13987     FAIL;
13989   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13990   emit_insn (gen_asinxf2 (op0, op1));
13991   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13992   DONE;
13995 (define_expand "acosxf2"
13996   [(set (match_dup 2)
13997         (mult:XF (match_operand:XF 1 "register_operand")
13998                  (match_dup 1)))
13999    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14000    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14001    (parallel [(set (match_operand:XF 0 "register_operand")
14002                    (unspec:XF [(match_dup 1) (match_dup 5)]
14003                               UNSPEC_FPATAN))
14004               (clobber (match_scratch:XF 6))])]
14005   "TARGET_USE_FANCY_MATH_387
14006    && flag_unsafe_math_optimizations"
14008   int i;
14010   if (optimize_insn_for_size_p ())
14011     FAIL;
14013   for (i = 2; i < 6; i++)
14014     operands[i] = gen_reg_rtx (XFmode);
14016   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14019 (define_expand "acos<mode>2"
14020   [(use (match_operand:MODEF 0 "register_operand"))
14021    (use (match_operand:MODEF 1 "general_operand"))]
14022  "TARGET_USE_FANCY_MATH_387
14023    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14024        || TARGET_MIX_SSE_I387)
14025    && flag_unsafe_math_optimizations"
14027   rtx op0 = gen_reg_rtx (XFmode);
14028   rtx op1 = gen_reg_rtx (XFmode);
14030   if (optimize_insn_for_size_p ())
14031     FAIL;
14033   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14034   emit_insn (gen_acosxf2 (op0, op1));
14035   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14036   DONE;
14039 (define_insn "fyl2xxf3_i387"
14040   [(set (match_operand:XF 0 "register_operand" "=f")
14041         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14042                     (match_operand:XF 2 "register_operand" "u")]
14043                    UNSPEC_FYL2X))
14044    (clobber (match_scratch:XF 3 "=2"))]
14045   "TARGET_USE_FANCY_MATH_387
14046    && flag_unsafe_math_optimizations"
14047   "fyl2x"
14048   [(set_attr "type" "fpspc")
14049    (set_attr "mode" "XF")])
14051 (define_insn "fyl2x_extend<mode>xf3_i387"
14052   [(set (match_operand:XF 0 "register_operand" "=f")
14053         (unspec:XF [(float_extend:XF
14054                       (match_operand:MODEF 1 "register_operand" "0"))
14055                     (match_operand:XF 2 "register_operand" "u")]
14056                    UNSPEC_FYL2X))
14057    (clobber (match_scratch:XF 3 "=2"))]
14058   "TARGET_USE_FANCY_MATH_387
14059    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14060        || TARGET_MIX_SSE_I387)
14061    && flag_unsafe_math_optimizations"
14062   "fyl2x"
14063   [(set_attr "type" "fpspc")
14064    (set_attr "mode" "XF")])
14066 (define_expand "logxf2"
14067   [(parallel [(set (match_operand:XF 0 "register_operand")
14068                    (unspec:XF [(match_operand:XF 1 "register_operand")
14069                                (match_dup 2)] UNSPEC_FYL2X))
14070               (clobber (match_scratch:XF 3))])]
14071   "TARGET_USE_FANCY_MATH_387
14072    && flag_unsafe_math_optimizations"
14074   operands[2] = gen_reg_rtx (XFmode);
14075   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14078 (define_expand "log<mode>2"
14079   [(use (match_operand:MODEF 0 "register_operand"))
14080    (use (match_operand:MODEF 1 "register_operand"))]
14081   "TARGET_USE_FANCY_MATH_387
14082    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14083        || TARGET_MIX_SSE_I387)
14084    && flag_unsafe_math_optimizations"
14086   rtx op0 = gen_reg_rtx (XFmode);
14088   rtx op2 = gen_reg_rtx (XFmode);
14089   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14091   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14092   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14093   DONE;
14096 (define_expand "log10xf2"
14097   [(parallel [(set (match_operand:XF 0 "register_operand")
14098                    (unspec:XF [(match_operand:XF 1 "register_operand")
14099                                (match_dup 2)] UNSPEC_FYL2X))
14100               (clobber (match_scratch:XF 3))])]
14101   "TARGET_USE_FANCY_MATH_387
14102    && flag_unsafe_math_optimizations"
14104   operands[2] = gen_reg_rtx (XFmode);
14105   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14108 (define_expand "log10<mode>2"
14109   [(use (match_operand:MODEF 0 "register_operand"))
14110    (use (match_operand:MODEF 1 "register_operand"))]
14111   "TARGET_USE_FANCY_MATH_387
14112    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14113        || TARGET_MIX_SSE_I387)
14114    && flag_unsafe_math_optimizations"
14116   rtx op0 = gen_reg_rtx (XFmode);
14118   rtx op2 = gen_reg_rtx (XFmode);
14119   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14121   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14122   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14123   DONE;
14126 (define_expand "log2xf2"
14127   [(parallel [(set (match_operand:XF 0 "register_operand")
14128                    (unspec:XF [(match_operand:XF 1 "register_operand")
14129                                (match_dup 2)] UNSPEC_FYL2X))
14130               (clobber (match_scratch:XF 3))])]
14131   "TARGET_USE_FANCY_MATH_387
14132    && flag_unsafe_math_optimizations"
14134   operands[2] = gen_reg_rtx (XFmode);
14135   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14138 (define_expand "log2<mode>2"
14139   [(use (match_operand:MODEF 0 "register_operand"))
14140    (use (match_operand:MODEF 1 "register_operand"))]
14141   "TARGET_USE_FANCY_MATH_387
14142    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14143        || TARGET_MIX_SSE_I387)
14144    && flag_unsafe_math_optimizations"
14146   rtx op0 = gen_reg_rtx (XFmode);
14148   rtx op2 = gen_reg_rtx (XFmode);
14149   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14151   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14152   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14153   DONE;
14156 (define_insn "fyl2xp1xf3_i387"
14157   [(set (match_operand:XF 0 "register_operand" "=f")
14158         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14159                     (match_operand:XF 2 "register_operand" "u")]
14160                    UNSPEC_FYL2XP1))
14161    (clobber (match_scratch:XF 3 "=2"))]
14162   "TARGET_USE_FANCY_MATH_387
14163    && flag_unsafe_math_optimizations"
14164   "fyl2xp1"
14165   [(set_attr "type" "fpspc")
14166    (set_attr "mode" "XF")])
14168 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14169   [(set (match_operand:XF 0 "register_operand" "=f")
14170         (unspec:XF [(float_extend:XF
14171                       (match_operand:MODEF 1 "register_operand" "0"))
14172                     (match_operand:XF 2 "register_operand" "u")]
14173                    UNSPEC_FYL2XP1))
14174    (clobber (match_scratch:XF 3 "=2"))]
14175   "TARGET_USE_FANCY_MATH_387
14176    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14177        || TARGET_MIX_SSE_I387)
14178    && flag_unsafe_math_optimizations"
14179   "fyl2xp1"
14180   [(set_attr "type" "fpspc")
14181    (set_attr "mode" "XF")])
14183 (define_expand "log1pxf2"
14184   [(use (match_operand:XF 0 "register_operand"))
14185    (use (match_operand:XF 1 "register_operand"))]
14186   "TARGET_USE_FANCY_MATH_387
14187    && flag_unsafe_math_optimizations"
14189   if (optimize_insn_for_size_p ())
14190     FAIL;
14192   ix86_emit_i387_log1p (operands[0], operands[1]);
14193   DONE;
14196 (define_expand "log1p<mode>2"
14197   [(use (match_operand:MODEF 0 "register_operand"))
14198    (use (match_operand:MODEF 1 "register_operand"))]
14199   "TARGET_USE_FANCY_MATH_387
14200    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14201        || TARGET_MIX_SSE_I387)
14202    && flag_unsafe_math_optimizations"
14204   rtx op0;
14206   if (optimize_insn_for_size_p ())
14207     FAIL;
14209   op0 = gen_reg_rtx (XFmode);
14211   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14213   ix86_emit_i387_log1p (op0, operands[1]);
14214   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14215   DONE;
14218 (define_insn "fxtractxf3_i387"
14219   [(set (match_operand:XF 0 "register_operand" "=f")
14220         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14221                    UNSPEC_XTRACT_FRACT))
14222    (set (match_operand:XF 1 "register_operand" "=u")
14223         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14224   "TARGET_USE_FANCY_MATH_387
14225    && flag_unsafe_math_optimizations"
14226   "fxtract"
14227   [(set_attr "type" "fpspc")
14228    (set_attr "mode" "XF")])
14230 (define_insn "fxtract_extend<mode>xf3_i387"
14231   [(set (match_operand:XF 0 "register_operand" "=f")
14232         (unspec:XF [(float_extend:XF
14233                       (match_operand:MODEF 2 "register_operand" "0"))]
14234                    UNSPEC_XTRACT_FRACT))
14235    (set (match_operand:XF 1 "register_operand" "=u")
14236         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14237   "TARGET_USE_FANCY_MATH_387
14238    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14239        || TARGET_MIX_SSE_I387)
14240    && flag_unsafe_math_optimizations"
14241   "fxtract"
14242   [(set_attr "type" "fpspc")
14243    (set_attr "mode" "XF")])
14245 (define_expand "logbxf2"
14246   [(parallel [(set (match_dup 2)
14247                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14248                               UNSPEC_XTRACT_FRACT))
14249               (set (match_operand:XF 0 "register_operand")
14250                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14251   "TARGET_USE_FANCY_MATH_387
14252    && flag_unsafe_math_optimizations"
14253   "operands[2] = gen_reg_rtx (XFmode);")
14255 (define_expand "logb<mode>2"
14256   [(use (match_operand:MODEF 0 "register_operand"))
14257    (use (match_operand:MODEF 1 "register_operand"))]
14258   "TARGET_USE_FANCY_MATH_387
14259    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14260        || TARGET_MIX_SSE_I387)
14261    && flag_unsafe_math_optimizations"
14263   rtx op0 = gen_reg_rtx (XFmode);
14264   rtx op1 = gen_reg_rtx (XFmode);
14266   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14267   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14268   DONE;
14271 (define_expand "ilogbxf2"
14272   [(use (match_operand:SI 0 "register_operand"))
14273    (use (match_operand:XF 1 "register_operand"))]
14274   "TARGET_USE_FANCY_MATH_387
14275    && flag_unsafe_math_optimizations"
14277   rtx op0, op1;
14279   if (optimize_insn_for_size_p ())
14280     FAIL;
14282   op0 = gen_reg_rtx (XFmode);
14283   op1 = gen_reg_rtx (XFmode);
14285   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14286   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14287   DONE;
14290 (define_expand "ilogb<mode>2"
14291   [(use (match_operand:SI 0 "register_operand"))
14292    (use (match_operand:MODEF 1 "register_operand"))]
14293   "TARGET_USE_FANCY_MATH_387
14294    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14295        || TARGET_MIX_SSE_I387)
14296    && flag_unsafe_math_optimizations"
14298   rtx op0, op1;
14300   if (optimize_insn_for_size_p ())
14301     FAIL;
14303   op0 = gen_reg_rtx (XFmode);
14304   op1 = gen_reg_rtx (XFmode);
14306   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14307   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14308   DONE;
14311 (define_insn "*f2xm1xf2_i387"
14312   [(set (match_operand:XF 0 "register_operand" "=f")
14313         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14314                    UNSPEC_F2XM1))]
14315   "TARGET_USE_FANCY_MATH_387
14316    && flag_unsafe_math_optimizations"
14317   "f2xm1"
14318   [(set_attr "type" "fpspc")
14319    (set_attr "mode" "XF")])
14321 (define_insn "*fscalexf4_i387"
14322   [(set (match_operand:XF 0 "register_operand" "=f")
14323         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14324                     (match_operand:XF 3 "register_operand" "1")]
14325                    UNSPEC_FSCALE_FRACT))
14326    (set (match_operand:XF 1 "register_operand" "=u")
14327         (unspec:XF [(match_dup 2) (match_dup 3)]
14328                    UNSPEC_FSCALE_EXP))]
14329   "TARGET_USE_FANCY_MATH_387
14330    && flag_unsafe_math_optimizations"
14331   "fscale"
14332   [(set_attr "type" "fpspc")
14333    (set_attr "mode" "XF")])
14335 (define_expand "expNcorexf3"
14336   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14337                                (match_operand:XF 2 "register_operand")))
14338    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14339    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14340    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14341    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14342    (parallel [(set (match_operand:XF 0 "register_operand")
14343                    (unspec:XF [(match_dup 8) (match_dup 4)]
14344                               UNSPEC_FSCALE_FRACT))
14345               (set (match_dup 9)
14346                    (unspec:XF [(match_dup 8) (match_dup 4)]
14347                               UNSPEC_FSCALE_EXP))])]
14348   "TARGET_USE_FANCY_MATH_387
14349    && flag_unsafe_math_optimizations"
14351   int i;
14353   if (optimize_insn_for_size_p ())
14354     FAIL;
14356   for (i = 3; i < 10; i++)
14357     operands[i] = gen_reg_rtx (XFmode);
14359   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14362 (define_expand "expxf2"
14363   [(use (match_operand:XF 0 "register_operand"))
14364    (use (match_operand:XF 1 "register_operand"))]
14365   "TARGET_USE_FANCY_MATH_387
14366    && flag_unsafe_math_optimizations"
14368   rtx op2;
14370   if (optimize_insn_for_size_p ())
14371     FAIL;
14373   op2 = gen_reg_rtx (XFmode);
14374   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14376   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14377   DONE;
14380 (define_expand "exp<mode>2"
14381   [(use (match_operand:MODEF 0 "register_operand"))
14382    (use (match_operand:MODEF 1 "general_operand"))]
14383  "TARGET_USE_FANCY_MATH_387
14384    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14385        || TARGET_MIX_SSE_I387)
14386    && flag_unsafe_math_optimizations"
14388   rtx op0, op1;
14390   if (optimize_insn_for_size_p ())
14391     FAIL;
14393   op0 = gen_reg_rtx (XFmode);
14394   op1 = gen_reg_rtx (XFmode);
14396   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14397   emit_insn (gen_expxf2 (op0, op1));
14398   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14399   DONE;
14402 (define_expand "exp10xf2"
14403   [(use (match_operand:XF 0 "register_operand"))
14404    (use (match_operand:XF 1 "register_operand"))]
14405   "TARGET_USE_FANCY_MATH_387
14406    && flag_unsafe_math_optimizations"
14408   rtx op2;
14410   if (optimize_insn_for_size_p ())
14411     FAIL;
14413   op2 = gen_reg_rtx (XFmode);
14414   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14416   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14417   DONE;
14420 (define_expand "exp10<mode>2"
14421   [(use (match_operand:MODEF 0 "register_operand"))
14422    (use (match_operand:MODEF 1 "general_operand"))]
14423  "TARGET_USE_FANCY_MATH_387
14424    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14425        || TARGET_MIX_SSE_I387)
14426    && flag_unsafe_math_optimizations"
14428   rtx op0, op1;
14430   if (optimize_insn_for_size_p ())
14431     FAIL;
14433   op0 = gen_reg_rtx (XFmode);
14434   op1 = gen_reg_rtx (XFmode);
14436   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14437   emit_insn (gen_exp10xf2 (op0, op1));
14438   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14439   DONE;
14442 (define_expand "exp2xf2"
14443   [(use (match_operand:XF 0 "register_operand"))
14444    (use (match_operand:XF 1 "register_operand"))]
14445   "TARGET_USE_FANCY_MATH_387
14446    && flag_unsafe_math_optimizations"
14448   rtx op2;
14450   if (optimize_insn_for_size_p ())
14451     FAIL;
14453   op2 = gen_reg_rtx (XFmode);
14454   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14456   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14457   DONE;
14460 (define_expand "exp2<mode>2"
14461   [(use (match_operand:MODEF 0 "register_operand"))
14462    (use (match_operand:MODEF 1 "general_operand"))]
14463  "TARGET_USE_FANCY_MATH_387
14464    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14465        || TARGET_MIX_SSE_I387)
14466    && flag_unsafe_math_optimizations"
14468   rtx op0, op1;
14470   if (optimize_insn_for_size_p ())
14471     FAIL;
14473   op0 = gen_reg_rtx (XFmode);
14474   op1 = gen_reg_rtx (XFmode);
14476   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14477   emit_insn (gen_exp2xf2 (op0, op1));
14478   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14479   DONE;
14482 (define_expand "expm1xf2"
14483   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14484                                (match_dup 2)))
14485    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14486    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14487    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14488    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14489    (parallel [(set (match_dup 7)
14490                    (unspec:XF [(match_dup 6) (match_dup 4)]
14491                               UNSPEC_FSCALE_FRACT))
14492               (set (match_dup 8)
14493                    (unspec:XF [(match_dup 6) (match_dup 4)]
14494                               UNSPEC_FSCALE_EXP))])
14495    (parallel [(set (match_dup 10)
14496                    (unspec:XF [(match_dup 9) (match_dup 8)]
14497                               UNSPEC_FSCALE_FRACT))
14498               (set (match_dup 11)
14499                    (unspec:XF [(match_dup 9) (match_dup 8)]
14500                               UNSPEC_FSCALE_EXP))])
14501    (set (match_dup 12) (minus:XF (match_dup 10)
14502                                  (float_extend:XF (match_dup 13))))
14503    (set (match_operand:XF 0 "register_operand")
14504         (plus:XF (match_dup 12) (match_dup 7)))]
14505   "TARGET_USE_FANCY_MATH_387
14506    && flag_unsafe_math_optimizations"
14508   int i;
14510   if (optimize_insn_for_size_p ())
14511     FAIL;
14513   for (i = 2; i < 13; i++)
14514     operands[i] = gen_reg_rtx (XFmode);
14516   operands[13]
14517     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14519   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14522 (define_expand "expm1<mode>2"
14523   [(use (match_operand:MODEF 0 "register_operand"))
14524    (use (match_operand:MODEF 1 "general_operand"))]
14525  "TARGET_USE_FANCY_MATH_387
14526    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14527        || TARGET_MIX_SSE_I387)
14528    && flag_unsafe_math_optimizations"
14530   rtx op0, op1;
14532   if (optimize_insn_for_size_p ())
14533     FAIL;
14535   op0 = gen_reg_rtx (XFmode);
14536   op1 = gen_reg_rtx (XFmode);
14538   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14539   emit_insn (gen_expm1xf2 (op0, op1));
14540   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14541   DONE;
14544 (define_expand "ldexpxf3"
14545   [(set (match_dup 3)
14546         (float:XF (match_operand:SI 2 "register_operand")))
14547    (parallel [(set (match_operand:XF 0 " register_operand")
14548                    (unspec:XF [(match_operand:XF 1 "register_operand")
14549                                (match_dup 3)]
14550                               UNSPEC_FSCALE_FRACT))
14551               (set (match_dup 4)
14552                    (unspec:XF [(match_dup 1) (match_dup 3)]
14553                               UNSPEC_FSCALE_EXP))])]
14554   "TARGET_USE_FANCY_MATH_387
14555    && flag_unsafe_math_optimizations"
14557   if (optimize_insn_for_size_p ())
14558     FAIL;
14560   operands[3] = gen_reg_rtx (XFmode);
14561   operands[4] = gen_reg_rtx (XFmode);
14564 (define_expand "ldexp<mode>3"
14565   [(use (match_operand:MODEF 0 "register_operand"))
14566    (use (match_operand:MODEF 1 "general_operand"))
14567    (use (match_operand:SI 2 "register_operand"))]
14568  "TARGET_USE_FANCY_MATH_387
14569    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14570        || TARGET_MIX_SSE_I387)
14571    && flag_unsafe_math_optimizations"
14573   rtx op0, op1;
14575   if (optimize_insn_for_size_p ())
14576     FAIL;
14578   op0 = gen_reg_rtx (XFmode);
14579   op1 = gen_reg_rtx (XFmode);
14581   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14582   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14583   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14584   DONE;
14587 (define_expand "scalbxf3"
14588   [(parallel [(set (match_operand:XF 0 " register_operand")
14589                    (unspec:XF [(match_operand:XF 1 "register_operand")
14590                                (match_operand:XF 2 "register_operand")]
14591                               UNSPEC_FSCALE_FRACT))
14592               (set (match_dup 3)
14593                    (unspec:XF [(match_dup 1) (match_dup 2)]
14594                               UNSPEC_FSCALE_EXP))])]
14595   "TARGET_USE_FANCY_MATH_387
14596    && flag_unsafe_math_optimizations"
14598   if (optimize_insn_for_size_p ())
14599     FAIL;
14601   operands[3] = gen_reg_rtx (XFmode);
14604 (define_expand "scalb<mode>3"
14605   [(use (match_operand:MODEF 0 "register_operand"))
14606    (use (match_operand:MODEF 1 "general_operand"))
14607    (use (match_operand:MODEF 2 "general_operand"))]
14608  "TARGET_USE_FANCY_MATH_387
14609    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14610        || TARGET_MIX_SSE_I387)
14611    && flag_unsafe_math_optimizations"
14613   rtx op0, op1, op2;
14615   if (optimize_insn_for_size_p ())
14616     FAIL;
14618   op0 = gen_reg_rtx (XFmode);
14619   op1 = gen_reg_rtx (XFmode);
14620   op2 = gen_reg_rtx (XFmode);
14622   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14623   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14624   emit_insn (gen_scalbxf3 (op0, op1, op2));
14625   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14626   DONE;
14629 (define_expand "significandxf2"
14630   [(parallel [(set (match_operand:XF 0 "register_operand")
14631                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14632                               UNSPEC_XTRACT_FRACT))
14633               (set (match_dup 2)
14634                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14635   "TARGET_USE_FANCY_MATH_387
14636    && flag_unsafe_math_optimizations"
14637   "operands[2] = gen_reg_rtx (XFmode);")
14639 (define_expand "significand<mode>2"
14640   [(use (match_operand:MODEF 0 "register_operand"))
14641    (use (match_operand:MODEF 1 "register_operand"))]
14642   "TARGET_USE_FANCY_MATH_387
14643    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14644        || TARGET_MIX_SSE_I387)
14645    && flag_unsafe_math_optimizations"
14647   rtx op0 = gen_reg_rtx (XFmode);
14648   rtx op1 = gen_reg_rtx (XFmode);
14650   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14651   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14652   DONE;
14656 (define_insn "sse4_1_round<mode>2"
14657   [(set (match_operand:MODEF 0 "register_operand" "=x")
14658         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14659                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14660                       UNSPEC_ROUND))]
14661   "TARGET_ROUND"
14662   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14663   [(set_attr "type" "ssecvt")
14664    (set_attr "prefix_extra" "1")
14665    (set_attr "prefix" "maybe_vex")
14666    (set_attr "mode" "<MODE>")])
14668 (define_insn "rintxf2"
14669   [(set (match_operand:XF 0 "register_operand" "=f")
14670         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14671                    UNSPEC_FRNDINT))]
14672   "TARGET_USE_FANCY_MATH_387
14673    && flag_unsafe_math_optimizations"
14674   "frndint"
14675   [(set_attr "type" "fpspc")
14676    (set_attr "mode" "XF")])
14678 (define_expand "rint<mode>2"
14679   [(use (match_operand:MODEF 0 "register_operand"))
14680    (use (match_operand:MODEF 1 "register_operand"))]
14681   "(TARGET_USE_FANCY_MATH_387
14682     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14683         || TARGET_MIX_SSE_I387)
14684     && flag_unsafe_math_optimizations)
14685    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14686        && !flag_trapping_math)"
14688   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14689       && !flag_trapping_math)
14690     {
14691       if (TARGET_ROUND)
14692         emit_insn (gen_sse4_1_round<mode>2
14693                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14694       else if (optimize_insn_for_size_p ())
14695         FAIL;
14696       else
14697         ix86_expand_rint (operands[0], operands[1]);
14698     }
14699   else
14700     {
14701       rtx op0 = gen_reg_rtx (XFmode);
14702       rtx op1 = gen_reg_rtx (XFmode);
14704       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14705       emit_insn (gen_rintxf2 (op0, op1));
14707       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14708     }
14709   DONE;
14712 (define_expand "round<mode>2"
14713   [(match_operand:X87MODEF 0 "register_operand")
14714    (match_operand:X87MODEF 1 "nonimmediate_operand")]
14715   "(TARGET_USE_FANCY_MATH_387
14716     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14717         || TARGET_MIX_SSE_I387)
14718     && flag_unsafe_math_optimizations)
14719    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14720        && !flag_trapping_math && !flag_rounding_math)"
14722   if (optimize_insn_for_size_p ())
14723     FAIL;
14725   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14726       && !flag_trapping_math && !flag_rounding_math)
14727     {
14728       if (TARGET_ROUND)
14729         {
14730           operands[1] = force_reg (<MODE>mode, operands[1]);
14731           ix86_expand_round_sse4 (operands[0], operands[1]);
14732         }
14733       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14734         ix86_expand_round (operands[0], operands[1]);
14735       else
14736         ix86_expand_rounddf_32 (operands[0], operands[1]);
14737     }
14738   else
14739     {
14740       operands[1] = force_reg (<MODE>mode, operands[1]);
14741       ix86_emit_i387_round (operands[0], operands[1]);
14742     }
14743   DONE;
14746 (define_insn_and_split "*fistdi2_1"
14747   [(set (match_operand:DI 0 "nonimmediate_operand")
14748         (unspec:DI [(match_operand:XF 1 "register_operand")]
14749                    UNSPEC_FIST))]
14750   "TARGET_USE_FANCY_MATH_387
14751    && can_create_pseudo_p ()"
14752   "#"
14753   "&& 1"
14754   [(const_int 0)]
14756   if (memory_operand (operands[0], VOIDmode))
14757     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14758   else
14759     {
14760       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14761       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14762                                          operands[2]));
14763     }
14764   DONE;
14766   [(set_attr "type" "fpspc")
14767    (set_attr "mode" "DI")])
14769 (define_insn "fistdi2"
14770   [(set (match_operand:DI 0 "memory_operand" "=m")
14771         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14772                    UNSPEC_FIST))
14773    (clobber (match_scratch:XF 2 "=&1f"))]
14774   "TARGET_USE_FANCY_MATH_387"
14775   "* return output_fix_trunc (insn, operands, false);"
14776   [(set_attr "type" "fpspc")
14777    (set_attr "mode" "DI")])
14779 (define_insn "fistdi2_with_temp"
14780   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14781         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14782                    UNSPEC_FIST))
14783    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14784    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14785   "TARGET_USE_FANCY_MATH_387"
14786   "#"
14787   [(set_attr "type" "fpspc")
14788    (set_attr "mode" "DI")])
14790 (define_split
14791   [(set (match_operand:DI 0 "register_operand")
14792         (unspec:DI [(match_operand:XF 1 "register_operand")]
14793                    UNSPEC_FIST))
14794    (clobber (match_operand:DI 2 "memory_operand"))
14795    (clobber (match_scratch 3))]
14796   "reload_completed"
14797   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14798               (clobber (match_dup 3))])
14799    (set (match_dup 0) (match_dup 2))])
14801 (define_split
14802   [(set (match_operand:DI 0 "memory_operand")
14803         (unspec:DI [(match_operand:XF 1 "register_operand")]
14804                    UNSPEC_FIST))
14805    (clobber (match_operand:DI 2 "memory_operand"))
14806    (clobber (match_scratch 3))]
14807   "reload_completed"
14808   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14809               (clobber (match_dup 3))])])
14811 (define_insn_and_split "*fist<mode>2_1"
14812   [(set (match_operand:SWI24 0 "register_operand")
14813         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14814                       UNSPEC_FIST))]
14815   "TARGET_USE_FANCY_MATH_387
14816    && can_create_pseudo_p ()"
14817   "#"
14818   "&& 1"
14819   [(const_int 0)]
14821   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14822   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14823                                         operands[2]));
14824   DONE;
14826   [(set_attr "type" "fpspc")
14827    (set_attr "mode" "<MODE>")])
14829 (define_insn "fist<mode>2"
14830   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14831         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14832                       UNSPEC_FIST))]
14833   "TARGET_USE_FANCY_MATH_387"
14834   "* return output_fix_trunc (insn, operands, false);"
14835   [(set_attr "type" "fpspc")
14836    (set_attr "mode" "<MODE>")])
14838 (define_insn "fist<mode>2_with_temp"
14839   [(set (match_operand:SWI24 0 "register_operand" "=r")
14840         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14841                       UNSPEC_FIST))
14842    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14843   "TARGET_USE_FANCY_MATH_387"
14844   "#"
14845   [(set_attr "type" "fpspc")
14846    (set_attr "mode" "<MODE>")])
14848 (define_split
14849   [(set (match_operand:SWI24 0 "register_operand")
14850         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14851                       UNSPEC_FIST))
14852    (clobber (match_operand:SWI24 2 "memory_operand"))]
14853   "reload_completed"
14854   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14855    (set (match_dup 0) (match_dup 2))])
14857 (define_split
14858   [(set (match_operand:SWI24 0 "memory_operand")
14859         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14860                       UNSPEC_FIST))
14861    (clobber (match_operand:SWI24 2 "memory_operand"))]
14862   "reload_completed"
14863   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14865 (define_expand "lrintxf<mode>2"
14866   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14867      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14868                      UNSPEC_FIST))]
14869   "TARGET_USE_FANCY_MATH_387")
14871 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
14872   [(set (match_operand:SWI48 0 "nonimmediate_operand")
14873      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
14874                    UNSPEC_FIX_NOTRUNC))]
14875   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
14877 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14878   [(match_operand:SWI248x 0 "nonimmediate_operand")
14879    (match_operand:X87MODEF 1 "register_operand")]
14880   "(TARGET_USE_FANCY_MATH_387
14881     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14882         || TARGET_MIX_SSE_I387)
14883     && flag_unsafe_math_optimizations)
14884    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14885        && <SWI248x:MODE>mode != HImode 
14886        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14887        && !flag_trapping_math && !flag_rounding_math)"
14889   if (optimize_insn_for_size_p ())
14890     FAIL;
14892   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14893       && <SWI248x:MODE>mode != HImode
14894       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14895       && !flag_trapping_math && !flag_rounding_math)
14896     ix86_expand_lround (operands[0], operands[1]);
14897   else
14898     ix86_emit_i387_round (operands[0], operands[1]);
14899   DONE;
14902 (define_int_iterator FRNDINT_ROUNDING
14903         [UNSPEC_FRNDINT_FLOOR
14904          UNSPEC_FRNDINT_CEIL
14905          UNSPEC_FRNDINT_TRUNC])
14907 (define_int_iterator FIST_ROUNDING
14908         [UNSPEC_FIST_FLOOR
14909          UNSPEC_FIST_CEIL])
14911 ;; Base name for define_insn
14912 (define_int_attr rounding_insn
14913         [(UNSPEC_FRNDINT_FLOOR "floor")
14914          (UNSPEC_FRNDINT_CEIL "ceil")
14915          (UNSPEC_FRNDINT_TRUNC "btrunc")
14916          (UNSPEC_FIST_FLOOR "floor")
14917          (UNSPEC_FIST_CEIL "ceil")])
14919 (define_int_attr rounding
14920         [(UNSPEC_FRNDINT_FLOOR "floor")
14921          (UNSPEC_FRNDINT_CEIL "ceil")
14922          (UNSPEC_FRNDINT_TRUNC "trunc")
14923          (UNSPEC_FIST_FLOOR "floor")
14924          (UNSPEC_FIST_CEIL "ceil")])
14926 (define_int_attr ROUNDING
14927         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
14928          (UNSPEC_FRNDINT_CEIL "CEIL")
14929          (UNSPEC_FRNDINT_TRUNC "TRUNC")
14930          (UNSPEC_FIST_FLOOR "FLOOR")
14931          (UNSPEC_FIST_CEIL "CEIL")])
14933 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14934 (define_insn_and_split "frndintxf2_<rounding>"
14935   [(set (match_operand:XF 0 "register_operand")
14936         (unspec:XF [(match_operand:XF 1 "register_operand")]
14937                    FRNDINT_ROUNDING))
14938    (clobber (reg:CC FLAGS_REG))]
14939   "TARGET_USE_FANCY_MATH_387
14940    && flag_unsafe_math_optimizations
14941    && can_create_pseudo_p ()"
14942   "#"
14943   "&& 1"
14944   [(const_int 0)]
14946   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
14948   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14949   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
14951   emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
14952                                              operands[2], operands[3]));
14953   DONE;
14955   [(set_attr "type" "frndint")
14956    (set_attr "i387_cw" "<rounding>")
14957    (set_attr "mode" "XF")])
14959 (define_insn "frndintxf2_<rounding>_i387"
14960   [(set (match_operand:XF 0 "register_operand" "=f")
14961         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14962                    FRNDINT_ROUNDING))
14963    (use (match_operand:HI 2 "memory_operand" "m"))
14964    (use (match_operand:HI 3 "memory_operand" "m"))]
14965   "TARGET_USE_FANCY_MATH_387
14966    && flag_unsafe_math_optimizations"
14967   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14968   [(set_attr "type" "frndint")
14969    (set_attr "i387_cw" "<rounding>")
14970    (set_attr "mode" "XF")])
14972 (define_expand "<rounding_insn>xf2"
14973   [(parallel [(set (match_operand:XF 0 "register_operand")
14974                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14975                               FRNDINT_ROUNDING))
14976               (clobber (reg:CC FLAGS_REG))])]
14977   "TARGET_USE_FANCY_MATH_387
14978    && flag_unsafe_math_optimizations
14979    && !optimize_insn_for_size_p ()")
14981 (define_expand "<rounding_insn><mode>2"
14982   [(parallel [(set (match_operand:MODEF 0 "register_operand")
14983                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
14984                                  FRNDINT_ROUNDING))
14985               (clobber (reg:CC FLAGS_REG))])]
14986   "(TARGET_USE_FANCY_MATH_387
14987     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14988         || TARGET_MIX_SSE_I387)
14989     && flag_unsafe_math_optimizations)
14990    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14991        && !flag_trapping_math)"
14993   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14994       && !flag_trapping_math)
14995     {
14996       if (TARGET_ROUND)
14997         emit_insn (gen_sse4_1_round<mode>2
14998                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
14999       else if (optimize_insn_for_size_p ())
15000         FAIL;
15001       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15002         {
15003           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15004             ix86_expand_floorceil (operands[0], operands[1], true);
15005           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15006             ix86_expand_floorceil (operands[0], operands[1], false);
15007           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15008             ix86_expand_trunc (operands[0], operands[1]);
15009           else
15010             gcc_unreachable ();
15011         }
15012       else
15013         {
15014           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15015             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15016           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15017             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15018           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15019             ix86_expand_truncdf_32 (operands[0], operands[1]);
15020           else
15021             gcc_unreachable ();
15022         }
15023     }
15024   else
15025     {
15026       rtx op0, op1;
15028       if (optimize_insn_for_size_p ())
15029         FAIL;
15031       op0 = gen_reg_rtx (XFmode);
15032       op1 = gen_reg_rtx (XFmode);
15033       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15034       emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15036       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15037     }
15038   DONE;
15041 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15042 (define_insn_and_split "frndintxf2_mask_pm"
15043   [(set (match_operand:XF 0 "register_operand")
15044         (unspec:XF [(match_operand:XF 1 "register_operand")]
15045                    UNSPEC_FRNDINT_MASK_PM))
15046    (clobber (reg:CC FLAGS_REG))]
15047   "TARGET_USE_FANCY_MATH_387
15048    && flag_unsafe_math_optimizations
15049    && can_create_pseudo_p ()"
15050   "#"
15051   "&& 1"
15052   [(const_int 0)]
15054   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15056   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15057   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15059   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15060                                           operands[2], operands[3]));
15061   DONE;
15063   [(set_attr "type" "frndint")
15064    (set_attr "i387_cw" "mask_pm")
15065    (set_attr "mode" "XF")])
15067 (define_insn "frndintxf2_mask_pm_i387"
15068   [(set (match_operand:XF 0 "register_operand" "=f")
15069         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15070                    UNSPEC_FRNDINT_MASK_PM))
15071    (use (match_operand:HI 2 "memory_operand" "m"))
15072    (use (match_operand:HI 3 "memory_operand" "m"))]
15073   "TARGET_USE_FANCY_MATH_387
15074    && flag_unsafe_math_optimizations"
15075   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15076   [(set_attr "type" "frndint")
15077    (set_attr "i387_cw" "mask_pm")
15078    (set_attr "mode" "XF")])
15080 (define_expand "nearbyintxf2"
15081   [(parallel [(set (match_operand:XF 0 "register_operand")
15082                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15083                               UNSPEC_FRNDINT_MASK_PM))
15084               (clobber (reg:CC FLAGS_REG))])]
15085   "TARGET_USE_FANCY_MATH_387
15086    && flag_unsafe_math_optimizations")
15088 (define_expand "nearbyint<mode>2"
15089   [(use (match_operand:MODEF 0 "register_operand"))
15090    (use (match_operand:MODEF 1 "register_operand"))]
15091   "TARGET_USE_FANCY_MATH_387
15092    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15093        || TARGET_MIX_SSE_I387)
15094    && flag_unsafe_math_optimizations"
15096   rtx op0 = gen_reg_rtx (XFmode);
15097   rtx op1 = gen_reg_rtx (XFmode);
15099   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15100   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15102   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15103   DONE;
15106 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15107 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15108   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15109         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15110                         FIST_ROUNDING))
15111    (clobber (reg:CC FLAGS_REG))]
15112   "TARGET_USE_FANCY_MATH_387
15113    && flag_unsafe_math_optimizations
15114    && can_create_pseudo_p ()"
15115   "#"
15116   "&& 1"
15117   [(const_int 0)]
15119   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15121   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15122   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15123   if (memory_operand (operands[0], VOIDmode))
15124     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15125                                            operands[2], operands[3]));
15126   else
15127     {
15128       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15129       emit_insn (gen_fist<mode>2_<rounding>_with_temp
15130                   (operands[0], operands[1], operands[2],
15131                    operands[3], operands[4]));
15132     }
15133   DONE;
15135   [(set_attr "type" "fistp")
15136    (set_attr "i387_cw" "<rounding>")
15137    (set_attr "mode" "<MODE>")])
15139 (define_insn "fistdi2_<rounding>"
15140   [(set (match_operand:DI 0 "memory_operand" "=m")
15141         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15142                    FIST_ROUNDING))
15143    (use (match_operand:HI 2 "memory_operand" "m"))
15144    (use (match_operand:HI 3 "memory_operand" "m"))
15145    (clobber (match_scratch:XF 4 "=&1f"))]
15146   "TARGET_USE_FANCY_MATH_387
15147    && flag_unsafe_math_optimizations"
15148   "* return output_fix_trunc (insn, operands, false);"
15149   [(set_attr "type" "fistp")
15150    (set_attr "i387_cw" "<rounding>")
15151    (set_attr "mode" "DI")])
15153 (define_insn "fistdi2_<rounding>_with_temp"
15154   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15155         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15156                    FIST_ROUNDING))
15157    (use (match_operand:HI 2 "memory_operand" "m,m"))
15158    (use (match_operand:HI 3 "memory_operand" "m,m"))
15159    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15160    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15161   "TARGET_USE_FANCY_MATH_387
15162    && flag_unsafe_math_optimizations"
15163   "#"
15164   [(set_attr "type" "fistp")
15165    (set_attr "i387_cw" "<rounding>")
15166    (set_attr "mode" "DI")])
15168 (define_split
15169   [(set (match_operand:DI 0 "register_operand")
15170         (unspec:DI [(match_operand:XF 1 "register_operand")]
15171                    FIST_ROUNDING))
15172    (use (match_operand:HI 2 "memory_operand"))
15173    (use (match_operand:HI 3 "memory_operand"))
15174    (clobber (match_operand:DI 4 "memory_operand"))
15175    (clobber (match_scratch 5))]
15176   "reload_completed"
15177   [(parallel [(set (match_dup 4)
15178                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15179               (use (match_dup 2))
15180               (use (match_dup 3))
15181               (clobber (match_dup 5))])
15182    (set (match_dup 0) (match_dup 4))])
15184 (define_split
15185   [(set (match_operand:DI 0 "memory_operand")
15186         (unspec:DI [(match_operand:XF 1 "register_operand")]
15187                    FIST_ROUNDING))
15188    (use (match_operand:HI 2 "memory_operand"))
15189    (use (match_operand:HI 3 "memory_operand"))
15190    (clobber (match_operand:DI 4 "memory_operand"))
15191    (clobber (match_scratch 5))]
15192   "reload_completed"
15193   [(parallel [(set (match_dup 0)
15194                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15195               (use (match_dup 2))
15196               (use (match_dup 3))
15197               (clobber (match_dup 5))])])
15199 (define_insn "fist<mode>2_<rounding>"
15200   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15201         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15202                       FIST_ROUNDING))
15203    (use (match_operand:HI 2 "memory_operand" "m"))
15204    (use (match_operand:HI 3 "memory_operand" "m"))]
15205   "TARGET_USE_FANCY_MATH_387
15206    && flag_unsafe_math_optimizations"
15207   "* return output_fix_trunc (insn, operands, false);"
15208   [(set_attr "type" "fistp")
15209    (set_attr "i387_cw" "<rounding>")
15210    (set_attr "mode" "<MODE>")])
15212 (define_insn "fist<mode>2_<rounding>_with_temp"
15213   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15214         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15215                       FIST_ROUNDING))
15216    (use (match_operand:HI 2 "memory_operand" "m,m"))
15217    (use (match_operand:HI 3 "memory_operand" "m,m"))
15218    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15219   "TARGET_USE_FANCY_MATH_387
15220    && flag_unsafe_math_optimizations"
15221   "#"
15222   [(set_attr "type" "fistp")
15223    (set_attr "i387_cw" "<rounding>")
15224    (set_attr "mode" "<MODE>")])
15226 (define_split
15227   [(set (match_operand:SWI24 0 "register_operand")
15228         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15229                       FIST_ROUNDING))
15230    (use (match_operand:HI 2 "memory_operand"))
15231    (use (match_operand:HI 3 "memory_operand"))
15232    (clobber (match_operand:SWI24 4 "memory_operand"))]
15233   "reload_completed"
15234   [(parallel [(set (match_dup 4)
15235                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15236               (use (match_dup 2))
15237               (use (match_dup 3))])
15238    (set (match_dup 0) (match_dup 4))])
15240 (define_split
15241   [(set (match_operand:SWI24 0 "memory_operand")
15242         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15243                       FIST_ROUNDING))
15244    (use (match_operand:HI 2 "memory_operand"))
15245    (use (match_operand:HI 3 "memory_operand"))
15246    (clobber (match_operand:SWI24 4 "memory_operand"))]
15247   "reload_completed"
15248   [(parallel [(set (match_dup 0)
15249                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15250               (use (match_dup 2))
15251               (use (match_dup 3))])])
15253 (define_expand "l<rounding_insn>xf<mode>2"
15254   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15255                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15256                                    FIST_ROUNDING))
15257               (clobber (reg:CC FLAGS_REG))])]
15258   "TARGET_USE_FANCY_MATH_387
15259    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15260    && flag_unsafe_math_optimizations")
15262 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15263   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15264                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15265                                  FIST_ROUNDING))
15266               (clobber (reg:CC FLAGS_REG))])]
15267   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15268    && !flag_trapping_math"
15270   if (TARGET_64BIT && optimize_insn_for_size_p ())
15271     FAIL;
15273   if (ROUND_<ROUNDING> == ROUND_FLOOR)
15274     ix86_expand_lfloorceil (operands[0], operands[1], true);
15275   else if (ROUND_<ROUNDING> == ROUND_CEIL)
15276     ix86_expand_lfloorceil (operands[0], operands[1], false);
15277   else
15278     gcc_unreachable ();
15280   DONE;
15283 (define_insn "fxam<mode>2_i387"
15284   [(set (match_operand:HI 0 "register_operand" "=a")
15285         (unspec:HI
15286           [(match_operand:X87MODEF 1 "register_operand" "f")]
15287           UNSPEC_FXAM))]
15288   "TARGET_USE_FANCY_MATH_387"
15289   "fxam\n\tfnstsw\t%0"
15290   [(set_attr "type" "multi")
15291    (set_attr "length" "4")
15292    (set_attr "unit" "i387")
15293    (set_attr "mode" "<MODE>")])
15295 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15296   [(set (match_operand:HI 0 "register_operand")
15297         (unspec:HI
15298           [(match_operand:MODEF 1 "memory_operand")]
15299           UNSPEC_FXAM_MEM))]
15300   "TARGET_USE_FANCY_MATH_387
15301    && can_create_pseudo_p ()"
15302   "#"
15303   "&& 1"
15304   [(set (match_dup 2)(match_dup 1))
15305    (set (match_dup 0)
15306         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15308   operands[2] = gen_reg_rtx (<MODE>mode);
15310   MEM_VOLATILE_P (operands[1]) = 1;
15312   [(set_attr "type" "multi")
15313    (set_attr "unit" "i387")
15314    (set_attr "mode" "<MODE>")])
15316 (define_expand "isinfxf2"
15317   [(use (match_operand:SI 0 "register_operand"))
15318    (use (match_operand:XF 1 "register_operand"))]
15319   "TARGET_USE_FANCY_MATH_387
15320    && TARGET_C99_FUNCTIONS"
15322   rtx mask = GEN_INT (0x45);
15323   rtx val = GEN_INT (0x05);
15325   rtx cond;
15327   rtx scratch = gen_reg_rtx (HImode);
15328   rtx res = gen_reg_rtx (QImode);
15330   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15332   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15333   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15334   cond = gen_rtx_fmt_ee (EQ, QImode,
15335                          gen_rtx_REG (CCmode, FLAGS_REG),
15336                          const0_rtx);
15337   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15338   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15339   DONE;
15342 (define_expand "isinf<mode>2"
15343   [(use (match_operand:SI 0 "register_operand"))
15344    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15345   "TARGET_USE_FANCY_MATH_387
15346    && TARGET_C99_FUNCTIONS
15347    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15349   rtx mask = GEN_INT (0x45);
15350   rtx val = GEN_INT (0x05);
15352   rtx cond;
15354   rtx scratch = gen_reg_rtx (HImode);
15355   rtx res = gen_reg_rtx (QImode);
15357   /* Remove excess precision by forcing value through memory. */
15358   if (memory_operand (operands[1], VOIDmode))
15359     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15360   else
15361     {
15362       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15364       emit_move_insn (temp, operands[1]);
15365       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15366     }
15368   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15369   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15370   cond = gen_rtx_fmt_ee (EQ, QImode,
15371                          gen_rtx_REG (CCmode, FLAGS_REG),
15372                          const0_rtx);
15373   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15374   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15375   DONE;
15378 (define_expand "signbitxf2"
15379   [(use (match_operand:SI 0 "register_operand"))
15380    (use (match_operand:XF 1 "register_operand"))]
15381   "TARGET_USE_FANCY_MATH_387"
15383   rtx scratch = gen_reg_rtx (HImode);
15385   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15386   emit_insn (gen_andsi3 (operands[0],
15387              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15388   DONE;
15391 (define_insn "movmsk_df"
15392   [(set (match_operand:SI 0 "register_operand" "=r")
15393         (unspec:SI
15394           [(match_operand:DF 1 "register_operand" "x")]
15395           UNSPEC_MOVMSK))]
15396   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15397   "%vmovmskpd\t{%1, %0|%0, %1}"
15398   [(set_attr "type" "ssemov")
15399    (set_attr "prefix" "maybe_vex")
15400    (set_attr "mode" "DF")])
15402 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15403 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15404 (define_expand "signbitdf2"
15405   [(use (match_operand:SI 0 "register_operand"))
15406    (use (match_operand:DF 1 "register_operand"))]
15407   "TARGET_USE_FANCY_MATH_387
15408    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15410   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15411     {
15412       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15413       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15414     }
15415   else
15416     {
15417       rtx scratch = gen_reg_rtx (HImode);
15419       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15420       emit_insn (gen_andsi3 (operands[0],
15421                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15422     }
15423   DONE;
15426 (define_expand "signbitsf2"
15427   [(use (match_operand:SI 0 "register_operand"))
15428    (use (match_operand:SF 1 "register_operand"))]
15429   "TARGET_USE_FANCY_MATH_387
15430    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15432   rtx scratch = gen_reg_rtx (HImode);
15434   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15435   emit_insn (gen_andsi3 (operands[0],
15436              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15437   DONE;
15440 ;; Block operation instructions
15442 (define_insn "cld"
15443   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15444   ""
15445   "cld"
15446   [(set_attr "length" "1")
15447    (set_attr "length_immediate" "0")
15448    (set_attr "modrm" "0")])
15450 (define_expand "movmem<mode>"
15451   [(use (match_operand:BLK 0 "memory_operand"))
15452    (use (match_operand:BLK 1 "memory_operand"))
15453    (use (match_operand:SWI48 2 "nonmemory_operand"))
15454    (use (match_operand:SWI48 3 "const_int_operand"))
15455    (use (match_operand:SI 4 "const_int_operand"))
15456    (use (match_operand:SI 5 "const_int_operand"))]
15457   ""
15459  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15460                          operands[4], operands[5]))
15461    DONE;
15462  else
15463    FAIL;
15466 ;; Most CPUs don't like single string operations
15467 ;; Handle this case here to simplify previous expander.
15469 (define_expand "strmov"
15470   [(set (match_dup 4) (match_operand 3 "memory_operand"))
15471    (set (match_operand 1 "memory_operand") (match_dup 4))
15472    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15473               (clobber (reg:CC FLAGS_REG))])
15474    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15475               (clobber (reg:CC FLAGS_REG))])]
15476   ""
15478   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15480   /* If .md ever supports :P for Pmode, these can be directly
15481      in the pattern above.  */
15482   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15483   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15485   /* Can't use this if the user has appropriated esi or edi.  */
15486   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15487       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15488     {
15489       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15490                                       operands[2], operands[3],
15491                                       operands[5], operands[6]));
15492       DONE;
15493     }
15495   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15498 (define_expand "strmov_singleop"
15499   [(parallel [(set (match_operand 1 "memory_operand")
15500                    (match_operand 3 "memory_operand"))
15501               (set (match_operand 0 "register_operand")
15502                    (match_operand 4))
15503               (set (match_operand 2 "register_operand")
15504                    (match_operand 5))])]
15505   ""
15506   "ix86_current_function_needs_cld = 1;")
15508 (define_insn "*strmovdi_rex_1"
15509   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15510         (mem:DI (match_operand:P 3 "register_operand" "1")))
15511    (set (match_operand:P 0 "register_operand" "=D")
15512         (plus:P (match_dup 2)
15513                 (const_int 8)))
15514    (set (match_operand:P 1 "register_operand" "=S")
15515         (plus:P (match_dup 3)
15516                 (const_int 8)))]
15517   "TARGET_64BIT
15518    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15519   "%^movsq"
15520   [(set_attr "type" "str")
15521    (set_attr "memory" "both")
15522    (set_attr "mode" "DI")])
15524 (define_insn "*strmovsi_1"
15525   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15526         (mem:SI (match_operand:P 3 "register_operand" "1")))
15527    (set (match_operand:P 0 "register_operand" "=D")
15528         (plus:P (match_dup 2)
15529                 (const_int 4)))
15530    (set (match_operand:P 1 "register_operand" "=S")
15531         (plus:P (match_dup 3)
15532                 (const_int 4)))]
15533   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15534   "%^movs{l|d}"
15535   [(set_attr "type" "str")
15536    (set_attr "memory" "both")
15537    (set_attr "mode" "SI")])
15539 (define_insn "*strmovhi_1"
15540   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15541         (mem:HI (match_operand:P 3 "register_operand" "1")))
15542    (set (match_operand:P 0 "register_operand" "=D")
15543         (plus:P (match_dup 2)
15544                 (const_int 2)))
15545    (set (match_operand:P 1 "register_operand" "=S")
15546         (plus:P (match_dup 3)
15547                 (const_int 2)))]
15548   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15549   "%^movsw"
15550   [(set_attr "type" "str")
15551    (set_attr "memory" "both")
15552    (set_attr "mode" "HI")])
15554 (define_insn "*strmovqi_1"
15555   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15556         (mem:QI (match_operand:P 3 "register_operand" "1")))
15557    (set (match_operand:P 0 "register_operand" "=D")
15558         (plus:P (match_dup 2)
15559                 (const_int 1)))
15560    (set (match_operand:P 1 "register_operand" "=S")
15561         (plus:P (match_dup 3)
15562                 (const_int 1)))]
15563   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15564   "%^movsb"
15565   [(set_attr "type" "str")
15566    (set_attr "memory" "both")
15567    (set (attr "prefix_rex")
15568         (if_then_else
15569           (match_test "<P:MODE>mode == DImode")
15570           (const_string "0")
15571           (const_string "*")))
15572    (set_attr "mode" "QI")])
15574 (define_expand "rep_mov"
15575   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15576               (set (match_operand 0 "register_operand")
15577                    (match_operand 5))
15578               (set (match_operand 2 "register_operand")
15579                    (match_operand 6))
15580               (set (match_operand 1 "memory_operand")
15581                    (match_operand 3 "memory_operand"))
15582               (use (match_dup 4))])]
15583   ""
15584   "ix86_current_function_needs_cld = 1;")
15586 (define_insn "*rep_movdi_rex64"
15587   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15588    (set (match_operand:P 0 "register_operand" "=D")
15589         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15590                           (const_int 3))
15591                 (match_operand:P 3 "register_operand" "0")))
15592    (set (match_operand:P 1 "register_operand" "=S")
15593         (plus:P (ashift:P (match_dup 5) (const_int 3))
15594                 (match_operand:P 4 "register_operand" "1")))
15595    (set (mem:BLK (match_dup 3))
15596         (mem:BLK (match_dup 4)))
15597    (use (match_dup 5))]
15598   "TARGET_64BIT
15599    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15600   "%^rep{%;} movsq"
15601   [(set_attr "type" "str")
15602    (set_attr "prefix_rep" "1")
15603    (set_attr "memory" "both")
15604    (set_attr "mode" "DI")])
15606 (define_insn "*rep_movsi"
15607   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15608    (set (match_operand:P 0 "register_operand" "=D")
15609         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15610                           (const_int 2))
15611                  (match_operand:P 3 "register_operand" "0")))
15612    (set (match_operand:P 1 "register_operand" "=S")
15613         (plus:P (ashift:P (match_dup 5) (const_int 2))
15614                 (match_operand:P 4 "register_operand" "1")))
15615    (set (mem:BLK (match_dup 3))
15616         (mem:BLK (match_dup 4)))
15617    (use (match_dup 5))]
15618   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15619   "%^rep{%;} movs{l|d}"
15620   [(set_attr "type" "str")
15621    (set_attr "prefix_rep" "1")
15622    (set_attr "memory" "both")
15623    (set_attr "mode" "SI")])
15625 (define_insn "*rep_movqi"
15626   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15627    (set (match_operand:P 0 "register_operand" "=D")
15628         (plus:P (match_operand:P 3 "register_operand" "0")
15629                 (match_operand:P 5 "register_operand" "2")))
15630    (set (match_operand:P 1 "register_operand" "=S")
15631         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15632    (set (mem:BLK (match_dup 3))
15633         (mem:BLK (match_dup 4)))
15634    (use (match_dup 5))]
15635   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15636   "%^rep{%;} movsb"
15637   [(set_attr "type" "str")
15638    (set_attr "prefix_rep" "1")
15639    (set_attr "memory" "both")
15640    (set_attr "mode" "QI")])
15642 (define_expand "setmem<mode>"
15643    [(use (match_operand:BLK 0 "memory_operand"))
15644     (use (match_operand:SWI48 1 "nonmemory_operand"))
15645     (use (match_operand:QI 2 "nonmemory_operand"))
15646     (use (match_operand 3 "const_int_operand"))
15647     (use (match_operand:SI 4 "const_int_operand"))
15648     (use (match_operand:SI 5 "const_int_operand"))]
15649   ""
15651  if (ix86_expand_setmem (operands[0], operands[1],
15652                          operands[2], operands[3],
15653                          operands[4], operands[5]))
15654    DONE;
15655  else
15656    FAIL;
15659 ;; Most CPUs don't like single string operations
15660 ;; Handle this case here to simplify previous expander.
15662 (define_expand "strset"
15663   [(set (match_operand 1 "memory_operand")
15664         (match_operand 2 "register_operand"))
15665    (parallel [(set (match_operand 0 "register_operand")
15666                    (match_dup 3))
15667               (clobber (reg:CC FLAGS_REG))])]
15668   ""
15670   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15671     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15673   /* If .md ever supports :P for Pmode, this can be directly
15674      in the pattern above.  */
15675   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15676                               GEN_INT (GET_MODE_SIZE (GET_MODE
15677                                                       (operands[2]))));
15678   /* Can't use this if the user has appropriated eax or edi.  */
15679   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15680       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15681     {
15682       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15683                                       operands[3]));
15684       DONE;
15685     }
15688 (define_expand "strset_singleop"
15689   [(parallel [(set (match_operand 1 "memory_operand")
15690                    (match_operand 2 "register_operand"))
15691               (set (match_operand 0 "register_operand")
15692                    (match_operand 3))
15693               (unspec [(const_int 0)] UNSPEC_STOS)])]
15694   ""
15695   "ix86_current_function_needs_cld = 1;")
15697 (define_insn "*strsetdi_rex_1"
15698   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15699         (match_operand:DI 2 "register_operand" "a"))
15700    (set (match_operand:P 0 "register_operand" "=D")
15701         (plus:P (match_dup 1)
15702                 (const_int 8)))
15703    (unspec [(const_int 0)] UNSPEC_STOS)]
15704   "TARGET_64BIT
15705    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15706   "%^stosq"
15707   [(set_attr "type" "str")
15708    (set_attr "memory" "store")
15709    (set_attr "mode" "DI")])
15711 (define_insn "*strsetsi_1"
15712   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15713         (match_operand:SI 2 "register_operand" "a"))
15714    (set (match_operand:P 0 "register_operand" "=D")
15715         (plus:P (match_dup 1)
15716                 (const_int 4)))
15717    (unspec [(const_int 0)] UNSPEC_STOS)]
15718   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15719   "%^stos{l|d}"
15720   [(set_attr "type" "str")
15721    (set_attr "memory" "store")
15722    (set_attr "mode" "SI")])
15724 (define_insn "*strsethi_1"
15725   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15726         (match_operand:HI 2 "register_operand" "a"))
15727    (set (match_operand:P 0 "register_operand" "=D")
15728         (plus:P (match_dup 1)
15729                 (const_int 2)))
15730    (unspec [(const_int 0)] UNSPEC_STOS)]
15731   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15732   "%^stosw"
15733   [(set_attr "type" "str")
15734    (set_attr "memory" "store")
15735    (set_attr "mode" "HI")])
15737 (define_insn "*strsetqi_1"
15738   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15739         (match_operand:QI 2 "register_operand" "a"))
15740    (set (match_operand:P 0 "register_operand" "=D")
15741         (plus:P (match_dup 1)
15742                 (const_int 1)))
15743    (unspec [(const_int 0)] UNSPEC_STOS)]
15744   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15745   "%^stosb"
15746   [(set_attr "type" "str")
15747    (set_attr "memory" "store")
15748    (set (attr "prefix_rex")
15749         (if_then_else
15750           (match_test "<P:MODE>mode == DImode")
15751           (const_string "0")
15752           (const_string "*")))
15753    (set_attr "mode" "QI")])
15755 (define_expand "rep_stos"
15756   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15757               (set (match_operand 0 "register_operand")
15758                    (match_operand 4))
15759               (set (match_operand 2 "memory_operand") (const_int 0))
15760               (use (match_operand 3 "register_operand"))
15761               (use (match_dup 1))])]
15762   ""
15763   "ix86_current_function_needs_cld = 1;")
15765 (define_insn "*rep_stosdi_rex64"
15766   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15767    (set (match_operand:P 0 "register_operand" "=D")
15768         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15769                           (const_int 3))
15770                  (match_operand:P 3 "register_operand" "0")))
15771    (set (mem:BLK (match_dup 3))
15772         (const_int 0))
15773    (use (match_operand:DI 2 "register_operand" "a"))
15774    (use (match_dup 4))]
15775   "TARGET_64BIT
15776    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15777   "%^rep{%;} stosq"
15778   [(set_attr "type" "str")
15779    (set_attr "prefix_rep" "1")
15780    (set_attr "memory" "store")
15781    (set_attr "mode" "DI")])
15783 (define_insn "*rep_stossi"
15784   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15785    (set (match_operand:P 0 "register_operand" "=D")
15786         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15787                           (const_int 2))
15788                  (match_operand:P 3 "register_operand" "0")))
15789    (set (mem:BLK (match_dup 3))
15790         (const_int 0))
15791    (use (match_operand:SI 2 "register_operand" "a"))
15792    (use (match_dup 4))]
15793   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15794   "%^rep{%;} stos{l|d}"
15795   [(set_attr "type" "str")
15796    (set_attr "prefix_rep" "1")
15797    (set_attr "memory" "store")
15798    (set_attr "mode" "SI")])
15800 (define_insn "*rep_stosqi"
15801   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15802    (set (match_operand:P 0 "register_operand" "=D")
15803         (plus:P (match_operand:P 3 "register_operand" "0")
15804                 (match_operand:P 4 "register_operand" "1")))
15805    (set (mem:BLK (match_dup 3))
15806         (const_int 0))
15807    (use (match_operand:QI 2 "register_operand" "a"))
15808    (use (match_dup 4))]
15809   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15810   "%^rep{%;} stosb"
15811   [(set_attr "type" "str")
15812    (set_attr "prefix_rep" "1")
15813    (set_attr "memory" "store")
15814    (set (attr "prefix_rex")
15815         (if_then_else
15816           (match_test "<P:MODE>mode == DImode")
15817           (const_string "0")
15818           (const_string "*")))
15819    (set_attr "mode" "QI")])
15821 (define_expand "cmpstrnsi"
15822   [(set (match_operand:SI 0 "register_operand")
15823         (compare:SI (match_operand:BLK 1 "general_operand")
15824                     (match_operand:BLK 2 "general_operand")))
15825    (use (match_operand 3 "general_operand"))
15826    (use (match_operand 4 "immediate_operand"))]
15827   ""
15829   rtx addr1, addr2, out, outlow, count, countreg, align;
15831   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15832     FAIL;
15834   /* Can't use this if the user has appropriated ecx, esi or edi.  */
15835   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
15836     FAIL;
15838   out = operands[0];
15839   if (!REG_P (out))
15840     out = gen_reg_rtx (SImode);
15842   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
15843   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
15844   if (addr1 != XEXP (operands[1], 0))
15845     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15846   if (addr2 != XEXP (operands[2], 0))
15847     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15849   count = operands[3];
15850   countreg = ix86_zero_extend_to_Pmode (count);
15852   /* %%% Iff we are testing strict equality, we can use known alignment
15853      to good advantage.  This may be possible with combine, particularly
15854      once cc0 is dead.  */
15855   align = operands[4];
15857   if (CONST_INT_P (count))
15858     {
15859       if (INTVAL (count) == 0)
15860         {
15861           emit_move_insn (operands[0], const0_rtx);
15862           DONE;
15863         }
15864       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15865                                      operands[1], operands[2]));
15866     }
15867   else
15868     {
15869       rtx (*gen_cmp) (rtx, rtx);
15871       gen_cmp = (TARGET_64BIT
15872                  ? gen_cmpdi_1 : gen_cmpsi_1);
15874       emit_insn (gen_cmp (countreg, countreg));
15875       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15876                                   operands[1], operands[2]));
15877     }
15879   outlow = gen_lowpart (QImode, out);
15880   emit_insn (gen_cmpintqi (outlow));
15881   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15883   if (operands[0] != out)
15884     emit_move_insn (operands[0], out);
15886   DONE;
15889 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15891 (define_expand "cmpintqi"
15892   [(set (match_dup 1)
15893         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15894    (set (match_dup 2)
15895         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15896    (parallel [(set (match_operand:QI 0 "register_operand")
15897                    (minus:QI (match_dup 1)
15898                              (match_dup 2)))
15899               (clobber (reg:CC FLAGS_REG))])]
15900   ""
15902   operands[1] = gen_reg_rtx (QImode);
15903   operands[2] = gen_reg_rtx (QImode);
15906 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15907 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15909 (define_expand "cmpstrnqi_nz_1"
15910   [(parallel [(set (reg:CC FLAGS_REG)
15911                    (compare:CC (match_operand 4 "memory_operand")
15912                                (match_operand 5 "memory_operand")))
15913               (use (match_operand 2 "register_operand"))
15914               (use (match_operand:SI 3 "immediate_operand"))
15915               (clobber (match_operand 0 "register_operand"))
15916               (clobber (match_operand 1 "register_operand"))
15917               (clobber (match_dup 2))])]
15918   ""
15919   "ix86_current_function_needs_cld = 1;")
15921 (define_insn "*cmpstrnqi_nz_1"
15922   [(set (reg:CC FLAGS_REG)
15923         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15924                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15925    (use (match_operand:P 6 "register_operand" "2"))
15926    (use (match_operand:SI 3 "immediate_operand" "i"))
15927    (clobber (match_operand:P 0 "register_operand" "=S"))
15928    (clobber (match_operand:P 1 "register_operand" "=D"))
15929    (clobber (match_operand:P 2 "register_operand" "=c"))]
15930   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15931   "%^repz{%;} cmpsb"
15932   [(set_attr "type" "str")
15933    (set_attr "mode" "QI")
15934    (set (attr "prefix_rex")
15935         (if_then_else
15936           (match_test "<P:MODE>mode == DImode")
15937           (const_string "0")
15938           (const_string "*")))
15939    (set_attr "prefix_rep" "1")])
15941 ;; The same, but the count is not known to not be zero.
15943 (define_expand "cmpstrnqi_1"
15944   [(parallel [(set (reg:CC FLAGS_REG)
15945                 (if_then_else:CC (ne (match_operand 2 "register_operand")
15946                                      (const_int 0))
15947                   (compare:CC (match_operand 4 "memory_operand")
15948                               (match_operand 5 "memory_operand"))
15949                   (const_int 0)))
15950               (use (match_operand:SI 3 "immediate_operand"))
15951               (use (reg:CC FLAGS_REG))
15952               (clobber (match_operand 0 "register_operand"))
15953               (clobber (match_operand 1 "register_operand"))
15954               (clobber (match_dup 2))])]
15955   ""
15956   "ix86_current_function_needs_cld = 1;")
15958 (define_insn "*cmpstrnqi_1"
15959   [(set (reg:CC FLAGS_REG)
15960         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15961                              (const_int 0))
15962           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15963                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
15964           (const_int 0)))
15965    (use (match_operand:SI 3 "immediate_operand" "i"))
15966    (use (reg:CC FLAGS_REG))
15967    (clobber (match_operand:P 0 "register_operand" "=S"))
15968    (clobber (match_operand:P 1 "register_operand" "=D"))
15969    (clobber (match_operand:P 2 "register_operand" "=c"))]
15970   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15971   "%^repz{%;} cmpsb"
15972   [(set_attr "type" "str")
15973    (set_attr "mode" "QI")
15974    (set (attr "prefix_rex")
15975         (if_then_else
15976           (match_test "<P:MODE>mode == DImode")
15977           (const_string "0")
15978           (const_string "*")))
15979    (set_attr "prefix_rep" "1")])
15981 (define_expand "strlen<mode>"
15982   [(set (match_operand:P 0 "register_operand")
15983         (unspec:P [(match_operand:BLK 1 "general_operand")
15984                    (match_operand:QI 2 "immediate_operand")
15985                    (match_operand 3 "immediate_operand")]
15986                   UNSPEC_SCAS))]
15987   ""
15989  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15990    DONE;
15991  else
15992    FAIL;
15995 (define_expand "strlenqi_1"
15996   [(parallel [(set (match_operand 0 "register_operand")
15997                    (match_operand 2))
15998               (clobber (match_operand 1 "register_operand"))
15999               (clobber (reg:CC FLAGS_REG))])]
16000   ""
16001   "ix86_current_function_needs_cld = 1;")
16003 (define_insn "*strlenqi_1"
16004   [(set (match_operand:P 0 "register_operand" "=&c")
16005         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16006                    (match_operand:QI 2 "register_operand" "a")
16007                    (match_operand:P 3 "immediate_operand" "i")
16008                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16009    (clobber (match_operand:P 1 "register_operand" "=D"))
16010    (clobber (reg:CC FLAGS_REG))]
16011   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16012   "%^repnz{%;} scasb"
16013   [(set_attr "type" "str")
16014    (set_attr "mode" "QI")
16015    (set (attr "prefix_rex")
16016         (if_then_else
16017           (match_test "<P:MODE>mode == DImode")
16018           (const_string "0")
16019           (const_string "*")))
16020    (set_attr "prefix_rep" "1")])
16022 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16023 ;; handled in combine, but it is not currently up to the task.
16024 ;; When used for their truth value, the cmpstrn* expanders generate
16025 ;; code like this:
16027 ;;   repz cmpsb
16028 ;;   seta       %al
16029 ;;   setb       %dl
16030 ;;   cmpb       %al, %dl
16031 ;;   jcc        label
16033 ;; The intermediate three instructions are unnecessary.
16035 ;; This one handles cmpstrn*_nz_1...
16036 (define_peephole2
16037   [(parallel[
16038      (set (reg:CC FLAGS_REG)
16039           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16040                       (mem:BLK (match_operand 5 "register_operand"))))
16041      (use (match_operand 6 "register_operand"))
16042      (use (match_operand:SI 3 "immediate_operand"))
16043      (clobber (match_operand 0 "register_operand"))
16044      (clobber (match_operand 1 "register_operand"))
16045      (clobber (match_operand 2 "register_operand"))])
16046    (set (match_operand:QI 7 "register_operand")
16047         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16048    (set (match_operand:QI 8 "register_operand")
16049         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16050    (set (reg FLAGS_REG)
16051         (compare (match_dup 7) (match_dup 8)))
16052   ]
16053   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16054   [(parallel[
16055      (set (reg:CC FLAGS_REG)
16056           (compare:CC (mem:BLK (match_dup 4))
16057                       (mem:BLK (match_dup 5))))
16058      (use (match_dup 6))
16059      (use (match_dup 3))
16060      (clobber (match_dup 0))
16061      (clobber (match_dup 1))
16062      (clobber (match_dup 2))])])
16064 ;; ...and this one handles cmpstrn*_1.
16065 (define_peephole2
16066   [(parallel[
16067      (set (reg:CC FLAGS_REG)
16068           (if_then_else:CC (ne (match_operand 6 "register_operand")
16069                                (const_int 0))
16070             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16071                         (mem:BLK (match_operand 5 "register_operand")))
16072             (const_int 0)))
16073      (use (match_operand:SI 3 "immediate_operand"))
16074      (use (reg:CC FLAGS_REG))
16075      (clobber (match_operand 0 "register_operand"))
16076      (clobber (match_operand 1 "register_operand"))
16077      (clobber (match_operand 2 "register_operand"))])
16078    (set (match_operand:QI 7 "register_operand")
16079         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16080    (set (match_operand:QI 8 "register_operand")
16081         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16082    (set (reg FLAGS_REG)
16083         (compare (match_dup 7) (match_dup 8)))
16084   ]
16085   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16086   [(parallel[
16087      (set (reg:CC FLAGS_REG)
16088           (if_then_else:CC (ne (match_dup 6)
16089                                (const_int 0))
16090             (compare:CC (mem:BLK (match_dup 4))
16091                         (mem:BLK (match_dup 5)))
16092             (const_int 0)))
16093      (use (match_dup 3))
16094      (use (reg:CC FLAGS_REG))
16095      (clobber (match_dup 0))
16096      (clobber (match_dup 1))
16097      (clobber (match_dup 2))])])
16099 ;; Conditional move instructions.
16101 (define_expand "mov<mode>cc"
16102   [(set (match_operand:SWIM 0 "register_operand")
16103         (if_then_else:SWIM (match_operand 1 "comparison_operator")
16104                            (match_operand:SWIM 2 "<general_operand>")
16105                            (match_operand:SWIM 3 "<general_operand>")))]
16106   ""
16107   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16109 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16110 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16111 ;; So just document what we're doing explicitly.
16113 (define_expand "x86_mov<mode>cc_0_m1"
16114   [(parallel
16115     [(set (match_operand:SWI48 0 "register_operand")
16116           (if_then_else:SWI48
16117             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16118              [(match_operand 1 "flags_reg_operand")
16119               (const_int 0)])
16120             (const_int -1)
16121             (const_int 0)))
16122      (clobber (reg:CC FLAGS_REG))])])
16124 (define_insn "*x86_mov<mode>cc_0_m1"
16125   [(set (match_operand:SWI48 0 "register_operand" "=r")
16126         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16127                              [(reg FLAGS_REG) (const_int 0)])
16128           (const_int -1)
16129           (const_int 0)))
16130    (clobber (reg:CC FLAGS_REG))]
16131   ""
16132   "sbb{<imodesuffix>}\t%0, %0"
16133   ; Since we don't have the proper number of operands for an alu insn,
16134   ; fill in all the blanks.
16135   [(set_attr "type" "alu")
16136    (set_attr "use_carry" "1")
16137    (set_attr "pent_pair" "pu")
16138    (set_attr "memory" "none")
16139    (set_attr "imm_disp" "false")
16140    (set_attr "mode" "<MODE>")
16141    (set_attr "length_immediate" "0")])
16143 (define_insn "*x86_mov<mode>cc_0_m1_se"
16144   [(set (match_operand:SWI48 0 "register_operand" "=r")
16145         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16146                              [(reg FLAGS_REG) (const_int 0)])
16147                             (const_int 1)
16148                             (const_int 0)))
16149    (clobber (reg:CC FLAGS_REG))]
16150   ""
16151   "sbb{<imodesuffix>}\t%0, %0"
16152   [(set_attr "type" "alu")
16153    (set_attr "use_carry" "1")
16154    (set_attr "pent_pair" "pu")
16155    (set_attr "memory" "none")
16156    (set_attr "imm_disp" "false")
16157    (set_attr "mode" "<MODE>")
16158    (set_attr "length_immediate" "0")])
16160 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16161   [(set (match_operand:SWI48 0 "register_operand" "=r")
16162         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16163                     [(reg FLAGS_REG) (const_int 0)])))
16164    (clobber (reg:CC FLAGS_REG))]
16165   ""
16166   "sbb{<imodesuffix>}\t%0, %0"
16167   [(set_attr "type" "alu")
16168    (set_attr "use_carry" "1")
16169    (set_attr "pent_pair" "pu")
16170    (set_attr "memory" "none")
16171    (set_attr "imm_disp" "false")
16172    (set_attr "mode" "<MODE>")
16173    (set_attr "length_immediate" "0")])
16175 (define_insn "*mov<mode>cc_noc"
16176   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16177         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16178                                [(reg FLAGS_REG) (const_int 0)])
16179           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16180           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16181   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16182   "@
16183    cmov%O2%C1\t{%2, %0|%0, %2}
16184    cmov%O2%c1\t{%3, %0|%0, %3}"
16185   [(set_attr "type" "icmov")
16186    (set_attr "mode" "<MODE>")])
16188 ;; Don't do conditional moves with memory inputs.  This splitter helps
16189 ;; register starved x86_32 by forcing inputs into registers before reload.
16190 (define_split
16191   [(set (match_operand:SWI248 0 "register_operand")
16192         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16193                                [(reg FLAGS_REG) (const_int 0)])
16194           (match_operand:SWI248 2 "nonimmediate_operand")
16195           (match_operand:SWI248 3 "nonimmediate_operand")))]
16196   "!TARGET_64BIT && TARGET_CMOVE
16197    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16198    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16199    && can_create_pseudo_p ()
16200    && optimize_insn_for_speed_p ()"
16201   [(set (match_dup 0)
16202         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16204   if (MEM_P (operands[2]))
16205     operands[2] = force_reg (<MODE>mode, operands[2]);
16206   if (MEM_P (operands[3]))
16207     operands[3] = force_reg (<MODE>mode, operands[3]);
16210 (define_insn "*movqicc_noc"
16211   [(set (match_operand:QI 0 "register_operand" "=r,r")
16212         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16213                            [(reg FLAGS_REG) (const_int 0)])
16214                       (match_operand:QI 2 "register_operand" "r,0")
16215                       (match_operand:QI 3 "register_operand" "0,r")))]
16216   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16217   "#"
16218   [(set_attr "type" "icmov")
16219    (set_attr "mode" "QI")])
16221 (define_split
16222   [(set (match_operand:SWI12 0 "register_operand")
16223         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16224                               [(reg FLAGS_REG) (const_int 0)])
16225                       (match_operand:SWI12 2 "register_operand")
16226                       (match_operand:SWI12 3 "register_operand")))]
16227   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16228    && reload_completed"
16229   [(set (match_dup 0)
16230         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16232   operands[0] = gen_lowpart (SImode, operands[0]);
16233   operands[2] = gen_lowpart (SImode, operands[2]);
16234   operands[3] = gen_lowpart (SImode, operands[3]);
16237 ;; Don't do conditional moves with memory inputs
16238 (define_peephole2
16239   [(match_scratch:SWI248 2 "r")
16240    (set (match_operand:SWI248 0 "register_operand")
16241         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16242                                [(reg FLAGS_REG) (const_int 0)])
16243           (match_dup 0)
16244           (match_operand:SWI248 3 "memory_operand")))]
16245   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16246    && optimize_insn_for_speed_p ()"
16247   [(set (match_dup 2) (match_dup 3))
16248    (set (match_dup 0)
16249         (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16251 (define_peephole2
16252   [(match_scratch:SWI248 2 "r")
16253    (set (match_operand:SWI248 0 "register_operand")
16254         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16255                                [(reg FLAGS_REG) (const_int 0)])
16256           (match_operand:SWI248 3 "memory_operand")
16257           (match_dup 0)))]
16258   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16259    && optimize_insn_for_speed_p ()"
16260   [(set (match_dup 2) (match_dup 3))
16261    (set (match_dup 0)
16262         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16264 (define_expand "mov<mode>cc"
16265   [(set (match_operand:X87MODEF 0 "register_operand")
16266         (if_then_else:X87MODEF
16267           (match_operand 1 "comparison_operator")
16268           (match_operand:X87MODEF 2 "register_operand")
16269           (match_operand:X87MODEF 3 "register_operand")))]
16270   "(TARGET_80387 && TARGET_CMOVE)
16271    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16272   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16274 (define_insn "*movxfcc_1"
16275   [(set (match_operand:XF 0 "register_operand" "=f,f")
16276         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16277                                 [(reg FLAGS_REG) (const_int 0)])
16278                       (match_operand:XF 2 "register_operand" "f,0")
16279                       (match_operand:XF 3 "register_operand" "0,f")))]
16280   "TARGET_80387 && TARGET_CMOVE"
16281   "@
16282    fcmov%F1\t{%2, %0|%0, %2}
16283    fcmov%f1\t{%3, %0|%0, %3}"
16284   [(set_attr "type" "fcmov")
16285    (set_attr "mode" "XF")])
16287 (define_insn "*movdfcc_1_rex64"
16288   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16289         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16290                                 [(reg FLAGS_REG) (const_int 0)])
16291                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16292                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16293   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16294    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16295   "@
16296    fcmov%F1\t{%2, %0|%0, %2}
16297    fcmov%f1\t{%3, %0|%0, %3}
16298    cmov%O2%C1\t{%2, %0|%0, %2}
16299    cmov%O2%c1\t{%3, %0|%0, %3}"
16300   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16301    (set_attr "mode" "DF,DF,DI,DI")])
16303 (define_insn "*movdfcc_1"
16304   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16305         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16306                                 [(reg FLAGS_REG) (const_int 0)])
16307                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16308                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16309   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16310    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16311   "@
16312    fcmov%F1\t{%2, %0|%0, %2}
16313    fcmov%f1\t{%3, %0|%0, %3}
16314    #
16315    #"
16316   [(set_attr "type" "fcmov,fcmov,multi,multi")
16317    (set_attr "mode" "DF,DF,DI,DI")])
16319 (define_split
16320   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16321         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16322                                 [(reg FLAGS_REG) (const_int 0)])
16323                       (match_operand:DF 2 "nonimmediate_operand")
16324                       (match_operand:DF 3 "nonimmediate_operand")))]
16325   "!TARGET_64BIT && reload_completed"
16326   [(set (match_dup 2)
16327         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16328    (set (match_dup 3)
16329         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16331   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16332   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16335 (define_insn "*movsfcc_1_387"
16336   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16337         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16338                                 [(reg FLAGS_REG) (const_int 0)])
16339                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16340                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16341   "TARGET_80387 && TARGET_CMOVE
16342    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16343   "@
16344    fcmov%F1\t{%2, %0|%0, %2}
16345    fcmov%f1\t{%3, %0|%0, %3}
16346    cmov%O2%C1\t{%2, %0|%0, %2}
16347    cmov%O2%c1\t{%3, %0|%0, %3}"
16348   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16349    (set_attr "mode" "SF,SF,SI,SI")])
16351 ;; Don't do conditional moves with memory inputs.  This splitter helps
16352 ;; register starved x86_32 by forcing inputs into registers before reload.
16353 (define_split
16354   [(set (match_operand:MODEF 0 "register_operand")
16355         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16356                               [(reg FLAGS_REG) (const_int 0)])
16357           (match_operand:MODEF 2 "nonimmediate_operand")
16358           (match_operand:MODEF 3 "nonimmediate_operand")))]
16359   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16360    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16361    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16362    && can_create_pseudo_p ()
16363    && optimize_insn_for_speed_p ()"
16364   [(set (match_dup 0)
16365         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16367   if (MEM_P (operands[2]))
16368     operands[2] = force_reg (<MODE>mode, operands[2]);
16369   if (MEM_P (operands[3]))
16370     operands[3] = force_reg (<MODE>mode, operands[3]);
16373 ;; Don't do conditional moves with memory inputs
16374 (define_peephole2
16375   [(match_scratch:MODEF 2 "r")
16376    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16377         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16378                               [(reg FLAGS_REG) (const_int 0)])
16379           (match_dup 0)
16380           (match_operand:MODEF 3 "memory_operand")))]
16381   "(<MODE>mode != DFmode || TARGET_64BIT)
16382    && TARGET_80387 && TARGET_CMOVE
16383    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16384    && optimize_insn_for_speed_p ()"
16385   [(set (match_dup 2) (match_dup 3))
16386    (set (match_dup 0)
16387         (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16389 (define_peephole2
16390   [(match_scratch:MODEF 2 "r")
16391    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16392         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16393                               [(reg FLAGS_REG) (const_int 0)])
16394           (match_operand:MODEF 3 "memory_operand")
16395           (match_dup 0)))]
16396   "(<MODE>mode != DFmode || TARGET_64BIT)
16397    && TARGET_80387 && TARGET_CMOVE
16398    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16399    && optimize_insn_for_speed_p ()"
16400   [(set (match_dup 2) (match_dup 3))
16401    (set (match_dup 0)
16402         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16404 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16405 ;; the scalar versions to have only XMM registers as operands.
16407 ;; XOP conditional move
16408 (define_insn "*xop_pcmov_<mode>"
16409   [(set (match_operand:MODEF 0 "register_operand" "=x")
16410         (if_then_else:MODEF
16411           (match_operand:MODEF 1 "register_operand" "x")
16412           (match_operand:MODEF 2 "register_operand" "x")
16413           (match_operand:MODEF 3 "register_operand" "x")))]
16414   "TARGET_XOP"
16415   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16416   [(set_attr "type" "sse4arg")])
16418 ;; These versions of the min/max patterns are intentionally ignorant of
16419 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16420 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16421 ;; are undefined in this condition, we're certain this is correct.
16423 (define_insn "<code><mode>3"
16424   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16425         (smaxmin:MODEF
16426           (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16427           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16428   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16429   "@
16430    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16431    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16432   [(set_attr "isa" "noavx,avx")
16433    (set_attr "prefix" "orig,vex")
16434    (set_attr "type" "sseadd")
16435    (set_attr "mode" "<MODE>")])
16437 ;; These versions of the min/max patterns implement exactly the operations
16438 ;;   min = (op1 < op2 ? op1 : op2)
16439 ;;   max = (!(op1 < op2) ? op1 : op2)
16440 ;; Their operands are not commutative, and thus they may be used in the
16441 ;; presence of -0.0 and NaN.
16443 (define_int_iterator IEEE_MAXMIN
16444         [UNSPEC_IEEE_MAX
16445          UNSPEC_IEEE_MIN])
16447 (define_int_attr ieee_maxmin
16448         [(UNSPEC_IEEE_MAX "max")
16449          (UNSPEC_IEEE_MIN "min")])
16451 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16452   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16453         (unspec:MODEF
16454           [(match_operand:MODEF 1 "register_operand" "0,x")
16455            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16456           IEEE_MAXMIN))]
16457   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16458   "@
16459    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16460    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16461   [(set_attr "isa" "noavx,avx")
16462    (set_attr "prefix" "orig,vex")
16463    (set_attr "type" "sseadd")
16464    (set_attr "mode" "<MODE>")])
16466 ;; Make two stack loads independent:
16467 ;;   fld aa              fld aa
16468 ;;   fld %st(0)     ->   fld bb
16469 ;;   fmul bb             fmul %st(1), %st
16471 ;; Actually we only match the last two instructions for simplicity.
16472 (define_peephole2
16473   [(set (match_operand 0 "fp_register_operand")
16474         (match_operand 1 "fp_register_operand"))
16475    (set (match_dup 0)
16476         (match_operator 2 "binary_fp_operator"
16477            [(match_dup 0)
16478             (match_operand 3 "memory_operand")]))]
16479   "REGNO (operands[0]) != REGNO (operands[1])"
16480   [(set (match_dup 0) (match_dup 3))
16481    (set (match_dup 0) (match_dup 4))]
16483   ;; The % modifier is not operational anymore in peephole2's, so we have to
16484   ;; swap the operands manually in the case of addition and multiplication.
16486   rtx op0, op1;
16488   if (COMMUTATIVE_ARITH_P (operands[2]))
16489     op0 = operands[0], op1 = operands[1];
16490   else
16491     op0 = operands[1], op1 = operands[0];
16493   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16494                                 GET_MODE (operands[2]),
16495                                 op0, op1);
16498 ;; Conditional addition patterns
16499 (define_expand "add<mode>cc"
16500   [(match_operand:SWI 0 "register_operand")
16501    (match_operand 1 "ordered_comparison_operator")
16502    (match_operand:SWI 2 "register_operand")
16503    (match_operand:SWI 3 "const_int_operand")]
16504   ""
16505   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16507 ;; Misc patterns (?)
16509 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16510 ;; Otherwise there will be nothing to keep
16512 ;; [(set (reg ebp) (reg esp))]
16513 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16514 ;;  (clobber (eflags)]
16515 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16517 ;; in proper program order.
16519 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16520   [(set (match_operand:P 0 "register_operand" "=r,r")
16521         (plus:P (match_operand:P 1 "register_operand" "0,r")
16522                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16523    (clobber (reg:CC FLAGS_REG))
16524    (clobber (mem:BLK (scratch)))]
16525   ""
16527   switch (get_attr_type (insn))
16528     {
16529     case TYPE_IMOV:
16530       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16532     case TYPE_ALU:
16533       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16534       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16535         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16537       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16539     default:
16540       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16541       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16542     }
16544   [(set (attr "type")
16545         (cond [(and (eq_attr "alternative" "0")
16546                     (not (match_test "TARGET_OPT_AGU")))
16547                  (const_string "alu")
16548                (match_operand:<MODE> 2 "const0_operand")
16549                  (const_string "imov")
16550               ]
16551               (const_string "lea")))
16552    (set (attr "length_immediate")
16553         (cond [(eq_attr "type" "imov")
16554                  (const_string "0")
16555                (and (eq_attr "type" "alu")
16556                     (match_operand 2 "const128_operand"))
16557                  (const_string "1")
16558               ]
16559               (const_string "*")))
16560    (set_attr "mode" "<MODE>")])
16562 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16563   [(set (match_operand:P 0 "register_operand" "=r")
16564         (minus:P (match_operand:P 1 "register_operand" "0")
16565                  (match_operand:P 2 "register_operand" "r")))
16566    (clobber (reg:CC FLAGS_REG))
16567    (clobber (mem:BLK (scratch)))]
16568   ""
16569   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16570   [(set_attr "type" "alu")
16571    (set_attr "mode" "<MODE>")])
16573 (define_insn "allocate_stack_worker_probe_<mode>"
16574   [(set (match_operand:P 0 "register_operand" "=a")
16575         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16576                             UNSPECV_STACK_PROBE))
16577    (clobber (reg:CC FLAGS_REG))]
16578   "ix86_target_stack_probe ()"
16579   "call\t___chkstk_ms"
16580   [(set_attr "type" "multi")
16581    (set_attr "length" "5")])
16583 (define_expand "allocate_stack"
16584   [(match_operand 0 "register_operand")
16585    (match_operand 1 "general_operand")]
16586   "ix86_target_stack_probe ()"
16588   rtx x;
16590 #ifndef CHECK_STACK_LIMIT
16591 #define CHECK_STACK_LIMIT 0
16592 #endif
16594   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16595       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16596     x = operands[1];
16597   else
16598     {
16599       rtx (*insn) (rtx, rtx);
16601       x = copy_to_mode_reg (Pmode, operands[1]);
16603       insn = (TARGET_64BIT
16604               ? gen_allocate_stack_worker_probe_di
16605               : gen_allocate_stack_worker_probe_si);
16607       emit_insn (insn (x, x));
16608     }
16610   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16611                            stack_pointer_rtx, 0, OPTAB_DIRECT);
16613   if (x != stack_pointer_rtx)
16614     emit_move_insn (stack_pointer_rtx, x);
16616   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16617   DONE;
16620 ;; Use IOR for stack probes, this is shorter.
16621 (define_expand "probe_stack"
16622   [(match_operand 0 "memory_operand")]
16623   ""
16625   rtx (*gen_ior3) (rtx, rtx, rtx);
16627   gen_ior3 = (GET_MODE (operands[0]) == DImode
16628               ? gen_iordi3 : gen_iorsi3);
16630   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16631   DONE;
16634 (define_insn "adjust_stack_and_probe<mode>"
16635   [(set (match_operand:P 0 "register_operand" "=r")
16636         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16637                             UNSPECV_PROBE_STACK_RANGE))
16638    (set (reg:P SP_REG)
16639         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16640    (clobber (reg:CC FLAGS_REG))
16641    (clobber (mem:BLK (scratch)))]
16642   ""
16643   "* return output_adjust_stack_and_probe (operands[0]);"
16644   [(set_attr "type" "multi")])
16646 (define_insn "probe_stack_range<mode>"
16647   [(set (match_operand:P 0 "register_operand" "=r")
16648         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16649                             (match_operand:P 2 "const_int_operand" "n")]
16650                             UNSPECV_PROBE_STACK_RANGE))
16651    (clobber (reg:CC FLAGS_REG))]
16652   ""
16653   "* return output_probe_stack_range (operands[0], operands[2]);"
16654   [(set_attr "type" "multi")])
16656 (define_expand "builtin_setjmp_receiver"
16657   [(label_ref (match_operand 0))]
16658   "!TARGET_64BIT && flag_pic"
16660 #if TARGET_MACHO
16661   if (TARGET_MACHO)
16662     {
16663       rtx xops[3];
16664       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16665       rtx label_rtx = gen_label_rtx ();
16666       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16667       xops[0] = xops[1] = picreg;
16668       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16669       ix86_expand_binary_operator (MINUS, SImode, xops);
16670     }
16671   else
16672 #endif
16673     emit_insn (gen_set_got (pic_offset_table_rtx));
16674   DONE;
16677 (define_insn_and_split "nonlocal_goto_receiver"
16678   [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16679   "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16680   "#"
16681   "&& reload_completed"
16682   [(const_int 0)]
16684   if (crtl->uses_pic_offset_table)
16685     {
16686       rtx xops[3];
16687       rtx label_rtx = gen_label_rtx ();
16688       rtx tmp;
16690       /* Get a new pic base.  */
16691       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16692       /* Correct this with the offset from the new to the old.  */
16693       xops[0] = xops[1] = pic_offset_table_rtx;
16694       label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16695       tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16696                             UNSPEC_MACHOPIC_OFFSET);
16697       xops[2] = gen_rtx_CONST (Pmode, tmp);
16698       ix86_expand_binary_operator (MINUS, SImode, xops);
16699     }
16700   else
16701     /* No pic reg restore needed.  */
16702     emit_note (NOTE_INSN_DELETED);
16704   DONE;
16707 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16709 (define_split
16710   [(set (match_operand 0 "register_operand")
16711         (match_operator 3 "promotable_binary_operator"
16712            [(match_operand 1 "register_operand")
16713             (match_operand 2 "aligned_operand")]))
16714    (clobber (reg:CC FLAGS_REG))]
16715   "! TARGET_PARTIAL_REG_STALL && reload_completed
16716    && ((GET_MODE (operands[0]) == HImode
16717         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16718             /* ??? next two lines just !satisfies_constraint_K (...) */
16719             || !CONST_INT_P (operands[2])
16720             || satisfies_constraint_K (operands[2])))
16721        || (GET_MODE (operands[0]) == QImode
16722            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16723   [(parallel [(set (match_dup 0)
16724                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16725               (clobber (reg:CC FLAGS_REG))])]
16727   operands[0] = gen_lowpart (SImode, operands[0]);
16728   operands[1] = gen_lowpart (SImode, operands[1]);
16729   if (GET_CODE (operands[3]) != ASHIFT)
16730     operands[2] = gen_lowpart (SImode, operands[2]);
16731   PUT_MODE (operands[3], SImode);
16734 ; Promote the QImode tests, as i386 has encoding of the AND
16735 ; instruction with 32-bit sign-extended immediate and thus the
16736 ; instruction size is unchanged, except in the %eax case for
16737 ; which it is increased by one byte, hence the ! optimize_size.
16738 (define_split
16739   [(set (match_operand 0 "flags_reg_operand")
16740         (match_operator 2 "compare_operator"
16741           [(and (match_operand 3 "aligned_operand")
16742                 (match_operand 4 "const_int_operand"))
16743            (const_int 0)]))
16744    (set (match_operand 1 "register_operand")
16745         (and (match_dup 3) (match_dup 4)))]
16746   "! TARGET_PARTIAL_REG_STALL && reload_completed
16747    && optimize_insn_for_speed_p ()
16748    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16749        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16750    /* Ensure that the operand will remain sign-extended immediate.  */
16751    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16752   [(parallel [(set (match_dup 0)
16753                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16754                                     (const_int 0)]))
16755               (set (match_dup 1)
16756                    (and:SI (match_dup 3) (match_dup 4)))])]
16758   operands[4]
16759     = gen_int_mode (INTVAL (operands[4])
16760                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16761   operands[1] = gen_lowpart (SImode, operands[1]);
16762   operands[3] = gen_lowpart (SImode, operands[3]);
16765 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16766 ; the TEST instruction with 32-bit sign-extended immediate and thus
16767 ; the instruction size would at least double, which is not what we
16768 ; want even with ! optimize_size.
16769 (define_split
16770   [(set (match_operand 0 "flags_reg_operand")
16771         (match_operator 1 "compare_operator"
16772           [(and (match_operand:HI 2 "aligned_operand")
16773                 (match_operand:HI 3 "const_int_operand"))
16774            (const_int 0)]))]
16775   "! TARGET_PARTIAL_REG_STALL && reload_completed
16776    && ! TARGET_FAST_PREFIX
16777    && optimize_insn_for_speed_p ()
16778    /* Ensure that the operand will remain sign-extended immediate.  */
16779    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16780   [(set (match_dup 0)
16781         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16782                          (const_int 0)]))]
16784   operands[3]
16785     = gen_int_mode (INTVAL (operands[3])
16786                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16787   operands[2] = gen_lowpart (SImode, operands[2]);
16790 (define_split
16791   [(set (match_operand 0 "register_operand")
16792         (neg (match_operand 1 "register_operand")))
16793    (clobber (reg:CC FLAGS_REG))]
16794   "! TARGET_PARTIAL_REG_STALL && reload_completed
16795    && (GET_MODE (operands[0]) == HImode
16796        || (GET_MODE (operands[0]) == QImode
16797            && (TARGET_PROMOTE_QImode
16798                || optimize_insn_for_size_p ())))"
16799   [(parallel [(set (match_dup 0)
16800                    (neg:SI (match_dup 1)))
16801               (clobber (reg:CC FLAGS_REG))])]
16803   operands[0] = gen_lowpart (SImode, operands[0]);
16804   operands[1] = gen_lowpart (SImode, operands[1]);
16807 (define_split
16808   [(set (match_operand 0 "register_operand")
16809         (not (match_operand 1 "register_operand")))]
16810   "! TARGET_PARTIAL_REG_STALL && reload_completed
16811    && (GET_MODE (operands[0]) == HImode
16812        || (GET_MODE (operands[0]) == QImode
16813            && (TARGET_PROMOTE_QImode
16814                || optimize_insn_for_size_p ())))"
16815   [(set (match_dup 0)
16816         (not:SI (match_dup 1)))]
16818   operands[0] = gen_lowpart (SImode, operands[0]);
16819   operands[1] = gen_lowpart (SImode, operands[1]);
16822 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16823 ;; transform a complex memory operation into two memory to register operations.
16825 ;; Don't push memory operands
16826 (define_peephole2
16827   [(set (match_operand:SWI 0 "push_operand")
16828         (match_operand:SWI 1 "memory_operand"))
16829    (match_scratch:SWI 2 "<r>")]
16830   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16831    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16832   [(set (match_dup 2) (match_dup 1))
16833    (set (match_dup 0) (match_dup 2))])
16835 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16836 ;; SImode pushes.
16837 (define_peephole2
16838   [(set (match_operand:SF 0 "push_operand")
16839         (match_operand:SF 1 "memory_operand"))
16840    (match_scratch:SF 2 "r")]
16841   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16842    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16843   [(set (match_dup 2) (match_dup 1))
16844    (set (match_dup 0) (match_dup 2))])
16846 ;; Don't move an immediate directly to memory when the instruction
16847 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16848 (define_peephole2
16849   [(match_scratch:SWI124 1 "<r>")
16850    (set (match_operand:SWI124 0 "memory_operand")
16851         (const_int 0))]
16852   "optimize_insn_for_speed_p ()
16853    && ((<MODE>mode == HImode
16854        && TARGET_LCP_STALL)
16855        || (!TARGET_USE_MOV0
16856           && TARGET_SPLIT_LONG_MOVES
16857           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16858    && peep2_regno_dead_p (0, FLAGS_REG)"
16859   [(parallel [(set (match_dup 2) (const_int 0))
16860               (clobber (reg:CC FLAGS_REG))])
16861    (set (match_dup 0) (match_dup 1))]
16862   "operands[2] = gen_lowpart (SImode, operands[1]);")
16864 (define_peephole2
16865   [(match_scratch:SWI124 2 "<r>")
16866    (set (match_operand:SWI124 0 "memory_operand")
16867         (match_operand:SWI124 1 "immediate_operand"))]
16868   "optimize_insn_for_speed_p ()
16869    && ((<MODE>mode == HImode
16870        && TARGET_LCP_STALL)
16871        || (TARGET_SPLIT_LONG_MOVES
16872           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16873   [(set (match_dup 2) (match_dup 1))
16874    (set (match_dup 0) (match_dup 2))])
16876 ;; Don't compare memory with zero, load and use a test instead.
16877 (define_peephole2
16878   [(set (match_operand 0 "flags_reg_operand")
16879         (match_operator 1 "compare_operator"
16880           [(match_operand:SI 2 "memory_operand")
16881            (const_int 0)]))
16882    (match_scratch:SI 3 "r")]
16883   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16884   [(set (match_dup 3) (match_dup 2))
16885    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16887 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16888 ;; Don't split NOTs with a displacement operand, because resulting XOR
16889 ;; will not be pairable anyway.
16891 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16892 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16893 ;; so this split helps here as well.
16895 ;; Note: Can't do this as a regular split because we can't get proper
16896 ;; lifetime information then.
16898 (define_peephole2
16899   [(set (match_operand:SWI124 0 "nonimmediate_operand")
16900         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
16901   "optimize_insn_for_speed_p ()
16902    && ((TARGET_NOT_UNPAIRABLE
16903         && (!MEM_P (operands[0])
16904             || !memory_displacement_operand (operands[0], <MODE>mode)))
16905        || (TARGET_NOT_VECTORMODE
16906            && long_memory_operand (operands[0], <MODE>mode)))
16907    && peep2_regno_dead_p (0, FLAGS_REG)"
16908   [(parallel [(set (match_dup 0)
16909                    (xor:SWI124 (match_dup 1) (const_int -1)))
16910               (clobber (reg:CC FLAGS_REG))])])
16912 ;; Non pairable "test imm, reg" instructions can be translated to
16913 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16914 ;; byte opcode instead of two, have a short form for byte operands),
16915 ;; so do it for other CPUs as well.  Given that the value was dead,
16916 ;; this should not create any new dependencies.  Pass on the sub-word
16917 ;; versions if we're concerned about partial register stalls.
16919 (define_peephole2
16920   [(set (match_operand 0 "flags_reg_operand")
16921         (match_operator 1 "compare_operator"
16922           [(and:SI (match_operand:SI 2 "register_operand")
16923                    (match_operand:SI 3 "immediate_operand"))
16924            (const_int 0)]))]
16925   "ix86_match_ccmode (insn, CCNOmode)
16926    && (true_regnum (operands[2]) != AX_REG
16927        || satisfies_constraint_K (operands[3]))
16928    && peep2_reg_dead_p (1, operands[2])"
16929   [(parallel
16930      [(set (match_dup 0)
16931            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16932                             (const_int 0)]))
16933       (set (match_dup 2)
16934            (and:SI (match_dup 2) (match_dup 3)))])])
16936 ;; We don't need to handle HImode case, because it will be promoted to SImode
16937 ;; on ! TARGET_PARTIAL_REG_STALL
16939 (define_peephole2
16940   [(set (match_operand 0 "flags_reg_operand")
16941         (match_operator 1 "compare_operator"
16942           [(and:QI (match_operand:QI 2 "register_operand")
16943                    (match_operand:QI 3 "immediate_operand"))
16944            (const_int 0)]))]
16945   "! TARGET_PARTIAL_REG_STALL
16946    && ix86_match_ccmode (insn, CCNOmode)
16947    && true_regnum (operands[2]) != AX_REG
16948    && peep2_reg_dead_p (1, operands[2])"
16949   [(parallel
16950      [(set (match_dup 0)
16951            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16952                             (const_int 0)]))
16953       (set (match_dup 2)
16954            (and:QI (match_dup 2) (match_dup 3)))])])
16956 (define_peephole2
16957   [(set (match_operand 0 "flags_reg_operand")
16958         (match_operator 1 "compare_operator"
16959           [(and:SI
16960              (zero_extract:SI
16961                (match_operand 2 "ext_register_operand")
16962                (const_int 8)
16963                (const_int 8))
16964              (match_operand 3 "const_int_operand"))
16965            (const_int 0)]))]
16966   "! TARGET_PARTIAL_REG_STALL
16967    && ix86_match_ccmode (insn, CCNOmode)
16968    && true_regnum (operands[2]) != AX_REG
16969    && peep2_reg_dead_p (1, operands[2])"
16970   [(parallel [(set (match_dup 0)
16971                    (match_op_dup 1
16972                      [(and:SI
16973                         (zero_extract:SI
16974                           (match_dup 2)
16975                           (const_int 8)
16976                           (const_int 8))
16977                         (match_dup 3))
16978                       (const_int 0)]))
16979               (set (zero_extract:SI (match_dup 2)
16980                                     (const_int 8)
16981                                     (const_int 8))
16982                    (and:SI
16983                      (zero_extract:SI
16984                        (match_dup 2)
16985                        (const_int 8)
16986                        (const_int 8))
16987                      (match_dup 3)))])])
16989 ;; Don't do logical operations with memory inputs.
16990 (define_peephole2
16991   [(match_scratch:SI 2 "r")
16992    (parallel [(set (match_operand:SI 0 "register_operand")
16993                    (match_operator:SI 3 "arith_or_logical_operator"
16994                      [(match_dup 0)
16995                       (match_operand:SI 1 "memory_operand")]))
16996               (clobber (reg:CC FLAGS_REG))])]
16997   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16998   [(set (match_dup 2) (match_dup 1))
16999    (parallel [(set (match_dup 0)
17000                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17001               (clobber (reg:CC FLAGS_REG))])])
17003 (define_peephole2
17004   [(match_scratch:SI 2 "r")
17005    (parallel [(set (match_operand:SI 0 "register_operand")
17006                    (match_operator:SI 3 "arith_or_logical_operator"
17007                      [(match_operand:SI 1 "memory_operand")
17008                       (match_dup 0)]))
17009               (clobber (reg:CC FLAGS_REG))])]
17010   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17011   [(set (match_dup 2) (match_dup 1))
17012    (parallel [(set (match_dup 0)
17013                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17014               (clobber (reg:CC FLAGS_REG))])])
17016 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17017 ;; refers to the destination of the load!
17019 (define_peephole2
17020   [(set (match_operand:SI 0 "register_operand")
17021         (match_operand:SI 1 "register_operand"))
17022    (parallel [(set (match_dup 0)
17023                    (match_operator:SI 3 "commutative_operator"
17024                      [(match_dup 0)
17025                       (match_operand:SI 2 "memory_operand")]))
17026               (clobber (reg:CC FLAGS_REG))])]
17027   "REGNO (operands[0]) != REGNO (operands[1])
17028    && GENERAL_REGNO_P (REGNO (operands[0]))
17029    && GENERAL_REGNO_P (REGNO (operands[1]))"
17030   [(set (match_dup 0) (match_dup 4))
17031    (parallel [(set (match_dup 0)
17032                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17033               (clobber (reg:CC FLAGS_REG))])]
17034   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17036 (define_peephole2
17037   [(set (match_operand 0 "register_operand")
17038         (match_operand 1 "register_operand"))
17039    (set (match_dup 0)
17040                    (match_operator 3 "commutative_operator"
17041                      [(match_dup 0)
17042                       (match_operand 2 "memory_operand")]))]
17043   "REGNO (operands[0]) != REGNO (operands[1])
17044    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17045        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17046   [(set (match_dup 0) (match_dup 2))
17047    (set (match_dup 0)
17048         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17050 ; Don't do logical operations with memory outputs
17052 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17053 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17054 ; the same decoder scheduling characteristics as the original.
17056 (define_peephole2
17057   [(match_scratch:SI 2 "r")
17058    (parallel [(set (match_operand:SI 0 "memory_operand")
17059                    (match_operator:SI 3 "arith_or_logical_operator"
17060                      [(match_dup 0)
17061                       (match_operand:SI 1 "nonmemory_operand")]))
17062               (clobber (reg:CC FLAGS_REG))])]
17063   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17064    /* Do not split stack checking probes.  */
17065    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17066   [(set (match_dup 2) (match_dup 0))
17067    (parallel [(set (match_dup 2)
17068                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17069               (clobber (reg:CC FLAGS_REG))])
17070    (set (match_dup 0) (match_dup 2))])
17072 (define_peephole2
17073   [(match_scratch:SI 2 "r")
17074    (parallel [(set (match_operand:SI 0 "memory_operand")
17075                    (match_operator:SI 3 "arith_or_logical_operator"
17076                      [(match_operand:SI 1 "nonmemory_operand")
17077                       (match_dup 0)]))
17078               (clobber (reg:CC FLAGS_REG))])]
17079   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17080    /* Do not split stack checking probes.  */
17081    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17082   [(set (match_dup 2) (match_dup 0))
17083    (parallel [(set (match_dup 2)
17084                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17085               (clobber (reg:CC FLAGS_REG))])
17086    (set (match_dup 0) (match_dup 2))])
17088 ;; Attempt to use arith or logical operations with memory outputs with
17089 ;; setting of flags.
17090 (define_peephole2
17091   [(set (match_operand:SWI 0 "register_operand")
17092         (match_operand:SWI 1 "memory_operand"))
17093    (parallel [(set (match_dup 0)
17094                    (match_operator:SWI 3 "plusminuslogic_operator"
17095                      [(match_dup 0)
17096                       (match_operand:SWI 2 "<nonmemory_operand>")]))
17097               (clobber (reg:CC FLAGS_REG))])
17098    (set (match_dup 1) (match_dup 0))
17099    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17100   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17101    && peep2_reg_dead_p (4, operands[0])
17102    && !reg_overlap_mentioned_p (operands[0], operands[1])
17103    && !reg_overlap_mentioned_p (operands[0], operands[2])
17104    && (<MODE>mode != QImode
17105        || immediate_operand (operands[2], QImode)
17106        || q_regs_operand (operands[2], QImode))
17107    && ix86_match_ccmode (peep2_next_insn (3),
17108                          (GET_CODE (operands[3]) == PLUS
17109                           || GET_CODE (operands[3]) == MINUS)
17110                          ? CCGOCmode : CCNOmode)"
17111   [(parallel [(set (match_dup 4) (match_dup 5))
17112               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17113                                                   (match_dup 2)]))])]
17115   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17116   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17117                                 copy_rtx (operands[1]),
17118                                 copy_rtx (operands[2]));
17119   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17120                                  operands[5], const0_rtx);
17123 (define_peephole2
17124   [(parallel [(set (match_operand:SWI 0 "register_operand")
17125                    (match_operator:SWI 2 "plusminuslogic_operator"
17126                      [(match_dup 0)
17127                       (match_operand:SWI 1 "memory_operand")]))
17128               (clobber (reg:CC FLAGS_REG))])
17129    (set (match_dup 1) (match_dup 0))
17130    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17131   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17132    && GET_CODE (operands[2]) != MINUS
17133    && peep2_reg_dead_p (3, operands[0])
17134    && !reg_overlap_mentioned_p (operands[0], operands[1])
17135    && ix86_match_ccmode (peep2_next_insn (2),
17136                          GET_CODE (operands[2]) == PLUS
17137                          ? CCGOCmode : CCNOmode)"
17138   [(parallel [(set (match_dup 3) (match_dup 4))
17139               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17140                                                   (match_dup 0)]))])]
17142   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17143   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17144                                 copy_rtx (operands[1]),
17145                                 copy_rtx (operands[0]));
17146   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17147                                  operands[4], const0_rtx);
17150 (define_peephole2
17151   [(set (match_operand:SWI12 0 "register_operand")
17152         (match_operand:SWI12 1 "memory_operand"))
17153    (parallel [(set (match_operand:SI 4 "register_operand")
17154                    (match_operator:SI 3 "plusminuslogic_operator"
17155                      [(match_dup 4)
17156                       (match_operand:SI 2 "nonmemory_operand")]))
17157               (clobber (reg:CC FLAGS_REG))])
17158    (set (match_dup 1) (match_dup 0))
17159    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17160   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17161    && REG_P (operands[0]) && REG_P (operands[4])
17162    && REGNO (operands[0]) == REGNO (operands[4])
17163    && peep2_reg_dead_p (4, operands[0])
17164    && (<MODE>mode != QImode
17165        || immediate_operand (operands[2], SImode)
17166        || q_regs_operand (operands[2], SImode))
17167    && !reg_overlap_mentioned_p (operands[0], operands[1])
17168    && !reg_overlap_mentioned_p (operands[0], operands[2])
17169    && ix86_match_ccmode (peep2_next_insn (3),
17170                          (GET_CODE (operands[3]) == PLUS
17171                           || GET_CODE (operands[3]) == MINUS)
17172                          ? CCGOCmode : CCNOmode)"
17173   [(parallel [(set (match_dup 4) (match_dup 5))
17174               (set (match_dup 1) (match_dup 6))])]
17176   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17177   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17178   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17179                                 copy_rtx (operands[1]), operands[2]);
17180   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17181                                  operands[5], const0_rtx);
17182   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17183                                 copy_rtx (operands[1]),
17184                                 copy_rtx (operands[2]));
17187 ;; Attempt to always use XOR for zeroing registers.
17188 (define_peephole2
17189   [(set (match_operand 0 "register_operand")
17190         (match_operand 1 "const0_operand"))]
17191   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17192    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17193    && GENERAL_REG_P (operands[0])
17194    && peep2_regno_dead_p (0, FLAGS_REG)"
17195   [(parallel [(set (match_dup 0) (const_int 0))
17196               (clobber (reg:CC FLAGS_REG))])]
17197   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17199 (define_peephole2
17200   [(set (strict_low_part (match_operand 0 "register_operand"))
17201         (const_int 0))]
17202   "(GET_MODE (operands[0]) == QImode
17203     || GET_MODE (operands[0]) == HImode)
17204    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17205    && peep2_regno_dead_p (0, FLAGS_REG)"
17206   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17207               (clobber (reg:CC FLAGS_REG))])])
17209 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17210 (define_peephole2
17211   [(set (match_operand:SWI248 0 "register_operand")
17212         (const_int -1))]
17213   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17214    && peep2_regno_dead_p (0, FLAGS_REG)"
17215   [(parallel [(set (match_dup 0) (const_int -1))
17216               (clobber (reg:CC FLAGS_REG))])]
17218   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17219     operands[0] = gen_lowpart (SImode, operands[0]);
17222 ;; Attempt to convert simple lea to add/shift.
17223 ;; These can be created by move expanders.
17224 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17225 ;; relevant lea instructions were already split.
17227 (define_peephole2
17228   [(set (match_operand:SWI48 0 "register_operand")
17229         (plus:SWI48 (match_dup 0)
17230                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
17231   "!TARGET_OPT_AGU
17232    && peep2_regno_dead_p (0, FLAGS_REG)"
17233   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17234               (clobber (reg:CC FLAGS_REG))])])
17236 (define_peephole2
17237   [(set (match_operand:SWI48 0 "register_operand")
17238         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17239                     (match_dup 0)))]
17240   "!TARGET_OPT_AGU
17241    && peep2_regno_dead_p (0, FLAGS_REG)"
17242   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17243               (clobber (reg:CC FLAGS_REG))])])
17245 (define_peephole2
17246   [(set (match_operand:DI 0 "register_operand")
17247         (zero_extend:DI
17248           (plus:SI (match_operand:SI 1 "register_operand")
17249                    (match_operand:SI 2 "nonmemory_operand"))))]
17250   "TARGET_64BIT && !TARGET_OPT_AGU
17251    && REGNO (operands[0]) == REGNO (operands[1])
17252    && peep2_regno_dead_p (0, FLAGS_REG)"
17253   [(parallel [(set (match_dup 0)
17254                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17255               (clobber (reg:CC FLAGS_REG))])])
17257 (define_peephole2
17258   [(set (match_operand:DI 0 "register_operand")
17259         (zero_extend:DI
17260           (plus:SI (match_operand:SI 1 "nonmemory_operand")
17261                    (match_operand:SI 2 "register_operand"))))]
17262   "TARGET_64BIT && !TARGET_OPT_AGU
17263    && REGNO (operands[0]) == REGNO (operands[2])
17264    && peep2_regno_dead_p (0, FLAGS_REG)"
17265   [(parallel [(set (match_dup 0)
17266                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17267               (clobber (reg:CC FLAGS_REG))])])
17269 (define_peephole2
17270   [(set (match_operand:SWI48 0 "register_operand")
17271         (mult:SWI48 (match_dup 0)
17272                     (match_operand:SWI48 1 "const_int_operand")))]
17273   "exact_log2 (INTVAL (operands[1])) >= 0
17274    && peep2_regno_dead_p (0, FLAGS_REG)"
17275   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17276               (clobber (reg:CC FLAGS_REG))])]
17277   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17279 (define_peephole2
17280   [(set (match_operand:DI 0 "register_operand")
17281         (zero_extend:DI
17282           (mult:SI (match_operand:SI 1 "register_operand")
17283                    (match_operand:SI 2 "const_int_operand"))))]
17284   "TARGET_64BIT
17285    && exact_log2 (INTVAL (operands[2])) >= 0
17286    && REGNO (operands[0]) == REGNO (operands[1])
17287    && peep2_regno_dead_p (0, FLAGS_REG)"
17288   [(parallel [(set (match_dup 0)
17289                    (zero_extend (ashift:SI (match_dup 1) (match_dup 2))))
17290               (clobber (reg:CC FLAGS_REG))])]
17291   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17293 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17294 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17295 ;; On many CPUs it is also faster, since special hardware to avoid esp
17296 ;; dependencies is present.
17298 ;; While some of these conversions may be done using splitters, we use
17299 ;; peepholes in order to allow combine_stack_adjustments pass to see
17300 ;; nonobfuscated RTL.
17302 ;; Convert prologue esp subtractions to push.
17303 ;; We need register to push.  In order to keep verify_flow_info happy we have
17304 ;; two choices
17305 ;; - use scratch and clobber it in order to avoid dependencies
17306 ;; - use already live register
17307 ;; We can't use the second way right now, since there is no reliable way how to
17308 ;; verify that given register is live.  First choice will also most likely in
17309 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17310 ;; call clobbered registers are dead.  We may want to use base pointer as an
17311 ;; alternative when no register is available later.
17313 (define_peephole2
17314   [(match_scratch:W 1 "r")
17315    (parallel [(set (reg:P SP_REG)
17316                    (plus:P (reg:P SP_REG)
17317                            (match_operand:P 0 "const_int_operand")))
17318               (clobber (reg:CC FLAGS_REG))
17319               (clobber (mem:BLK (scratch)))])]
17320   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17321    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17322   [(clobber (match_dup 1))
17323    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17324               (clobber (mem:BLK (scratch)))])])
17326 (define_peephole2
17327   [(match_scratch:W 1 "r")
17328    (parallel [(set (reg:P SP_REG)
17329                    (plus:P (reg:P SP_REG)
17330                            (match_operand:P 0 "const_int_operand")))
17331               (clobber (reg:CC FLAGS_REG))
17332               (clobber (mem:BLK (scratch)))])]
17333   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17334    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17335   [(clobber (match_dup 1))
17336    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17337    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17338               (clobber (mem:BLK (scratch)))])])
17340 ;; Convert esp subtractions to push.
17341 (define_peephole2
17342   [(match_scratch:W 1 "r")
17343    (parallel [(set (reg:P SP_REG)
17344                    (plus:P (reg:P SP_REG)
17345                            (match_operand:P 0 "const_int_operand")))
17346               (clobber (reg:CC FLAGS_REG))])]
17347   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17348    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17349   [(clobber (match_dup 1))
17350    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17352 (define_peephole2
17353   [(match_scratch:W 1 "r")
17354    (parallel [(set (reg:P SP_REG)
17355                    (plus:P (reg:P SP_REG)
17356                            (match_operand:P 0 "const_int_operand")))
17357               (clobber (reg:CC FLAGS_REG))])]
17358   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17359    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17360   [(clobber (match_dup 1))
17361    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17362    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17364 ;; Convert epilogue deallocator to pop.
17365 (define_peephole2
17366   [(match_scratch:W 1 "r")
17367    (parallel [(set (reg:P SP_REG)
17368                    (plus:P (reg:P SP_REG)
17369                            (match_operand:P 0 "const_int_operand")))
17370               (clobber (reg:CC FLAGS_REG))
17371               (clobber (mem:BLK (scratch)))])]
17372   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17373    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17374   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17375               (clobber (mem:BLK (scratch)))])])
17377 ;; Two pops case is tricky, since pop causes dependency
17378 ;; on destination register.  We use two registers if available.
17379 (define_peephole2
17380   [(match_scratch:W 1 "r")
17381    (match_scratch:W 2 "r")
17382    (parallel [(set (reg:P SP_REG)
17383                    (plus:P (reg:P SP_REG)
17384                            (match_operand:P 0 "const_int_operand")))
17385               (clobber (reg:CC FLAGS_REG))
17386               (clobber (mem:BLK (scratch)))])]
17387   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17388    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17389   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17390               (clobber (mem:BLK (scratch)))])
17391    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17393 (define_peephole2
17394   [(match_scratch:W 1 "r")
17395    (parallel [(set (reg:P SP_REG)
17396                    (plus:P (reg:P SP_REG)
17397                            (match_operand:P 0 "const_int_operand")))
17398               (clobber (reg:CC FLAGS_REG))
17399               (clobber (mem:BLK (scratch)))])]
17400   "optimize_insn_for_size_p ()
17401    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17402   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17403               (clobber (mem:BLK (scratch)))])
17404    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17406 ;; Convert esp additions to pop.
17407 (define_peephole2
17408   [(match_scratch:W 1 "r")
17409    (parallel [(set (reg:P SP_REG)
17410                    (plus:P (reg:P SP_REG)
17411                            (match_operand:P 0 "const_int_operand")))
17412               (clobber (reg:CC FLAGS_REG))])]
17413   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17414   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17416 ;; Two pops case is tricky, since pop causes dependency
17417 ;; on destination register.  We use two registers if available.
17418 (define_peephole2
17419   [(match_scratch:W 1 "r")
17420    (match_scratch:W 2 "r")
17421    (parallel [(set (reg:P SP_REG)
17422                    (plus:P (reg:P SP_REG)
17423                            (match_operand:P 0 "const_int_operand")))
17424               (clobber (reg:CC FLAGS_REG))])]
17425   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17426   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17427    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17429 (define_peephole2
17430   [(match_scratch:W 1 "r")
17431    (parallel [(set (reg:P SP_REG)
17432                    (plus:P (reg:P SP_REG)
17433                            (match_operand:P 0 "const_int_operand")))
17434               (clobber (reg:CC FLAGS_REG))])]
17435   "optimize_insn_for_size_p ()
17436    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17437   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17438    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17440 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17441 ;; required and register dies.  Similarly for 128 to -128.
17442 (define_peephole2
17443   [(set (match_operand 0 "flags_reg_operand")
17444         (match_operator 1 "compare_operator"
17445           [(match_operand 2 "register_operand")
17446            (match_operand 3 "const_int_operand")]))]
17447   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17448      && incdec_operand (operands[3], GET_MODE (operands[3])))
17449     || (!TARGET_FUSE_CMP_AND_BRANCH
17450         && INTVAL (operands[3]) == 128))
17451    && ix86_match_ccmode (insn, CCGCmode)
17452    && peep2_reg_dead_p (1, operands[2])"
17453   [(parallel [(set (match_dup 0)
17454                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17455               (clobber (match_dup 2))])])
17457 ;; Convert imul by three, five and nine into lea
17458 (define_peephole2
17459   [(parallel
17460     [(set (match_operand:SWI48 0 "register_operand")
17461           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17462                       (match_operand:SWI48 2 "const359_operand")))
17463      (clobber (reg:CC FLAGS_REG))])]
17464   "!TARGET_PARTIAL_REG_STALL
17465    || <MODE>mode == SImode
17466    || optimize_function_for_size_p (cfun)"
17467   [(set (match_dup 0)
17468         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17469                     (match_dup 1)))]
17470   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17472 (define_peephole2
17473   [(parallel
17474     [(set (match_operand:SWI48 0 "register_operand")
17475           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17476                       (match_operand:SWI48 2 "const359_operand")))
17477      (clobber (reg:CC FLAGS_REG))])]
17478   "optimize_insn_for_speed_p ()
17479    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17480   [(set (match_dup 0) (match_dup 1))
17481    (set (match_dup 0)
17482         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17483                     (match_dup 0)))]
17484   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17486 ;; imul $32bit_imm, mem, reg is vector decoded, while
17487 ;; imul $32bit_imm, reg, reg is direct decoded.
17488 (define_peephole2
17489   [(match_scratch:SWI48 3 "r")
17490    (parallel [(set (match_operand:SWI48 0 "register_operand")
17491                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17492                                (match_operand:SWI48 2 "immediate_operand")))
17493               (clobber (reg:CC FLAGS_REG))])]
17494   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17495    && !satisfies_constraint_K (operands[2])"
17496   [(set (match_dup 3) (match_dup 1))
17497    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17498               (clobber (reg:CC FLAGS_REG))])])
17500 (define_peephole2
17501   [(match_scratch:SI 3 "r")
17502    (parallel [(set (match_operand:DI 0 "register_operand")
17503                    (zero_extend:DI
17504                      (mult:SI (match_operand:SI 1 "memory_operand")
17505                               (match_operand:SI 2 "immediate_operand"))))
17506               (clobber (reg:CC FLAGS_REG))])]
17507   "TARGET_64BIT
17508    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17509    && !satisfies_constraint_K (operands[2])"
17510   [(set (match_dup 3) (match_dup 1))
17511    (parallel [(set (match_dup 0)
17512                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17513               (clobber (reg:CC FLAGS_REG))])])
17515 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17516 ;; Convert it into imul reg, reg
17517 ;; It would be better to force assembler to encode instruction using long
17518 ;; immediate, but there is apparently no way to do so.
17519 (define_peephole2
17520   [(parallel [(set (match_operand:SWI248 0 "register_operand")
17521                    (mult:SWI248
17522                     (match_operand:SWI248 1 "nonimmediate_operand")
17523                     (match_operand:SWI248 2 "const_int_operand")))
17524               (clobber (reg:CC FLAGS_REG))])
17525    (match_scratch:SWI248 3 "r")]
17526   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17527    && satisfies_constraint_K (operands[2])"
17528   [(set (match_dup 3) (match_dup 2))
17529    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17530               (clobber (reg:CC FLAGS_REG))])]
17532   if (!rtx_equal_p (operands[0], operands[1]))
17533     emit_move_insn (operands[0], operands[1]);
17536 ;; After splitting up read-modify operations, array accesses with memory
17537 ;; operands might end up in form:
17538 ;;  sall    $2, %eax
17539 ;;  movl    4(%esp), %edx
17540 ;;  addl    %edx, %eax
17541 ;; instead of pre-splitting:
17542 ;;  sall    $2, %eax
17543 ;;  addl    4(%esp), %eax
17544 ;; Turn it into:
17545 ;;  movl    4(%esp), %edx
17546 ;;  leal    (%edx,%eax,4), %eax
17548 (define_peephole2
17549   [(match_scratch:W 5 "r")
17550    (parallel [(set (match_operand 0 "register_operand")
17551                    (ashift (match_operand 1 "register_operand")
17552                            (match_operand 2 "const_int_operand")))
17553                (clobber (reg:CC FLAGS_REG))])
17554    (parallel [(set (match_operand 3 "register_operand")
17555                    (plus (match_dup 0)
17556                          (match_operand 4 "x86_64_general_operand")))
17557                    (clobber (reg:CC FLAGS_REG))])]
17558   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17559    /* Validate MODE for lea.  */
17560    && ((!TARGET_PARTIAL_REG_STALL
17561         && (GET_MODE (operands[0]) == QImode
17562             || GET_MODE (operands[0]) == HImode))
17563        || GET_MODE (operands[0]) == SImode
17564        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17565    && (rtx_equal_p (operands[0], operands[3])
17566        || peep2_reg_dead_p (2, operands[0]))
17567    /* We reorder load and the shift.  */
17568    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17569   [(set (match_dup 5) (match_dup 4))
17570    (set (match_dup 0) (match_dup 1))]
17572   enum machine_mode op1mode = GET_MODE (operands[1]);
17573   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17574   int scale = 1 << INTVAL (operands[2]);
17575   rtx index = gen_lowpart (word_mode, operands[1]);
17576   rtx base = gen_lowpart (word_mode, operands[5]);
17577   rtx dest = gen_lowpart (mode, operands[3]);
17579   operands[1] = gen_rtx_PLUS (word_mode, base,
17580                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17581   operands[5] = base;
17582   if (mode != word_mode)
17583     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17584   if (op1mode != word_mode)
17585     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17586   operands[0] = dest;
17589 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17590 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17591 ;; caught for use by garbage collectors and the like.  Using an insn that
17592 ;; maps to SIGILL makes it more likely the program will rightfully die.
17593 ;; Keeping with tradition, "6" is in honor of #UD.
17594 (define_insn "trap"
17595   [(trap_if (const_int 1) (const_int 6))]
17596   ""
17597   { return ASM_SHORT "0x0b0f"; }
17598   [(set_attr "length" "2")])
17600 (define_expand "prefetch"
17601   [(prefetch (match_operand 0 "address_operand")
17602              (match_operand:SI 1 "const_int_operand")
17603              (match_operand:SI 2 "const_int_operand"))]
17604   "TARGET_PREFETCH_SSE || TARGET_PRFCHW"
17606   bool write = INTVAL (operands[1]) != 0;
17607   int locality = INTVAL (operands[2]);
17609   gcc_assert (IN_RANGE (locality, 0, 3));
17611   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17612      supported by SSE counterpart or the SSE prefetch is not available
17613      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17614      of locality.  */
17615   if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17616     operands[2] = GEN_INT (3);
17617   else
17618     operands[1] = const0_rtx;
17621 (define_insn "*prefetch_sse"
17622   [(prefetch (match_operand 0 "address_operand" "p")
17623              (const_int 0)
17624              (match_operand:SI 1 "const_int_operand"))]
17625   "TARGET_PREFETCH_SSE"
17627   static const char * const patterns[4] = {
17628    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17629   };
17631   int locality = INTVAL (operands[1]);
17632   gcc_assert (IN_RANGE (locality, 0, 3));
17634   return patterns[locality];
17636   [(set_attr "type" "sse")
17637    (set_attr "atom_sse_attr" "prefetch")
17638    (set (attr "length_address")
17639         (symbol_ref "memory_address_length (operands[0], false)"))
17640    (set_attr "memory" "none")])
17642 (define_insn "*prefetch_3dnow"
17643   [(prefetch (match_operand 0 "address_operand" "p")
17644              (match_operand:SI 1 "const_int_operand" "n")
17645              (const_int 3))]
17646   "TARGET_PRFCHW"
17648   if (INTVAL (operands[1]) == 0)
17649     return "prefetch\t%a0";
17650   else
17651     return "prefetchw\t%a0";
17653   [(set_attr "type" "mmx")
17654    (set (attr "length_address")
17655         (symbol_ref "memory_address_length (operands[0], false)"))
17656    (set_attr "memory" "none")])
17658 (define_expand "stack_protect_set"
17659   [(match_operand 0 "memory_operand")
17660    (match_operand 1 "memory_operand")]
17661   "!TARGET_HAS_BIONIC"
17663   rtx (*insn)(rtx, rtx);
17665 #ifdef TARGET_THREAD_SSP_OFFSET
17666   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17667   insn = (TARGET_LP64
17668           ? gen_stack_tls_protect_set_di
17669           : gen_stack_tls_protect_set_si);
17670 #else
17671   insn = (TARGET_LP64
17672           ? gen_stack_protect_set_di
17673           : gen_stack_protect_set_si);
17674 #endif
17676   emit_insn (insn (operands[0], operands[1]));
17677   DONE;
17680 (define_insn "stack_protect_set_<mode>"
17681   [(set (match_operand:PTR 0 "memory_operand" "=m")
17682         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17683                     UNSPEC_SP_SET))
17684    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17685    (clobber (reg:CC FLAGS_REG))]
17686   "!TARGET_HAS_BIONIC"
17687   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17688   [(set_attr "type" "multi")])
17690 (define_insn "stack_tls_protect_set_<mode>"
17691   [(set (match_operand:PTR 0 "memory_operand" "=m")
17692         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17693                     UNSPEC_SP_TLS_SET))
17694    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17695    (clobber (reg:CC FLAGS_REG))]
17696   ""
17697   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17698   [(set_attr "type" "multi")])
17700 (define_expand "stack_protect_test"
17701   [(match_operand 0 "memory_operand")
17702    (match_operand 1 "memory_operand")
17703    (match_operand 2)]
17704   "!TARGET_HAS_BIONIC"
17706   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17708   rtx (*insn)(rtx, rtx, rtx);
17710 #ifdef TARGET_THREAD_SSP_OFFSET
17711   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17712   insn = (TARGET_LP64
17713           ? gen_stack_tls_protect_test_di
17714           : gen_stack_tls_protect_test_si);
17715 #else
17716   insn = (TARGET_LP64
17717           ? gen_stack_protect_test_di
17718           : gen_stack_protect_test_si);
17719 #endif
17721   emit_insn (insn (flags, operands[0], operands[1]));
17723   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17724                                   flags, const0_rtx, operands[2]));
17725   DONE;
17728 (define_insn "stack_protect_test_<mode>"
17729   [(set (match_operand:CCZ 0 "flags_reg_operand")
17730         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17731                      (match_operand:PTR 2 "memory_operand" "m")]
17732                     UNSPEC_SP_TEST))
17733    (clobber (match_scratch:PTR 3 "=&r"))]
17734   "!TARGET_HAS_BIONIC"
17735   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17736   [(set_attr "type" "multi")])
17738 (define_insn "stack_tls_protect_test_<mode>"
17739   [(set (match_operand:CCZ 0 "flags_reg_operand")
17740         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17741                      (match_operand:PTR 2 "const_int_operand" "i")]
17742                     UNSPEC_SP_TLS_TEST))
17743    (clobber (match_scratch:PTR 3 "=r"))]
17744   ""
17745   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17746   [(set_attr "type" "multi")])
17748 (define_insn "sse4_2_crc32<mode>"
17749   [(set (match_operand:SI 0 "register_operand" "=r")
17750         (unspec:SI
17751           [(match_operand:SI 1 "register_operand" "0")
17752            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17753           UNSPEC_CRC32))]
17754   "TARGET_SSE4_2 || TARGET_CRC32"
17755   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17756   [(set_attr "type" "sselog1")
17757    (set_attr "prefix_rep" "1")
17758    (set_attr "prefix_extra" "1")
17759    (set (attr "prefix_data16")
17760      (if_then_else (match_operand:HI 2)
17761        (const_string "1")
17762        (const_string "*")))
17763    (set (attr "prefix_rex")
17764      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17765        (const_string "1")
17766        (const_string "*")))
17767    (set_attr "mode" "SI")])
17769 (define_insn "sse4_2_crc32di"
17770   [(set (match_operand:DI 0 "register_operand" "=r")
17771         (unspec:DI
17772           [(match_operand:DI 1 "register_operand" "0")
17773            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17774           UNSPEC_CRC32))]
17775   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17776   "crc32{q}\t{%2, %0|%0, %2}"
17777   [(set_attr "type" "sselog1")
17778    (set_attr "prefix_rep" "1")
17779    (set_attr "prefix_extra" "1")
17780    (set_attr "mode" "DI")])
17782 (define_insn "rdpmc"
17783   [(set (match_operand:DI 0 "register_operand" "=A")
17784         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17785                             UNSPECV_RDPMC))]
17786   "!TARGET_64BIT"
17787   "rdpmc"
17788   [(set_attr "type" "other")
17789    (set_attr "length" "2")])
17791 (define_insn "rdpmc_rex64"
17792   [(set (match_operand:DI 0 "register_operand" "=a")
17793         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17794                             UNSPECV_RDPMC))
17795    (set (match_operand:DI 1 "register_operand" "=d")
17796         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
17797   "TARGET_64BIT"
17798   "rdpmc"
17799   [(set_attr "type" "other")
17800    (set_attr "length" "2")])
17802 (define_insn "rdtsc"
17803   [(set (match_operand:DI 0 "register_operand" "=A")
17804         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17805   "!TARGET_64BIT"
17806   "rdtsc"
17807   [(set_attr "type" "other")
17808    (set_attr "length" "2")])
17810 (define_insn "rdtsc_rex64"
17811   [(set (match_operand:DI 0 "register_operand" "=a")
17812         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17813    (set (match_operand:DI 1 "register_operand" "=d")
17814         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17815   "TARGET_64BIT"
17816   "rdtsc"
17817   [(set_attr "type" "other")
17818    (set_attr "length" "2")])
17820 (define_insn "rdtscp"
17821   [(set (match_operand:DI 0 "register_operand" "=A")
17822         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17823    (set (match_operand:SI 1 "register_operand" "=c")
17824         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17825   "!TARGET_64BIT"
17826   "rdtscp"
17827   [(set_attr "type" "other")
17828    (set_attr "length" "3")])
17830 (define_insn "rdtscp_rex64"
17831   [(set (match_operand:DI 0 "register_operand" "=a")
17832         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17833    (set (match_operand:DI 1 "register_operand" "=d")
17834         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17835    (set (match_operand:SI 2 "register_operand" "=c")
17836         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17837   "TARGET_64BIT"
17838   "rdtscp"
17839   [(set_attr "type" "other")
17840    (set_attr "length" "3")])
17842 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17844 ;; FXSR, XSAVE and XSAVEOPT instructions
17846 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17848 (define_insn "fxsave"
17849   [(set (match_operand:BLK 0 "memory_operand" "=m")
17850         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
17851   "TARGET_FXSR"
17852   "fxsave\t%0"
17853   [(set_attr "type" "other")
17854    (set_attr "memory" "store")
17855    (set (attr "length")
17856         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17858 (define_insn "fxsave64"
17859   [(set (match_operand:BLK 0 "memory_operand" "=m")
17860         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
17861   "TARGET_64BIT && TARGET_FXSR"
17862   "fxsave64\t%0"
17863   [(set_attr "type" "other")
17864    (set_attr "memory" "store")
17865    (set (attr "length")
17866         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17868 (define_insn "fxrstor"
17869   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17870                     UNSPECV_FXRSTOR)]
17871   "TARGET_FXSR"
17872   "fxrstor\t%0"
17873   [(set_attr "type" "other")
17874    (set_attr "memory" "load")
17875    (set (attr "length")
17876         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17878 (define_insn "fxrstor64"
17879   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17880                     UNSPECV_FXRSTOR64)]
17881   "TARGET_64BIT && TARGET_FXSR"
17882   "fxrstor64\t%0"
17883   [(set_attr "type" "other")
17884    (set_attr "memory" "load")
17885    (set (attr "length")
17886         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17888 (define_int_iterator ANY_XSAVE
17889         [UNSPECV_XSAVE
17890          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")])
17892 (define_int_iterator ANY_XSAVE64
17893         [UNSPECV_XSAVE64
17894          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")])
17896 (define_int_attr xsave
17897         [(UNSPECV_XSAVE "xsave")
17898          (UNSPECV_XSAVE64 "xsave64")
17899          (UNSPECV_XSAVEOPT "xsaveopt")
17900          (UNSPECV_XSAVEOPT64 "xsaveopt64")])
17902 (define_insn "<xsave>"
17903   [(set (match_operand:BLK 0 "memory_operand" "=m")
17904         (unspec_volatile:BLK
17905          [(match_operand:DI 1 "register_operand" "A")]
17906          ANY_XSAVE))]
17907   "!TARGET_64BIT && TARGET_XSAVE"
17908   "<xsave>\t%0"
17909   [(set_attr "type" "other")
17910    (set_attr "memory" "store")
17911    (set (attr "length")
17912         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17914 (define_insn "<xsave>_rex64"
17915   [(set (match_operand:BLK 0 "memory_operand" "=m")
17916         (unspec_volatile:BLK
17917          [(match_operand:SI 1 "register_operand" "a")
17918           (match_operand:SI 2 "register_operand" "d")]
17919          ANY_XSAVE))]
17920   "TARGET_64BIT && TARGET_XSAVE"
17921   "<xsave>\t%0"
17922   [(set_attr "type" "other")
17923    (set_attr "memory" "store")
17924    (set (attr "length")
17925         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17927 (define_insn "<xsave>"
17928   [(set (match_operand:BLK 0 "memory_operand" "=m")
17929         (unspec_volatile:BLK
17930          [(match_operand:SI 1 "register_operand" "a")
17931           (match_operand:SI 2 "register_operand" "d")]
17932          ANY_XSAVE64))]
17933   "TARGET_64BIT && TARGET_XSAVE"
17934   "<xsave>\t%0"
17935   [(set_attr "type" "other")
17936    (set_attr "memory" "store")
17937    (set (attr "length")
17938         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17940 (define_insn "xrstor"
17941    [(unspec_volatile:BLK
17942      [(match_operand:BLK 0 "memory_operand" "m")
17943       (match_operand:DI 1 "register_operand" "A")]
17944      UNSPECV_XRSTOR)]
17945   "!TARGET_64BIT && TARGET_XSAVE"
17946   "xrstor\t%0"
17947   [(set_attr "type" "other")
17948    (set_attr "memory" "load")
17949    (set (attr "length")
17950         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17952 (define_insn "xrstor_rex64"
17953    [(unspec_volatile:BLK
17954      [(match_operand:BLK 0 "memory_operand" "m")
17955       (match_operand:SI 1 "register_operand" "a")
17956       (match_operand:SI 2 "register_operand" "d")]
17957      UNSPECV_XRSTOR)]
17958   "TARGET_64BIT && TARGET_XSAVE"
17959   "xrstor\t%0"
17960   [(set_attr "type" "other")
17961    (set_attr "memory" "load")
17962    (set (attr "length")
17963         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17965 (define_insn "xrstor64"
17966    [(unspec_volatile:BLK
17967      [(match_operand:BLK 0 "memory_operand" "m")
17968       (match_operand:SI 1 "register_operand" "a")
17969       (match_operand:SI 2 "register_operand" "d")]
17970      UNSPECV_XRSTOR64)]
17971   "TARGET_64BIT && TARGET_XSAVE"
17972   "xrstor64\t%0"
17973   [(set_attr "type" "other")
17974    (set_attr "memory" "load")
17975    (set (attr "length")
17976         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17978 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17980 ;; LWP instructions
17982 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17984 (define_expand "lwp_llwpcb"
17985   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17986                     UNSPECV_LLWP_INTRINSIC)]
17987   "TARGET_LWP")
17989 (define_insn "*lwp_llwpcb<mode>1"
17990   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17991                     UNSPECV_LLWP_INTRINSIC)]
17992   "TARGET_LWP"
17993   "llwpcb\t%0"
17994   [(set_attr "type" "lwp")
17995    (set_attr "mode" "<MODE>")
17996    (set_attr "length" "5")])
17998 (define_expand "lwp_slwpcb"
17999   [(set (match_operand 0 "register_operand" "=r")
18000         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18001   "TARGET_LWP"
18003   rtx (*insn)(rtx);
18005   insn = (Pmode == DImode
18006           ? gen_lwp_slwpcbdi
18007           : gen_lwp_slwpcbsi);
18009   emit_insn (insn (operands[0]));
18010   DONE;
18013 (define_insn "lwp_slwpcb<mode>"
18014   [(set (match_operand:P 0 "register_operand" "=r")
18015         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18016   "TARGET_LWP"
18017   "slwpcb\t%0"
18018   [(set_attr "type" "lwp")
18019    (set_attr "mode" "<MODE>")
18020    (set_attr "length" "5")])
18022 (define_expand "lwp_lwpval<mode>3"
18023   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18024                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18025                      (match_operand:SI 3 "const_int_operand" "i")]
18026                     UNSPECV_LWPVAL_INTRINSIC)]
18027   "TARGET_LWP"
18028   ;; Avoid unused variable warning.
18029   "(void) operands[0];")
18031 (define_insn "*lwp_lwpval<mode>3_1"
18032   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18033                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18034                      (match_operand:SI 2 "const_int_operand" "i")]
18035                     UNSPECV_LWPVAL_INTRINSIC)]
18036   "TARGET_LWP"
18037   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18038   [(set_attr "type" "lwp")
18039    (set_attr "mode" "<MODE>")
18040    (set (attr "length")
18041         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18043 (define_expand "lwp_lwpins<mode>3"
18044   [(set (reg:CCC FLAGS_REG)
18045         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18046                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18047                               (match_operand:SI 3 "const_int_operand" "i")]
18048                              UNSPECV_LWPINS_INTRINSIC))
18049    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18050         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18051   "TARGET_LWP")
18053 (define_insn "*lwp_lwpins<mode>3_1"
18054   [(set (reg:CCC FLAGS_REG)
18055         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18056                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18057                               (match_operand:SI 2 "const_int_operand" "i")]
18058                              UNSPECV_LWPINS_INTRINSIC))]
18059   "TARGET_LWP"
18060   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18061   [(set_attr "type" "lwp")
18062    (set_attr "mode" "<MODE>")
18063    (set (attr "length")
18064         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18066 (define_int_iterator RDFSGSBASE
18067         [UNSPECV_RDFSBASE
18068          UNSPECV_RDGSBASE])
18070 (define_int_iterator WRFSGSBASE
18071         [UNSPECV_WRFSBASE
18072          UNSPECV_WRGSBASE])
18074 (define_int_attr fsgs
18075         [(UNSPECV_RDFSBASE "fs")
18076          (UNSPECV_RDGSBASE "gs")
18077          (UNSPECV_WRFSBASE "fs")
18078          (UNSPECV_WRGSBASE "gs")])
18080 (define_insn "rd<fsgs>base<mode>"
18081   [(set (match_operand:SWI48 0 "register_operand" "=r")
18082         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18083   "TARGET_64BIT && TARGET_FSGSBASE"
18084   "rd<fsgs>base\t%0"
18085   [(set_attr "type" "other")
18086    (set_attr "prefix_extra" "2")])
18088 (define_insn "wr<fsgs>base<mode>"
18089   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18090                     WRFSGSBASE)]
18091   "TARGET_64BIT && TARGET_FSGSBASE"
18092   "wr<fsgs>base\t%0"
18093   [(set_attr "type" "other")
18094    (set_attr "prefix_extra" "2")])
18096 (define_insn "rdrand<mode>_1"
18097   [(set (match_operand:SWI248 0 "register_operand" "=r")
18098         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18099    (set (reg:CCC FLAGS_REG)
18100         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18101   "TARGET_RDRND"
18102   "rdrand\t%0"
18103   [(set_attr "type" "other")
18104    (set_attr "prefix_extra" "1")])
18106 (define_insn "rdseed<mode>_1"
18107   [(set (match_operand:SWI248 0 "register_operand" "=r")
18108         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18109    (set (reg:CCC FLAGS_REG)
18110         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18111   "TARGET_RDSEED"
18112   "rdseed\t%0"
18113   [(set_attr "type" "other")
18114    (set_attr "prefix_extra" "1")])
18116 (define_expand "pause"
18117   [(set (match_dup 0)
18118         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18119   ""
18121   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18122   MEM_VOLATILE_P (operands[0]) = 1;
18125 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18126 ;; They have the same encoding.
18127 (define_insn "*pause"
18128   [(set (match_operand:BLK 0)
18129         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18130   ""
18131   "rep%; nop"
18132   [(set_attr "length" "2")
18133    (set_attr "memory" "unknown")])
18135 (define_expand "xbegin"
18136   [(set (match_operand:SI 0 "register_operand")
18137         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18138   "TARGET_RTM"
18140   rtx label = gen_label_rtx ();
18142   /* xbegin is emitted as jump_insn, so reload won't be able
18143      to reload its operand.  Force the value into AX hard register.  */
18144   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18145   emit_move_insn (ax_reg, constm1_rtx);
18147   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18149   emit_label (label);
18150   LABEL_NUSES (label) = 1;
18152   emit_move_insn (operands[0], ax_reg);
18154   DONE;
18157 (define_insn "xbegin_1"
18158   [(set (pc)
18159         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18160                           (const_int 0))
18161                       (label_ref (match_operand 1))
18162                       (pc)))
18163    (set (match_operand:SI 0 "register_operand" "+a")
18164         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18165   "TARGET_RTM"
18166   "xbegin\t%l1"
18167   [(set_attr "type" "other")
18168    (set_attr "length" "6")])
18170 (define_insn "xend"
18171   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18172   "TARGET_RTM"
18173   "xend"
18174   [(set_attr "type" "other")
18175    (set_attr "length" "3")])
18177 (define_insn "xabort"
18178   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18179                     UNSPECV_XABORT)]
18180   "TARGET_RTM"
18181   "xabort\t%0"
18182   [(set_attr "type" "other")
18183    (set_attr "length" "3")])
18185 (define_expand "xtest"
18186   [(set (match_operand:QI 0 "register_operand")
18187         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18188   "TARGET_RTM"
18190   emit_insn (gen_xtest_1 ());
18192   ix86_expand_setcc (operands[0], NE,
18193                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18194   DONE;
18197 (define_insn "xtest_1"
18198   [(set (reg:CCZ FLAGS_REG)
18199         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18200   "TARGET_RTM"
18201   "xtest"
18202   [(set_attr "type" "other")
18203    (set_attr "length" "3")])
18205 (include "mmx.md")
18206 (include "sse.md")
18207 (include "sync.md")